PXE Private Execution Operations
Overview
Use this skill for direct @aztec/pxe work.
Primary scope:
- private execution lifecycle (
simulateTx, profileTx, proveTx, executeUtility)
- note discovery/synchronization behavior and scope control
- sender/recipient tagging workflows
- private event retrieval and filter handling
- oracle compatibility checks and PXE debug helpers
Out of scope:
- Noir/Aztec.nr contract authoring (use
aztec-contracts)
- generic Aztec.js app flows that do not need direct PXE control (use
aztec-js)
- deployment-focused procedures (use
aztec-deployment)
Required Repository State
Use the upstream repository and pin:
- Repo:
https://github.com/AztecProtocol/aztec-packages
- Tag:
v4.2.0
- Commit:
f8c89cf4345df6c4ca9e66ea9b738e96070abc5a
- Source root:
yarn-project/pxe
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 PXE as a serialized execution environment: high-level jobs are queued and run one-at-a-time.
- Always pass an explicit
scopes: AztecAddress[] list; the 'ALL_SCOPES' sentinel was removed. To emulate the old "see everything" behavior, pass the enumerated list of registered addresses: scopes = (await pxe.getRegisteredAccounts()).map(a => a.address).
- Capsule access is enforced at the PXE level in v4.2.0: a contract touching capsules scoped to an address not in the tx's
scopes list fails at runtime with Scope 0x… is not in the allowed scopes list: [...]. AztecAddress::zero() is always permitted (global scope).
- Register recipient accounts with
registerAccount(...) before expecting note or private event visibility.
- Register counterpart senders with
registerSender(...) when syncing tagged logs across peers.
- Use
simulateTx before proveTx; only prove after simulation and sync checks pass.
- For private events,
filter.scopes must be non-empty and block range follows [fromBlock, toBlock).
- Use
debug.getNotes(...) only for diagnostics; prefer contract utility functions for production reads.
- If oracle interface changes, run oracle version checks before trusting cross-version simulations.
Quick Start
# install dependencies in your app
scripts/install_pxe_deps.sh npm
# check node reachability + optional pxe source path validation
scripts/preflight_pxe.sh http://localhost:8080 /path/to/aztec-packages/yarn-project/pxe
import { createAztecNodeClient, waitForNode } from '@aztec/aztec.js/node';
import { createPXE, getPXEConfig } from '@aztec/pxe/server';
const node = createAztecNodeClient('http://localhost:8080');
await waitForNode(node);
const pxe = await createPXE(node, getPXEConfig(), {
loggerActorLabel: 'app-pxe',
});
Core Workflows
1. Boot PXE and Anchor State
- Build node client and wait for JSON-RPC readiness.
- Create PXE via
createPXE(...) from @aztec/pxe/server or @aztec/pxe/client/lazy.
- Use
getSyncedBlockHeader() to confirm the current anchor block before execution.
2. Register Accounts, Senders, and Contract Data
- Register account recipients via
registerAccount(secretKey, partialAddress).
- Register known counterpart senders via
registerSender(senderAddress).
- Register artifacts/instances via
registerContractClass(...) and registerContract(...).
- Verify registration with
getRegisteredAccounts(), getSenders(), getContractInstance().
3. Run Private Execution Lifecycle
simulateTx(txRequest, opts) for private (and optional public) simulation.
opts.overrides?: SimulationOverrides injects simulation-time contract instances/artifacts (useful for testing).
profileTx(txRequest, { profileMode, scopes }) for execution/gate diagnostics.
profileMode values: 'full' | 'execution-steps' | 'gates'.
proveTx(txRequest, scopes) only after simulation correctness is confirmed.
- Returns
TxProvingResult; publicInputs is non-optional on the result.
executeUtility(functionCall, { authwits, scopes }) for utility paths and sync-state calls.
4. Note Discovery and Synchronization
- PXE sync occurs before simulation/event operations; keep one execution flow per state transition.
- Contract sync is scope-aware;
[] scopes deny access and skip sync.
- Use
debug.sync() to force an explicit sync checkpoint when diagnosing stale state.
- Use
debug.getNotes({ contractAddress, owner?, storageSlot?, status?, siloedNullifier?, scopes }) for note-level diagnostics.
5. Tagging (Sender / Recipient)
- Sender-side index progression is maintained per directional secret
(sender, recipient, contract).
- Recipient-side log loading scans bounded windows of tagging indexes and updates aged/finalized indices.
- Registering sender addresses improves recipient decryption coverage for incoming private logs.
- If tags are reused unexpectedly, inspect pending/finalized index movement and tx inclusion timing.
6. Private Events
- Retrieve private events via
getPrivateEvents(eventSelector, filter).
- Required filter fields:
contractAddress
scopes (non-empty)
- Optional filters:
txHash, fromBlock, toBlock (toBlock exclusive).
- If events are missing, ensure account registration, scope inclusion, and anchor sync point.
7. Oracle and Debug Workflows
- Verify oracle compatibility with
scripts/check_oracle_version.sh against your pinned aztec-packages checkout.
- Use
utilityLog outputs and simulation traces (profileTx) to localize oracle call failures.
- Treat
PXEDebugUtils APIs as unstable and diagnostics-only.
8. Shutdown and Resource Hygiene
- Call
pxe.stop() on teardown to end queued jobs cleanly.
- Preserve persistent store state across sessions when reproducing note/tagging issues.
Tooling / Commands
# preflight node/package manager/source checks
scripts/preflight_pxe.sh [node-url] [pxe-dir]
# install core PXE dependencies
scripts/install_pxe_deps.sh <npm|yarn|pnpm> [version]
# wait for node JSON-RPC readiness
scripts/wait_for_aztec_node.sh <node-url> [timeout-seconds] [interval-seconds]
# run a TypeScript example via tsx
scripts/run_pxe_example.sh <entry-file.ts> [-- <extra-args...>]
# summarize pxe package exports + method surfaces
scripts/summarize_pxe_surface.sh <aztec-packages-dir>
# run @aztec/pxe package tests
scripts/run_pxe_tests.sh <aztec-packages-dir> [test-path-pattern]
# run oracle interface compatibility check
scripts/check_oracle_version.sh <aztec-packages-dir>
Edge Cases and Failure Handling
At least one scope is required to get private events:
provide non-empty filter.scopes.
- Missing private notes/events despite successful tx:
verify recipient account registration and scope membership.
Incompatible oracle version error:
run oracle version check and align Aztec.nr/PXE versions.
- Simulations appear stale after chain changes:
force
debug.sync() and re-run with fresh anchor block.
- Interleaved requests behave unpredictably:
avoid app-side concurrent PXE operation bursts; serialize user flows.
- Tagging sync does not advance:
verify sender registration and inspect finalized/aged tagging index windows.
Next Steps / Related Files
- Use
reference.md for source map and API/file coverage.
- Use
patterns.md for reusable workflow snippets.
- Use
scripts/ for repeatable diagnostics and verification.
1---2name: aztec-pxe3description: Use this skill when implementing or debugging direct PXE workflows in TypeScript, including private execution lifecycle, note discovery/synchronization, sender/recipient tagging, private events, scopes, and oracle/debug checks.4license: Proprietary. LICENSE.txt has complete terms5---67# PXE Private Execution Operations89## Overview1011Use this skill for direct `@aztec/pxe` work.1213Primary scope:1415- private execution lifecycle (`simulateTx`, `profileTx`, `proveTx`, `executeUtility`)16- note discovery/synchronization behavior and scope control17- sender/recipient tagging workflows18- private event retrieval and filter handling19- oracle compatibility checks and PXE debug helpers2021Out of scope:2223- Noir/Aztec.nr contract authoring (use `aztec-contracts`)24- generic Aztec.js app flows that do not need direct PXE control (use `aztec-js`)25- deployment-focused procedures (use `aztec-deployment`)2627## Required Repository State2829Use the upstream repository and pin:3031- Repo: `https://github.com/AztecProtocol/aztec-packages`32- Tag: `v4.2.0`33- Commit: `f8c89cf4345df6c4ca9e66ea9b738e96070abc5a`34- Source root: `yarn-project/pxe`3536Checkout example:3738```bash39git clone https://github.com/AztecProtocol/aztec-packages.git40cd aztec-packages41git checkout v4.2.042git status43```4445Expected status includes `HEAD detached at v4.2.0`.4647## Operating Rules4849- Treat PXE as a serialized execution environment: high-level jobs are queued and run one-at-a-time.50- Always pass an explicit `scopes: AztecAddress[]` list; the `'ALL_SCOPES'` sentinel was removed. To emulate the old "see everything" behavior, pass the enumerated list of registered addresses: `scopes = (await pxe.getRegisteredAccounts()).map(a => a.address)`.51- Capsule access is enforced at the PXE level in v4.2.0: a contract touching capsules scoped to an address not in the tx's `scopes` list fails at runtime with `Scope 0x… is not in the allowed scopes list: [...]`. `AztecAddress::zero()` is always permitted (global scope).52- Register recipient accounts with `registerAccount(...)` before expecting note or private event visibility.53- Register counterpart senders with `registerSender(...)` when syncing tagged logs across peers.54- Use `simulateTx` before `proveTx`; only prove after simulation and sync checks pass.55- For private events, `filter.scopes` must be non-empty and block range follows `[fromBlock, toBlock)`.56- Use `debug.getNotes(...)` only for diagnostics; prefer contract utility functions for production reads.57- If oracle interface changes, run oracle version checks before trusting cross-version simulations.5859## Quick Start6061```bash62# install dependencies in your app63scripts/install_pxe_deps.sh npm6465# check node reachability + optional pxe source path validation66scripts/preflight_pxe.sh http://localhost:8080 /path/to/aztec-packages/yarn-project/pxe67```6869```typescript70import { createAztecNodeClient, waitForNode } from '@aztec/aztec.js/node';71import { createPXE, getPXEConfig } from '@aztec/pxe/server';7273const node = createAztecNodeClient('http://localhost:8080');74await waitForNode(node);7576const pxe = await createPXE(node, getPXEConfig(), {77 loggerActorLabel: 'app-pxe',78});79```8081## Core Workflows8283### 1. Boot PXE and Anchor State 8485- Build node client and wait for JSON-RPC readiness.86- Create PXE via `createPXE(...)` from `@aztec/pxe/server` or `@aztec/pxe/client/lazy`.87- Use `getSyncedBlockHeader()` to confirm the current anchor block before execution.8889### 2. Register Accounts, Senders, and Contract Data9091- Register account recipients via `registerAccount(secretKey, partialAddress)`.92- Register known counterpart senders via `registerSender(senderAddress)`.93- Register artifacts/instances via `registerContractClass(...)` and `registerContract(...)`.94- Verify registration with `getRegisteredAccounts()`, `getSenders()`, `getContractInstance()`.9596### 3. Run Private Execution Lifecycle9798- `simulateTx(txRequest, opts)` for private (and optional public) simulation.99 - `opts.overrides?: SimulationOverrides` injects simulation-time contract instances/artifacts (useful for testing).100- `profileTx(txRequest, { profileMode, scopes })` for execution/gate diagnostics.101 - `profileMode` values: `'full'` | `'execution-steps'` | `'gates'`.102- `proveTx(txRequest, scopes)` only after simulation correctness is confirmed.103 - Returns `TxProvingResult`; `publicInputs` is non-optional on the result.104- `executeUtility(functionCall, { authwits, scopes })` for utility paths and sync-state calls.105106### 4. Note Discovery and Synchronization107108- PXE sync occurs before simulation/event operations; keep one execution flow per state transition.109- Contract sync is scope-aware; `[]` scopes deny access and skip sync.110- Use `debug.sync()` to force an explicit sync checkpoint when diagnosing stale state.111- Use `debug.getNotes({ contractAddress, owner?, storageSlot?, status?, siloedNullifier?, scopes })` for note-level diagnostics.112113### 5. Tagging (Sender / Recipient)114115- Sender-side index progression is maintained per directional secret `(sender, recipient, contract)`.116- Recipient-side log loading scans bounded windows of tagging indexes and updates aged/finalized indices.117- Registering sender addresses improves recipient decryption coverage for incoming private logs.118- If tags are reused unexpectedly, inspect pending/finalized index movement and tx inclusion timing.119120### 6. Private Events121122- Retrieve private events via `getPrivateEvents(eventSelector, filter)`.123- Required filter fields:124- `contractAddress`125- `scopes` (non-empty)126- Optional filters: `txHash`, `fromBlock`, `toBlock` (`toBlock` exclusive).127- If events are missing, ensure account registration, scope inclusion, and anchor sync point.128129### 7. Oracle and Debug Workflows130131- Verify oracle compatibility with `scripts/check_oracle_version.sh` against your pinned `aztec-packages` checkout.132- Use `utilityLog` outputs and simulation traces (`profileTx`) to localize oracle call failures.133- Treat `PXEDebugUtils` APIs as unstable and diagnostics-only.134135### 8. Shutdown and Resource Hygiene136137- Call `pxe.stop()` on teardown to end queued jobs cleanly.138- Preserve persistent store state across sessions when reproducing note/tagging issues.139140## Tooling / Commands141142```bash143# preflight node/package manager/source checks144scripts/preflight_pxe.sh [node-url] [pxe-dir]145146# install core PXE dependencies147scripts/install_pxe_deps.sh <npm|yarn|pnpm> [version]148149# wait for node JSON-RPC readiness150scripts/wait_for_aztec_node.sh <node-url> [timeout-seconds] [interval-seconds]151152# run a TypeScript example via tsx153scripts/run_pxe_example.sh <entry-file.ts> [-- <extra-args...>]154155# summarize pxe package exports + method surfaces156scripts/summarize_pxe_surface.sh <aztec-packages-dir>157158# run @aztec/pxe package tests159scripts/run_pxe_tests.sh <aztec-packages-dir> [test-path-pattern]160161# run oracle interface compatibility check162scripts/check_oracle_version.sh <aztec-packages-dir>163```164165## Edge Cases and Failure Handling166167- `At least one scope is required to get private events`:168provide non-empty `filter.scopes`.169- Missing private notes/events despite successful tx:170verify recipient account registration and scope membership.171- `Incompatible oracle version` error:172run oracle version check and align Aztec.nr/PXE versions.173- Simulations appear stale after chain changes:174force `debug.sync()` and re-run with fresh anchor block.175- Interleaved requests behave unpredictably:176avoid app-side concurrent PXE operation bursts; serialize user flows.177- Tagging sync does not advance:178verify sender registration and inspect finalized/aged tagging index windows.179180## Next Steps / Related Files181182- Use `reference.md` for source map and API/file coverage.183- Use `patterns.md` for reusable workflow snippets.184- Use `scripts/` for repeatable diagnostics and verification.