🎭 Theater & Live Performance · design exchange

SceneSwap Marketplace

Trade and license scene and set designs through a verified onchain marketplace.

Flow EVM smart contract· onchain logic
Section · Onchain

The primitive.

full primer →

Design exchange gets a tiny Solidity contract deployed to Flow EVM Testnet; directors see a 'verified onchain' badge with the live contract address and a one-tap Flowscan link.

Why this primitiveFlow EVM Testnet smart contracts securely facilitate ownership transfer and licensing payments.

Kernel
a Solidity contract deployed to Flow EVM Testnet (chainId 545) via Hardhat, then verified on Flowscan (Blockscout)
Drives the UI as
a 'verified onchain' badge with the live contract address and a Flowscan link
Appendix · Secrets

Required keys.

FLOW_EVM_PRIVATE_KEY
Hardhat deployer key. Fund it (free) on Flow EVM Testnet via the faucet.
open ↗
PRIVY_APP_ID
Enables Google sign-in and an embedded wallet (user pays fractional-cent FLOW gas).
open ↗
PINATA_JWT
Pins images / JSON / manifests to IPFS.
open ↗
FLOW_EVM_RPC_URL
Optional. Defaults to the public Flow EVM RPC.
open ↗

Add these in your Lovable project under Settings → Secrets before pasting the prompt below.

Appendix · Mega-prompt

The build prompt.

Paste into a fresh Lovable project. Make sure all five secrets above are set first. read the build strategy →

Build "SceneSwap Marketplace" in ONE Lovable message. Single-page demo.

CONCEPT
Trade and license scene and set designs through a verified onchain marketplace.
Discipline: Theater & Live Performance (design exchange).
Onchain primitive: Flow EVM smart contract. Why this primitive: Flow EVM Testnet smart contracts securely facilitate ownership transfer and licensing payments.

5-CREDIT BUDGET (HARD LIMIT):
- ONE single-page app. No router, no Lovable Cloud, no database, no auth flows beyond Privy drop-in.
- ONE Solidity contract, <=80 lines, deployed to Flow EVM Testnet (chainId 545), verified on Flowscan (Blockscout).
- Privy is the auth layer (Google login, embedded wallet). USER PAYS GAS from the embedded wallet — Flow testnet gas is fractional cents.
- Pinata/IPFS only if the idea genuinely needs to store a file or metadata.
- At most ONE AI call per user action (use Lovable AI Gateway with LOVABLE_API_KEY if AI is part of the idea).
- Skip tests, skip CI, skip docs pages. Ship the demo, nothing else.

STACK
- React + Vite single page (the index route).
- Chain: Flow EVM Testnet — chainId 545, RPC https://testnet.evm.nodes.onflow.org,
  explorer https://testnet.flowscan.io/evm. Define it in src/lib/flow-chain.ts via
  viem's `defineChain({ id:545, name:'Flow EVM Testnet',
    nativeCurrency:{ name:'Flow', symbol:'FLOW', decimals:18 },
    rpcUrls:{ default:{ http:['https://testnet.evm.nodes.onflow.org'] } },
    blockExplorers:{ default:{ name:'Flowscan', url:'https://testnet.flowscan.io/evm' } } })`.
  Never stub the chain as a bare `{ id, name }` object anywhere — Privy requires a full viem chain.
- SSR-safe Privy mount is mandatory. Never import @privy-io/react-auth at
  module scope of a route file — it crashes SSR. Use
  lazy(() => import('./privy-client-entry')) inside <ClientOnly> + <Suspense>,
  and put <PrivyProvider> only inside privy-client-entry.tsx.
- PrivyProvider config (pass the viem `flowEvmTestnet` chain — do NOT stub as {id,name}):
    <PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
      config={{ loginMethods:['google','email'],
                embeddedWallets:{ ethereum:{ createOnLogin:'users-without-wallets' } },
                appearance:{ theme:'dark' },
                supportedChains:[flowEvmTestnet],
                defaultChain: flowEvmTestnet }}>
- Read the embedded wallet from useWallets, not user.wallet:
    const embedded = wallets.find(w => w.walletClientType === 'privy');
- Every send goes through Privy `useSendTransaction` with `address` ONLY.
  DO NOT PASS `sponsor: true` — ZeroDev and native Privy gas sponsorship do
  NOT cover Flow EVM. The user's embedded wallet pays the gas directly
  (fractional-cent testnet FLOW). Wrap in a 45s Promise.race timeout that
  tells the user to fund the wallet from the faucet:
    await Promise.race([
      sendTransaction(
        { to, data, chainId: 545 },
        { address: embedded.address }
      ),
      new Promise((_, r) => setTimeout(() => r(new Error(
        "Transaction timed out after 45s. Fund your embedded wallet with testnet FLOW at https://testnet-faucet.onflow.org."
      )), 45_000)),
    ]);
- Do NOT pass uiOptions:{ showWalletUIs:false } — it aborts with
  "signal is aborted without reason". The approval sheet still shows on
  the embedded-EOA path; the fee reads a few cents in FLOW.
- Do NOT add ZeroDev / SmartWalletsProvider / a paymaster URL / a bundler
  key. There is no Privy dashboard toggle for Flow EVM sponsorship — user
  pays gas, period. Show a "Need FLOW? Faucet ↗" link when signed in.
- Hardhat in /contracts (kept outside the Vite bundle). Install
  `@nomicfoundation/hardhat-toolbox` AND `@nomicfoundation/hardhat-verify@latest` (>=3.x).
- hardhat.config.cjs — Flowscan is a Blockscout instance; declare it via
  `customChains` and pass the `apiKey` field with a placeholder string
  ("empty" — Blockscout ignores the value, but the field MUST exist):
    require("@nomicfoundation/hardhat-toolbox");
    require("@nomicfoundation/hardhat-verify");
    module.exports = {
      solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
      networks: { flowEvmTestnet: {
        url: process.env.FLOW_EVM_RPC_URL || "https://testnet.evm.nodes.onflow.org",
        accounts: [process.env.FLOW_EVM_PRIVATE_KEY.startsWith("0x")
          ? process.env.FLOW_EVM_PRIVATE_KEY : "0x" + process.env.FLOW_EVM_PRIVATE_KEY],
        chainId: 545,
      } },
      etherscan: {
        apiKey: { flowEvmTestnet: "empty" },
        customChains: [{
          network: "flowEvmTestnet",
          chainId: 545,
          urls: { apiURL: "https://testnet.flowscan.io/evm/api",
                  browserURL: "https://testnet.flowscan.io/evm" },
        }],
      },
      sourcify: { enabled: false },
    };
- Deploy: `npx hardhat run scripts/deploy.cjs --network flowEvmTestnet`.
- Verify (run RIGHT AFTER deploy, no constructor args for these contracts):
  `npx hardhat verify --network flowEvmTestnet <address>`
  On success the source becomes readable at
  `https://testnet.flowscan.io/evm/address/<address>#code`.
- Frontend reads: `createPublicClient({ chain: flowEvmTestnet, transport: http() })`.
  The public Flow EVM RPC handles wide getLogs ranges — `fromBlock = head - 50000n` is fine.
- Write the deployed address to `src/data/contract.json` so the UI links to
  `https://testnet.flowscan.io/evm/address/<address>`.

CONTRACT (contracts/SceneSwapMarketplace.sol):
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title SceneSwapMarketplace
/// @notice Trade and license scene and set designs through a verified onchain marketplace.
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
contract SceneSwapMarketplace {
    event Logged(address indexed author, string cid, uint256 at);
    /// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
    function log(string calldata cid) external {
        emit Logged(msg.sender, cid, block.timestamp);
    }
}
```

USER FLOW
1. Land on page -> 'Sign in with Google' (Privy) -> embedded wallet auto-provisioned on Flow EVM Testnet.
2. Show a "Need FLOW? Faucet ↗" link to https://testnet-faucet.onflow.org so the user can top up.
3. User performs a design exchange action; the app calls `log(payload)` on the contract via the Privy embedded wallet and shows the Flowscan link as proof.
4. Footer renders: "Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14"

REQUIRED SECRETS (Lovable -> Project Settings -> Secrets):
- FLOW_EVM_PRIVATE_KEY  Flow EVM Testnet deployer key. Fund it (free): https://testnet-faucet.onflow.org
- PRIVY_APP_ID          Google sign-in + embedded wallet. Docs: https://docs.privy.io/llms-full.txt
- PINATA_JWT            IPFS uploads (only if app pins media). Docs: https://docs.pinata.cloud/llms-full.txt
- FLOW_EVM_RPC_URL      Optional. Defaults to https://testnet.evm.nodes.onflow.org (public RPC works fine).

CREDIT (must appear in UI footer AND as NatSpec on every deployed contract):
Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
Appendix · Market

Market sizing.

TAM
$1.2B
set design and rental market
SAM
$250M
digital creative marketplaces
SOM
$50M
early adopters in blockchain design exchange

Indicative figures for hackathon pitches — refine with your own research before raising.

See also

Adjacent entries.