🎭 Theater & Live Performance · program design

PlayBill Archive

Pin historic and current playbill designs on IPFS for theatrical heritage and design reference.

IPFS via Pinata· decentralized storage
Section · Onchain

The primitive.

full primer →

Every program design artefact is pinned to IPFS through Pinata; directors get a permanent CID and a public gateway preview instead of a fragile cloud URL.

Why this primitivePinata offers permanent, decentralized hosting of program designs as image and JSON manifests.

Kernel
a Pinata JWT upload that pins images / JSON / manifests to IPFS and returns a permanent CID
Drives the UI as
a 'pinned to IPFS' chip with the CID and an ipfs.io gateway preview
Appendix · Secrets

Required keys.

METAMASK_PRIVATE_KEY
Exported from MetaMask. Fund on BNB Smart Chain Testnet via the BNB faucet.
open ↗
BSC_TESTNET_RPC_URL
BSC Testnet HTTPS RPC. Public: https://data-seed-prebsc-1-s1.bnbchain.org:8545 (or your own provider).
open ↗
BSCSCAN_API_KEY
Etherscan v2 key (chainid=97) for npx hardhat verify.
open ↗
PRIVY_APP_ID
Enables Google sign-in + embedded wallet on BNB Testnet.
open ↗
PINATA_JWT
Pins images / JSON / manifests to IPFS.
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 "PlayBill Archive" in ONE Lovable message. Single-page demo.

CONCEPT
Pin historic and current playbill designs on IPFS for theatrical heritage and design reference.
Discipline: Theater & Live Performance (program design).
Onchain primitive: IPFS via Pinata. Why this primitive: Pinata offers permanent, decentralized hosting of program designs as image and JSON manifests.

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 BSC Testnet, verified on BscScan.
- Privy is the auth + embedded-wallet layer (Google login, wallet auto-provisioned).
- Gas is USER-PAID. There is NO sponsorship on BSC Testnet in this template — the user needs a small tBNB balance from the faucet. Surface a "Get tBNB" faucet link in the UI.
- 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).
- 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 uses viem's `bscTestnet` chain (chainId 97):
    import { bscTestnet } from 'viem/chains';
    <PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
      config={{ loginMethods:['google','email'],
                embeddedWallets:{ ethereum:{ createOnLogin:'users-without-wallets' } },
                defaultChain: bscTestnet,
                supportedChains: [bscTestnet],
                appearance:{ theme:'dark' } }}>
- Read the embedded wallet from useWallets, not user.wallet:
    const embedded = wallets.find(w => w.walletClientType === 'privy');
- Every send goes through Privy `useSendTransaction` with `chainId: 97` and
  `address` (NO `sponsor` — BSC Testnet is user-paid in this template):
    await sendTransaction(
      { to, data, chainId: 97 },
      { address: embedded.address }
    );
- Do NOT pass uiOptions:{ showWalletUIs:false } — it aborts with
  "signal is aborted without reason". The approval sheet is expected on
  the embedded-EOA path; the user pays a tiny tBNB fee.
- Do NOT add ZeroDev / SmartWalletsProvider / a paymaster URL. This
  template is intentionally user-paid on BSC Testnet.
- USER FUNDING: the embedded wallet needs a small tBNB balance. Show a
  "Get tBNB" link next to the connect button pointing at
  https://www.bnbchain.org/en/testnet-faucet. Catch "insufficient funds"
  errors and re-surface the faucet link inline.
- src/lib/pinata.ts uploads via `fetch('https://api.pinata.cloud/pinning/pinFileToIPFS', { method:'POST', headers:{ Authorization: `Bearer ${import.meta.env.VITE_PINATA_JWT}` }, body: fd })`.
- Hardhat in /contracts (kept outside the Vite bundle). Install
  `@nomicfoundation/hardhat-toolbox` AND `@nomicfoundation/hardhat-verify@latest`
  (>=3.x — older versions still hit Etherscan v1 and fail with
  "You are using a deprecated V1 endpoint, switch to Etherscan API V2").
- hardhat.config.cjs uses the Etherscan v2 single-key shape with a
  customChains entry pointing v2 at BscScan (chainid=97):
    require("@nomicfoundation/hardhat-toolbox");
    require("@nomicfoundation/hardhat-verify");
    module.exports = {
      solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
      networks: { bscTestnet: {
        url: process.env.BSC_TESTNET_RPC_URL || "https://data-seed-prebsc-1-s1.bnbchain.org:8545",
        accounts: [process.env.METAMASK_PRIVATE_KEY.startsWith("0x")
          ? process.env.METAMASK_PRIVATE_KEY : "0x" + process.env.METAMASK_PRIVATE_KEY],
        chainId: 97,
      } },
      etherscan: {
        apiKey: process.env.BSCSCAN_API_KEY,
        customChains: [{
          network: "bscTestnet",
          chainId: 97,
          urls: {
            apiURL: "https://api.etherscan.io/v2/api?chainid=97",
            browserURL: "https://testnet.bscscan.com",
          },
        }],
      },
      sourcify: { enabled: false },
    };
- Deploy: `npx hardhat run scripts/deploy.cjs --network bscTestnet`.
- Verify: `npx hardhat verify --network bscTestnet <address>` — verified source
  appears at `https://testnet.bscscan.com/address/<address>#code`.
- Frontend reads: create a viem public client on bscTestnet using the same RPC —
  `createPublicClient({ chain: bscTestnet, transport: http(import.meta.env.VITE_BSC_TESTNET_RPC_URL) })`.
  Cap `getLogs` ranges to `fromBlock = head - 9000n`; the public RPC rate-limits wider windows.
- Write the deployed address to `src/data/contract.json` so the UI links to
  `https://testnet.bscscan.com/address/<address>`.

CONTRACT (contracts/PlayBillArchive.sol):
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title CIDLogPlayBillArchive
/// @notice Pin historic and current playbill designs on IPFS for theatrical heritage and design reference.
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
contract CIDLogPlayBillArchive {
    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 BSC Testnet.
2. Prompt user to fund with tBNB (faucet link) if balance is zero.
3. On submit, pin the program design artefact to Pinata, then call `log(cid)` on the contract via Privy `useSendTransaction` (user-paid). Render the CID, IPFS gateway preview, and BscScan tx link.
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):
- METAMASK_PRIVATE_KEY   BSC Testnet deployer key. Fund it with tBNB: https://www.bnbchain.org/en/testnet-faucet
- BSC_TESTNET_RPC_URL    BSC Testnet HTTPS RPC. Public: https://data-seed-prebsc-1-s1.bnbchain.org:8545 (rate-limited).
                          Also expose as VITE_BSC_TESTNET_RPC_URL for the frontend viem client.
- BSCSCAN_API_KEY        For `npx hardhat verify` via Etherscan v2 (chainid=97). Get: https://etherscan.io/myapikey
- PRIVY_APP_ID           Google/email sign-in + embedded wallet. Docs: https://docs.privy.io/llms-full.txt
                          Also expose as VITE_PRIVY_APP_ID for the client.
- PINATA_JWT             IPFS uploads (only if the app pins media). Docs: https://docs.pinata.cloud/llms-full.txt
                          Also expose as VITE_PINATA_JWT for the client.

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
$1B
theatrical print design
SAM
$150M
digital program archives
SOM
$10M
IPFS playbill archival platforms

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

See also

Adjacent entries.