Aztec Account Lifecycle and Routing
Overview
Use this skill for Aztec account implementation and account-lifecycle work.
Primary scope:
- choosing and implementing account flavors (
Schnorr, ECDSA)
- deterministic account creation inputs (
secret, salt, signing key/public key)
- deployment via
AccountManager and wallet account helpers
- reconstructing accounts and wallets from existing material
- account abstraction entrypoints and tx routing behavior
- account self-funded deployment and fee routing
- key-store expectations for key derivation, validation, and app-secret derivation
Out of scope:
- generic contract deployment and app interaction flows that do not depend on account internals (use
aztec-js or aztec-deployment)
- direct PXE debugging beyond account registration/sync expectations (use
aztec-pxe)
- wallet-provider connectivity or extension transport work (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
- Primary roots:
yarn-project/accounts
yarn-project/entrypoints
yarn-project/key-store
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
- Treat
secret + salt + account flavor + signing key/public key as the account identity tuple. Change any of them and the address changes.
- Prefer
Schnorr for most production use cases, and ECDSA for Ethereum-style signer integrations.
- Distinguish the account secret from the signing key:
- the secret derives the privacy/viewing/nullifier/tagging keys
- the signing key authorizes authwits for the account contract
- Prefer eager account exports in Node.js. The
lazy account modules explicitly note they are incompatible with Node.js at this pin.
- Base account contracts in
@aztec/accounts only define account behavior; actual deploy/recovery lifecycle is wired through AccountManager and wallet helpers.
- Reconstruct accounts with the exact same flavor and key material used originally. Recovery is deterministic; it is not an address lookup service.
- When using bare
AccountManager.create(...), register the resulting instance/artifact with the wallet/PXE before relying on it for interactions.
- For self-funded deployment, understand that fee execution is wrapped back through the account entrypoint via
AccountEntrypointMetaPaymentMethod.
- Key stores should gate key access and signatures with explicit user authorization; do not treat PXE as a secure private-key vault.
Quick Start
# install core account-related packages
scripts/install_aztec_accounts_deps.sh npm
import { Fr, GrumpkinScalar } from '@aztec/aztec.js/fields';
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);
const accountManager = await wallet.createSchnorrAccount(
Fr.random(),
Fr.random(),
GrumpkinScalar.random(),
);
const deployMethod = await accountManager.getDeployMethod();
await deployMethod.send({ from: existingFundedAccountAddress });
console.log(accountManager.address.toString());
Core Workflows
1. Choose the Right Account Flavor
SchnorrAccountContract
- Grumpkin signing key for auth
- separate account secret for privacy keys
- recommended default
EcdsaKAccountContract
- secp256k1 auth key
- use for Ethereum-wallet style integrations
EcdsaRAccountContract
- secp256r1 auth key
- use when the signer lives on P-256 infrastructure
EcdsaRSSHAccountContract
- secp256r1 auth via SSH agent signing
- recovery depends on the same SSH public key identity
2. Compute and Inspect a Deterministic Account Before Deployment
- Use wallet helpers such as
EmbeddedWallet.createSchnorrAccount(...) or AccountManager.create(...).
- Read the predicted address and public keys from
accountManager.getCompleteAddress().
- For Schnorr-only address prediction without wallet setup, use
getSchnorrAccountContractAddress(secret, salt, signingKey?).
- Use
accountManager.getInstance() when you need the contract instance definition before publishing.
3. Deploy an Account Contract
- Build the manager through wallet helpers or
AccountManager.create(...).
- Call
accountManager.getDeployMethod().
- Use an externally funded payer for the simplest flow:
await deployMethod.send({ from: fundedAccountAddress })
- Account deployments force
universalDeployment: true.
- At this pin, deploy-account defaults also bias toward:
skipClassPublication: true
skipInstancePublication: true
skipInitialization: false
skipClassPublication: true is unavailable for account contracts that expose public functions with a private initializer: v4.2.0 emits a separate public init nullifier via an auto-enqueued public call, which requires the account class to be published onchain.
- If the account is self-funding,
DeployAccountMethod routes fee execution through AccountEntrypointMetaPaymentMethod.
4. Reconstruct an Existing Account or Wallet
- Recovery is deterministic:
- same secret
- same salt
- same account flavor
- same signing key or signing public key material
- Embedded wallet pattern:
- recreate the wallet
- call the same
createSchnorrAccount(...), createECDSAKAccount(...), or createECDSARAccount(...)
- the wallet re-registers the account contract instance/artifact and rebuilds the same address
- Lower-level pattern:
- instantiate the account contract class directly
- call
AccountManager.create(wallet, secret, contract, salt)
- register the instance/artifact with the wallet or PXE
- call
getAccount() for the runtime account object
5. Understand Account Abstraction Routing
DefaultAccountContract wires a BaseAccount around DefaultAccountEntrypoint.
DefaultAccountEntrypoint:
- encodes app calls into an account
entrypoint(...) payload
- injects auth witnesses for the encoded call hash
- applies tx options such as
cancellable, txNonce, and fee-routing mode
DefaultEntrypoint:
- direct single-call private entrypoint
- rejects multi-call payloads
DefaultMultiCallEntrypoint:
- wraps multiple calls through the protocol multicall entrypoint
- used by
SignerlessAccount
- Use the account entrypoint whenever the account contract must authorize or fee-route the action.
6. Fee Routing Semantics
AccountFeePaymentMethodOptions controls how the account entrypoint treats fees:
EXTERNAL
PREEXISTING_FEE_JUICE
FEE_JUICE_WITH_CLAIM
AccountEntrypointMetaPaymentMethod computes these automatically when self-funding deployment:
- no inner calls => preexisting Fee Juice
- inner fee-claim calls => Fee Juice with claim
- external payer => external
- For self-deployment, deployment payload construction happens before fee payload wrapping so the account contract can exist before paying.
7. Key-Store Integration Expectations
KeyStore is a secure input component for PXE, not just a convenience map.
- Core responsibilities:
- create/add accounts from a secret and partial address
- persist master secret keys and public keys by account
- derive app-scoped secrets for kernel validation
- answer key-validation requests without exposing unnecessary material
- Important methods:
createAccount()
addAccount(sk, partialAddress)
getAccounts() / hasAccount(account)
getKeyValidationRequest(pkMHash, contractAddress)
getMasterIncomingViewingSecretKey(account)
getAppOutgoingViewingSecretKey(account, app)
getMasterSecretKey(pkM)
accountHasKey(account, pkMHash)
- Key-store UX/security expectation from the package README:
- prompt before signatures or sensitive key release
- protect stored secrets with encryption and recovery controls
8. Testing and Local-Network Helpers
@aztec/accounts/testing exposes deterministic/local-network-friendly helpers:
getInitialTestAccountsData()
generateSchnorrAccounts(numberOfAccounts)
- Use these when you need known account secrets, salts, signing keys, and predicted addresses for tests.
9. README vs Code Surface
- The pinned
yarn-project/accounts/README.md still shows getSchnorrAccount(...) and getSchnorrWallet(...).
- The current code surface in this pin is centered on:
- account contract classes in
@aztec/accounts/*
- address helpers such as
getSchnorrAccountContractAddress(...)
- lifecycle wiring through wallet helpers and
AccountManager
- Prefer code-backed patterns from
reference.md and patterns.md over the README snippets when they differ.
Tooling / Commands
# preflight node/package-manager checks and optional source-tree validation
scripts/preflight_aztec_accounts.sh [node-url] [aztec-packages-dir]
# install account-related SDK packages
scripts/install_aztec_accounts_deps.sh <npm|yarn|pnpm> [version]
# summarize exports and core source anchors from an aztec-packages checkout
scripts/summarize_accounts_surface.sh <aztec-packages-dir>
# run package tests for accounts, entrypoints, and key-store
scripts/run_accounts_tests.sh <aztec-packages-dir> [accounts|entrypoints|key-store]
Edge Cases and Failure Handling
- Recreated account address does not match expected address:
verify the exact flavor, secret, salt, and signing key/public key used for the original account.
- Account can be computed locally but cannot see notes/events:
the instance/artifact or account registration path was likely not re-established in the wallet/PXE.
getDeployMethod() throws about missing initializer:
that account contract does not expose an initializer path at this pin.
- Self-funded account deployment fails:
inspect the wrapped payment method and resulting
AccountFeePaymentMethodOptions.
lazy account modules fail under Node:
expected at this pin; switch to eager imports.
- SSH-backed ECDSA recovery fails:
confirm the same SSH public-key identity is available to the agent.
Next Steps / Related Files
- Use
reference.md for the pinned source map and API/file coverage.
- Use
patterns.md for reusable deployment and reconstruction snippets.
- Use
scripts/ for repeatable setup, inspection, and test workflows.
1---2name: aztec-accounts3description: Use this skill when working with Aztec account implementations and lifecycle flows, including Schnorr/ECDSA account flavors, account abstraction entrypoints, transaction routing, key-store integration, deployment, and wallet reconstruction.4license: Proprietary. LICENSE.txt has complete terms5---67# Aztec Account Lifecycle and Routing89## Overview1011Use this skill for Aztec account implementation and account-lifecycle work.1213Primary scope:1415- choosing and implementing account flavors (`Schnorr`, `ECDSA`)16- deterministic account creation inputs (`secret`, `salt`, signing key/public key)17- deployment via `AccountManager` and wallet account helpers18- reconstructing accounts and wallets from existing material19- account abstraction entrypoints and tx routing behavior20- account self-funded deployment and fee routing21- key-store expectations for key derivation, validation, and app-secret derivation2223Out of scope:2425- generic contract deployment and app interaction flows that do not depend on account internals (use `aztec-js` or `aztec-deployment`)26- direct PXE debugging beyond account registration/sync expectations (use `aztec-pxe`)27- wallet-provider connectivity or extension transport work (use `aztec-wallet-sdk`)2829## Required Repository State3031Use the upstream repository and pin:3233- Repo: `https://github.com/AztecProtocol/aztec-packages`34- Tag: `v4.2.0`35- Commit: `f8c89cf4345df6c4ca9e66ea9b738e96070abc5a`36- Primary roots:37 - `yarn-project/accounts`38 - `yarn-project/entrypoints`39 - `yarn-project/key-store`4041Checkout example:4243```bash44git clone https://github.com/AztecProtocol/aztec-packages.git45cd aztec-packages46git checkout v4.2.047git status48```4950Expected status includes `HEAD detached at v4.2.0`.5152## Operating Rules5354- Treat `secret + salt + account flavor + signing key/public key` as the account identity tuple. Change any of them and the address changes.55- Prefer `Schnorr` for most production use cases, and `ECDSA` for Ethereum-style signer integrations.56- Distinguish the account secret from the signing key:57 - the secret derives the privacy/viewing/nullifier/tagging keys58 - the signing key authorizes authwits for the account contract59- Prefer eager account exports in Node.js. The `lazy` account modules explicitly note they are incompatible with Node.js at this pin.60- Base account contracts in `@aztec/accounts` only define account behavior; actual deploy/recovery lifecycle is wired through `AccountManager` and wallet helpers.61- Reconstruct accounts with the exact same flavor and key material used originally. Recovery is deterministic; it is not an address lookup service.62- When using bare `AccountManager.create(...)`, register the resulting instance/artifact with the wallet/PXE before relying on it for interactions.63- For self-funded deployment, understand that fee execution is wrapped back through the account entrypoint via `AccountEntrypointMetaPaymentMethod`.64- Key stores should gate key access and signatures with explicit user authorization; do not treat PXE as a secure private-key vault.6566## Quick Start6768```bash69# install core account-related packages70scripts/install_aztec_accounts_deps.sh npm71```7273```typescript74import { Fr, GrumpkinScalar } from '@aztec/aztec.js/fields';75import { createAztecNodeClient, waitForNode } from '@aztec/aztec.js/node';76import { EmbeddedWallet } from '@aztec/wallets/embedded';7778const node = createAztecNodeClient('http://localhost:8080');79await waitForNode(node);8081const wallet = await EmbeddedWallet.create(node);82const accountManager = await wallet.createSchnorrAccount(83 Fr.random(),84 Fr.random(),85 GrumpkinScalar.random(),86);8788const deployMethod = await accountManager.getDeployMethod();89await deployMethod.send({ from: existingFundedAccountAddress });90console.log(accountManager.address.toString());91```9293## Core Workflows9495### 1. Choose the Right Account Flavor9697- `SchnorrAccountContract`98 - Grumpkin signing key for auth99 - separate account secret for privacy keys100 - recommended default101- `EcdsaKAccountContract`102 - secp256k1 auth key103 - use for Ethereum-wallet style integrations104- `EcdsaRAccountContract`105 - secp256r1 auth key106 - use when the signer lives on P-256 infrastructure107- `EcdsaRSSHAccountContract`108 - secp256r1 auth via SSH agent signing109 - recovery depends on the same SSH public key identity110111### 2. Compute and Inspect a Deterministic Account Before Deployment112113- Use wallet helpers such as `EmbeddedWallet.createSchnorrAccount(...)` or `AccountManager.create(...)`.114- Read the predicted address and public keys from `accountManager.getCompleteAddress()`.115- For Schnorr-only address prediction without wallet setup, use `getSchnorrAccountContractAddress(secret, salt, signingKey?)`.116- Use `accountManager.getInstance()` when you need the contract instance definition before publishing.117118### 3. Deploy an Account Contract119120- Build the manager through wallet helpers or `AccountManager.create(...)`.121- Call `accountManager.getDeployMethod()`.122- Use an externally funded payer for the simplest flow:123 - `await deployMethod.send({ from: fundedAccountAddress })`124- Account deployments force `universalDeployment: true`.125- At this pin, deploy-account defaults also bias toward:126 - `skipClassPublication: true`127 - `skipInstancePublication: true`128 - `skipInitialization: false`129- `skipClassPublication: true` is unavailable for account contracts that expose public functions with a private initializer: v4.2.0 emits a separate public init nullifier via an auto-enqueued public call, which requires the account class to be published onchain.130- If the account is self-funding, `DeployAccountMethod` routes fee execution through `AccountEntrypointMetaPaymentMethod`.131132### 4. Reconstruct an Existing Account or Wallet133134- Recovery is deterministic:135 - same secret136 - same salt137 - same account flavor138 - same signing key or signing public key material139- Embedded wallet pattern:140 - recreate the wallet141 - call the same `createSchnorrAccount(...)`, `createECDSAKAccount(...)`, or `createECDSARAccount(...)`142 - the wallet re-registers the account contract instance/artifact and rebuilds the same address143- Lower-level pattern:144 - instantiate the account contract class directly145 - call `AccountManager.create(wallet, secret, contract, salt)`146 - register the instance/artifact with the wallet or PXE147 - call `getAccount()` for the runtime account object148149### 5. Understand Account Abstraction Routing150151- `DefaultAccountContract` wires a `BaseAccount` around `DefaultAccountEntrypoint`.152- `DefaultAccountEntrypoint`:153 - encodes app calls into an account `entrypoint(...)` payload154 - injects auth witnesses for the encoded call hash155 - applies tx options such as `cancellable`, `txNonce`, and fee-routing mode156- `DefaultEntrypoint`:157 - direct single-call private entrypoint158 - rejects multi-call payloads159- `DefaultMultiCallEntrypoint`:160 - wraps multiple calls through the protocol multicall entrypoint161 - used by `SignerlessAccount`162- Use the account entrypoint whenever the account contract must authorize or fee-route the action.163164### 6. Fee Routing Semantics165166- `AccountFeePaymentMethodOptions` controls how the account entrypoint treats fees:167 - `EXTERNAL`168 - `PREEXISTING_FEE_JUICE`169 - `FEE_JUICE_WITH_CLAIM`170- `AccountEntrypointMetaPaymentMethod` computes these automatically when self-funding deployment:171 - no inner calls => preexisting Fee Juice172 - inner fee-claim calls => Fee Juice with claim173 - external payer => external174- For self-deployment, deployment payload construction happens before fee payload wrapping so the account contract can exist before paying.175176### 7. Key-Store Integration Expectations177178- `KeyStore` is a secure input component for PXE, not just a convenience map.179- Core responsibilities:180 - create/add accounts from a secret and partial address181 - persist master secret keys and public keys by account182 - derive app-scoped secrets for kernel validation183 - answer key-validation requests without exposing unnecessary material184- Important methods:185 - `createAccount()`186 - `addAccount(sk, partialAddress)`187 - `getAccounts()` / `hasAccount(account)`188 - `getKeyValidationRequest(pkMHash, contractAddress)`189 - `getMasterIncomingViewingSecretKey(account)`190 - `getAppOutgoingViewingSecretKey(account, app)`191 - `getMasterSecretKey(pkM)`192 - `accountHasKey(account, pkMHash)`193- Key-store UX/security expectation from the package README:194 - prompt before signatures or sensitive key release195 - protect stored secrets with encryption and recovery controls196197### 8. Testing and Local-Network Helpers198199- `@aztec/accounts/testing` exposes deterministic/local-network-friendly helpers:200 - `getInitialTestAccountsData()`201 - `generateSchnorrAccounts(numberOfAccounts)`202- Use these when you need known account secrets, salts, signing keys, and predicted addresses for tests.203204### 9. README vs Code Surface205206- The pinned `yarn-project/accounts/README.md` still shows `getSchnorrAccount(...)` and `getSchnorrWallet(...)`.207- The current code surface in this pin is centered on:208 - account contract classes in `@aztec/accounts/*`209 - address helpers such as `getSchnorrAccountContractAddress(...)`210 - lifecycle wiring through wallet helpers and `AccountManager`211- Prefer code-backed patterns from `reference.md` and `patterns.md` over the README snippets when they differ.212213## Tooling / Commands214215```bash216# preflight node/package-manager checks and optional source-tree validation217scripts/preflight_aztec_accounts.sh [node-url] [aztec-packages-dir]218219# install account-related SDK packages220scripts/install_aztec_accounts_deps.sh <npm|yarn|pnpm> [version]221222# summarize exports and core source anchors from an aztec-packages checkout223scripts/summarize_accounts_surface.sh <aztec-packages-dir>224225# run package tests for accounts, entrypoints, and key-store226scripts/run_accounts_tests.sh <aztec-packages-dir> [accounts|entrypoints|key-store]227```228229## Edge Cases and Failure Handling230231- Recreated account address does not match expected address:232verify the exact flavor, secret, salt, and signing key/public key used for the original account.233- Account can be computed locally but cannot see notes/events:234the instance/artifact or account registration path was likely not re-established in the wallet/PXE.235- `getDeployMethod()` throws about missing initializer:236that account contract does not expose an initializer path at this pin.237- Self-funded account deployment fails:238inspect the wrapped payment method and resulting `AccountFeePaymentMethodOptions`.239- `lazy` account modules fail under Node:240expected at this pin; switch to eager imports.241- SSH-backed ECDSA recovery fails:242confirm the same SSH public-key identity is available to the agent.243244## Next Steps / Related Files245246- Use `reference.md` for the pinned source map and API/file coverage.247- Use `patterns.md` for reusable deployment and reconstruction snippets.248- Use `scripts/` for repeatable setup, inspection, and test workflows.