From aztec
Aztec smart contract development, Noir programming, testing, deployment, and TypeScript integration. Use when working with Aztec contracts, notes, private state, or any Aztec SDK code. Use review-contract for security reviews.
npx claudepluginhub critesjosh/aztec-claude-plugin --plugin aztecThis skill is limited to using the following tools:
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.mdGenerates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Framework 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>" })