Private Execution Environment (PXE)
This page describes the Private Execution Environment (PXE, pronounced "pixie"), a client-side library for the execution of private operations. It is a TypeScript library that can be run within Node.js, inside wallet software or a browser.
The PXE generates proofs of private function execution, and sends these proofs along with public function execution requests to the sequencer. Private inputs never leave the client-side PXE.
The PXE is responsible for:
- storing secrets (e.g. encryption keys, notes, tagging secrets for note discovery) and exposing an interface for safely accessing them
- orchestrating private function (circuit) execution and proof generation, including implementing oracles needed for transaction execution
- syncing users' relevant network state, obtained from an Aztec node
- safely handling multiple accounts with siloed data and permissions
One PXE can handle data and secrets for multiple accounts, while also providing isolation between them as required.
System architecture
When the PXE queries the node for world state (e.g., to check if a nullifier exists), the node learns which data the user is interested in. This is a known tradeoff—users can mitigate this by running their own node.
Components
Contract Function Simulator
An application prompts the user's PXE to execute a transaction (e.g. execute function X with arguments Y from account Z). The application or wallet may handle gas estimation.
The contract function simulator handles execution of smart contract functions by simulating transactions. It generates the required data and inputs for these functions, including partial witnesses and public inputs.
Until simulated simulations are implemented (#9133), authentication witnesses are required for simulation before proving.
Proof Generation
After simulation, the wallet calls proveTx on the PXE with all of the data generated during simulation and any authentication witnesses (for allowing contracts to act on behalf of the user's account contract).
Once proven, the wallet sends the transaction to the network and sends the transaction hash back to the application.
Database
The PXE database stores various types of data locally:
- Notes: Data representing users' private state. Notes are stored onchain as encrypted logs. Once discovered via note tagging, notes are decrypted and stored locally in the PXE.
- Authentication Witnesses: Data used to approve others for executing transactions on your behalf. The PXE provides this data to transactions on-demand during transaction simulation via oracles.
- Capsules: Per-contract non-volatile local storage for caching computation results and persisting data across transactions. See Using Capsules for more details.
- Address Book: Complete addresses (address + public keys) for registered accounts and known senders. This enables the PXE to sync private logs tagged with registered sender addresses.
Note discovery is handled by Aztec contracts, not the PXE. This allows users to customize or update their note discovery mechanism as needed.
Contract management
Applications can add contract code required for a user to interact with the application to the user's PXE. The PXE will check whether the required contracts have already been registered. There are no getters to check whether a contract has been registered, as this could leak privacy (e.g. a dapp could check whether specific contracts have been registered in a user's PXE and infer information about their interaction history).
Keystore
The keystore securely stores cryptographic keys for registered accounts, including:
- Nullifier keys: Used to create nullifiers that invalidate notes when spent
- Incoming viewing keys: Used to decrypt notes sent to the account
- Outgoing viewing keys: Used to decrypt notes sent by the account
- Tagging keys: Used for note discovery via the tagging protocol
Oracles
Oracles are pieces of data that are injected into a smart contract function from the client side. Learn more about how oracles work.
Oracle versioning
The set of oracles that the PXE exposes to private and utility functions is versioned, so that contracts can declare which oracles they expect to be available. Every contract compiled with Aztec.nr records the oracle version it was built against, and the PXE checks this version before executing any oracle call.
The version uses two components, major.minor, with the following compatibility rules:
majormust match exactly. A major bump is a breaking change — oracles were removed or their signatures changed — and a PXE on a different major cannot safely run the contract.minorindicates additive changes (new oracles). The PXE uses a best-effort approach here: a contract compiled against a higherminorthan the PXE supports is still allowed to run, and an error is only thrown if the contract actually invokes an oracle the PXE does not know about. In practice, a contract built with a newer Aztec.nr may not use any of the newly added oracles at all, in which case it runs fine on an older PXE.
The canonical version constants live in the PXE (ORACLE_VERSION_MAJOR / ORACLE_VERSION_MINOR in yarn-project/pxe/src/oracle_version.ts) and in Aztec.nr (noir-projects/aztec-nr/aztec/src/oracle/version.nr). The two are kept in lockstep as part of each release.
Resolving a version mismatch
If you see an error like "Oracle '…' not found. … The contract was compiled with Aztec.nr oracle version X.Y, but this private execution environment only supports up to A.B", the contract uses one or more oracles from a newer Aztec.nr than your PXE supports.
To fix it, upgrade the software that ships the PXE (sandbox, wallet, or whatever embeds @aztec/pxe) to a release whose Aztec.nr version is at least as new as the one the contract was compiled with.
If the PXE reports a version that should include every oracle the contract needs but an oracle is still missing, that is a contract bug rather than a version problem and you should likely report it to the app developer.
For developers
To learn how to develop on top of the PXE, refer to these guides:
Next steps
- Wallets - Learn how wallets interact with the PXE
- State management - Understand how private state is managed
- Note discovery - Learn how notes are discovered and synced