🎮 Games & Interactive · guild treasury

Guild Treasury Shielded v10

A games & interactive tool that runs guild treasury through a shielded zkVault note flow — private amounts, public proofs.

Shielded payroll· zkvault
Section · Onchain

The primitive.

full primer →

One browser proving session splits a single guild treasury funding note into N employee notes; each recipient claims theirs without ever appearing in a public transfer.

Why this primitiveBatch-split one funding note into N recipient notes in one browser proving session.

Kernel
Batch-split one funding note into N recipient notes in one browser proving session.
Drives the UI as
CSV of payees → 'Run payroll' → each employee grabs their note.
Appendix · Secrets

Required keys.

METAMASK_PRIVATE_KEY
Sepolia deployer + fisher wallet (single-EOA model). Fund via the Google Cloud faucet.
open ↗
SEPOLIA_RPC_URL
Alchemy Sepolia HTTPS endpoint. Public RPCs throttle under hackathon load.
open ↗
ETHERSCAN_API_KEY
Required for forge verify-contract after deploy.
open ↗
PRIVY_APP_ID
Enables Google sign-in and sponsored transactions. Toggle Gas sponsorship → Sepolia in the dashboard.
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 "Guild Treasury Shielded v10" in ONE Lovable message. Single-page demo on Ethereum Sepolia.

CONCEPT
A games & interactive tool that runs guild treasury through a shielded zkVault note flow — private amounts, public proofs.
Discipline: Games & Interactive (guild treasury).
zkVault primitive: Shielded payroll. Why: Batch-split one funding note into N recipient notes in one browser proving session.

zkVAULT STANDING ORDERS (self-contained — do NOT rely on any external skill)

Chain: Ethereum Sepolia. Auth: Privy embedded wallet. Gas: Privy native sponsorship (same as EVVM).

zkVault is a shielded pool built on the EVVM stack. Deposit puts a note commitment on-chain; withdraw
and split spend notes with a Noir/UltraHonk zk-proof. The pool contracts wrap two verifiers:
SplitNoteVerifier and WithdrawFromPoolVerifier.

Proving runs IN THE BROWSER via bb.js 4.2.0 + @noir-lang/noir_js 1.0.0-beta.19 — exact pins. Do NOT
run the prover in a TSS server function on Cloudflare workerd; it crashes with
"path argument must be of type string". The submit route only signs + broadcasts.

Verifier ↔ bb.js pairing is load-bearing. A ProofLengthWrongWithLogN revert (selector 0x59895a53)
means the on-chain verifier was generated by a different bb.js version than the browser ships.
Fix: regenerate both verifiers from EVVM-org/ZkVaultService-contracts using the SAME bb.js version
(4.2.0), redeploy ShieldedPool + verifiers, update src/evvm/zkvault-deployment.json.

Single-EOA model (identical to EVVM standing orders): METAMASK_PRIVATE_KEY deploys the pool, fishes
proof submissions, and admins the registry.

Notes:
- Notes are opaque blobs held client-side; treat them like bearer secrets — never log, never store
  on the server, offer a "download note" and clipboard copy.
- Empty-state UX: when the user's wallet or EVVM USDC balance is 0, render an amber notice with the
  exact address to fund, a copy button, a Circle Sepolia USDC faucet link, and a refresh button.
  DO NOT let the primary action be clickable when it would revert.

Deployment (in a Lovable Linux sandbox):
1. bash scripts/install-foundry.sh
2. node scripts/deploy-evvm.mjs        # must succeed first — zkVault needs Core + Treasury
3. node scripts/set-evvm-id.mjs        # Core.setEvvmID(assignedId) — see EVVM standing orders
4. node scripts/deploy-zkvault.mjs     # deploys SplitNoteVerifier, WithdrawFromPoolVerifier,
                                        # ShieldedPool; writes src/evvm/zkvault-deployment.json.

Balance preflight: ShieldedPool.deposit pulls from the payer's EVVM USDC balance, so run
Core.getBalance(user, USDC) on mount + after every settle, gate the submit button when
balance < required, and point at the Fund-EVVM card. Skipping this hits InsufficientBalance
(selector 0xf4d678b8).

Decimal USDC UX (non-negotiable, same as EVVM): inputMode="decimal", parseUnits(str.trim(), 6)
in, `${formatUnits(wei, 6)} USDC` out. Never render raw atomic values or "USDC (micro)" labels.

Fisher response contract: { ok, txHash?, explorer?, revert?, error? }. Build explorer server-side.
On success render clickable "↗ View on Etherscan · <txHash slice>"; on failure surface the decoded
revert / error verbatim. Common selectors to decode: InvalidSignature 0x8baa579f,
InsufficientBalance 0xf4d678b8, ProofLengthWrongWithLogN 0x59895a53.

REQUIRED SECRETS: PRIVY_APP_ID, METAMASK_PRIVATE_KEY, SEPOLIA_RPC_URL, ETHERSCAN_API_KEY.

CREDIT LINE:
  Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14.


MINIMUM VIABLE FLOW
1. Landing page. Google sign-in via Privy. Embedded wallet auto-provisioned.
2. Show shielded-note inventory (persisted in localStorage as encrypted blobs — treat as bearer).
3. Primary action: "Guild Treasury Shielded v10" — the inputs are the ones "guild treasury" naturally requires.
4. On submit:
   a. Browser builds the circuit inputs (see src/lib/shielded/*Inputs.ts).
   b. Browser runs the Noir prover via src/lib/noir/prove.client.ts (bb.js 4.2.0). Show a spinner
      with real "Generating proof…" progress; typical time 8–20s on a laptop.
   c. POST { proof, publicInputs, args } to /api/public/fisher/zkv-submit-<flow>.
   d. Fisher route calls ShieldedPool with METAMASK_PRIVATE_KEY paying gas.
5. If the tx reverts with selector 0x59895a53 (ProofLengthWrongWithLogN), surface a clear message
   naming the bb.js version mismatch and pointing at scripts/deploy-zkvault.mjs.
6. UI shows a Sepolia Etherscan link and a receipt tuned to "guild treasury".

CONTRACTS: reuse src/evvm/zkvault-deployment.json. If not deployed, run:
   node scripts/deploy-evvm.mjs && node scripts/deploy-zkvault.mjs

TAILORING NOTES for "guild treasury":
- Copy, iconography, and success states must read as Games & Interactive, not generic web3.
- Use the vocabulary the audience already knows (indie game devs, modders, esports operators).
- Keep the build to ONE index route + ONE fisher submit route.

CREDIT (footer + on-chain @notice):
  Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14.
Appendix · Market

Market sizing.

TAM
the interactive-entertainment market ($187B; 3B players)
SAM
A privacy-preserving payments slice of Games & Interactive
estimate 10% of TAM.
SOM
The indie game devs early-adopter segment
estimate 1% of TAM in year one.

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

See also

Adjacent entries.