From aztec
Guides Aztec smart contract development in Noir: notes, private state, testing, deployment, TypeScript integration. Corrects common pitfalls like integer overflow and msg_sender.
How this skill is triggered — by the user, by Claude, or both
Slash command
/aztec:aztec-developerThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Framework knowledge for Aztec smart contract development that is NOT obvious from reading source code.
contract-dev/authwit.mdcontract-dev/compressed-string.mdcontract-dev/contract-structure.mdcontract-dev/cross-contract-calls.mdcontract-dev/data-types.mdcontract-dev/delayed-public-mutable.mdcontract-dev/events.mdcontract-dev/index.mdcontract-dev/notes.mdcontract-dev/partial-notes.mdcontract-dev/public-structs.mdcontract-dev/storage.mdcontract-dev/transaction-lifecycle.mdtxe/authwit.mdtxe/debugging.mdtxe/deploy-contract-with-keys.mdtxe/index.mdtxe/setup.mdtxe/test-running.mdtxe/writing-tests.mdFramework knowledge for Aztec smart contract development that is NOT obvious from reading source code.
These are facts Claude frequently gets wrong about Aztec. Consult this before making claims:
Noir integer types (u8, u64, u128) PANIC on overflow — they do NOT wrap. Only Field arithmetic wraps (around the field modulus). This means u64 addition is already overflow-safe in Noir — no explicit guard is needed. However, Field should never be used for amounts that need overflow protection.
#[note] Macro Injects RandomnessThe #[note] attribute macro automatically injects a NoteHeader field containing a nonce for commitment uniqueness. You do NOT need to add a manual randomness field to note structs. A note with only amount and owner fields is valid — the macro handles the rest.
Owned<PrivateSet<T>> Requires Double .at()For storage declared as Map<AztecAddress, Owned<PrivateSet<NoteType>>>:
self.storage.private_balances.at(owner_address).at(owner_address).insert(note)
The first .at() indexes the Map by key. The second .at() authenticates the Owned wrapper with the owner. This is correct, not a bug.
pop_notes vs get_notesget_notes() reads notes without nullifying them — notes remain in the database after the callpop_notes() reads and nullifies in one step — the correct choice when consuming notes (e.g., spending a balance)get_notes() to read notes you intend to consume, you must manually nullify them or they can be re-readenqueue vs enqueue_incognitoself.enqueue(...) — the msg_sender of the enqueued public call is visible on-chainself.enqueue_incognito(...) — hides the msg_sender in the public callenqueue_incognito when the shield or private→public boundary should not reveal who initiated the actionu128, Not u64u64 max is ~18.4 × 10¹⁸. With 18 decimal places (standard), this limits total supply to ~18.4 tokens. Always use u128 for token amounts to match ERC-20 semantics. The standard Aztec note type for balances is UintNote (from uint_note crate) which stores value: u128.
self.msg_sender() vs self.context.maybe_msg_sender()self.msg_sender() — returns AztecAddress directly, panics if sender is Noneself.context.maybe_msg_sender() — returns Option<AztecAddress>, safe for entrypoints and incognito callsNone at: (1) tx entrypoints (account contracts), (2) public calls via enqueue_incognito()AztecAddress.ZEROWhen deploying an account contract, the account doesn't exist on-chain yet, so it can't be the sender. Use from: AztecAddress.ZERO for the deployment transaction.
Call .simulate() before .send() for every state-changing transaction. Simulation runs locally and surfaces revert reasons immediately. Without it, a failing transaction hangs until the send timeout (up to 600s) with an opaque error.
| Concept | What It Means in Aztec |
|---|---|
| Notes | Encrypted UTXOs — the only way to store private state. Only the owner can nullify. |
| Nullifiers | On-chain markers that "spend" a note without revealing which one. Prevents double-spend. |
| Enqueue | Private functions can't directly modify public state — they enqueue public calls for the sequencer. |
| Owned<T> | Wrapper that ties a private state variable to a specific owner. Required for private sets/maps. |
| Need | Use |
|---|---|
| Public value anyone can read/write | PublicMutable<T> |
| Private value only owner accesses | Owned<PrivateMutable<T>> |
| Private set of notes (e.g., balances) | Owned<PrivateSet<T>> |
| Per-user storage | Map<AztecAddress, T> |
| Public value readable from private (with delay) | DelayedPublicMutable<T> |
For API docs and code examples beyond what's here, use:
aztec_sync_repos() # sync first
aztec_search_code({ query: "<pattern>", filePattern: "*.nr" })
aztec_list_examples()
aztec_search_docs({ query: "<question>" })
npx claudepluginhub critesjosh/aztec-claude-plugin --plugin aztecDevelops secure smart contracts by integrating OpenZeppelin libraries for ERC tokens, access control, pausability, governance, and accounts. Supports Solidity, Cairo, Stylus, Stellar.
Guides building zero-knowledge proof verifiers and privacy patterns on Stellar/Soroban, covering Groth16, BLS12-381, BN254, Poseidon, Noir/RISC Zero integration, and more.
Authors Cairo smart contracts on Starknet, including storage, events, interfaces, and OpenZeppelin component composition with security patterns.