Aztec.js Application Development
Overview
Use this skill for Aztec TypeScript SDK work only.
Primary scope:
- network connection and node readiness
- wallet/account creation, deployment, and registration
- contract deployment and interaction from TypeScript
- transaction send/simulate/profile flows
- fee estimation and fee payment methods
- authwit creation and usage
- public/private event and log reads
- test workflow setup for local-network integration
Out of scope:
- Noir/Aztec.nr contract authoring and architecture
- operator/node/prover infrastructure runbooks
- wallet-provider connectivity / browser-extension transport (use
aztec-wallet-sdk)
Required Repository State
Use the upstream repository and pin:
- Repo:
https://github.com/AztecProtocol/aztec-packages
- Tag:
v4.2.0
- Commit:
f8c89cf4345df6c4ca9e66ea9b738e96070abc5a
Checkout example:
git clone https://github.com/AztecProtocol/aztec-packages.git
cd aztec-packages
git checkout v4.2.0
git status
Expected status includes HEAD detached at v4.2.0.
Operating Rules
- Keep guidance restricted to Aztec.js and related TypeScript SDK packages.
- Prefer subpath imports (for example
@aztec/aztec.js/node, @aztec/aztec.js/fields) over root imports.
- Treat wallet metadata checks as mandatory before first public calls:
getContractMetadata(address) — inspect initializationStatus (enum: INITIALIZED / UNINITIALIZED / UNKNOWN), isContractPublished
getContractClassMetadata(classId)
- Use explicit
from (or NO_FROM for bypass-entrypoint flows) and explicit fee options on tx-producing calls.
- Bypass-entrypoint sends use
NO_FROM from @aztec/aztec.js/account (the v4.1.x AztecAddress.ZERO sentinel was replaced). For multi-call self-deploy + fee-claim flows, wrap with DefaultMultiCallEntrypoint + mergeExecutionPayloads.
- When deploying a contract that initializes private storage in its constructor (e.g.
SinglePrivateImmutable / SinglePrivateMutable), use contract public keys when the contract owns private state, register the instance with its secret key before send, precompute the instance with the same address inputs the send path will derive (contractAddressSalt and deployer: from, or no deployer for universalDeploy/NO_FROM), and pass additionalScopes: [instance.address]; otherwise PXE-level scope enforcement rejects the construction-time access to the instance's own private slot. Cross-contract nullification (e.g. escrow withdraw) similarly requires additionalScopes listing each foreign address whose notes are nullified.
- Use
simulate before send when validating behavior or gas risk.
- Use
NO_WAIT only when tx hash persistence and polling are implemented.
- Keep SKILL instructions procedural; place deep API index in
reference.md.
Quick Start
# Install SDK dependencies (choose one package manager)
npm install @aztec/aztec.js @aztec/accounts @aztec/wallets @aztec/noir-contracts.js
# or: yarn add ...
# or: pnpm add ...
import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node";
import { EmbeddedWallet } from "@aztec/wallets/embedded";
const node = createAztecNodeClient("http://localhost:8080");
await waitForNode(node);
const wallet = await EmbeddedWallet.create(node);
Core Workflows
1. Connect and Validate Chain Context
- Create node client via
createAztecNodeClient(nodeUrl).
- Wait for readiness with
waitForNode(node).
- Read
node.getNodeInfo() and persist chain/version values.
- Register/fetch accounts in wallet before tx usage.
2. Create and Deploy Accounts
- Use
wallet.createSchnorrAccount(secret, salt, signingKey?).
- Deploy via account deploy method (
getDeployMethod().send({...})).
- For first deploy of a new account, use a payer that can fund fees.
- Confirm with
wallet.getContractMetadata(accountAddress).
3. Deploy and Register Contracts (SDK)
- Generate contract TS bindings from compiled artifacts.
- Deploy with
MyContract.deploy(wallet, ...ctorArgs).send({ from }). Waited deploys return { contract, receipt, ... }.
- Use deploy options when needed:
contractAddressSalt, universalDeploy
skipClassPublication, skipInstancePublication, skipInitialization
wait: NO_WAIT
- Verify readiness with metadata APIs before public interactions.
- Register externally deployed contracts via
wallet.registerContract(...).
4. Send Transactions Safely
- Build calls from
contract.methods.<fn>(...).
- Use
.simulate({ from }) for preflight behavior checks; returns { result, ... }.
- Use
.send({ from, fee?, wait? }) for state changes; waited sends return { receipt, ... }, NO_WAIT sends return { txHash, ... }.
- For atomic multi-call flows, use
new BatchCall(wallet, [call1, call2, ...]). Waited BatchCall.send() follows the same return shape ({ receipt, ... }).
- If using no-wait mode, poll receipt with node APIs.
5. Read Data and Events
- Use
simulate for typed state reads (private/public/utility); .simulate() returns { result, ... }, not the raw value.
- Read public events with
getPublicEvents(node, Contract.events.EventName, filter). Returns { events, maxLogsHit }.
- Read private events with
wallet.getPrivateEvents(eventDef, filter).
- Use raw logs only when ABI-level decoding is not required.
6. Fees and Gas Strategy
- Default method: account pays with Fee Juice.
- Estimate gas with
simulate({ fee: { estimateGas: true } }).
- Use
GasSettings.fallback({ maxFeesPerGas }) for on-chain sends (replaces v4.1.x GasSettings.default(...)). For simulation/estimation use GasSettings.forEstimation(...) alongside skipTxValidation: true. EmbeddedWallet.simulateTx wires the estimation variant automatically.
- Use payment-method classes for supported non-default payment:
SponsoredFeePaymentMethod (local/devnet)
FeeJuicePaymentMethodWithClaim (after bridging Fee Juice from L1)
- Avoid
PrivateFeePaymentMethod and PublicFeePaymentMethod: in v4.2.0 custom-token FPCs are not on the default public setup allowlist, so these methods (and the fpc-public / fpc-private CLI shortcuts) cannot be used on public/mainnet networks. They remain exported for local/custom-network flows but are deprecated.
- Set explicit gas settings when reliability matters.
7. Authwit
- Private authwit: create witness and include in tx
authWitnesses.
- Public authwit: register/revoke authorization via
SetPublicAuthwitContractInteraction.
- Arbitrary intent authwit: hash payload and sign as
IntentInnerHash.
- Treat nonces as mandatory replay protection.
8. Testing
- Use a local network and
EmbeddedWallet/test wallet adapters.
- Use prefunded local accounts for deterministic test setup.
- Use
.simulate() for assertions and failure-path checks.
- Use
.send() for integration behavior and receipt-level assertions.
9. API Coverage and Discovery
- This skill covers the full available devnet TypeScript API corpus listed in
reference.md.
- Package-level surface (classes/interfaces/functions/types/enums) is mapped there.
- Use
scripts/api_surface_summary.sh to re-generate API section counts from pinned docs.
Tooling / Commands
# preflight checks for Aztec.js dev env
scripts/preflight_aztec_js.sh http://localhost:8080
# install SDK packages with selected package manager
scripts/install_aztec_js_deps.sh npm
# wait for node JSON-RPC readiness
scripts/wait_for_aztec_node.sh http://localhost:8080
# summarize full API surface from a pinned aztec-packages checkout
scripts/api_surface_summary.sh /path/to/aztec-packages
# run a TS entrypoint via tsx
scripts/run_ts_example.sh ./src/index.ts
Edge Cases and Failure Handling
Cannot find the leaf for nullifier on deploy:
class publication/instance publication settings likely incompatible with call path.
- Contract deploy tx mined but public calls fail:
check
isContractPublished and class registration metadata.
simulate succeeds but send fails:
network-only checks (publication/init/fees) likely missing.
Timeout awaiting isMined or delayed receipts:
handle as pending; poll by tx hash instead of treating as terminal failure.
- Public authwit seems ignored:
verify public authwit registration tx was mined and nonce/action tuple matches.
- Private event read returns empty unexpectedly:
verify
scopes, caller registration, and block-range filter.
Next Steps / Related Files
- Use
reference.md for full API package coverage and method maps.
- Use
patterns.md for reusable copy-ready Aztec.js snippets.
- Use
scripts/ for repeatable local workflow helpers.
1---2name: aztec-js3description: Use this skill when building TypeScript applications with Aztec.js, including node/PXE connectivity, account lifecycle, contract deployment and interaction, transaction/fee handling, authwit authorization, event reads, and test automation.4license: Proprietary. LICENSE.txt has complete terms5---67# Aztec.js Application Development89## Overview1011Use this skill for Aztec TypeScript SDK work only.1213Primary scope:1415- network connection and node readiness16- wallet/account creation, deployment, and registration17- contract deployment and interaction from TypeScript18- transaction send/simulate/profile flows19- fee estimation and fee payment methods20- authwit creation and usage21- public/private event and log reads22- test workflow setup for local-network integration2324Out of scope:2526- Noir/Aztec.nr contract authoring and architecture27- operator/node/prover infrastructure runbooks28- wallet-provider connectivity / browser-extension transport (use `aztec-wallet-sdk`)2930## Required Repository State3132Use the upstream repository and pin:3334- Repo: `https://github.com/AztecProtocol/aztec-packages`35- Tag: `v4.2.0`36- Commit: `f8c89cf4345df6c4ca9e66ea9b738e96070abc5a`3738Checkout example:3940```bash41git clone https://github.com/AztecProtocol/aztec-packages.git42cd aztec-packages43git checkout v4.2.044git status45```4647Expected status includes `HEAD detached at v4.2.0`.4849## Operating Rules5051- Keep guidance restricted to Aztec.js and related TypeScript SDK packages.52- Prefer subpath imports (for example `@aztec/aztec.js/node`, `@aztec/aztec.js/fields`) over root imports.53- Treat wallet metadata checks as mandatory before first public calls:54- `getContractMetadata(address)` — inspect `initializationStatus` (enum: `INITIALIZED` / `UNINITIALIZED` / `UNKNOWN`), `isContractPublished`55- `getContractClassMetadata(classId)`56- Use explicit `from` (or `NO_FROM` for bypass-entrypoint flows) and explicit fee options on tx-producing calls.57- Bypass-entrypoint sends use `NO_FROM` from `@aztec/aztec.js/account` (the v4.1.x `AztecAddress.ZERO` sentinel was replaced). For multi-call self-deploy + fee-claim flows, wrap with `DefaultMultiCallEntrypoint` + `mergeExecutionPayloads`.58- When deploying a contract that initializes private storage in its constructor (e.g. `SinglePrivateImmutable` / `SinglePrivateMutable`), use contract public keys when the contract owns private state, register the instance with its secret key before send, precompute the instance with the same address inputs the send path will derive (`contractAddressSalt` and `deployer: from`, or no deployer for `universalDeploy`/`NO_FROM`), and pass `additionalScopes: [instance.address]`; otherwise PXE-level scope enforcement rejects the construction-time access to the instance's own private slot. Cross-contract nullification (e.g. escrow withdraw) similarly requires `additionalScopes` listing each foreign address whose notes are nullified.59- Use `simulate` before `send` when validating behavior or gas risk.60- Use `NO_WAIT` only when tx hash persistence and polling are implemented.61- Keep SKILL instructions procedural; place deep API index in `reference.md`.6263## Quick Start6465```bash66# Install SDK dependencies (choose one package manager)67npm install @aztec/aztec.js @aztec/accounts @aztec/wallets @aztec/noir-contracts.js68# or: yarn add ...69# or: pnpm add ...70```7172```typescript73import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node";74import { EmbeddedWallet } from "@aztec/wallets/embedded";7576const node = createAztecNodeClient("http://localhost:8080");77await waitForNode(node);78const wallet = await EmbeddedWallet.create(node);79```8081## Core Workflows8283### 1. Connect and Validate Chain Context8485- Create node client via `createAztecNodeClient(nodeUrl)`.86- Wait for readiness with `waitForNode(node)`.87- Read `node.getNodeInfo()` and persist chain/version values.88- Register/fetch accounts in wallet before tx usage.8990### 2. Create and Deploy Accounts9192- Use `wallet.createSchnorrAccount(secret, salt, signingKey?)`.93- Deploy via account deploy method (`getDeployMethod().send({...})`).94- For first deploy of a new account, use a payer that can fund fees.95- Confirm with `wallet.getContractMetadata(accountAddress)`.9697### 3. Deploy and Register Contracts (SDK)9899- Generate contract TS bindings from compiled artifacts.100- Deploy with `MyContract.deploy(wallet, ...ctorArgs).send({ from })`. Waited deploys return `{ contract, receipt, ... }`.101- Use deploy options when needed:102- `contractAddressSalt`, `universalDeploy`103- `skipClassPublication`, `skipInstancePublication`, `skipInitialization`104- `wait: NO_WAIT`105- Verify readiness with metadata APIs before public interactions.106- Register externally deployed contracts via `wallet.registerContract(...)`.107108### 4. Send Transactions Safely109110- Build calls from `contract.methods.<fn>(...)`.111- Use `.simulate({ from })` for preflight behavior checks; returns `{ result, ... }`.112- Use `.send({ from, fee?, wait? })` for state changes; waited sends return `{ receipt, ... }`, `NO_WAIT` sends return `{ txHash, ... }`.113- For atomic multi-call flows, use `new BatchCall(wallet, [call1, call2, ...])`. Waited `BatchCall.send()` follows the same return shape (`{ receipt, ... }`).114- If using no-wait mode, poll receipt with node APIs.115116### 5. Read Data and Events117118- Use `simulate` for typed state reads (private/public/utility); `.simulate()` returns `{ result, ... }`, not the raw value.119- Read public events with `getPublicEvents(node, Contract.events.EventName, filter)`. Returns `{ events, maxLogsHit }`.120- Read private events with `wallet.getPrivateEvents(eventDef, filter)`.121- Use raw logs only when ABI-level decoding is not required.122123### 6. Fees and Gas Strategy124125- Default method: account pays with Fee Juice.126- Estimate gas with `simulate({ fee: { estimateGas: true } })`.127- Use `GasSettings.fallback({ maxFeesPerGas })` for on-chain sends (replaces v4.1.x `GasSettings.default(...)`). For simulation/estimation use `GasSettings.forEstimation(...)` alongside `skipTxValidation: true`. `EmbeddedWallet.simulateTx` wires the estimation variant automatically.128- Use payment-method classes for supported non-default payment:129- `SponsoredFeePaymentMethod` (local/devnet)130- `FeeJuicePaymentMethodWithClaim` (after bridging Fee Juice from L1)131- Avoid `PrivateFeePaymentMethod` and `PublicFeePaymentMethod`: in v4.2.0 custom-token FPCs are not on the default public setup allowlist, so these methods (and the `fpc-public` / `fpc-private` CLI shortcuts) cannot be used on public/mainnet networks. They remain exported for local/custom-network flows but are deprecated.132- Set explicit gas settings when reliability matters.133134### 7. Authwit135136- Private authwit: create witness and include in tx `authWitnesses`.137- Public authwit: register/revoke authorization via `SetPublicAuthwitContractInteraction`.138- Arbitrary intent authwit: hash payload and sign as `IntentInnerHash`.139- Treat nonces as mandatory replay protection.140141### 8. Testing142143- Use a local network and `EmbeddedWallet`/test wallet adapters.144- Use prefunded local accounts for deterministic test setup.145- Use `.simulate()` for assertions and failure-path checks.146- Use `.send()` for integration behavior and receipt-level assertions.147148### 9. API Coverage and Discovery149150- This skill covers the full available devnet TypeScript API corpus listed in `reference.md`.151- Package-level surface (classes/interfaces/functions/types/enums) is mapped there.152- Use `scripts/api_surface_summary.sh` to re-generate API section counts from pinned docs.153154## Tooling / Commands155156```bash157# preflight checks for Aztec.js dev env158scripts/preflight_aztec_js.sh http://localhost:8080159160# install SDK packages with selected package manager161scripts/install_aztec_js_deps.sh npm162163# wait for node JSON-RPC readiness164scripts/wait_for_aztec_node.sh http://localhost:8080165166# summarize full API surface from a pinned aztec-packages checkout167scripts/api_surface_summary.sh /path/to/aztec-packages168169# run a TS entrypoint via tsx170scripts/run_ts_example.sh ./src/index.ts171```172173## Edge Cases and Failure Handling174175- `Cannot find the leaf for nullifier` on deploy:176class publication/instance publication settings likely incompatible with call path.177- Contract deploy tx mined but public calls fail:178check `isContractPublished` and class registration metadata.179- `simulate` succeeds but `send` fails:180network-only checks (publication/init/fees) likely missing.181- `Timeout awaiting isMined` or delayed receipts:182handle as pending; poll by tx hash instead of treating as terminal failure.183- Public authwit seems ignored:184verify public authwit registration tx was mined and nonce/action tuple matches.185- Private event read returns empty unexpectedly:186verify `scopes`, caller registration, and block-range filter.187188## Next Steps / Related Files189190- Use `reference.md` for full API package coverage and method maps.191- Use `patterns.md` for reusable copy-ready Aztec.js snippets.192- Use `scripts/` for repeatable local workflow helpers.