💃 Dance & Choreography · custom choreography kits

ChoreoCraft Tokens

Create and sell NFT-backed custom choreography kits for teachers and studios.

NFT provenance mint· onchain authorship
Section · Onchain

The primitive.

full primer →

Choreographers mint each custom choreography kits as an ERC-721 token on Cronos Testnet pointing at an IPFS CID, so authorship and timestamp are provable from a single Cronos Explorer link.

Why this primitiveNFT minting verifies ownership and uniqueness of choreography kit IP packages.

Kernel
an ERC-721 contract on Cronos that mints a creator-owned token pointing at an IPFS CID, verified on Cronos Explorer
Drives the UI as
a 'mint to claim authorship' button that returns the tokenId, owner address, and Cronos Explorer link
Appendix · Secrets

Required keys.

METAMASK_PRIVATE_KEY
Exported from MetaMask. Fund on Cronos Testnet via the Google Cloud faucet.
open ↗
CRONOS_RPC_URL
Cronos Testnet RPC endpoint (https://evm-t3.cronos.com).
open ↗
PRIVY_APP_ID
Enables Google sign-in and embedded-wallet transactions.
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 "ChoreoCraft Tokens" in ONE Lovable message. Single-page demo.

CONCEPT
Create and sell NFT-backed custom choreography kits for teachers and studios.
Discipline: Dance & Choreography (custom choreography kits).
Onchain primitive: NFT provenance mint. Why this primitive: NFT minting verifies ownership and uniqueness of choreography kit IP packages.

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 Cronos Testnet, verified on Cronos Explorer.
- Privy is always the auth layer (Google login, embedded wallet). Users pay their own gas in test CRO from https://faucet.cronos.com/ — Cronos gas is sub-cent.
- 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 (pin the embedded wallet to Cronos Testnet with viem's
  cronosTestnet — do NOT stub a chain as { id, name }):
    import { cronosTestnet } from 'viem/chains';
    <PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
      config={{ loginMethods:['google','email'],
                embeddedWallets:{ ethereum:{ createOnLogin:'users-without-wallets' } },
                appearance:{ theme:'dark' },
                defaultChain: cronosTestnet,
                supportedChains: [cronosTestnet] }}>
- Read the embedded wallet from useWallets, not user.wallet:
    const embedded = wallets.find(w => w.walletClientType === 'privy');
- Cronos has NO Privy native gas sponsorship — the user's embedded wallet pays
  its own gas in test CRO. Do NOT pass a sponsor/paymaster option. Every send
  goes through Privy `useSendTransaction` (chainId passed per-call), wrapped in a
  45s Promise.race timeout, and you catch "insufficient funds" to point users at
  the faucet:
    await Promise.race([
      sendTransaction({ to, data, chainId: 338 }),
      new Promise((_, r) => setTimeout(() => r(new Error(
        "Transaction timed out after 45s. Fund your wallet with test CRO at https://faucet.cronos.com/ and try again."
      )), 45_000)),
    ]);
- Show the embedded wallet address in the UI with a "Get test CRO" link to
  https://faucet.cronos.com/ so users can fund it before their first tx.
- Do NOT pass uiOptions:{ showWalletUIs:false } — it aborts with
  "signal is aborted without reason". The approval sheet still shows on
  the embedded-EOA path.
- Do NOT add ZeroDev / SmartWalletsProvider / a paymaster URL — not needed on Cronos.
- 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`.
- hardhat.config.cjs — Cronos Testnet network + Cronos Explorer (Blockscout) verify
  via customChains (NOT Etherscan):
    require("@nomicfoundation/hardhat-toolbox");
    require("@nomicfoundation/hardhat-verify");
    module.exports = {
      solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
      networks: { cronosTestnet: {
        url: process.env.CRONOS_RPC_URL || "https://evm-t3.cronos.com",
        accounts: [process.env.METAMASK_PRIVATE_KEY.startsWith("0x")
          ? process.env.METAMASK_PRIVATE_KEY : "0x" + process.env.METAMASK_PRIVATE_KEY],
        chainId: 338,
      } },
      etherscan: {
        // Cronos Explorer is Blockscout — no API key needed, but hardhat-verify
        // requires a non-empty string here, so pass a placeholder.
        apiKey: { cronosTestnet: "no-api-key-needed" },
        customChains: [{
          network: "cronosTestnet",
          chainId: 338,
          urls: {
            apiURL: "https://explorer-api.cronos.org/testnet/api/v1/hardhat/contract",
            browserURL: "https://explorer.cronos.com/testnet",
          },
        }],
      },
      sourcify: { enabled: false },
    };
- Deploy: `npx hardhat run scripts/deploy.cjs --network cronosTestnet`.
- Verify (run RIGHT AFTER deploy, no constructor args for these contracts):
  `npx hardhat verify --network cronosTestnet <address>`
  Source becomes readable at
  `https://explorer.cronos.com/testnet/address/<address>#code`.
- Frontend reads: create a viem public client with cronosTestnet —
  `createPublicClient({ chain: cronosTestnet, transport: http("https://evm-t3.cronos.com") })`.
  The Cronos Testnet RPC is a public endpoint, so no VITE_ secret is needed on the client.
- Write the deployed address to `src/data/contract.json` (chainId 338) so the UI links to
  `https://explorer.cronos.com/testnet/address/<address>`.

CONTRACT (contracts/ChoreoCraftTokens.sol):
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
/// @title ChoreoCraftTokens
/// @notice ERC-721 provenance for: Create and sell NFT-backed custom choreography kits for teachers and studios.
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
contract ChoreoCraftTokens is ERC721 {
    uint256 public nextId;
    mapping(uint256 => string) public cidOf;
    constructor() ERC721("ChoreoCraftTokens", "CHOREO") {}
    /// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
    function mint(string calldata cid) external returns (uint256 id) {
        id = ++nextId; cidOf[id] = cid; _safeMint(msg.sender, id);
    }
    function tokenURI(uint256 id) public view override returns (string memory) {
        return string(abi.encodePacked("ipfs://", cidOf[id]));
    }
}
```

USER FLOW
1. Land on page -> 'Sign in with Google' (Privy) -> embedded wallet auto-provisioned.
2. After the user creates a custom choreography kits artefact, pin the file to IPFS via Pinata, then call `mint(cid)` on the deployed contract via Privy's embedded wallet (user pays gas in test CRO). Show tokenId, IPFS preview (`https://gateway.pinata.cloud/ipfs/<cid>`), and a Cronos Explorer mint-tx link.
3. 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   Cronos Testnet deployer key. Fund it with test CRO: https://faucet.cronos.com/
- CRONOS_RPC_URL         Cronos Testnet RPC (https://evm-t3.cronos.com), used by Hardhat deploy. The browser client uses the public RPC directly — no VITE_ secret needed.
- 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
NOTE: Cronos Explorer is Blockscout — contract verification needs NO API key.

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
$3B
dance education content creation market
SAM
$300M
digital choreography toolkits
SOM
$30M
NFT choreography kit buyers

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

See also

Adjacent entries.