[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GRVVM14T4HTFZWQRZGS1K1":3,"skill-same:01M6GRVVM14T4HTFZWQRZGS1K1":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":6,"ownerHtmlUrl":47,"ownerBlogUrl":48,"ownerDescription":49,"updatedAt":50,"install":51,"resources":64},"01M6GRVVM14T4HTFZWQRZGS1K1","noir",null,"Use when building, reviewing, or shipping a privacy app with Noir circuits verified onchain. The boundaries agents get wrong unprompted — in-circuit hash choice, in-browser proving with NoirJS, note persistence and the offchain tree mirror, and who sends the transaction.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",80,"AGPL-3.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdev-tools\u002Faustintgriffith-official-noir\u002FSKILL.md",[],[5,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"app","when","Wrong","verified","mirror","tree","circuit","with","note","shipping","get","transaction","onchain","use","choice","privacy","persistence","browser","2026-11-10 10:12:30",false,"---\nname: noir\ndescription: Use when building, reviewing, or shipping a privacy app with Noir circuits verified onchain. The boundaries agents get wrong unprompted — in-circuit hash choice, in-browser proving with NoirJS, note persistence and the offchain tree mirror, and who sends the transaction.\n---\n\n# Privacy Apps with Noir\n\nA sound circuit is not a private app. These are the boundaries around it, where the failures actually happen.\n\n**Hash in-circuit with Poseidon, never keccak or SHA256.** Poseidon costs ~600 gates against ~30,000 for a bit-oriented hash, and members prove in a browser. It is not in the stdlib — add the dependency and import it:\n\n```toml\nposeidon = { git = \"https:\u002F\u002Fgithub.com\u002Fnoir-lang\u002Fposeidon\", tag = \"v0.3.0\" }\n```\n\n`use poseidon::poseidon::bn254::hash_2` — not `std::hash::poseidon` (removed). Whatever you pick, every layer must use the same algorithm and input order: commitment creation, Merkle parent hashing, the offchain mirror, the onchain tree. Poseidon and Poseidon2 are different functions with different outputs. Test one leaf hash and one parent hash across every layer before building on them.\n\n**Prove in-process with NoirJS, not by shelling out to the `bb` CLI.** A script that spawns `bb prove` and reads the proof off disk works on your laptop and can never become the browser prover the app needs. The packages are `@noir-lang\u002Fnoir_js` + `@aztec\u002Fbb.js` (not `backend_barretenberg`), and the class is `UltraHonkBackend` (not `UltraPlonkBackend`):\n\n```typescript\nconst backend = new UltraHonkBackend(circuit.bytecode, await Barretenberg.new());\nconst proof = await backend.generateProof(witness, { verifierTarget: \"evm\" });\n```\n\nThe API argument is required — the one-argument form docs still show throws `Cannot read properties of undefined (reading 'circuitProve')`. Ask for EVM serialization explicitly with `{ verifierTarget: \"evm\" }` (keccak transcript, ZK); the default serialization will not verify onchain, and the older `{ keccak: true }` is deprecated for `evm-no-zk` — a different target, whose proofs an `evm` verifier rejects. Keep `@aztec\u002Fbb.js` on the exact version of your `bb` CLI:\n\n```bash\nnpm install @noir-lang\u002Fnoir_js \"@aztec\u002Fbb.js@$(bb --version)\"\n```\n\n**Persist the note, and rebuild the path from events.** At commitment time generate a `nullifier` and a `secret`, and save them with the `leafIndex` — lose them and the user can never spend or vote. Anything you commit to that lives in a small domain — a bid, an age, a vote — needs one of those random fields as a blinding factor in the preimage, or the onchain commitment is brute-forceable. The client derives its Merkle witness by replaying the contract's insert events into an offchain mirror (`@zk-kit\u002Flean-imt`), so the contract has to emit the commitment, its leaf index, and the resulting root. Not a contract call returning a path, and not a hardcoded one. A model that writes only the circuit forgets all of this.\n\n**Nobody's wallet should send its own proof.** The ZK proof hides the commitment-nullifier link; `msg.sender` is public and links the two transactions anyway. Registering from the known wallet is fine when membership is public — acting from it is not. Route the acting transaction through a relayer, or send it from a fresh account whose gas an ERC-4337 paymaster sponsors — a paymaster alone hides nothing, since the UserOperation's `sender` is public, so reusing the registering account keeps the link. A burner funded from the user's own wallet recreates the link, and unlinkability is still bounded by the size of the anonymity set.\n\nAlso required, and usually already habit — confirm rather than rebuild:\n\n- `nargo compile` builds the circuit and `nargo execute` produces the witness from `Prover.toml`; everything else is `bb` — `bb prove`, `bb verify`, `bb write_vk`, and `bb write_solidity_verifier` fed by that VK. `nargo prove` \u002F `nargo verify` \u002F `nargo codegen-verifier` were removed. Generate the VK feeding the Solidity verifier with `--verifier_target evm` and keep prove, verify and VK on the same target: it names the transcript hash and the ZK setting together, which is the pair that has to match. The older `--oracle_hash keccak` still works, but it names only the hash. Smoke-test a real prove-and-verify before wiring a frontend.\n- Public inputs use post-colon syntax: `root: pub Field`.\n- Scope the nullifier to the action in-circuit — hash the proposal or pool id into it, or one member's votes link across proposals.\n- Bind the proof to what it authorizes: make the recipient (and any amount or fee) a public input the contract checks. A proof that does not commit to the recipient can be copied from the mempool and redirected by a front-runner or a relayer.\n- Keep hash domains separate: commitment and nullifier hash must not be the same function over overlapping inputs (add a domain tag or use different arities), or one value can stand in for the other.\n- Every private input must be constrained by an `assert` or by feeding a checked hash. An input the circuit never constrains can be set to anything, and the proof still verifies.\n- Count the vote or release the funds only after `verify()` returns true, recording the nullifier hash so a replay reverts. Never leave a `MockVerifier` in a deploy path.\n- Public input order must match across the circuit's `pub` params, the script's `publicInputs`, and the array the contract hands to `verify()`. Read the generated verifier's ABI rather than assuming its signature.\n- Merkle path indices are `[bool; DEPTH]`.\n- Accept any recent root (`mapping(bytes32 => bool) knownRoots`), not only the current one — an insert landing between proving and submitting otherwise reverts an honest proof.\n- The onchain tree is `@zk-kit\u002Flean-imt.sol` with a separately deployed `PoseidonT3`, the pair that matches the offchain `@zk-kit\u002Flean-imt`. A hand-rolled onchain tree drifts from the mirror.\n- Next.js \u002F Scaffold-ETH 2: set `config.experiments.asyncWebAssembly = true` in `next.config`, load the prover with `dynamic(..., { ssr: false })`, and copy the circuit JSON to `public\u002F` and `fetch()` it — a cross-package JSON import fails.\n- The generated verifier needs `pragma solidity >=0.8.27` and `evm_version = 'cancun'`; if the project's floor is lower, set `solc_version = '0.8.27'` and `evm_version = 'cancun'` in `foundry.toml`. Build it optimized or it exceeds the 24KB limit.\n\nInstall with `noirup -v \u003Cversion>`, then `bbup -v \u003Cversion>` — bare `bbup` resolves through a version map that lags nargo and 404s. Finish by compiling the circuit and building the contracts.\n","# Privacy Apps with Noir\n\nA sound circuit is not a private app. These are the boundaries around it, where the failures actually happen.\n\n**Hash in-circuit with Poseidon, never keccak or SHA256.** Poseidon costs ~600 gates against ~30,000 for a bit-oriented hash, and members prove in a browser. It is not in the stdlib — add the dependency and import it:\n\n```toml\nposeidon = { git = \"https:\u002F\u002Fgithub.com\u002Fnoir-lang\u002Fposeidon\", tag = \"v0.3.0\" }\n```\n\n`use poseidon::poseidon::bn254::hash_2` — not `std::hash::poseidon` (removed). Whatever you pick, every layer must use the same algorithm and input order: commitment creation, Merkle parent hashing, the offchain mirror, the onchain tree. Poseidon and Poseidon2 are different functions with different outputs. Test one leaf hash and one parent hash across every layer before building on them.\n\n**Prove in-process with NoirJS, not by shelling out to the `bb` CLI.** A script that spawns `bb prove` and reads the proof off disk works on your laptop and can never become the browser prover the app needs. The packages are `@noir-lang\u002Fnoir_js` + `@aztec\u002Fbb.js` (not `backend_barretenberg`), and the class is `UltraHonkBackend` (not `UltraPlonkBackend`):\n\n```typescript\nconst backend = new UltraHonkBackend(circuit.bytecode, await Barretenberg.new());\nconst proof = await backend.generateProof(witness, { verifierTarget: \"evm\" });\n```\n\nThe API argument is required — the one-argument form docs still show throws `Cannot read properties of undefined (reading 'circuitProve')`. Ask for EVM serialization explicitly with `{ verifierTarget: \"evm\" }` (keccak transcript, ZK); the default serialization will not verify onchain, and the older `{ keccak: true }` is deprecated for `evm-no-zk` — a different target, whose proofs an `evm` verifier rejects. Keep `@aztec\u002Fbb.js` on the exact version of your `bb` CLI:\n\n```bash\nnpm install @noir-lang\u002Fnoir_js \"@aztec\u002Fbb.js@$(bb --version)\"\n```\n\n**Persist the note, and rebuild the path from events.** At commitment time generate a `nullifier` and a `secret`, and save them with the `leafIndex` — lose them and the user can never spend or vote. Anything you commit to that lives in a small domain — a bid, an age, a vote — needs one of those random fields as a blinding factor in the preimage, or the onchain commitment is brute-forceable. The client derives its Merkle witness by replaying the contract's insert events into an offchain mirror (`@zk-kit\u002Flean-imt`), so the contract has to emit the commitment, its leaf index, and the resulting root. Not a contract call returning a path, and not a hardcoded one. A model that writes only the circuit forgets all of this.\n\n**Nobody's wallet should send its own proof.** The ZK proof hides the commitment-nullifier link; `msg.sender` is public and links the two transactions anyway. Registering from the known wallet is fine when membership is public — acting from it is not. Route the acting transaction through a relayer, or send it from a fresh account whose gas an ERC-4337 paymaster sponsors — a paymaster alone hides nothing, since the UserOperation's `sender` is public, so reusing the registering account keeps the link. A burner funded from the user's own wallet recreates the link, and unlinkability is still bounded by the size of the anonymity set.\n\nAlso required, and usually already habit — confirm rather than rebuild:\n\n- `nargo compile` builds the circuit and `nargo execute` produces the witness from `Prover.toml`; everything else is `bb` — `bb prove`, `bb verify`, `bb write_vk`, and `bb write_solidity_verifier` fed by that VK. `nargo prove` \u002F `nargo verify` \u002F `nargo codegen-verifier` were removed. Generate the VK feeding the Solidity verifier with `--verifier_target evm` and keep prove, verify and VK on the same target: it names the transcript hash and the ZK setting together, which is the pair that has to match. The older `--oracle_hash keccak` still works, but it names only the hash. Smoke-test a real prove-and-verify before wiring a frontend.\n- Public inputs use post-colon syntax: `root: pub Field`.\n- Scope the nullifier to the action in-circuit — hash the proposal or pool id into it, or one member's votes link across proposals.\n- Bind the proof to what it authorizes: make the recipient (and any amount or fee) a public input the contract checks. A proof that does not commit to the recipient can be copied from the mempool and redirected by a front-runner or a relayer.\n- Keep hash domains separate: commitment and nullifier hash must not be the same function over overlapping inputs (add a domain tag or use different arities), or one value can stand in for the other.\n- Every private input must be constrained by an `assert` or by feeding a checked hash. An input the circuit never constrains can be set to anything, and the proof still verifies.\n- Count the vote or release the funds only after `verify()` returns true, recording the nullifier hash so a replay reverts. Never leave a `MockVerifier` in a deploy path.\n- Public input order must match across the circuit's `pub` params, the script's `publicInputs`, and the array the contract hands to `verify()`. Read the generated verifier's ABI rather than assuming its signature.\n- Merkle path indices are `[bool; DEPTH]`.\n- Accept any recent root (`mapping(bytes32 => bool) knownRoots`), not only the current one — an insert landing between proving and submitting otherwise reverts an honest proof.\n- The onchain tree is `@zk-kit\u002Flean-imt.sol` with a separately deployed `PoseidonT3`, the pair that matches the offchain `@zk-kit\u002Flean-imt`. A hand-rolled onchain tree drifts from the mirror.\n- Next.js \u002F Scaffold-ETH 2: set `config.experiments.asyncWebAssembly = true` in `next.config`, load the prover with `dynamic(..., { ssr: false })`, and copy the circuit JSON to `public\u002F` and `fetch()` it — a cross-package JSON import fails.\n- The generated verifier needs `pragma solidity >=0.8.27` and `evm_version = 'cancun'`; if the project's floor is lower, set `solc_version = '0.8.27'` and `evm_version = 'cancun'` in `foundry.toml`. Build it optimized or it exceeds the 24KB limit.\n\nInstall with `noirup -v \u003Cversion>`, then `bbup -v \u003Cversion>` — bare `bbup` resolves through a version map that lags nargo and 404s. Finish by compiling the circuit and building the contracts.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fdev-tools\u002Faustintgriffith-official-noir",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-11 08:47:40",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill noir",{"tool":57,"command":58},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill noir",{"tool":60,"command":61},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill noir","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdev-tools\u002Faustintgriffith-official-noir\u002FSKILL.md",true,[65,71],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"SOURCE.md","REFERENCE","参考文档",341,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdev-tools\u002Faustintgriffith-official-noir\u002FSOURCE.md",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"TRUST.auto.yaml",2121,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdev-tools\u002Faustintgriffith-official-noir\u002FTRUST.auto.yaml",[76,103,126,144,157,167],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":81,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":37},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[85,86,87,88,89,90,19,91,92,93,94,95,96,97,98,36,99,100,101,102],"performance","recipe performance","recipe","mm","sentry","harness","deterministic","recipes","flow","cold","critical","analysis","tasks","react","layout","screen","network","metamask",{"skillNo":104,"name":105,"nameZh":6,"description":106,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":107,"licenseFileUrl":108,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":37},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[112,113,114,115,116,117,118,119,120,121,122,123,124,125],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":107,"licenseFileUrl":130,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":37},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[134,113,135,136,137,138,139,123,122,121,140,141,142,117,143,116,115],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":107,"licenseFileUrl":148,"sourceHtmlUrl":149,"categories":150,"keywords":151,"publishedAt":37},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[152,153,114,154,155,124,122,156,120,119,117,116],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":158,"name":159,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":160,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":37},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[164,165,166],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":171,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":37},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[175,176,177,178,179,180,181,32,182,183,184],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]