Loading...
Loading...
Build a privacy-preserving arcade leaderboard DApp on Midnight Network — players submit click-challenge scores with anonymous, public, or custom display names, and prove entry ownership via zero-knowledge proofs without revealing secret keys. Covers leaderboard.compact (Map, Counter, witnesses, persistentHash owner commitments), Next.js frontend, 1AM wallet integration, low-level deploy/call, indexer reads without wallet, and ZK asset hosting. Use for gamified on-chain rankings, pseudonymous competitions, score attestations, or teaching disclose()/witness patterns. Triggers: leaderboard dApp, privacy leaderboard, submit score, verify ownership, anonymous player name, ZK proof of ownership, persistentHash identity, arcade game on Midnight. Also use when extending locker-dapp or payment-dapp wallet/provider patterns to social or gaming flows.
npx skill4agent add kali-decoder/midnight-skills example-leaderboard-dappverifyOwnershipownerCommitment(secretKey)ownerHashtemplates/leaderboard-dapp/npm install && npm run compact && npm run sync:assets && npm run devcontract/app/leaderboard/lib/midnight.tsreferences/midnight-session.mdtemplates/leaderboard-dapp/lib/midnight.tslib/leaderboard.tssubmitScoreverifyOwnershiplib/display-name.tspublic/zk/leaderboard/references/midnight-session.mdcreateConnectedSessionreferences/gotchas.mdoffset: nullreferences/versions.json@midnight-ntwrk/*example-locker-dapp/templates/locker-dapp/example-payment-dapp/compact/disclose()persistentHashMapCounterassertsecurity/indexer/scoresMap<Uint<64>, ScoreEntry>localSecretKeyownerCommitment(sk)persistentHash"leaderboard:owner:"useCustomNameverifyOwnershiplocalStoragecreateUnprovenDeployTxsubmitTxAsyncdeployContract()indexerPublicDataProviderqueryContractStateoffset: nullleaderboard.compactlocalSecretKeygetCustomNamecreateConnectedSessionreferences/midnight-session.mdContractState.deserializeledger()submitScore(score, useCustomName)setCustomNameverifyOwnership(entryId)leaderboard-dapp/
├── package.json
├── next.config.mjs
├── lib/
│ ├── isomorphic-ws-fix.mjs
│ ├── midnight.ts # session, patched provider, hex helpers
│ ├── leaderboard.ts # deploy, submitScore, verifyOwnership, decode
│ └── display-name.ts # anonymous name generator
├── app/
│ ├── layout.tsx
│ └── leaderboard/
│ └── LeaderboardClient.tsx # game + wallet + leaderboard UI
├── contract/
│ ├── package.json
│ └── src/
│ ├── leaderboard.compact
│ ├── witnesses.ts
│ ├── index.ts
│ └── managed/leaderboard/ # compiler output (gitignored)
├── scripts/
│ └── sync-zk-assets.mjs # → public/zk/leaderboard/
└── public/zk/leaderboard/ # keys + zkir (gitignored until sync)contract/src/leaderboard.compactstruct ScoreEntry {
score: Uint<64>,
displayName: Bytes<32>,
ownerHash: Bytes<32>
}
export ledger scores: Map<Uint<64>, ScoreEntry>;
export ledger nextId: Counter;
witness localSecretKey(): Bytes<32>;
witness getCustomName(): Bytes<32>;
export circuit ownerCommitment(sk: Bytes<32>): Bytes<32> {
return persistentHash<Vector<2, Bytes<32>>>([pad(32, "leaderboard:owner:"), sk]);
}
export circuit submitScore(score: Uint<64>, useCustomName: Boolean): [] { /* ... */ }
export circuit verifyOwnership(targetEntryId: Uint<64>): [] { /* ... */ }useCustomName = falsedisplayName = persistentHash(sk)useCustomName = truedisplayName = getCustomName()ownerHash = ownerCommitment(sk)verifyOwnershipcd contract && npm run compact && cd ..
npm run sync:assetscontract/src/witnesses.tsexport type LeaderboardPrivateState = { secretKey: Uint8Array };
export const witnesses = {
localSecretKey: (ctx) => [ctx.privateState, ctx.privateState.secretKey] as const,
getCustomName: (ctx) => [ctx.privateState, customName] as const,
};
export const setCustomName = (name: string) => { /* encode to Bytes<32> */ };setCustomName(name)submitScorelib/leaderboard.ts| Function | Purpose |
|---|---|
| Persist 32-byte secret in |
| |
| |
| |
| Indexer poll + |
/zk/leaderboardpublic/zk/leaderboard/LeaderboardClient.tsxdetectWallet()wallet.connect('preprod')createConnectedSession(api, ZK_PATH)submitScoreverifyOwnership(entryId)| Component | Version |
|---|---|
| Compact compiler | 0.31.0 |
| Compact runtime | 0.16.0 |
| Ledger | 8.0.3 |
| midnight-js | 4.0.4 |
| proof server | 8.0.3 |
docker run -d -p 6300:6300 midnightntwrk/proof-server:8.0.3 -- \
midnight-proof-server --network preprodhttp://localhost:6300references/versions.jsonpublic/zk/leaderboardnpm run sync:assetslocalStorageverifyOwnershipgetConfiguration()cd templates/leaderboard-dapp
npm install
npm run compact
npm run sync:assets
npm run dev