PropBlueprint Cache
Store and share detailed prop blueprints and assembly guides pinned immutably on IPFS for artisans.
IPFS via Pinata· decentralized storage
Section · Onchain
full primer →The primitive.
Every prop 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 uploads ensure permanence and decentralized access to critical prop design files.
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
Required keys.
MONAD_RPC_URL
Monad Testnet HTTPS endpoint. Default: https://testnet-rpc.monad.xyz — use a provider endpoint for heavier load.
open ↗Add these in your Lovable project under Settings → Secrets before pasting the prompt below.
Appendix · Mega-prompt
The build prompt.
budget · 1 message
Paste into a fresh Lovable project. Make sure all five secrets above are set first. read the build strategy →
Build "PropBlueprint Cache" in ONE Lovable message. Single-page demo.
CONCEPT
Store and share detailed prop blueprints and assembly guides pinned immutably on IPFS for artisans.
Discipline: Theater & Live Performance (prop design).
Onchain primitive: IPFS via Pinata. Why this primitive: Pinata uploads ensure permanence and decentralized access to critical prop design files.
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 Monad Testnet, verified on MonadScan.
- Privy is always the auth + sponsored-tx layer (Google login, embedded wallet). Runtime gas is sponsored by the app — users never touch MON.
- 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: pass a viem `defineChain` for Monad Testnet as
`defaultChain` AND include it in `supportedChains` — Privy rejects unknown
chains. Do NOT stub `defaultChain` as `{ id, name }`:
import { defineChain } from 'viem';
const monadTestnet = defineChain({
id: 10143,
name: 'Monad Testnet',
nativeCurrency: { name: 'Monad', symbol: 'MON', decimals: 18 },
rpcUrls: { default: { http: ['https://testnet-rpc.monad.xyz'] } },
blockExplorers: { default: { name: 'MonadExplorer', url: 'https://testnet.monadexplorer.com' } },
});
<PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
config={{ loginMethods:['google','email'],
embeddedWallets:{ ethereum:{ createOnLogin:'users-without-wallets' } },
appearance:{ theme:'dark' },
defaultChain: monadTestnet,
supportedChains: [monadTestnet] }}>
- Read the embedded wallet from useWallets, not user.wallet:
const embedded = wallets.find(w => w.walletClientType === 'privy');
- Every send goes through Privy `useSendTransaction` with BOTH `address`
and `sponsor: true`, and `chainId: 10143` per-call. Wrap in a 45s
Promise.race timeout whose reject message names the exact dashboard
toggles so the failure mode is self-diagnosing:
await Promise.race([
sendTransaction(
{ to, data, chainId: 10143 },
{ address: embedded.address, sponsor: true }
),
new Promise((_, r) => setTimeout(() => r(new Error(
"Privy sendTransaction timed out after 45s. Enable Gas sponsorship -> App pays -> Monad Testnet -> Allow transactions from the client."
)), 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 sponsored fee reads US$0.00.
- Do NOT add ZeroDev / Pimlico / SmartWalletsProvider / a paymaster URL.
Privy natively sponsors gas on Monad Testnet with the dashboard toggles
below — no external paymaster stack needed.
- DASHBOARD PREREQUISITE (one-time): Privy dashboard -> Gas sponsorship
-> App pays -> add "Monad Testnet" -> toggle "Allow transactions from
the client" ON. Without this, sendTransaction hangs silently and the
45s timeout above fires with the exact remediation string.
- 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 (one key covers
every chain, including MonadScan). Set `bytecodeHash: "ipfs"` so Sourcify
(MonadVision) verification also works, and register `monadTestnet` under
`etherscan.customChains`:
require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-verify");
module.exports = {
solidity: { version: "0.8.24", settings: {
optimizer: { enabled: true, runs: 200 },
metadata: { bytecodeHash: "ipfs" },
} },
networks: { monadTestnet: {
url: process.env.MONAD_RPC_URL || "https://testnet-rpc.monad.xyz",
accounts: [process.env.METAMASK_PRIVATE_KEY.startsWith("0x")
? process.env.METAMASK_PRIVATE_KEY : "0x" + process.env.METAMASK_PRIVATE_KEY],
chainId: 10143,
} },
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
customChains: [{
network: "monadTestnet",
chainId: 10143,
urls: {
apiURL: "https://api.etherscan.io/v2/api?chainid=10143",
browserURL: "https://testnet.monadscan.com",
},
}],
},
sourcify: {
enabled: true,
apiUrl: "https://sourcify-api-monad.blockvision.org",
browserUrl: "https://monadvision.com",
},
};
- Deploy: `npx hardhat run scripts/deploy.cjs --network monadTestnet`.
- Verify (run RIGHT AFTER deploy, no constructor args for these contracts):
`npx hardhat verify --network monadTestnet <address>`
The verify command may print a warning but usually succeeds on both
Sourcify (MonadVision) and MonadScan — confirm at
`https://testnet.monadscan.com/address/<address>#code`.
- Write the deployed address to `src/data/contract.json` so the UI links to
`https://testnet.monadexplorer.com/address/<address>`.
CONTRACT (contracts/PropBlueprintCache.sol):
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title CIDLogPropBlueprintCache
/// @notice Store and share detailed prop blueprints and assembly guides pinned immutably on IPFS for artisans.
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
contract CIDLogPropBlueprintCache {
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.
2. On submit, pin the prop design artefact to Pinata, then call `log(cid)` on the contract via Privy sponsored tx. Render the CID, IPFS gateway preview, and Etherscan 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 Monad Testnet deployer key. Fund it: https://faucet.monad.xyz
- MONAD_RPC_URL Monad Testnet HTTPS endpoint. Default: https://testnet-rpc.monad.xyz. For heavier load use a provider endpoint (Alchemy / QuickNode / Chainstack) — public RPC throttles under hackathon traffic.
- ETHERSCAN_API_KEY Etherscan v2 key covers MonadScan too. Get: https://etherscan.io/myapikey
- 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
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
Market sizing.
TAM
$1.7B
prop manufacturing
SAM
$320M
digital prop design platforms
SOM
$18M
IPFS-based blueprint archives
Indicative figures for hackathon pitches — refine with your own research before raising.
Adjacent entries.
lighting design
StageLight Archive
Pin and access dynamic stage lighting setups with permanent IPFS storage for reliable reuse and sharing.
playwritingPlayScript Vault
Securely save, share, and version play scripts on IPFS to preserve authorship and facilitate collaboration.
costume designCostumeMood Board
Pin and share costume sketches and mood boards on IPFS for collaborative costume creation.
performance showcaseActorPortfolio Hub
Actors upload and pin portfolios including headshots and performance clips permanently on IPFS for casting accessibility.