diff --git a/boxes/boxes/react/src/config.ts b/boxes/boxes/react/src/config.ts index 04584897ff3f..ee7d53093ce5 100644 --- a/boxes/boxes/react/src/config.ts +++ b/boxes/boxes/react/src/config.ts @@ -1,7 +1,7 @@ +import { getInitialTestAccountsData } from '@aztec/accounts/testing'; import { AztecAddress, createAztecNodeClient, Wallet } from '@aztec/aztec.js'; +import { getPXEServiceConfig } from '@aztec/pxe/client/lazy'; import { TestWallet } from '@aztec/test-wallet/lazy'; -import { getPXEServiceConfig, createPXEService } from '@aztec/pxe/client/lazy'; -import { getInitialTestAccountsData } from '@aztec/accounts/testing'; export class PrivateEnv { private wallet!: Wallet; @@ -16,13 +16,7 @@ export class PrivateEnv { const config = getPXEServiceConfig(); config.dataDirectory = 'pxe'; config.proverEnabled = false; - const l1Contracts = await aztecNode.getL1ContractAddresses(); - const configWithContracts = { - ...config, - l1Contracts, - }; - const pxe = await createPXEService(aztecNode, configWithContracts); - const wallet = new TestWallet(pxe, aztecNode); + const wallet = await TestWallet.create(aztecNode, config); const [accountData] = await getInitialTestAccountsData(); if (!accountData) { diff --git a/boxes/boxes/vanilla/scripts/deploy.ts b/boxes/boxes/vanilla/scripts/deploy.ts index dbbff6a84170..2ef38da1bab6 100644 --- a/boxes/boxes/vanilla/scripts/deploy.ts +++ b/boxes/boxes/vanilla/scripts/deploy.ts @@ -1,5 +1,3 @@ -import fs from 'fs'; -import path from 'path'; import { AztecAddress, createAztecNodeClient, @@ -11,12 +9,14 @@ import { type Wallet, } from '@aztec/aztec.js'; import { type AztecNode } from '@aztec/aztec.js/interfaces'; -import { createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; +import { SPONSORED_FPC_SALT } from '@aztec/constants'; import { createStore } from '@aztec/kv-store/lmdb'; -import { getDefaultInitializer } from '@aztec/stdlib/abi'; import { SponsoredFPCContractArtifact } from '@aztec/noir-contracts.js/SponsoredFPC'; -import { SPONSORED_FPC_SALT } from '@aztec/constants'; -import { TestWallet } from '@aztec/test-wallet'; +import { getPXEServiceConfig } from '@aztec/pxe/server'; +import { getDefaultInitializer } from '@aztec/stdlib/abi'; +import { TestWallet } from '@aztec/test-wallet/server'; +import fs from 'fs'; +import path from 'path'; // @ts-ignore import { PrivateVotingContract } from '../artifacts/PrivateVoting.ts'; @@ -26,7 +26,7 @@ const WRITE_ENV_FILE = process.env.WRITE_ENV_FILE === 'false' ? false : true; const PXE_STORE_DIR = path.join(import.meta.dirname, '.store'); -async function setupPXE(aztecNode: AztecNode) { +async function setupWallet(aztecNode: AztecNode) { fs.rmSync(PXE_STORE_DIR, { recursive: true, force: true }); const store = await createStore('pxe', { @@ -37,15 +37,11 @@ async function setupPXE(aztecNode: AztecNode) { const config = getPXEServiceConfig(); config.dataDirectory = 'pxe'; config.proverEnabled = PROVER_ENABLED; - const configWithContracts = { - ...config, - }; - const pxe = await createPXEService(aztecNode, configWithContracts, { + return await TestWallet.create(aztecNode, config, { store, useLogSuffix: true, }); - return pxe; } async function getSponsoredPFCContract() { @@ -158,8 +154,7 @@ async function writeEnvFile(deploymentInfo) { async function createAccountAndDeployContract() { const aztecNode = createAztecNodeClient(AZTEC_NODE_URL); - const pxe = await setupPXE(aztecNode); - const wallet = new TestWallet(pxe, aztecNode); + const wallet = await setupWallet(aztecNode); // Register the SponsoredFPC contract (for sponsored fee payments) await wallet.registerContract( diff --git a/boxes/boxes/vite/src/config.ts b/boxes/boxes/vite/src/config.ts index 4ef91216f740..185f4606f2a1 100644 --- a/boxes/boxes/vite/src/config.ts +++ b/boxes/boxes/vite/src/config.ts @@ -1,11 +1,9 @@ +import { getInitialTestAccountsData } from "@aztec/accounts/testing"; import { AztecAddress, createAztecNodeClient, Wallet } from "@aztec/aztec.js"; -import { TestWallet } from "@aztec/test-wallet/lazy"; import { - PXEServiceConfig, - getPXEServiceConfig, - createPXEService, + getPXEServiceConfig } from "@aztec/pxe/client/lazy"; -import { getInitialTestAccountsData } from "@aztec/accounts/testing"; +import { TestWallet } from "@aztec/test-wallet/lazy"; export class PrivateEnv { private wallet!: Wallet; @@ -20,13 +18,7 @@ export class PrivateEnv { const config = getPXEServiceConfig(); config.dataDirectory = "pxe"; config.proverEnabled = false; - const l1Contracts = await aztecNode.getL1ContractAddresses(); - const configWithContracts = { - ...config, - l1Contracts, - } as PXEServiceConfig; - const pxe = await createPXEService(aztecNode, configWithContracts); - const wallet = new TestWallet(pxe, aztecNode); + const wallet = await TestWallet.create(aztecNode, config); const [accountData] = await getInitialTestAccountsData(); if (!accountData) { diff --git a/docker-compose.yml b/docker-compose.yml index 05392fc3bb08..591a06ec2c18 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,34 +1,5 @@ name: aztec-devnet services: - pxe: - image: aztecprotocol/aztec${AZTEC_DOCKER_TAG:-@sha256:03feac60e91f1aabf678cecbcd13271dda229120ec6007f2c1bac718ff550c70} - # need to run bb for proofs and bb is only built for x86 - platform: linux/amd64 - environment: - LOG_LEVEL: ${LOG_LEVEL:-info} - L1_CHAIN_ID: 31337 - VERSION: 1 - PXE_PROVER_ENABLED: ${PXE_PROVER_ENABLED:-1} - PXE_DATA_DIRECTORY: /var/lib/aztec/pxe - NODE_NO_WARNINGS: 1 - AZTEC_PORT: 8080 - MNEMONIC: "test test test test test test test test test test test junk" - entrypoint: > - sh -c ' - export AZTEC_NODE_URL=$$(cat /var/run/secrets/aztec-node-url); - while ! curl --head --silent $AZTEC_NODE_URL > /dev/null; do echo "Node $$AZTEC_NODE_URL not up. Retrying after 1s"; sleep 1; done; - node /usr/src/yarn-project/aztec/dest/bin/index.js start --pxe - ' - secrets: - - aztec-node-url - extra_hosts: - - "host.docker.internal:host-gateway" - volumes: - - aztec:/var/lib/aztec - ports: - - 8080:8080/tcp - profiles: - - pxe node: image: aztecprotocol/aztec${AZTEC_DOCKER_TAG:-@sha256:03feac60e91f1aabf678cecbcd13271dda229120ec6007f2c1bac718ff550c70} @@ -54,7 +25,7 @@ services: P2P_QUERY_FOR_IP: true P2P_ENABLED: true PEER_ID_PRIVATE_KEY: - AZTEC_PORT: 8999 + AZTEC_PORT: 8080 OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: ${OTEL_EXPORTER_OTLP_METRICS_ENDPOINT:-http://otel-collector:4318/v1/metrics} OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: ${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-http://otel-collector:4318/v1/traces} secrets: @@ -90,17 +61,16 @@ services: profiles: - node ports: - # the RPC endpoint - expose it on a different port to avoid conflicting with PXE - - 8999:8999/tcp + - 8080:8080/tcp - 9000:9000/tcp - 9001:9001/udp cli: image: aztecprotocol/aztec${AZTEC_DOCKER_TAG:-@sha256:03feac60e91f1aabf678cecbcd13271dda229120ec6007f2c1bac718ff550c70} - # run the same image as pxe + # run the same image as node platform: linux/amd64 environment: - PXE_URL: http://pxe:8080 + AZTEC_NODE_URL: http://node:8080 NODE_NO_WARNINGS: 1 SECRET_KEY: ETHEREUM_HOSTS: diff --git a/docs/docs/developers/guides/js_apps/how_to_connect_to_sandbox.md b/docs/docs/developers/guides/js_apps/how_to_connect_to_sandbox.md index 7fbf6be529a1..f7b63d5573b8 100644 --- a/docs/docs/developers/guides/js_apps/how_to_connect_to_sandbox.md +++ b/docs/docs/developers/guides/js_apps/how_to_connect_to_sandbox.md @@ -67,9 +67,11 @@ console.log('Chain ID:', nodeInfo.l1ChainId); Now that we have a PXE running, we can create a Wallet: ```typescript +import { createAztecNodeClient } from '@aztec/aztec.js'; import { TestWallet } from '@aztec/test-wallet'; -const wallet = new TestWallet(pxe); +const node = createAztecNodeClient('http://localhost:8080'); +const wallet = await TestWallet.create(node); ``` ### Get test accounts diff --git a/docs/docs/developers/reference/environment_reference/cli_reference.md b/docs/docs/developers/reference/environment_reference/cli_reference.md index 8a871fe5fddc..d4df3a1b008b 100644 --- a/docs/docs/developers/reference/environment_reference/cli_reference.md +++ b/docs/docs/developers/reference/environment_reference/cli_reference.md @@ -7,19 +7,17 @@ sidebar_position: 2 import { AztecTestnetVersion } from '@site/src/components/Snippets/general_snippets'; -This reference guide provides documentation for the Aztec CLI commands (`aztec`) and their options. The CLI is a powerful tool for interacting with the Aztec network, managing accounts, deploying contracts, and more. +This reference guide provides documentation for the Aztec CLI commands (`aztec`) and their options. The CLI is a powerful tool for interacting with the Aztec network. -Consider using the [`aztec-wallet`](./cli_wallet_reference.md) for account related or interacting with an existing network (e.g. testnet). +If you want to deploy contracts and manage accounts you will need to use [`aztec-wallet`](./cli_wallet_reference.md). ## Overview The Aztec CLI provides commands for: - **Starting and Testing**: Starting the Aztec Sandbox and running tests -- **Account Management**: Creating, deploying, and managing Aztec accounts - **Contract Operations**: Deploying, interacting with, and managing smart contracts - **Network Information**: Querying node and network status -- **Transaction Management**: Sending, canceling, and querying transactions - **Data Retrieval**: Accessing logs and contract data - **Development Tools**: Profiling, debugging, and code generation - **L1 Integration**: Managing L1 contracts and bridges @@ -29,14 +27,13 @@ The Aztec CLI provides commands for: Each command section includes detailed options and examples of usage. The documentation is organized to help you quickly find the commands you need for your specific use case. -Note: Most commands accept a `--rpc-url` option to specify the Aztec node URL, and many accept fee-related options for gas limit and price configuration. +Note: Most commands accept a `--node-url` option to specify the Aztec node URL, and many accept fee-related options for gas limit and price configuration. ## Common Commands - [`aztec get-node-info`](#get-node-info) - [`aztec get-l1-addresses`](#get-l1-addresses) - [`aztec get-block`](#get-block) -- [`aztec start --pxe`](#pxe-options) Example usage: @@ -48,7 +45,7 @@ aztec start --sandbox aztec start --sandbox --port 8081 # Start specific components -aztec start --pxe +aztec start --node # Start with Ethereum options aztec start --port 8081 --pxe --pxe.nodeUrl=$BOOTNODE --pxe.proverEnabled false --l1-chain-id 31337 @@ -192,20 +189,6 @@ aztec start --node --network testnet - `--tel.otel-export-timeout-ms `: The timeout for exporting metrics (default: 30000). - `--tel.otel-exclude-metrics `: A list of metric prefixes to exclude from export. -#### PXE Options - -- `--pxe`: Starts Aztec PXE with options. -- `--pxe.data-store-map-size-kb `: DB mapping size to be applied to all key/value stores (default: 134217728). -- `--pxe.rollup-version `: The version of the rollup. -- `--pxe.l2-block-batch-size `: Maximum amount of blocks to pull from the stream in one request when synchronizing (default: 200). -- `--pxe.bb-binary-path `: Path to the BB binary. -- `--pxe.bb-working-directory `: Working directory for the BB binary. -- `--pxe.bb-skip-cleanup `: True to skip cleanup of temporary files for debugging purposes. -- `--pxe.prover-enabled `: Enable real proofs (default: true). -- `--pxe.network `: External Aztec network to connect to (e.g. devnet). -- `--pxe.api-key `: API Key required by the external network's node. -- `--pxe.node-url `: Custom Aztec Node URL to connect to. - ##### Example Usage ```bash @@ -384,7 +367,6 @@ aztec start --network testnet --l1-rpc-urls https://example.com --l1-consensus-h - `--bot`: Starts Aztec Bot with options. - `--bot.node-url `: The URL to the Aztec node to check for tx pool status. - `--bot.node-admin-url `: The URL to the Aztec node admin API to force-flush txs if configured. -- `--bot.pxe-url `: URL to the PXE for sending txs, or undefined if an in-proc PXE is used. - `--bot.l1-mnemonic `: The mnemonic for the account to bridge fee juice from L1. - `--bot.l1-private-key `: The private key for the account to bridge fee juice from L1. - `--bot.sender-private-key `: Signing private key for the sender account. @@ -440,313 +422,7 @@ Options: - `-i, --interactive`: Keep STDIN open even if not attached. - `-t, --tty`: Allocate a pseudo-TTY. -## Account Management - -Consider using the [`aztec-wallet`](./cli_wallet_reference.md) for account management (or contract interaction) related actions, since it has a PXE internally and manages aliases to get you started quicker. - -`aztec` cli requires you to have a PXE running already (either as part of when you run the sandbox by default or just a separate PXE) - -### create-account - -Creates an Aztec account for sending transactions. - -```bash -aztec create-account [options] -``` - -Options: - -- `--skip-initialization`: Skip initializing the account contract. Useful for publicly deploying an existing account. -- `--public-deploy`: Publishes the account contract instance (and the class, if needed). Needed if the contract contains public functions. -- `-p, --public-key `: Public key that identifies a private signing key stored outside of the wallet. Used for ECDSA SSH accounts over the secp256r1 curve. -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `-sk, --secret-key `: Secret key for account. Uses random by default. (env: SECRET_KEY) -- `-t, --type `: Type of account to create (choices: "schnorr", "ecdsasecp256r1", "ecdsasecp256r1ssh", "ecdsasecp256k1", default: "schnorr") -- `--register-only`: Just register the account on the PXE. Do not deploy or initialize the account contract. -- `--json`: Emit output as json -- `--no-wait`: Skip waiting for the contract to be deployed. Print the hash of deployment transaction -- `--payment `: Fee payment method and arguments. - Parameters: - - `method`: Valid values: "fee_juice", "fpc-public", "fpc-private", "fpc-sponsored" Default: fee_juice - - `feePayer`: The account paying the fee. - - `asset`: The asset used for fee payment. Required for "fpc-public" and "fpc-private". - - `fpc`: The FPC contract that pays in fee juice. Not required for the "fee_juice" method. - - `claim`: Whether to use a previously stored claim to bridge fee juice. - - `claimSecret`: The secret to claim fee juice on L1. - - `claimAmount`: The amount of fee juice to be claimed. - - `messageLeafIndex`: The index of the claim in the l1toL2Message tree. - - `feeRecipient`: Recipient of the fee. - - Format: --payment method=name,feePayer=address,asset=address ... -- `--gas-limits `: Gas limits for the tx. -- `--max-fees-per-gas `: Maximum fees per gas unit for DA and L2 computation. -- `--max-priority-fees-per-gas `: Maximum priority fees per gas unit for DA and L2 computation. -- `--no-estimate-gas`: Whether to automatically estimate gas limits for the tx. -- `--estimate-gas-only`: Only report gas estimation for the tx, do not send it. - -### deploy-account - -Deploys an already registered aztec account that can be used for sending transactions. - -```bash -aztec deploy-account [options] -``` - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `--json`: Emit output as json -- `--no-wait`: Skip waiting for the contract to be deployed. Print the hash of deployment transaction -- `--register-class`: Register the contract class (useful for when the contract class has not been deployed yet). -- `--payment `: Fee payment method and arguments. - Parameters: - - `method`: Valid values: "fee_juice", "fpc-public", "fpc-private", "fpc-sponsored" Default: fee_juice - - `feePayer`: The account paying the fee. - - `asset`: The asset used for fee payment. Required for "fpc-public" and "fpc-private". - - `fpc`: The FPC contract that pays in fee juice. Not required for the "fee_juice" method. - - `claim`: Whether to use a previously stored claim to bridge fee juice. - - `claimSecret`: The secret to claim fee juice on L1. - - `claimAmount`: The amount of fee juice to be claimed. - - `messageLeafIndex`: The index of the claim in the l1toL2Message tree. - - `feeRecipient`: Recipient of the fee. - - Format: --payment method=name,feePayer=address,asset=address ... -- `--gas-limits `: Gas limits for the tx. -- `--max-fees-per-gas `: Maximum fees per gas unit for DA and L2 computation. -- `--max-priority-fees-per-gas `: Maximum priority fees per gas unit for DA and L2 computation. -- `--no-estimate-gas`: Whether to automatically estimate gas limits for the tx. -- `--estimate-gas-only`: Only report gas estimation for the tx, do not send it. - -### get-accounts - -Retrieves all Aztec accounts stored in the PXE. - -```bash -aztec get-accounts [options] -``` - -Options: - -- `--json`: Emit output as JSON. - -### get-account - -Retrieves an account given its Aztec address. - -```bash -aztec get-account
[options] -``` - -Arguments: - -- `address`: The Aztec address to get account for - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) - -### register-sender - -Registers a sender's address in the wallet, so the note synching process will look for notes sent by them. - -```bash -aztec register-sender [options] [address] -``` - -Arguments: - -- `address`: The address of the sender to register - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) - -### create-authwit - -Creates an authorization witness that can be privately sent to a caller so they can perform an action on behalf of the provided account. - -```bash -aztec create-authwit [options] -``` - -Arguments: - -- `functionName`: Name of function to authorize -- `caller`: Account to be authorized to perform the action - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `--args [args...]`: Function arguments (default: []) -- `-ca, --contract-address
`: Aztec address of the contract. -- `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract -- `-sk, --secret-key `: The sender's secret key (env: SECRET_KEY) - -### authorize-action - -Authorizes a public call on the caller, so they can perform an action on behalf of the provided account. - -```bash -aztec authorize-action [options] -``` - -Arguments: - -- `functionName`: Name of function to authorize -- `caller`: Account to be authorized to perform the action - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `--args [args...]`: Function arguments (default: []) -- `-ca, --contract-address
`: Aztec address of the contract. -- `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract -- `-sk, --secret-key `: The sender's secret key (env: SECRET_KEY) - -## Contract Deployment and Interaction - -### deploy - -Deploys a compiled Aztec.nr contract to Aztec. - -```bash -aztec deploy [options] -``` - -Arguments: - -- `artifact`: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract - -Options: - -- `--init `: The contract initializer function to call (default: "constructor"). -- `--no-init`: Leave the contract uninitialized. -- `-a, --args `: Contract constructor arguments. -- `-k, --public-key `: Optional encryption public key for this address. -- `-s, --salt `: Optional deployment salt for generating the deployment address. -- `-sk, --secret-key `: The sender's secret key (env: SECRET_KEY) -- `--universal`: Do not mix the sender address into the deployment. -- `--json`: Emit output as JSON. -- `--no-wait`: Skip waiting for the contract deployment. -- `--no-class-registration`: Don't register this contract class. -- `--no-public-deployment`: Don't emit this contract's public bytecode. -- `--payment `: Fee payment method and arguments. - Parameters: - - `method`: Valid values: "fee_juice", "fpc-public", "fpc-private", "fpc-sponsored" Default: fee_juice - - `feePayer`: The account paying the fee. - - `asset`: The asset used for fee payment. Required for "fpc-public" and "fpc-private". - - `fpc`: The FPC contract that pays in fee juice. Not required for the "fee_juice" method. - - `claim`: Whether to use a previously stored claim to bridge fee juice. - - `claimSecret`: The secret to claim fee juice on L1. - - `claimAmount`: The amount of fee juice to be claimed. - - `messageLeafIndex`: The index of the claim in the l1toL2Message tree. - - `feeRecipient`: Recipient of the fee. - - Format: --payment method=name,feePayer=address,asset=address ... -- `--gas-limits `: Gas limits for the tx. -- `--max-fees-per-gas `: Maximum fees per gas unit for DA and L2 computation. -- `--max-priority-fees-per-gas `: Maximum priority fees per gas unit for DA and L2 computation. -- `--no-estimate-gas`: Whether to automatically estimate gas limits for the tx. -- `--estimate-gas-only`: Only report gas estimation for the tx, do not send it. - -### send - -Calls a function on an Aztec contract. - -```bash -aztec send [options] -``` - -Arguments: - -- `functionName`: Name of function to execute - -Options: - -- `-a, --args [functionArgs...]`: Function arguments. -- `-c, --contract-artifact `: Compiled Aztec.nr contract's ABI. -- `-ca, --contract-address
`: Aztec address of the contract. -- `-sk, --secret-key `: The sender's secret key (env: SECRET_KEY) -- `--no-wait`: Print transaction hash without waiting for it to be mined. -- `--payment `: Fee payment method and arguments. - Parameters: - - `method`: Valid values: "fee_juice", "fpc-public", "fpc-private", "fpc-sponsored" Default: fee_juice - - `feePayer`: The account paying the fee. - - `asset`: The asset used for fee payment. Required for "fpc-public" and "fpc-private". - - `fpc`: The FPC contract that pays in fee juice. Not required for the "fee_juice" method. - - `claim`: Whether to use a previously stored claim to bridge fee juice. - - `claimSecret`: The secret to claim fee juice on L1. - - `claimAmount`: The amount of fee juice to be claimed. - - `messageLeafIndex`: The index of the claim in the l1toL2Message tree. - - `feeRecipient`: Recipient of the fee. - - Format: --payment method=name,feePayer=address,asset=address ... -- `--gas-limits `: Gas limits for the tx. -- `--max-fees-per-gas `: Maximum fees per gas unit for DA and L2 computation. -- `--max-priority-fees-per-gas `: Maximum priority fees per gas unit for DA and L2 computation. -- `--no-estimate-gas`: Whether to automatically estimate gas limits for the tx. -- `--estimate-gas-only`: Only report gas estimation for the tx, do not send it. - -### simulate - -Simulates the execution of a function on an Aztec contract. - -```bash -aztec simulate [options] -``` - -Arguments: - -- `functionName`: Name of function to simulate - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `--args [args...]`: Function arguments (default: []) -- `-ca, --contract-address
`: Aztec address of the contract. -- `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed - inside a nargo workspace, a package and contract name can be specified as -- `-sk, --secret-key `: The sender's secret key (env: SECRET_KEY) - -### add-contract - -Adds an existing contract to the PXE. This is useful if you have deployed a contract outside of the PXE and want to use it with the PXE. - -```bash -aztec add-contract [options] -``` - -Required options: - -- `-c, --contract-artifact `: Compiled Aztec.nr contract's ABI. -- `-ca, --contract-address
`: Aztec address of the contract. -- `--init-hash `: Initialization hash. - -Optional: - -- `--salt `: Optional deployment salt. -- `-p, --public-key `: Optional public key for this contract. -- `--portal-address
`: Optional address to a portal contract on L1. -- `--deployer-address
`: Optional address of the contract deployer. - -### register-contract - -Registers a contract in this wallet's PXE. - -```bash -aztec register-contract [options] [address] [artifact] -``` - -Arguments: - -- `address`: The address of the contract to register -- `artifact`: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo - workspace, a package and contract name can be specified as package@contract - -Options: - -- `--init `: The contract initializer function to call (default: "constructor") -- `-k, --public-key `: Optional encryption public key for this address. Set this value only if this contract is - expected to receive private notes, which will be encrypted using this public key. -- `-s, --salt `: Optional deployment salt as a hex string for generating the deployment address. -- `--deployer `: The address of the account that deployed the contract -- `--args [args...]`: Constructor arguments (default: []) +## Contract interaction ### inspect-contract @@ -793,14 +469,6 @@ Options: - `--node-url `: URL of the node. - `--json`: Emit output as JSON. -### get-pxe-info - -Retrieves information about a PXE at a URL. - -```bash -aztec get-pxe-info [options] -``` - ### block-number Retrieves the current Aztec L2 block number. @@ -809,72 +477,7 @@ Retrieves the current Aztec L2 block number. aztec block-number [options] ``` -### get-contract-data - -Gets information about the Aztec contract deployed at the specified address. - -```bash -aztec get-contract-data [options] -``` - -Arguments: - -- `contractAddress`: Aztec address of the contract. - -Options: - -- `-b, --include-bytecode`: Include the contract's public function bytecode, if any. - -## Transaction and Block Querying - -### get-tx - -Retrieves the receipt for a specified transaction hash. - -```bash -aztec get-tx [options] -``` - -Arguments: - -- `txHash`: A transaction hash to get the receipt for. - -Options: - -- `-u, --rpc-url ` URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `-p, --page ` The page number to display (default: 1) - `-s, --page-size ` The number of transactions to display per page (default: 10) -- `-h, --help` display help for command - -### cancel-tx - -Cancels a pending tx by reusing its nonce with a higher fee and an empty payload. - -```bash -aztec cancel-tx [options] -``` - -Arguments: - -- `txHash`: A transaction hash to cancel. - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `-sk, --secret-key `: The sender's secret key (env: SECRET_KEY) -- `--payment `: Fee payment method and arguments. - Parameters: - - `method`: Valid values: "fee_juice", "fpc-public", "fpc-private", "fpc-sponsored" Default: fee_juice - - `asset`: The asset used for fee payment. Required for "fpc-public" and "fpc-private". - - `fpc`: The FPC contract that pays in fee juice. Not required for the "fee_juice" method. - - `claim`: Whether to use a previously stored claim to bridge fee juice. - - `claimSecret`: The secret to claim fee juice on L1. - - `claimAmount`: The amount of fee juice to be claimed. - - `messageLeafIndex`: The index of the claim in the l1toL2Message tree. - - `feeRecipient`: Recipient of the fee. - - Format: --payment method=name,asset=address,fpc=address ... (default: "method=fee_juice") -- `-i, --increased-fees `: The amounts by which the fees are increased (default: "feePerDaGas":"0x0000000000000000000000000000000000000000000000000000000000000001","feePerL2Gas":"0x0000000000000000000000000000000000000000000000000000000000000001") -- `--max-fees-per-gas `: Maximum fees per gas unit for DA and L2 computation. +## Block Querying ### get-block @@ -955,27 +558,6 @@ Options: - `--contract [paths...]`: Paths to contracts to update dependencies. - `--aztec-version `: The version to update Aztec packages to (default: latest). -### profile - -Profiles a private function by counting the unconditional operations in its execution steps. - -```bash -aztec profile [options] -``` - -Arguments: - -- `functionName`: Name of function to simulate - -Options: - -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `--args [args...]`: Function arguments (default: []) -- `-ca, --contract-address
`: Aztec address of the contract. -- `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract -- `--debug-execution-steps-dir
`: Directory to write execution step artifacts for bb profiling/debugging. -- `-sk, --secret-key `: The sender's secret key (env: SECRET_KEY) - ### generate-secret-and-hash Generates an arbitrary secret (Fr), and its hash (using aztec-nr defaults). @@ -1222,31 +804,6 @@ Options: - `--l1-private-key `: The private key to use for deployment - `--json`: Output the claim in JSON format -### bridge-fee-juice - -Mints L1 Fee Juice and bridges them to L2. - -```bash -aztec bridge-fee-juice [options] -``` - -Arguments: - -- `amount`: The amount of Fee Juice to mint and bridge. -- `recipient`: Aztec address of the recipient. - -Options: - -- `--l1-rpc-urls `: List of Ethereum host URLs. Chain identifiers localhost and testnet can be used (comma separated) (default: ["http://host.docker.internal:8545"]) -- `-m, --mnemonic `: The mnemonic to use for deriving the Ethereum address that will mint and bridge (default: "test test test test test test test test test test test junk") -- `--mint`: Mint the tokens on L1 (default: false) -- `--l1-private-key `: The private key to the eth account bridging -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) -- `-c, --l1-chain-id `: Chain ID of the ethereum host (default: 31337, env: L1_CHAIN_ID) -- `--json`: Output the claim in JSON format -- `--no-wait`: Wait for the bridged funds to be available in L2, polling every 60 seconds -- `--interval `: The polling interval in seconds for the bridged funds (default: "60") - ### get-l1-to-l2-message-witness Gets a L1 to L2 message witness. @@ -1363,14 +920,6 @@ Options: - `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: PXE_URL) - `-c, --l1-chain-id `: Chain ID of the ethereum host (default: 31337, env: L1_CHAIN_ID) -### import-test-accounts - -Import test accounts from pxe. - -```bash -aztec import-test-accounts [options] -``` - ### preload-crs Preload the points data needed for proving and verifying. diff --git a/docs/docs/developers/reference/environment_reference/cli_wallet_reference.md b/docs/docs/developers/reference/environment_reference/cli_wallet_reference.md index 7b0ea81c7022..e652490a073b 100644 --- a/docs/docs/developers/reference/environment_reference/cli_wallet_reference.md +++ b/docs/docs/developers/reference/environment_reference/cli_wallet_reference.md @@ -35,7 +35,6 @@ The CLI wallet supports several global options that can be used with any command - `-V, --version`: Output the version number - `-d, --data-dir `: Storage directory for wallet data (default: "~/.aztec/wallet") - `-p, --prover `: The type of prover the wallet uses (choices: "wasm", "native", "none", default: "native", env: `PXE_PROVER`) -- `--remote-pxe`: Connect to an external PXE RPC server instead of the local one (env: `REMOTE_PXE`) - `-n, --node-url `: URL of the Aztec node to connect to (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `-h, --help`: Display help for command @@ -44,7 +43,6 @@ The CLI wallet supports several global options that can be used with any command Many options can be set using environment variables. For example: - `PXE_PROVER`: Set the prover type -- `REMOTE_PXE`: Enable remote PXE connection - `AZTEC_NODE_URL`: Set the node URL - `SECRET_KEY`: Set the secret key for account operations @@ -210,7 +208,7 @@ Generates a secret key and deploys an account contract. Uses a Schnorr single-ke - `--skip-initialization`: Skip initializing the account contract. Useful for publicly deploying an existing account. - `--public-deploy`: Publishes the account contract instance (and the class, if needed). Needed if the contract contains public functions. - `-p, --public-key `: Public key that identifies a private signing key stored outside of the wallet. Used for ECDSA SSH accounts over the secp256r1 curve. -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080") +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080") - `-sk, --secret-key `: Secret key for account. Uses random by default. (env: `SECRET_KEY`) - `-a, --alias `: Alias for the account. Used for easy reference in subsequent commands. - `-t, --type `: Type of account to create (choices: "schnorr", "ecdsasecp256r1", "ecdsasecp256r1ssh", "ecdsasecp256k1", default: "schnorr") @@ -249,7 +247,7 @@ aztec-wallet deploy-account [options] #### Options - `-f, --from `: Alias or address of the account to deploy -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `--json`: Emit output as json - `--no-wait`: Skip waiting for the contract to be deployed. Print the hash of deployment transaction - `--register-class`: Register the contract class (useful for when the contract class has not been deployed yet) @@ -308,7 +306,7 @@ aztec-wallet deploy [options] [artifact] - `-k, --public-key `: Optional encryption public key for this address. Set this value only if this contract is expected to receive private notes, which will be encrypted using this public key - `-s, --salt `: Optional deployment salt as a hex string for generating the deployment address - `--universal`: Do not mix the sender address into the deployment -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `--args [args...]`: Constructor arguments (default: []) - `-sk, --secret-key `: The sender's secret key (env: `SECRET_KEY`) - `-f, --from `: Alias or address of the account to deploy from @@ -360,7 +358,7 @@ aztec-wallet register-contract [options] [address] [artifact] - `-s, --salt `: Optional deployment salt as a hex string for generating the deployment address Sends a transaction by calling a function on an Aztec contract. - `--args [args...]`: Constructor arguments (default: []) -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `-f, --from `: Alias or address of the account to simulate from - `-a, --alias `: Alias for the contact. Used for easy reference in subsequent commands @@ -384,7 +382,7 @@ aztec-wallet send [options] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `--args [args...]`: Function arguments (default: []) - `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract - `-ca, --contract-address
`: Aztec address of the contract @@ -437,7 +435,7 @@ aztec-wallet simulate [options] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `--args [args...]`: Function arguments (default: []) - `-ca, --contract-address
`: Aztec address of the contract - `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract @@ -465,7 +463,7 @@ aztec-wallet profile [options] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `--args [args...]`: Function arguments (default: []) - `-ca, --contract-address
`: Aztec address of the contract - `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract @@ -495,7 +493,7 @@ aztec-wallet create-authwit [options] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `--args [args...]`: Function arguments (default: []) - `-ca, --contract-address
`: Aztec address of the contract - `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract @@ -532,7 +530,7 @@ aztec-wallet authorize-action [options] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `--args [args...]`: Function arguments (default: []) - `-ca, --contract-address
`: Aztec address of the contract - `-c, --contract-artifact `: Path to a compiled Aztec contract's artifact in JSON format. If executed inside a nargo workspace, a package and contract name can be specified as package@contract @@ -572,7 +570,7 @@ aztec-wallet bridge-fee-juice [options] - `-m, --mnemonic `: The mnemonic to use for deriving the Ethereum address that will mint and bridge (default: "test test test test test test test test test test test junk") - `--mint`: Mint the tokens on L1 (default: false) - `--l1-private-key `: The private key to the eth account bridging -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `-c, --l1-chain-id `: Chain ID of the ethereum host (default: 31337, env: `L1_CHAIN_ID`) - `--json`: Output the claim in JSON format - `--no-wait`: Wait for the bridged funds to be available in L2, polling every 60 seconds @@ -600,7 +598,7 @@ aztec-wallet get-tx [options] [txHash] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `-p, --page `: The page number to display (default: 1) - `-s, --page-size `: The number of transactions to display per page (default: 10) @@ -628,7 +626,6 @@ aztec-wallet cancel-tx [options] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) - `-sk, --secret-key `: The sender's secret key (env: `SECRET_KEY`) - `-f, --from `: Alias or address of the account to simulate from - `--payment `: Fee payment method and arguments @@ -665,7 +662,7 @@ aztec-wallet register-sender [options] [address] #### Options -- `-u, --rpc-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `PXE_URL`) +- `-n, --node-url `: URL of the PXE (default: "http://host.docker.internal:8080", env: `AZTEC_NODE_URL`) - `-f, --from `: Alias or address of the account to simulate from - `-a, --alias `: Alias for the sender. Used for easy reference in subsequent commands diff --git a/docs/docs/developers/reference/environment_reference/sandbox-reference.md b/docs/docs/developers/reference/environment_reference/sandbox-reference.md index e908c43cea12..533c2abbf4c5 100644 --- a/docs/docs/developers/reference/environment_reference/sandbox-reference.md +++ b/docs/docs/developers/reference/environment_reference/sandbox-reference.md @@ -71,13 +71,12 @@ SEQ_MIN_TX_PER_BLOCK=1 # Minimum txs to go on a block. (default: 1) VALIDATOR_PRIVATE_KEY=0x01234567890abcde01234567890abcde # Private key of the ethereum account that will be used to perform sequencer duties ``` -**PXE** +**Wallet** -Variables like `TEST_ACCOUNTS` & `PXE_PORT` are valid here as described above. +Variables like `AZTEC_NODE_URL` and `TEST_ACCOUNTS` are valid here as described above. ```sh -AZTEC_NODE_URL='http://localhost:8079' # The address of an Aztec Node URL that the PXE will connect to (default: http://localhost:8079) -PXE_PORT=8080 # The port that the PXE will be listening to (default: 8080) +AZTEC_NODE_URL='http://localhost:8080' # The address of an Aztec Node URL that the wallet will connect to (default: http://localhost:8080) TEST_ACCOUNTS='true' # Option to deploy 3 test account when sandbox starts. (default: true) ``` diff --git a/docs/docs/migration_notes.md b/docs/docs/migration_notes.md index 4c0e7b39c1f6..1dcf52565248 100644 --- a/docs/docs/migration_notes.md +++ b/docs/docs/migration_notes.md @@ -9,6 +9,42 @@ Aztec is in full-speed development. Literally every version breaks compatibility ## TBD +This release includes a major architectural change to the system. +The PXE JSON RPC Server has been removed, and PXE is now available only as a library to be used by wallets. + +## [Aztec.js] + +### CLI Wallet commands dropped from `aztec` command + +The following commands used to be exposed by both the `aztec` and the `aztec-wallet` commands: + +- import-test-accounts +- create-account +- deploy-account +- deploy +- send +- simulate +- profile +- bridge-fee-juice +- create-authwit +- authorize-action +- get-tx +- cancel-tx +- register-sender +- register-contract + +These were dropped from `aztec` and now are exposed only by the `cli-wallet` command exposed by the `@aztec/cli-wallet` package. + +### PXE commands dropped from `aztec` command + +The following commands were dropped from the `aztec` command: + +- `add-contract`: use can be replaced with `register-contract` on our `cli-wallet` +- `get-contract-data`: debug-only and not considered important enough to need a replacement +- `get-accounts`: debug-only and can be replaced by loading aliases from `cli-wallet` +- `get-account`: debug-only and can be replaced by loading aliases from `cli-wallet` +- `get-pxe-info`: debug-only and not considered important enough to need a replacement + ## [Aztec.nr] ### Historical block renamed as anchor block diff --git a/docs/docs/the_aztec_network/reference/cli_reference.md b/docs/docs/the_aztec_network/reference/cli_reference.md index 3a8188c37824..6a7b0100b4b1 100644 --- a/docs/docs/the_aztec_network/reference/cli_reference.md +++ b/docs/docs/the_aztec_network/reference/cli_reference.md @@ -815,9 +815,6 @@ If two subsystems can contain the same configuration option, only one needs to b --bot.nodeAdminUrl ($AZTEC_NODE_ADMIN_URL) The URL to the Aztec node admin API to force-flush txs if configured. - --bot.pxeUrl ($BOT_PXE_URL) - URL to the PXE for sending txs, or undefined if an in-proc PXE is used. - --bot.l1Mnemonic ($BOT_L1_MNEMONIC) The mnemonic for the account to bridge fee juice from L1. diff --git a/spartan/aztec-network/templates/_helpers.tpl b/spartan/aztec-network/templates/_helpers.tpl index c3f74f748b8d..29a48ec33c62 100644 --- a/spartan/aztec-network/templates/_helpers.tpl +++ b/spartan/aztec-network/templates/_helpers.tpl @@ -60,10 +60,6 @@ imagePullPolicy: {{ .Values.images.aztec.pullPolicy }} -{{- define "aztec-network.pxeUrl" -}} -http://{{ include "aztec-network.fullname" . }}-pxe.{{ .Release.Namespace }}:{{ .Values.pxe.service.nodePort }} -{{- end -}} - {{- define "aztec-network.bootNodeUrl" -}} http://{{ include "aztec-network.fullname" . }}-boot-node.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.bootNode.service.nodePort }} {{- end -}} @@ -257,30 +253,27 @@ Combined wait-for-services and configure-env container for full nodes # If we already have a registry address, and the bootstrap nodes are set, then we don't need to wait for the services if [ -n "{{ .Values.aztec.contracts.registryAddress }}" ] && [ -n "{{ .Values.aztec.bootstrapENRs }}" ]; then echo "Registry address and bootstrap nodes already set, skipping wait for services" - echo "{{ include "aztec-network.pxeUrl" . }}" > /shared/pxe/pxe_url else source /shared/config/service-addresses cat /shared/config/service-addresses {{- include "aztec-network.waitForEthereum" . | nindent 8 }} - if [ "{{ .Values.validator.dynamicBootNode }}" = "true" ]; then - echo "{{ include "aztec-network.pxeUrl" . }}" > /shared/pxe/pxe_url - else + if [ "{{ .Values.validator.dynamicBootNode }}" != "true" ]; then until curl --silent --head --fail "${BOOT_NODE_HOST}/status" > /dev/null; do echo "Waiting for boot node..." sleep 5 done echo "Boot node is ready!" - echo "${BOOT_NODE_HOST}" > /shared/pxe/pxe_url + echo "${BOOT_NODE_HOST}" > /shared/aztec_node/aztec_node_url fi fi # Configure environment source /shared/config/service-addresses - /scripts/configure-full-node-env.sh "$(cat /shared/pxe/pxe_url)" + /scripts/configure-full-node-env.sh "$(cat /shared/aztec_node/aztec_node_url)" volumeMounts: - - name: pxe-url - mountPath: /shared/pxe + - name: aztec-node-url + mountPath: /shared/aztec_node - name: scripts mountPath: /scripts - name: config diff --git a/spartan/aztec-network/templates/blob-sink.yaml b/spartan/aztec-network/templates/blob-sink.yaml index c656a7800062..3b240cddeb2c 100644 --- a/spartan/aztec-network/templates/blob-sink.yaml +++ b/spartan/aztec-network/templates/blob-sink.yaml @@ -126,7 +126,7 @@ spec: defaultMode: 0755 - name: contracts-env emptyDir: {} - - name: pxe-url + - name: aztec-node-url emptyDir: {} - name: config emptyDir: {} diff --git a/spartan/aztec-network/templates/full-node.yaml b/spartan/aztec-network/templates/full-node.yaml index 1d63ed8f73b2..f75f7d147775 100644 --- a/spartan/aztec-network/templates/full-node.yaml +++ b/spartan/aztec-network/templates/full-node.yaml @@ -198,7 +198,7 @@ spec: emptyDir: {} - name: contracts-env emptyDir: {} - - name: pxe-url + - name: aztec-node-url emptyDir: {} --- # Headless service for StatefulSet DNS entries diff --git a/spartan/aztec-network/templates/pxe.yaml b/spartan/aztec-network/templates/pxe.yaml deleted file mode 100644 index 451add017430..000000000000 --- a/spartan/aztec-network/templates/pxe.yaml +++ /dev/null @@ -1,180 +0,0 @@ -{{ if .Values.pxe.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "aztec-network.fullname" . }}-pxe - labels: - {{- include "aztec-network.labels" . | nindent 4 }} -spec: - replicas: {{ .Values.pxe.replicas }} - selector: - matchLabels: - {{- include "aztec-network.selectorLabels" . | nindent 6 }} - app: pxe - template: - metadata: - labels: - {{- include "aztec-network.selectorLabels" . | nindent 8 }} - app: pxe - spec: - {{- if .Values.network.gke }} - nodeSelector: - local-ssd: "{{ .Values.storage.localSsd }}" - node-type: network - {{- end }} - {{- if .Values.network.public }} - serviceAccountName: {{ include "aztec-network.fullname" . }}-node - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - {{- else }} - dnsPolicy: ClusterFirst - {{- end }} - volumes: - - name: config - emptyDir: {} - - name: scripts - configMap: - name: {{ include "aztec-network.fullname" . }}-scripts - defaultMode: 0755 - - name: scripts-output - emptyDir: {} - terminationGracePeriodSeconds: 5 # default is 30 - speed up initcontainer termination - initContainers: - {{- include "aztec-network.serviceAddressSetupContainer" . | nindent 8 }} - - - name: wait-for-host - image: {{ .Values.images.curl.image }} - command: - - /bin/sh - - -c - - | - source /shared/config/service-addresses - cat /shared/config/service-addresses - - {{- if .Values.pxe.nodeUrl }} - export AZTEC_NODE_URL={{ .Values.pxe.nodeUrl }} - {{- else }} - export AZTEC_NODE_URL=${BOOT_NODE_HOST} - {{- end }} - - until curl --head --silent ${AZTEC_NODE_URL}/status; do - echo "Waiting for boot node..." - sleep 5 - done - volumeMounts: - - name: config - mountPath: /shared/config - - containers: - - name: pxe - {{- include "aztec-network.image" . | nindent 10 }} - volumeMounts: - - name: config - mountPath: /shared/config - command: - - "/bin/bash" - - "-c" - - | - source /shared/config/service-addresses - cat /shared/config/service-addresses - {{- if .Values.pxe.nodeUrl }} - export AZTEC_NODE_URL={{ .Values.pxe.nodeUrl }} - {{- else }} - export AZTEC_NODE_URL=${BOOT_NODE_HOST} - {{- end }} - echo "AZTEC_NODE_URL=${AZTEC_NODE_URL}" - node --no-warnings /usr/src/yarn-project/aztec/dest/bin/index.js start --pxe - env: - - name: K8S_POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - - name: K8S_POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: K8S_NAMESPACE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: AZTEC_PORT - value: "{{ .Values.pxe.service.nodePort }}" - - name: LOG_JSON - value: "1" - - name: LOG_LEVEL - value: "{{ .Values.pxe.logLevel }}" - - name: PXE_PROVER_ENABLED - value: "{{ .Values.aztec.realProofs }}" - - name: USE_GCLOUD_LOGGING - value: "{{ .Values.telemetry.useGcloudLogging }}" - - name: L1_CHAIN_ID - value: "{{ .Values.ethereum.chainId }}" - - name: TEST_ACCOUNTS - value: "{{ .Values.aztec.testAccounts }}" - ports: - - name: http - containerPort: {{ .Values.pxe.service.nodePort }} - protocol: TCP - readinessProbe: - exec: - command: - - /bin/bash - - -c - - | - curl -s -X POST -H 'content-type: application/json' \ - -d '{"jsonrpc":"2.0","method":"pxe_getNodeInfo","params":[],"id":67}' \ - 127.0.0.1:{{ .Values.pxe.service.nodePort }} | grep -q '"rollupVersion":[1-9][0-9]*' - initialDelaySeconds: {{ .Values.pxe.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.pxe.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.pxe.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.pxe.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.pxe.readinessProbe.failureThreshold }} - resources: - {{- toYaml .Values.pxe.resources | nindent 12 }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ include "aztec-network.fullname" . }}-pxe - labels: - {{- include "aztec-network.labels" . | nindent 4 }} - app: pxe -spec: - type: ClusterIP - selector: - {{- include "aztec-network.selectorLabels" . | nindent 4 }} - app: pxe - ports: - - protocol: TCP - port: {{ .Values.pxe.service.nodePort }} - targetPort: {{ .Values.pxe.service.nodePort }} - {{- if and (eq .Values.pxe.service.type "NodePort") .Values.pxe.service.nodePort }} - nodePort: {{ .Values.pxe.service.nodePort }} - {{- end }} ---- -{{if .Values.network.public }} -apiVersion: v1 -kind: Service -metadata: - name: pxe-lb - annotations: - service.beta.kubernetes.io/aws-load-balancer-type: "nlb" - service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" - service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" - labels: - {{- include "aztec-network.labels" . | nindent 4 }} -spec: - type: LoadBalancer - selector: - {{- include "aztec-network.selectorLabels" . | nindent 4 }} - app: pxe - ports: - - protocol: TCP - port: {{ .Values.pxe.service.nodePort }} - targetPort: {{ .Values.pxe.service.nodePort }} - {{- if and (eq .Values.pxe.service.type "NodePort") .Values.pxe.service.nodePort }} - nodePort: {{ .Values.pxe.service.nodePort }} - {{- end }} ---- -{{ end }} -{{ end }} diff --git a/spartan/aztec-network/templates/transaction-bot.yaml b/spartan/aztec-network/templates/transaction-bot.yaml index b5111a7084ac..b32f8a7f7857 100644 --- a/spartan/aztec-network/templates/transaction-bot.yaml +++ b/spartan/aztec-network/templates/transaction-bot.yaml @@ -127,7 +127,7 @@ spec: sleep $sleep_duration fi - node --no-warnings /usr/src/yarn-project/aztec/dest/bin/index.js start --pxe --bot + node --no-warnings /usr/src/yarn-project/aztec/dest/bin/index.js start --bot env: - name: K8S_POD_UID valueFrom: diff --git a/spartan/aztec-network/templates/validator.yaml b/spartan/aztec-network/templates/validator.yaml index ac6536d11b21..42400d5aa7c0 100644 --- a/spartan/aztec-network/templates/validator.yaml +++ b/spartan/aztec-network/templates/validator.yaml @@ -275,7 +275,7 @@ spec: defaultMode: 0755 - name: contracts-env emptyDir: {} - - name: pxe-url + - name: aztec-node-url emptyDir: {} - name: config emptyDir: {} diff --git a/spartan/scripts/post_deploy_spartan.sh b/spartan/scripts/post_deploy_spartan.sh index 2121a9cb1194..b075f95d5834 100755 --- a/spartan/scripts/post_deploy_spartan.sh +++ b/spartan/scripts/post_deploy_spartan.sh @@ -24,11 +24,9 @@ function get_load_balancer_url() { # Fetch the service URLs based on the namespace for injection in the test-transfer.sh export BOOTNODE_URL=$($(dirname $0)/get_service_address boot-node 8080) -export PXE_URL=$($(dirname $0)/get_service_address pxe 8080) export ETHEREUM_HOSTS=$($(dirname $0)/get_service_address eth-execution 8545) echo "BOOTNODE_URL: $BOOTNODE_URL" -echo "PXE_URL: $PXE_URL" echo "ETHEREUM_HOSTS: $ETHEREUM_HOSTS" echo "Bootstrapping contracts for test network. NOTE: This took one hour last run." diff --git a/spartan/scripts/test_spartan.sh b/spartan/scripts/test_spartan.sh index 83a616977f92..69b3ab74b24f 100755 --- a/spartan/scripts/test_spartan.sh +++ b/spartan/scripts/test_spartan.sh @@ -25,11 +25,9 @@ function get_load_balancer_url() { # Fetch the service URLs based on the namespace for injection in the test-transfer.sh export BOOTNODE_URL=http://$(get_load_balancer_url $NAMESPACE "$NAMESPACE-aztec-network-boot-node-lb-tcp"):8080 -export PXE_URL=http://$(get_load_balancer_url $NAMESPACE "$NAMESPACE-aztec-network-pxe-lb"):8080 export ETHEREUM_HOSTS=http://$(get_load_balancer_url $NAMESPACE "$NAMESPACE-aztec-network-ethereum-lb"):8545 echo "BOOTNODE_URL: $BOOTNODE_URL" -echo "PXE_URL: $PXE_URL" echo "ETHEREUM_HOSTS: $ETHEREUM_HOSTS" # hack to ensure L2 contracts are considered deployed diff --git a/yarn-project/accounts/src/testing/index.ts b/yarn-project/accounts/src/testing/index.ts index f170063d326f..7106b4998b0d 100644 --- a/yarn-project/accounts/src/testing/index.ts +++ b/yarn-project/accounts/src/testing/index.ts @@ -5,7 +5,7 @@ * * @packageDocumentation */ -import { Fr, type PXE } from '@aztec/aztec.js'; +import { Fr } from '@aztec/aztec.js'; import { deriveSigningKey } from '@aztec/stdlib/keys'; import { getSchnorrAccountContractAddress } from '../schnorr/index.js'; @@ -43,18 +43,6 @@ export function getInitialTestAccountsData(): Promise { ); } -/** - * Queries a PXE for it's registered accounts. - * @param testWalletOrPxe - Test wallet or pxe instance to use to get the registered accounts. - * @returns A set of key data for each of the initial accounts. - */ -export async function getDeployedTestAccounts(testWalletOrPxe: { getPxe(): PXE } | PXE): Promise { - const pxe = 'getPxe' in testWalletOrPxe ? testWalletOrPxe.getPxe() : testWalletOrPxe; - const registeredAccounts = await pxe.getRegisteredAccounts(); - const testAccounts = await getInitialTestAccountsData(); - return testAccounts.filter(t => registeredAccounts.some(r => r.address.equals(t.address))); -} - /** * Generate a fixed amount of random schnorr account contract instance. */ diff --git a/yarn-project/accounts/src/testing/lazy.ts b/yarn-project/accounts/src/testing/lazy.ts index 4aaf5b1d3aed..baa41a986737 100644 --- a/yarn-project/accounts/src/testing/lazy.ts +++ b/yarn-project/accounts/src/testing/lazy.ts @@ -5,7 +5,7 @@ * * @packageDocumentation */ -import { Fr, type PXE } from '@aztec/aztec.js'; +import { Fr } from '@aztec/aztec.js'; import { deriveSigningKey } from '@aztec/stdlib/keys'; import { getSchnorrAccountContractAddress } from '../schnorr/lazy.js'; @@ -37,17 +37,6 @@ export function getInitialTestAccountsData(): Promise { ); } -/** - * Queries a PXE for it's registered accounts. - * @param pxe - PXE instance. - * @returns A set of key data for each of the initial accounts. - */ -export async function getDeployedTestAccounts(pxe: PXE): Promise { - const registeredAccounts = await pxe.getRegisteredAccounts(); - const testAccounts = await getInitialTestAccountsData(); - return testAccounts.filter(t => registeredAccounts.some(r => r.address.equals(t.address))); -} - /** * Generate a fixed amount of random schnorr account contract instance. */ diff --git a/yarn-project/aztec.js/package.json b/yarn-project/aztec.js/package.json index 8414523e9640..d741fd7de06c 100644 --- a/yarn-project/aztec.js/package.json +++ b/yarn-project/aztec.js/package.json @@ -19,7 +19,6 @@ "./fields": "./dest/api/fields.js", "./log": "./dest/api/log.js", "./log_id": "./dest/api/log_id.js", - "./rpc": "./dest/api/rpc.js", "./tx_hash": "./dest/api/tx_hash.js", "./wallet": "./dest/api/wallet.js", "./utils": "./dest/api/utils.js", diff --git a/yarn-project/aztec.js/src/api/rpc.ts b/yarn-project/aztec.js/src/api/rpc.ts deleted file mode 100644 index 7f12bc9cba0f..000000000000 --- a/yarn-project/aztec.js/src/api/rpc.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { createPXEClient } from '../rpc_clients/pxe_client.js'; -export { createCompatibleClient } from '../rpc_clients/node/index.js'; diff --git a/yarn-project/aztec.js/src/api/utils.ts b/yarn-project/aztec.js/src/api/utils.ts index eeec2653e9f3..937aea78b6b9 100644 --- a/yarn-project/aztec.js/src/api/utils.ts +++ b/yarn-project/aztec.js/src/api/utils.ts @@ -8,7 +8,6 @@ export { type U128Like, type WrappedFieldLike, } from '../utils/abi_types.js'; -export { waitForPXE } from '../utils/pxe.js'; export { waitForNode, createAztecNodeClient, type AztecNode } from '../utils/node.js'; export { getFeeJuiceBalance } from '../utils/fee_juice.js'; export { readFieldCompressedString } from '../utils/field_compressed_string.js'; diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index e312dca6dc00..5985166b6b08 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -82,5 +82,4 @@ export * from './api/fee.js'; export * from './api/log.js'; export * from './api/contract.js'; export * from './api/utils.js'; -export * from './api/rpc.js'; export * from './api/wallet.js'; diff --git a/yarn-project/aztec.js/src/rpc_clients/node/index.ts b/yarn-project/aztec.js/src/rpc_clients/node/index.ts deleted file mode 100644 index 7c8a3f9d2401..000000000000 --- a/yarn-project/aztec.js/src/rpc_clients/node/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { jsonStringify } from '@aztec/foundation/json-rpc'; -import { type Logger, createLogger } from '@aztec/foundation/log'; -import { NoRetryError, makeBackoff, retry } from '@aztec/foundation/retry'; -import type { PXE } from '@aztec/stdlib/interfaces/client'; -import type { ComponentsVersions } from '@aztec/stdlib/versioning'; - -import { Axios, type AxiosError } from 'axios'; -import { inspect } from 'util'; - -import { createPXEClient } from '../pxe_client.js'; - -/** - * A fetch implementation using axios. - * @param host - The URL of the host. - * @param rpcMethod - The RPC method to call. - * @param body - The body of the request. - * @returns The response data. - */ -async function axiosFetch(host: string, body: unknown) { - const request = new Axios({ - headers: { 'content-type': 'application/json' }, - transformRequest: [(data: any) => jsonStringify(data)], - transformResponse: [(data: any) => JSON.parse(data)], - }); - const [url, content] = [host, body]; - const resp = await request.post(url, content).catch((error: AxiosError) => { - if (error.response) { - return error.response; - } - const errorMessage = `Error fetching from host ${host}: ${inspect(error)}`; - throw new Error(errorMessage); - }); - - const isOK = resp.status >= 200 && resp.status < 300; - if (isOK) { - const headers = { - get: (header: string) => - // eslint-disable-next-line @typescript-eslint/no-base-to-string - typeof resp.headers.get === 'function' ? resp.headers.get(header)?.toString() : undefined, - }; - return { response: resp.data, headers }; - } else { - const errorMessage = `Error ${resp.status} from json-rpc server ${host}: ${resp.data}`; - if (resp.status >= 400 && resp.status < 500) { - throw new NoRetryError(errorMessage); - } else { - throw new Error(errorMessage); - } - } -} - -/** - * Creates a PXE client with a given set of retries on non-server errors. - * Checks that PXE matches the expected version, and warns if not. - * @param rpcUrl - URL of the RPC server wrapping the PXE. - * @param _logger - Debug logger to warn version incompatibilities. - * @returns A PXE client. - */ -export function createCompatibleClient( - rpcUrl: string, - logger: Logger = createLogger('aztecjs:pxe_client'), - versions: Partial = {}, -): Promise { - // Use axios due to timeout issues with fetch when proving TXs. - const fetch = async (host: string, body: unknown) => { - return await retry( - () => axiosFetch(host, body), - `JsonRpcClient request to ${host}`, - makeBackoff([1, 2, 3]), - logger, - false, - ); - }; - const pxe = createPXEClient(rpcUrl, versions, fetch); - - return Promise.resolve(pxe); -} diff --git a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts b/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts deleted file mode 100644 index 1aaaade58baa..000000000000 --- a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createSafeJsonRpcClient, makeFetch } from '@aztec/foundation/json-rpc/client'; -import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; -import { type PXE, PXESchema } from '@aztec/stdlib/interfaces/client'; -import { type ComponentsVersions, getVersioningResponseHandler } from '@aztec/stdlib/versioning'; - -/** - * Creates a JSON-RPC client to remotely talk to PXE. - * @param url - The URL of the PXE. - * @param fetch - The fetch implementation to use. - * @returns A JSON-RPC client of PXE. - */ -export function createPXEClient( - url: string, - versions: Partial = {}, - fetch = makeFetch([1, 2, 3], false), -): PXE { - return createSafeJsonRpcClient(url, PXESchema, { - namespaceMethods: 'pxe', - fetch, - onResponse: getVersioningResponseHandler({ - l2ProtocolContractsTreeRoot: protocolContractTreeRoot.toString(), - ...versions, - }), - }); -} diff --git a/yarn-project/aztec.js/src/utils/pxe.ts b/yarn-project/aztec.js/src/utils/pxe.ts deleted file mode 100644 index 8a8e3bb8241b..000000000000 --- a/yarn-project/aztec.js/src/utils/pxe.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { Logger } from '@aztec/foundation/log'; -import { retryUntil } from '@aztec/foundation/retry'; -import type { PXE } from '@aztec/stdlib/interfaces/client'; - -export const waitForPXE = async (pxe: PXE, logger?: Logger) => { - await retryUntil(async () => { - try { - logger?.verbose('Attempting to contact PXE...'); - await pxe.getPXEInfo(); - logger?.verbose('Contacted PXE'); - return true; - } catch { - logger?.verbose('Failed to contact PXE'); - } - return undefined; - }, 'RPC Get PXE Info'); -}; diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 045fdab074bb..281edc4e4bb7 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -57,7 +57,8 @@ export abstract class BaseWallet implements Wallet { protected baseFeePadding = 0.5; - constructor( + // Protected because we want to force wallets to instantiate their own PXE. + protected constructor( protected readonly pxe: PXE, protected readonly aztecNode: AztecNode, ) {} diff --git a/yarn-project/aztec.js/src/wallet/wallet.ts b/yarn-project/aztec.js/src/wallet/wallet.ts index 94aa62324684..9f322656c583 100644 --- a/yarn-project/aztec.js/src/wallet/wallet.ts +++ b/yarn-project/aztec.js/src/wallet/wallet.ts @@ -10,19 +10,20 @@ import { import { AuthWitness } from '@aztec/stdlib/auth-witness'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { + ContractClassWithIdSchema, type ContractInstanceWithAddress, ContractInstanceWithAddressSchema, type ContractInstantiationData, } from '@aztec/stdlib/contract'; import { Gas } from '@aztec/stdlib/gas'; import { - ContractClassMetadataSchema, - ContractMetadataSchema, + type ContractClassMetadata, + type ContractMetadata, EventMetadataDefinitionSchema, type PXE, } from '@aztec/stdlib/interfaces/client'; import { PublicKeys } from '@aztec/stdlib/keys'; -import { AbiDecodedSchema, type ApiSchemaFor, optional, schemas } from '@aztec/stdlib/schemas'; +import { AbiDecodedSchema, type ApiSchemaFor, type ZodFor, optional, schemas } from '@aztec/stdlib/schemas'; import { Capsule, HashedValues, @@ -182,6 +183,18 @@ const MessageHashOrIntentSchema = z.union([ }), ]); +const ContractMetadataSchema = z.object({ + contractInstance: z.union([ContractInstanceWithAddressSchema, z.undefined()]), + isContractInitialized: z.boolean(), + isContractPublished: z.boolean(), +}) satisfies ZodFor; + +const ContractClassMetadataSchema = z.object({ + contractClass: z.union([ContractClassWithIdSchema, z.undefined()]), + isContractClassPubliclyRegistered: z.boolean(), + artifact: z.union([ContractArtifactSchema, z.undefined()]), +}) satisfies ZodFor; + export const WalletSchema: ApiSchemaFor = { getChainInfo: z .function() diff --git a/yarn-project/aztec/package.json b/yarn-project/aztec/package.json index 0e8dde38a654..0b2ceebe876b 100644 --- a/yarn-project/aztec/package.json +++ b/yarn-project/aztec/package.json @@ -39,7 +39,6 @@ "@aztec/bot": "workspace:^", "@aztec/builder": "workspace:^", "@aztec/cli": "workspace:^", - "@aztec/cli-wallet": "workspace:^", "@aztec/constants": "workspace:^", "@aztec/entrypoints": "workspace:^", "@aztec/ethereum": "workspace:^", diff --git a/yarn-project/aztec/src/bin/index.ts b/yarn-project/aztec/src/bin/index.ts index 58dff5bda51b..99508283ba92 100644 --- a/yarn-project/aztec/src/bin/index.ts +++ b/yarn-project/aztec/src/bin/index.ts @@ -1,7 +1,6 @@ #!/usr/bin/env node // import { injectCommands as injectBuilderCommands } from '@aztec/builder'; -import { injectCommands as injectWalletCommands } from '@aztec/cli-wallet'; import { injectCommands as injectAztecNodeCommands } from '@aztec/cli/aztec_node'; import { enrichEnvironmentWithChainConfig } from '@aztec/cli/config'; import { injectCommands as injectContractCommands } from '@aztec/cli/contracts'; @@ -9,7 +8,6 @@ import { injectCommands as injectDevnetCommands } from '@aztec/cli/devnet'; import { injectCommands as injectInfrastructureCommands } from '@aztec/cli/infrastructure'; import { injectCommands as injectL1Commands } from '@aztec/cli/l1'; import { injectCommands as injectMiscCommands } from '@aztec/cli/misc'; -import { injectCommands as injectPXECommands } from '@aztec/cli/pxe'; import { getActiveNetworkName } from '@aztec/foundation/config'; import { createConsoleLogger, createLogger } from '@aztec/foundation/log'; @@ -50,11 +48,9 @@ async function main() { program = injectContractCommands(program, userLog, debugLogger); program = injectInfrastructureCommands(program, userLog); program = injectL1Commands(program, userLog, debugLogger); - program = injectPXECommands(program, userLog, debugLogger); program = injectAztecNodeCommands(program, userLog, debugLogger); program = injectMiscCommands(program, userLog); program = injectDevnetCommands(program, userLog, debugLogger); - program = injectWalletCommands(program, userLog, debugLogger); await program.parseAsync(process.argv); } diff --git a/yarn-project/aztec/src/cli/aztec_start_action.ts b/yarn-project/aztec/src/cli/aztec_start_action.ts index 30cea42205ac..1da7d86e45e4 100644 --- a/yarn-project/aztec/src/cli/aztec_start_action.ts +++ b/yarn-project/aztec/src/cli/aztec_start_action.ts @@ -5,7 +5,7 @@ import { } from '@aztec/foundation/json-rpc/server'; import type { LogFn, Logger } from '@aztec/foundation/log'; import type { ChainConfig } from '@aztec/stdlib/config'; -import { AztecNodeApiSchema, PXESchema } from '@aztec/stdlib/interfaces/client'; +import { AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client'; import { getVersioningMiddleware } from '@aztec/stdlib/versioning'; import { getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client'; @@ -29,7 +29,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg userLog(`${splash}\n${github}\n\n`); userLog(`Setting up Aztec Sandbox ${cliVersion}, please stand by...`); - const { node, pxe, stop } = await createSandbox( + const { node, stop } = await createSandbox( { l1Mnemonic: sandboxOptions.l1Mnemonic, l1RpcUrls: options.l1RpcUrls, @@ -44,11 +44,6 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg // Start Node and PXE JSON-RPC server signalHandlers.push(stop); services.node = [node, AztecNodeApiSchema]; - if (!sandboxOptions.noPXE) { - services.pxe = [pxe, PXESchema]; - } else { - userLog(`Not exposing PXE API through JSON-RPC server`); - } } else { if (options.node) { const { startNode } = await import('./cmds/start_node.js'); @@ -62,9 +57,6 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg } else if (options.blobSink) { const { startBlobSink } = await import('./cmds/start_blob_sink.js'); await startBlobSink(options, signalHandlers, userLog); - } else if (options.pxe) { - const { startPXEServiceGetWallet } = await import('./cmds/start_pxe.js'); - ({ config } = await startPXEServiceGetWallet(options, services, userLog)); } else if (options.archiver) { const { startArchiver } = await import('./cmds/start_archiver.js'); ({ config } = await startArchiver(options, signalHandlers, services)); diff --git a/yarn-project/aztec/src/cli/cmds/start_bot.ts b/yarn-project/aztec/src/cli/cmds/start_bot.ts index 3b7f6410aade..53acde9a8689 100644 --- a/yarn-project/aztec/src/cli/cmds/start_bot.ts +++ b/yarn-project/aztec/src/cli/cmds/start_bot.ts @@ -2,6 +2,7 @@ import { type BotConfig, BotRunner, BotStore, botConfigMappings, getBotRunnerApi import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server'; import type { LogFn } from '@aztec/foundation/log'; import { createStore, openTmpStore } from '@aztec/kv-store/lmdb-v2'; +import { type CliPXEOptions, type PXEServiceConfig, allPxeConfigMappings } from '@aztec/pxe/config'; import { type AztecNode, type AztecNodeAdmin, createAztecNodeClient } from '@aztec/stdlib/interfaces/client'; import type { TelemetryClient } from '@aztec/telemetry-client'; import { @@ -36,9 +37,8 @@ export async function startBot( const aztecNode = createAztecNodeClient(config.nodeUrl, getVersions(), fetch); - // Start a PXE client and get a wallet that is used by the bot if required - const { startPXEServiceGetWallet } = await import('./start_pxe.js'); - const { wallet } = await startPXEServiceGetWallet(options, services, userLog, { node: aztecNode }); + const pxeConfig = extractRelevantOptions(options, allPxeConfigMappings, 'pxe'); + const wallet = await TestWallet.create(aztecNode, pxeConfig); const telemetry = initTelemetryClient(getTelemetryClientConfig()); await addBot(options, signalHandlers, services, wallet, aztecNode, telemetry, undefined); diff --git a/yarn-project/aztec/src/cli/cmds/start_node.ts b/yarn-project/aztec/src/cli/cmds/start_node.ts index e34036f37820..d0dbbeaea0e1 100644 --- a/yarn-project/aztec/src/cli/cmds/start_node.ts +++ b/yarn-project/aztec/src/cli/cmds/start_node.ts @@ -7,6 +7,7 @@ import { getPublicClient } from '@aztec/ethereum'; import { SecretValue } from '@aztec/foundation/config'; import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server'; import type { LogFn } from '@aztec/foundation/log'; +import { type CliPXEOptions, type PXEServiceConfig, allPxeConfigMappings } from '@aztec/pxe/config'; import { AztecNodeAdminApiSchema, AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client'; import { P2PApiSchema } from '@aztec/stdlib/interfaces/server'; import { @@ -14,6 +15,7 @@ import { initTelemetryClient, telemetryClientConfigMappings, } from '@aztec/telemetry-client'; +import { TestWallet } from '@aztec/test-wallet'; import { getGenesisValues } from '@aztec/world-state/testing'; import { createAztecNode } from '../../sandbox/index.js'; @@ -131,8 +133,9 @@ export async function startNode( // Add a txs bot if requested if (options.bot) { const { addBot } = await import('./start_bot.js'); - const { startPXEServiceGetWallet } = await import('./start_pxe.js'); - const { wallet } = await startPXEServiceGetWallet(options, services, userLog, { node }); + + const pxeConfig = extractRelevantOptions(options, allPxeConfigMappings, 'pxe'); + const wallet = await TestWallet.create(node, pxeConfig); await addBot(options, signalHandlers, services, wallet, node, telemetry, undefined); } diff --git a/yarn-project/aztec/src/cli/cmds/start_pxe.ts b/yarn-project/aztec/src/cli/cmds/start_pxe.ts deleted file mode 100644 index eb943474e0a8..000000000000 --- a/yarn-project/aztec/src/cli/cmds/start_pxe.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server'; -import type { LogFn } from '@aztec/foundation/log'; -import { type CliPXEOptions, type PXEServiceConfig, allPxeConfigMappings, createPXEService } from '@aztec/pxe/server'; -import { type AztecNode, PXESchema, createAztecNodeClient } from '@aztec/stdlib/interfaces/client'; -import { makeTracedFetch } from '@aztec/telemetry-client'; -import { TestWallet } from '@aztec/test-wallet'; - -import { extractRelevantOptions } from '../util.js'; -import { getVersions } from '../versioning.js'; - -export type { CliPXEOptions, PXEServiceConfig }; - -export async function startPXEServiceGetWallet( - options: any, - services: NamespacedApiHandlers, - userLog: LogFn, - deps: { node?: AztecNode } = {}, -): Promise<{ wallet: TestWallet; config: PXEServiceConfig & CliPXEOptions }> { - const pxeConfig = extractRelevantOptions(options, allPxeConfigMappings, 'pxe'); - const nodeUrl = pxeConfig.nodeUrl; - - if (!nodeUrl && !deps.node) { - userLog('Aztec Node URL (nodeUrl | AZTEC_NODE_URL) option is required to start PXE without --node option'); - process.exit(1); - } - - const node = deps.node ?? createAztecNodeClient(nodeUrl!, getVersions(pxeConfig), makeTracedFetch([1, 2, 3], true)); - const pxe = await createPXEService(node, pxeConfig as PXEServiceConfig); - - const wallet = new TestWallet(pxe, node); - - // Add PXE to services list - services.pxe = [pxe, PXESchema]; - - return { wallet, config: pxeConfig }; -} diff --git a/yarn-project/aztec/src/cli/util.ts b/yarn-project/aztec/src/cli/util.ts index 4f712573a980..4af01a4699d7 100644 --- a/yarn-project/aztec/src/cli/util.ts +++ b/yarn-project/aztec/src/cli/util.ts @@ -4,10 +4,10 @@ import type { ViemClient } from '@aztec/ethereum'; import type { ConfigMappingsType } from '@aztec/foundation/config'; import { type LogFn, createLogger } from '@aztec/foundation/log'; import type { SharedNodeConfig } from '@aztec/node-lib/config'; -import type { PXEService } from '@aztec/pxe/server'; import type { ProverConfig } from '@aztec/stdlib/interfaces/server'; import { UpdateChecker } from '@aztec/stdlib/update-checker'; import { getTelemetryClient } from '@aztec/telemetry-client'; +import type { TestWallet } from '@aztec/test-wallet'; import chalk from 'chalk'; import type { Command } from 'commander'; @@ -67,7 +67,7 @@ export const installSignalHandlers = (logFn: LogFn, cb?: Array<() => Promise a.equals(completeAddress))) { + if (registeredAccounts.find(a => a.item.equals(completeAddress.address))) { accountLogStrings.push(` Address: ${completeAddress.address.toString()}\n`); accountLogStrings.push(` Partial Address: ${completeAddress.partialAddress.toString()}\n`); accountLogStrings.push(` Secret Key: ${accountWithSecretKey.secretKey.toString()}\n`); diff --git a/yarn-project/aztec/src/examples/token.ts b/yarn-project/aztec/src/examples/token.ts index 84ed02f6f70f..83b0b240edf4 100644 --- a/yarn-project/aztec/src/examples/token.ts +++ b/yarn-project/aztec/src/examples/token.ts @@ -1,17 +1,14 @@ -import { getDeployedTestAccounts } from '@aztec/accounts/testing'; -import { createAztecNodeClient, createPXEClient } from '@aztec/aztec.js'; +import { getInitialTestAccountsData } from '@aztec/accounts/testing'; +import { createAztecNodeClient } from '@aztec/aztec.js'; import { createLogger } from '@aztec/foundation/log'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; const logger = createLogger('example:token'); -const nodeUrl = 'http://localhost:8079'; -const url = 'http://localhost:8080'; +const nodeUrl = 'http://localhost:8080'; const node = createAztecNodeClient(nodeUrl); -const pxe = createPXEClient(url); -const wallet = new TestWallet(pxe, node); const ALICE_MINT_BALANCE = 333n; const TRANSFER_AMOUNT = 33n; @@ -22,13 +19,15 @@ const TRANSFER_AMOUNT = 33n; async function main() { logger.info('Running token contract test on HTTP interface.'); - const accounts = await getDeployedTestAccounts(wallet); - const [alice, bob] = await Promise.all( - accounts.map(async acc => { - const accountManager = await wallet.createSchnorrAccount(acc.secret, acc.salt); - return accountManager.getAddress(); - }), - ); + const wallet = await TestWallet.create(node); + + // During sandbox setup we deploy a few accounts. Below we add them to our wallet. + const [aliceInitialAccountData, bobInitialAccountData] = await getInitialTestAccountsData(); + await wallet.createSchnorrAccount(aliceInitialAccountData.secret, aliceInitialAccountData.salt); + await wallet.createSchnorrAccount(bobInitialAccountData.secret, bobInitialAccountData.salt); + + const alice = aliceInitialAccountData.address; + const bob = bobInitialAccountData.address; logger.info(`Fetched Alice and Bob accounts: ${alice.toString()}, ${bob.toString()}`); diff --git a/yarn-project/aztec/src/index.ts b/yarn-project/aztec/src/index.ts index 3718ea80ed4b..efdac22245e2 100644 --- a/yarn-project/aztec/src/index.ts +++ b/yarn-project/aztec/src/index.ts @@ -1,6 +1,6 @@ export { createSandbox, - getDeployedBananaCoinAddress, - getDeployedBananaFPCAddress, - getDeployedSponsoredFPCAddress, + registerDeployedBananaCoinInWalletAndGetAddress, + registerDeployedBananaFPCInWalletAndGetAddress, + registerDeployedSponsoredFPCInWalletAndGetAddress, } from './sandbox/index.js'; diff --git a/yarn-project/aztec/src/sandbox/banana_fpc.ts b/yarn-project/aztec/src/sandbox/banana_fpc.ts index 7aa579b3f0c1..422e30fc4719 100644 --- a/yarn-project/aztec/src/sandbox/banana_fpc.ts +++ b/yarn-project/aztec/src/sandbox/banana_fpc.ts @@ -6,7 +6,6 @@ import { FPCContract } from '@aztec/noir-contracts.js/FPC'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { type ContractInstanceWithAddress, getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contract'; -import type { TestWallet } from '@aztec/test-wallet'; const BANANA_COIN_SALT = new Fr(0); const bananaCoinArgs = { @@ -62,22 +61,18 @@ export async function setupBananaFPC(initialAccounts: InitialAccountData[], wall log(`FPC: ${fpc.address}`); } -export async function getDeployedBananaCoinAddress(wallet: TestWallet) { +export async function registerDeployedBananaCoinInWalletAndGetAddress(wallet: Wallet) { const initialAccounts = await getInitialTestAccountsData(); - const bananaCoin = await getBananaCoinAddress(initialAccounts); - const contracts = await wallet.getContracts(); - if (!contracts.find(c => c.equals(bananaCoin))) { - throw new Error('BananaCoin not deployed.'); - } - return bananaCoin; + const bananaCoin = await getBananaCoinInstance(initialAccounts); + // The following is no-op if the contract is already registered + await wallet.registerContract(bananaCoin, TokenContract.artifact); + return bananaCoin.address; } -export async function getDeployedBananaFPCAddress(wallet: TestWallet) { +export async function registerDeployedBananaFPCInWalletAndGetAddress(wallet: Wallet) { const initialAccounts = await getInitialTestAccountsData(); const fpc = await getBananaFPCInstance(initialAccounts); - const contracts = await wallet.getContracts(); - if (!contracts.find(c => c.equals(fpc.address))) { - throw new Error('BananaFPC not deployed.'); - } + // The following is no-op if the contract is already registered + await wallet.registerContract(fpc, FPCContract.artifact); return fpc.address; } diff --git a/yarn-project/aztec/src/sandbox/index.ts b/yarn-project/aztec/src/sandbox/index.ts index 4f41efff8269..98ecfc04cc84 100644 --- a/yarn-project/aztec/src/sandbox/index.ts +++ b/yarn-project/aztec/src/sandbox/index.ts @@ -1,4 +1,7 @@ export * from './sandbox.js'; -export { getDeployedBananaCoinAddress, getDeployedBananaFPCAddress } from './banana_fpc.js'; -export { getDeployedSponsoredFPCAddress } from './sponsored_fpc.js'; +export { + registerDeployedBananaCoinInWalletAndGetAddress, + registerDeployedBananaFPCInWalletAndGetAddress, +} from './banana_fpc.js'; +export { registerDeployedSponsoredFPCInWalletAndGetAddress } from './sponsored_fpc.js'; diff --git a/yarn-project/aztec/src/sandbox/sandbox.ts b/yarn-project/aztec/src/sandbox/sandbox.ts index bf8ecddf66c8..1b0bd137c5af 100644 --- a/yarn-project/aztec/src/sandbox/sandbox.ts +++ b/yarn-project/aztec/src/sandbox/sandbox.ts @@ -3,7 +3,6 @@ import { getInitialTestAccountsData } from '@aztec/accounts/testing'; import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node'; import { EthAddress } from '@aztec/aztec.js'; import { type BlobSinkClientInterface, createBlobSinkClient } from '@aztec/blob-sink/client'; -import { setupSponsoredFPC } from '@aztec/cli/cli-utils'; import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants'; import { NULL_KEY, @@ -20,15 +19,13 @@ import { type LogFn, createLogger } from '@aztec/foundation/log'; import { DateProvider, TestDateProvider } from '@aztec/foundation/timer'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; -import { type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; -import type { AztecNode } from '@aztec/stdlib/interfaces/client'; import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; import { type TelemetryClient, getConfigEnvVars as getTelemetryClientConfig, initTelemetryClient, } from '@aztec/telemetry-client'; -import { TestWallet, deployFundedSchnorrAccounts } from '@aztec/test-wallet'; +import { TestWallet, deployFundedSchnorrAccounts } from '@aztec/test-wallet/server'; import { getGenesisValues } from '@aztec/world-state/testing'; import { type HDAccount, type PrivateKeyAccount, createPublicClient, fallback, http as httpViemTransport } from 'viem'; @@ -196,22 +193,26 @@ export async function createSandbox(config: Partial = {}, userLog { telemetry, blobSinkClient, dateProvider }, { prefilledPublicData }, ); - const pxeServiceConfig = { proverEnabled: aztecNodeConfig.realProofs }; - const pxe = await createAztecPXE(node, pxeServiceConfig); - const wallet = new TestWallet(pxe, node); if (initialAccounts.length) { + const pxeServiceConfig = { proverEnabled: aztecNodeConfig.realProofs }; + const wallet = await TestWallet.create(node, pxeServiceConfig); + userLog('Setting up funded test accounts...'); const accountManagers = await deployFundedSchnorrAccounts(wallet, initialAccounts); const accountsWithSecrets = accountManagers.map((manager, i) => ({ account: manager, secretKey: initialAccounts[i].secret, })); - const accLogs = await createAccountLogs(accountsWithSecrets, pxe); + const accLogs = await createAccountLogs(accountsWithSecrets, wallet); userLog(accLogs.join('')); await setupBananaFPC(initialAccounts, wallet, userLog); - await setupSponsoredFPC(pxe, userLog); + + userLog(`SponsoredFPC: ${await getSponsoredFPCAddress()}`); + + // We no longer need the wallet once we've setup the accounts so we stop the underlying PXE job queue + await wallet.stop(); } const stop = async () => { @@ -219,7 +220,7 @@ export async function createSandbox(config: Partial = {}, userLog await watcher?.stop(); }; - return { node, pxe, stop }; + return { node, stop }; } /** @@ -241,13 +242,3 @@ export async function createAztecNode( const node = await AztecNodeService.createAndSync(aztecNodeConfig, deps, options); return node; } - -/** - * Create and start a new Aztec PXE HTTP Server - * @param config - Optional PXE settings. - */ -export async function createAztecPXE(node: AztecNode, config: Partial = {}) { - const pxeServiceConfig: PXEServiceConfig = { ...getPXEServiceConfig(), ...config }; - const pxe = await createPXEService(node, pxeServiceConfig); - return pxe; -} diff --git a/yarn-project/aztec/src/sandbox/sponsored_fpc.ts b/yarn-project/aztec/src/sandbox/sponsored_fpc.ts index 73c293fcb25f..2f12e5d99bb6 100644 --- a/yarn-project/aztec/src/sandbox/sponsored_fpc.ts +++ b/yarn-project/aztec/src/sandbox/sponsored_fpc.ts @@ -1,7 +1,11 @@ -import { type ContractInstanceWithAddress, Fr, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js'; +import { + type ContractInstanceWithAddress, + Fr, + type Wallet, + getContractInstanceFromInstantiationParams, +} from '@aztec/aztec.js'; import { SPONSORED_FPC_SALT } from '@aztec/constants'; import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC'; -import type { TestWallet } from '@aztec/test-wallet'; async function getSponsoredFPCInstance(): Promise { return await getContractInstanceFromInstantiationParams(SponsoredFPCContract.artifact, { @@ -13,11 +17,9 @@ export async function getSponsoredFPCAddress() { return (await getSponsoredFPCInstance()).address; } -export async function getDeployedSponsoredFPCAddress(wallet: TestWallet) { - const fpc = await getSponsoredFPCAddress(); - const contracts = await wallet.getContracts(); - if (!contracts.find(c => c.equals(fpc))) { - throw new Error('SponsoredFPC not deployed.'); - } - return fpc; +export async function registerDeployedSponsoredFPCInWalletAndGetAddress(wallet: Wallet) { + const fpc = await getSponsoredFPCInstance(); + // The following is no-op if the contract is already registered + await wallet.registerContract(fpc, SponsoredFPCContract.artifact); + return fpc.address; } diff --git a/yarn-project/aztec/tsconfig.json b/yarn-project/aztec/tsconfig.json index 968be7a666b9..6554fab92e3f 100644 --- a/yarn-project/aztec/tsconfig.json +++ b/yarn-project/aztec/tsconfig.json @@ -36,9 +36,6 @@ { "path": "../cli" }, - { - "path": "../cli-wallet" - }, { "path": "../constants" }, diff --git a/yarn-project/bot/src/config.ts b/yarn-project/bot/src/config.ts index 893b82530ad3..a45cb1cbc4cb 100644 --- a/yarn-project/bot/src/config.ts +++ b/yarn-project/bot/src/config.ts @@ -32,8 +32,6 @@ export type BotConfig = { nodeUrl: string | undefined; /** The URL to the Aztec node admin API to force-flush txs if configured. */ nodeAdminUrl: string | undefined; - /** URL to the PXE for sending txs, or undefined if an in-proc PXE is used. */ - pxeUrl: string | undefined; /** Url of the ethereum host. */ l1RpcUrls: string[] | undefined; /** The mnemonic for the account to bridge fee juice from L1. */ @@ -86,7 +84,6 @@ export const BotConfigSchema = z .object({ nodeUrl: z.string().optional(), nodeAdminUrl: z.string().optional(), - pxeUrl: z.string().optional(), l1RpcUrls: z.array(z.string()).optional(), l1Mnemonic: schemas.SecretValue(z.string()).optional(), l1PrivateKey: schemas.SecretValue(z.string()).optional(), @@ -116,7 +113,6 @@ export const BotConfigSchema = z .transform(config => ({ nodeUrl: undefined, nodeAdminUrl: undefined, - pxeUrl: undefined, l1RpcUrls: undefined, senderSalt: undefined, l2GasLimit: undefined, @@ -138,10 +134,6 @@ export const botConfigMappings: ConfigMappingsType = { env: 'AZTEC_NODE_ADMIN_URL', description: 'The URL to the Aztec node admin API to force-flush txs if configured.', }, - pxeUrl: { - env: 'BOT_PXE_URL', - description: 'URL to the PXE for sending txs, or undefined if an in-proc PXE is used.', - }, l1RpcUrls: { env: 'ETHEREUM_HOSTS', description: 'URL of the ethereum host.', diff --git a/yarn-project/cli-wallet/README.md b/yarn-project/cli-wallet/README.md index 25516c37c97b..22a71f0843bf 100644 --- a/yarn-project/cli-wallet/README.md +++ b/yarn-project/cli-wallet/README.md @@ -1,2 +1,32 @@ # Aztec wallet Documentation +### Run tests locally + +1) Start a local Ethereum node (Anvil) in one terminal: + +```bash +anvil --host 127.0.0.1 --port 8545 +``` + +2) In another terminal, start the Aztec sandbox from `yarn-project/aztec`: + +```bash +cd yarn-project/aztec +NODE_NO_WARNINGS=1 ETHEREUM_HOSTS=http://127.0.0.1:8545 node ./dest/bin/index.js start --sandbox +``` + +3) Run the wallet tests from `yarn-project/cli-wallet/test`: + +```bash +cd yarn-project/cli-wallet/test +./test.sh --filter +``` + +Notes: +- **Filter tests**: Omit `--filter` to run all tests, or pass part of a test filename to run a subset. +- **Docker mode**: You can run tests using Docker by adding `--docker`: + +```bash +./test.sh --docker --filter +``` + diff --git a/yarn-project/cli-wallet/src/bin/index.ts b/yarn-project/cli-wallet/src/bin/index.ts index 544605aa46de..a85615425fb2 100644 --- a/yarn-project/cli-wallet/src/bin/index.ts +++ b/yarn-project/cli-wallet/src/bin/index.ts @@ -1,4 +1,4 @@ -import { Fr, ProtocolContractAddress, computeSecretHash, fileURLToPath } from '@aztec/aztec.js'; +import { Fr, ProtocolContractAddress, computeSecretHash, createAztecNodeClient, fileURLToPath } from '@aztec/aztec.js'; import { LOCALHOST } from '@aztec/cli/cli-utils'; import { type LogFn, createConsoleLogger, createLogger } from '@aztec/foundation/log'; import { openStoreAt } from '@aztec/kv-store/lmdb-v2'; @@ -12,14 +12,16 @@ import { dirname, join, resolve } from 'path'; import { injectCommands } from '../cmds/index.js'; import { Aliases, WalletDB } from '../storage/wallet_db.js'; +import { CliWalletAndNodeWrapper } from '../utils/cli_wallet_and_node_wrapper.js'; import { createAliasOption } from '../utils/options/index.js'; -import { PXEWrapper } from '../utils/pxe_wrapper.js'; +import { CLIWallet } from '../utils/wallet.js'; const userLog = createConsoleLogger(); const debugLogger = createLogger('wallet'); const { WALLET_DATA_DIRECTORY = join(homedir(), '.aztec/wallet') } = process.env; +// TODO: This function is only used in 1 place so we could just inline this function injectInternalCommands(program: Command, log: LogFn, db: WalletDB) { program .command('alias') @@ -70,7 +72,7 @@ async function main() { const walletVersion = getPackageVersion() ?? '0.0.0'; const db = WalletDB.getInstance(); - const pxeWrapper = new PXEWrapper(); + const walletAndNodeWrapper = new CliWalletAndNodeWrapper(); const program = new Command('wallet'); program @@ -78,45 +80,40 @@ async function main() { .version(walletVersion) .option('-d, --data-dir ', 'Storage directory for wallet data', WALLET_DATA_DIRECTORY) .addOption( - new Option('-p, --prover ', 'The type of prover the wallet uses (only applies if not using a remote PXE)') + new Option('-p, --prover ', 'The type of prover the wallet uses') .choices(['wasm', 'native', 'none']) .env('PXE_PROVER') .default('native'), ) - .addOption( - new Option('--remote-pxe', 'Connect to an external PXE RPC server instead of the local one') - .env('REMOTE_PXE') - .default(false) - .conflicts('rpc-url'), - ) .addOption( new Option('-n, --node-url ', 'URL of the Aztec node to connect to') .env('AZTEC_NODE_URL') .default(`http://${LOCALHOST}:8080`), ) .hook('preSubcommand', async command => { - const { dataDir, remotePxe, nodeUrl, prover } = command.optsWithGlobals(); + const { dataDir, nodeUrl, prover } = command.optsWithGlobals(); - if (!remotePxe) { - debugLogger.info('Using local PXE service'); + const proverEnabled = prover !== 'none'; - const proverEnabled = prover !== 'none'; + const bbBinaryPath = + prover === 'native' + ? resolve(dirname(fileURLToPath(import.meta.url)), '../../../../barretenberg/cpp/build/bin/bb') + : undefined; + const bbWorkingDirectory = dataDir + '/bb'; + mkdirSync(bbWorkingDirectory, { recursive: true }); - const bbBinaryPath = - prover === 'native' - ? resolve(dirname(fileURLToPath(import.meta.url)), '../../../../barretenberg/cpp/build/bin/bb') - : undefined; - const bbWorkingDirectory = dataDir + '/bb'; - mkdirSync(bbWorkingDirectory, { recursive: true }); + const overridePXEConfig: Partial = { + proverEnabled, + bbBinaryPath: prover === 'native' ? bbBinaryPath : undefined, + bbWorkingDirectory: prover === 'native' ? bbWorkingDirectory : undefined, + dataDirectory: join(dataDir, 'pxe'), + }; - const overridePXEConfig: Partial = { - proverEnabled, - bbBinaryPath: prover === 'native' ? bbBinaryPath : undefined, - bbWorkingDirectory: prover === 'native' ? bbWorkingDirectory : undefined, - }; + const node = createAztecNodeClient(nodeUrl); + const wallet = await CLIWallet.create(node, userLog, db, overridePXEConfig); + + walletAndNodeWrapper.setNodeAndWallet(node, wallet); - pxeWrapper.prepare(nodeUrl, join(dataDir, 'pxe'), overridePXEConfig); - } await db.init(await openStoreAt(dataDir)); let protocolContractsRegistered; try { @@ -137,7 +134,7 @@ async function main() { } }); - injectCommands(program, userLog, debugLogger, db, pxeWrapper); + injectCommands(program, userLog, debugLogger, walletAndNodeWrapper, db); injectInternalCommands(program, userLog, db); await program.parseAsync(process.argv); } diff --git a/yarn-project/cli-wallet/src/cmds/authorize_action.ts b/yarn-project/cli-wallet/src/cmds/authorize_action.ts index 12d536499733..4508a5ad7594 100644 --- a/yarn-project/cli-wallet/src/cmds/authorize_action.ts +++ b/yarn-project/cli-wallet/src/cmds/authorize_action.ts @@ -2,7 +2,7 @@ import { type AztecAddress, Contract, SetPublicAuthwitContractInteraction, type import { prepTx } from '@aztec/cli/utils'; import type { LogFn } from '@aztec/foundation/log'; -import { DEFAULT_TX_TIMEOUT_S } from '../utils/pxe_wrapper.js'; +import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js'; export async function authorizeAction( wallet: Wallet, diff --git a/yarn-project/cli-wallet/src/cmds/bridge_fee_juice.ts b/yarn-project/cli-wallet/src/cmds/bridge_fee_juice.ts index afeafa7932fd..45a3deae97c5 100644 --- a/yarn-project/cli-wallet/src/cmds/bridge_fee_juice.ts +++ b/yarn-project/cli-wallet/src/cmds/bridge_fee_juice.ts @@ -1,4 +1,4 @@ -import { type AztecNode, L1FeeJuicePortalManager, type PXE } from '@aztec/aztec.js'; +import { type AztecNode, L1FeeJuicePortalManager } from '@aztec/aztec.js'; import { prettyPrintJSON } from '@aztec/cli/utils'; import { createEthereumChain, createExtendedL1Client } from '@aztec/ethereum'; import { Fr } from '@aztec/foundation/fields'; @@ -6,10 +6,12 @@ import type { LogFn, Logger } from '@aztec/foundation/log'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging'; +import type { CLIWallet } from '../utils/wallet.js'; + export async function bridgeL1FeeJuice( amount: bigint, recipient: AztecAddress, - pxe: PXE, + wallet: CLIWallet, node: AztecNode, l1RpcUrls: string[], chainId: number, @@ -28,7 +30,7 @@ export async function bridgeL1FeeJuice( const { protocolContractAddresses: { feeJuice: feeJuiceAddress }, - } = await pxe.getPXEInfo(); + } = await wallet.getPXEInfo(); // Setup portal manager const portal = await L1FeeJuicePortalManager.new(node, client, debugLogger); diff --git a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts index c6c30de0869c..5d0b9b158eca 100644 --- a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts +++ b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts @@ -4,7 +4,7 @@ import { Fr } from '@aztec/foundation/fields'; import type { LogFn } from '@aztec/foundation/log'; import { GasFees, GasSettings } from '@aztec/stdlib/gas'; -import { DEFAULT_TX_TIMEOUT_S } from '../utils/pxe_wrapper.js'; +import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js'; import type { CLIWallet } from '../utils/wallet.js'; export async function cancelTx( diff --git a/yarn-project/cli-wallet/src/cmds/check_tx.ts b/yarn-project/cli-wallet/src/cmds/check_tx.ts index 36b454633762..4e294e608022 100644 --- a/yarn-project/cli-wallet/src/cmds/check_tx.ts +++ b/yarn-project/cli-wallet/src/cmds/check_tx.ts @@ -1,12 +1,199 @@ -import type { AztecNode, PXE, TxHash } from '@aztec/aztec.js'; -import { inspectTx } from '@aztec/cli/inspect'; +import { + type AztecAddress, + type AztecNode, + type ContractArtifact, + type ExtendedNote, + Fr, + ProtocolContractAddress, + type TxHash, +} from '@aztec/aztec.js'; import type { LogFn } from '@aztec/foundation/log'; +import { siloNullifier } from '@aztec/stdlib/hash'; -export async function checkTx(client: PXE, aztecNode: AztecNode, txHash: TxHash, statusOnly: boolean, log: LogFn) { +import type { CLIWallet } from '../utils/wallet.js'; + +export async function checkTx( + wallet: CLIWallet, + aztecNode: AztecNode, + txHash: TxHash, + statusOnly: boolean, + log: LogFn, +) { if (statusOnly) { const receipt = await aztecNode.getTxReceipt(txHash); return receipt.status; } else { - await inspectTx(client, aztecNode, txHash, log, { includeBlockInfo: true }); + await inspectTx(wallet, aztecNode, txHash, log, { includeBlockInfo: true }); + } +} + +// The rest of the code here was copied over here from CLI because in CLI I needed to prune the inspect function of the PXE +// dependency when dropping PXE JSON RPC Server. + +async function inspectTx( + wallet: CLIWallet, + aztecNode: AztecNode, + txHash: TxHash, + log: LogFn, + opts: { includeBlockInfo?: boolean; artifactMap?: ArtifactMap } = {}, +) { + const [receipt, effectsInBlock] = await Promise.all([aztecNode.getTxReceipt(txHash), aztecNode.getTxEffect(txHash)]); + // Base tx data + log(`Tx ${txHash.toString()}`); + log(` Status: ${receipt.status} ${effectsInBlock ? `(${effectsInBlock.data.revertCode.getDescription()})` : ''}`); + if (receipt.error) { + log(` Error: ${receipt.error}`); + } + + if (!effectsInBlock) { + return; + } + + const effects = effectsInBlock.data; + const artifactMap = opts?.artifactMap ?? (await getKnownArtifacts(wallet)); + + if (opts.includeBlockInfo) { + log(` Block: ${receipt.blockNumber} (${receipt.blockHash?.toString()})`); + } + if (receipt.transactionFee) { + log(` Fee: ${receipt.transactionFee.toString()}`); + } + + // Public logs + const publicLogs = effects.publicLogs; + if (publicLogs.length > 0) { + log(' Logs:'); + for (const publicLog of publicLogs) { + log(` ${publicLog.toHumanReadable()}`); + } + } + + // Public data writes + const writes = effects.publicDataWrites; + if (writes.length > 0) { + log(' Public data writes:'); + for (const write of writes) { + log(` Leaf ${write.leafSlot.toString()} = ${write.value.toString()}`); + } + } + + // Created notes + const notes = effects.noteHashes; + if (notes.length > 0) { + log(' Created notes:'); + log(` Total: ${notes.length}`); + for (const note of notes) { + log(` Note hash: ${note.toShortString()}`); + } + } + + // Nullifiers + const nullifierCount = effects.nullifiers.length; + const { deployNullifiers, initNullifiers, classNullifiers } = await getKnownNullifiers(wallet, artifactMap); + if (nullifierCount > 0) { + log(' Nullifiers:'); + for (const nullifier of effects.nullifiers) { + const deployed = deployNullifiers[nullifier.toString()]; + const note = deployed + ? (await wallet.getNotes({ siloedNullifier: nullifier, contractAddress: deployed }))[0] + : undefined; + const initialized = initNullifiers[nullifier.toString()]; + const registered = classNullifiers[nullifier.toString()]; + if (nullifier.toBuffer().equals(txHash.toBuffer())) { + log(` Transaction hash nullifier ${nullifier.toShortString()}`); + } else if (note) { + inspectNote(note, artifactMap, log, `Nullifier ${nullifier.toShortString()} for note`); + } else if (deployed) { + log( + ` Contract ${toFriendlyAddress(deployed, artifactMap)} deployed via nullifier ${nullifier.toShortString()}`, + ); + } else if (initialized) { + log( + ` Contract ${toFriendlyAddress( + initialized, + artifactMap, + )} initialized via nullifier ${nullifier.toShortString()}`, + ); + } else if (registered) { + log(` Class ${registered} registered via nullifier ${nullifier.toShortString()}`); + } else { + log(` Unknown nullifier ${nullifier.toString()}`); + } + } + } + + // L2 to L1 messages + if (effects.l2ToL1Msgs.length > 0) { + log(` L2 to L1 messages:`); + for (const msg of effects.l2ToL1Msgs) { + log(` ${msg.toString()}`); + } + } +} + +function inspectNote(note: ExtendedNote, artifactMap: ArtifactMap, log: LogFn, text = 'Note') { + const artifact = artifactMap[note.contractAddress.toString()]; + const contract = artifact?.name ?? note.contractAddress.toString(); + log(` ${text} at ${contract}`); + log(` Recipient: ${toFriendlyAddress(note.recipient, artifactMap)}`); + for (const field of note.note.items) { + log(` ${field.toString()}`); + } +} + +function toFriendlyAddress(address: AztecAddress, artifactMap: ArtifactMap) { + const artifact = artifactMap[address.toString()]; + if (!artifact) { + return address.toString(); + } + + return `${artifact.name}<${address.toString()}>`; +} + +async function getKnownNullifiers(wallet: CLIWallet, artifactMap: ArtifactMap) { + const knownContracts = await wallet.getContracts(); + const deployerAddress = ProtocolContractAddress.ContractInstanceRegistry; + const classRegistryAddress = ProtocolContractAddress.ContractClassRegistry; + const initNullifiers: Record = {}; + const deployNullifiers: Record = {}; + const classNullifiers: Record = {}; + for (const contract of knownContracts) { + initNullifiers[(await siloNullifier(contract, contract.toField())).toString()] = contract; + deployNullifiers[(await siloNullifier(deployerAddress, contract.toField())).toString()] = contract; + } + for (const artifact of Object.values(artifactMap)) { + classNullifiers[(await siloNullifier(classRegistryAddress, artifact.classId)).toString()] = + `${artifact.name}Class<${artifact.classId}>`; + } + return { initNullifiers, deployNullifiers, classNullifiers }; +} + +type ArtifactMap = Record; +type ContractArtifactWithClassId = ContractArtifact & { classId: Fr }; + +async function getKnownArtifacts(wallet: CLIWallet): Promise { + const knownContractAddresses = await wallet.getContracts(); + const knownContracts = ( + await Promise.all(knownContractAddresses.map(contractAddress => wallet.getContractMetadata(contractAddress))) + ).map(contractMetadata => contractMetadata.contractInstance); + const classIds = [...new Set(knownContracts.map(contract => contract?.currentContractClassId))]; + const knownArtifacts = ( + await Promise.all(classIds.map(classId => (classId ? wallet.getContractClassMetadata(classId) : undefined))) + ).map(contractClassMetadata => + contractClassMetadata + ? { ...contractClassMetadata.artifact, classId: contractClassMetadata.contractClass?.id } + : undefined, + ); + const map: Record = {}; + for (const instance of knownContracts) { + if (instance) { + const artifact = knownArtifacts.find(a => + a?.classId?.equals(instance.currentContractClassId), + ) as ContractArtifactWithClassId; + if (artifact) { + map[instance.address.toString()] = artifact; + } + } } + return map; } diff --git a/yarn-project/cli-wallet/src/cmds/create_account.ts b/yarn-project/cli-wallet/src/cmds/create_account.ts index c5c047fcaa1d..ca60cb251a64 100644 --- a/yarn-project/cli-wallet/src/cmds/create_account.ts +++ b/yarn-project/cli-wallet/src/cmds/create_account.ts @@ -3,9 +3,9 @@ import { prettyPrintJSON } from '@aztec/cli/cli-utils'; import { Fr } from '@aztec/foundation/fields'; import type { LogFn, Logger } from '@aztec/foundation/log'; +import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js'; import { CLIFeeArgs } from '../utils/options/fees.js'; import { printProfileResult } from '../utils/profiling.js'; -import { DEFAULT_TX_TIMEOUT_S } from '../utils/pxe_wrapper.js'; import { type AccountType, CLIWallet } from '../utils/wallet.js'; export async function createAccount( diff --git a/yarn-project/cli-wallet/src/cmds/deploy.ts b/yarn-project/cli-wallet/src/cmds/deploy.ts index 23df3b5f5118..8622d2151e87 100644 --- a/yarn-project/cli-wallet/src/cmds/deploy.ts +++ b/yarn-project/cli-wallet/src/cmds/deploy.ts @@ -4,9 +4,9 @@ import type { LogFn, Logger } from '@aztec/foundation/log'; import { getAllFunctionAbis, getInitializer } from '@aztec/stdlib/abi'; import { PublicKeys } from '@aztec/stdlib/keys'; +import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js'; import { CLIFeeArgs } from '../utils/options/fees.js'; import { printProfileResult } from '../utils/profiling.js'; -import { DEFAULT_TX_TIMEOUT_S } from '../utils/pxe_wrapper.js'; export async function deploy( wallet: Wallet, diff --git a/yarn-project/cli-wallet/src/cmds/deploy_account.ts b/yarn-project/cli-wallet/src/cmds/deploy_account.ts index 0953627ecf0c..033589f9ddfe 100644 --- a/yarn-project/cli-wallet/src/cmds/deploy_account.ts +++ b/yarn-project/cli-wallet/src/cmds/deploy_account.ts @@ -2,9 +2,9 @@ import { AztecAddress, type DeployOptions, ProtocolContractAddress } from '@azte import { prettyPrintJSON } from '@aztec/cli/cli-utils'; import type { LogFn, Logger } from '@aztec/foundation/log'; +import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js'; import type { CLIFeeArgs } from '../utils/options/fees.js'; import { printProfileResult } from '../utils/profiling.js'; -import { DEFAULT_TX_TIMEOUT_S } from '../utils/pxe_wrapper.js'; import type { CLIWallet } from '../utils/wallet.js'; export async function deployAccount( diff --git a/yarn-project/cli-wallet/src/cmds/index.ts b/yarn-project/cli-wallet/src/cmds/index.ts index d22301e9df6d..5da52434d123 100644 --- a/yarn-project/cli-wallet/src/cmds/index.ts +++ b/yarn-project/cli-wallet/src/cmds/index.ts @@ -1,5 +1,4 @@ import { getIdentities } from '@aztec/accounts/utils'; -import { createCompatibleClient } from '@aztec/aztec.js/rpc'; import { TxHash } from '@aztec/aztec.js/tx_hash'; import { ETHEREUM_HOSTS, @@ -7,20 +6,18 @@ import { addOptions, createSecretKeyOption, l1ChainIdOption, - nodeOption, parseBigint, parseFieldFromHexString, parsePublicKey, - pxeOption, } from '@aztec/cli/utils'; import type { LogFn, Logger } from '@aztec/foundation/log'; import { GasFees } from '@aztec/stdlib/gas'; -import { createAztecNodeClient } from '@aztec/stdlib/interfaces/client'; import { type Command, Option } from 'commander'; import inquirer from 'inquirer'; import type { WalletDB } from '../storage/wallet_db.js'; +import type { CliWalletAndNodeWrapper } from '../utils/cli_wallet_and_node_wrapper.js'; import { ARTIFACT_DESCRIPTION, CLIFeeArgs, @@ -45,33 +42,25 @@ import { parseGasFees, parsePaymentMethod, } from '../utils/options/index.js'; -import type { PXEWrapper } from '../utils/pxe_wrapper.js'; -import { type AccountType, CLIWallet } from '../utils/wallet.js'; +import type { AccountType } from '../utils/wallet.js'; +// TODO: This function is only used in 1 place so we could just inline this export function injectCommands( program: Command, log: LogFn, debugLogger: Logger, - db?: WalletDB, - pxeWrapper?: PXEWrapper, + walletAndNodeWrapper: CliWalletAndNodeWrapper, + db: WalletDB, ) { program .command('import-test-accounts') .description('Import test accounts from pxe.') - .addOption(pxeOption) - .addOption(nodeOption) .option('--json', 'Emit output as json') .action(async options => { - if (!db) { - throw new Error(`A db is required to store the imported test accounts.`); - } - + const { json } = options; + const wallet = walletAndNodeWrapper.wallet; const { importTestAccounts } = await import('./import_test_accounts.js'); - const { rpcUrl, json, nodeUrl } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); await importTestAccounts(wallet, db, json, log); }); @@ -93,8 +82,6 @@ export function injectCommands( '-p, --public-key ', 'Public key that identifies a private signing key stored outside of the wallet. Used for ECDSA SSH accounts over the secp256r1 curve.', ) - .addOption(pxeOption) - .addOption(nodeOption) .addOption( createSecretKeyOption('Secret key for account. Uses random by default.', false, sk => aliasedSecretKeyParser(sk, db), @@ -115,19 +102,7 @@ export function injectCommands( addOptions(createAccountCommand, CLIFeeArgsWithFeePayer.getOptions()).action(async (_options, command) => { const { createAccount } = await import('./create_account.js'); const options = command.optsWithGlobals(); - const { - type, - secretKey, - wait, - registerOnly, - skipInitialization, - publicDeploy, - rpcUrl, - alias, - json, - verbose, - nodeUrl, - } = options; + const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, alias, json, verbose } = options; let { publicKey } = options; if ((type as AccountType) === 'ecdsasecp256r1ssh' && !publicKey) { const identities = await getIdentities(); @@ -142,9 +117,8 @@ export function injectCommands( ]); publicKey = answers.identity.split(' ')[1]; } - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + + const wallet = walletAndNodeWrapper.wallet; const accountCreationResult = await createAccount( wallet, type, @@ -171,8 +145,6 @@ export function injectCommands( .command('deploy-account') .description('Deploys an already registered aztec account that can be used for sending transactions.') .addOption(createAccountOption('Alias or address of the account to deploy', !db, db)) - .addOption(pxeOption) - .addOption(nodeOption) .option('--json', 'Emit output as json') // `options.wait` is default true. Passing `--no-wait` will set it to false. // https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue @@ -190,11 +162,9 @@ export function injectCommands( addOptions(deployAccountCommand, CLIFeeArgsWithFeePayer.getOptions()).action(async (_options, command) => { const { deployAccount } = await import('./deploy_account.js'); const options = command.optsWithGlobals(); - const { rpcUrl, wait, from: parsedFromAddress, json, registerClass, publicDeploy, verbose, nodeUrl } = options; + const { wait, from: parsedFromAddress, json, registerClass, publicDeploy, verbose } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const wallet = walletAndNodeWrapper.wallet; await deployAccount( wallet, @@ -227,8 +197,6 @@ export function injectCommands( parseFieldFromHexString, ) .option('--universal', 'Do not mix the sender address into the deployment.') - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createArgsOption(true, db)) .addOption(createAccountOption('Alias or address of the account to deploy from', !db, db)) .addOption(createAliasOption('Alias for the contract. Used for easy reference subsequent commands.', !db)) @@ -259,16 +227,13 @@ export function injectCommands( init, publicDeployment, universal, - rpcUrl, from: parsedFromAddress, alias, timeout, verbose, - nodeUrl, } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + + const wallet = walletAndNodeWrapper.wallet; const artifactPath = await artifactPathPromise; debugLogger.info(`Using wallet with address ${parsedFromAddress.toString()}`); @@ -301,8 +266,6 @@ export function injectCommands( .command('send') .description('Calls a function on an Aztec contract.') .argument('', 'Name of function to execute') - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createArgsOption(false, db)) .addOption(createArtifactOption(db)) .addOption(createContractAddressOption(db)) @@ -330,16 +293,13 @@ export function injectCommands( contractAddress, from: parsedFromAddress, wait, - rpcUrl, alias, cancel, authWitness: authWitnessArray, verbose, - nodeUrl, } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + + const wallet = walletAndNodeWrapper.wallet; const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db); debugLogger.info(`Using wallet with address ${parsedFromAddress.toString()}`); @@ -369,8 +329,6 @@ export function injectCommands( .command('simulate') .description('Simulates the execution of a function on an Aztec contract.') .argument('', 'Name of function to simulate') - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createArgsOption(false, db)) .addOption(createContractAddressOption(db)) .addOption(createArtifactOption(db)) @@ -389,15 +347,11 @@ export function injectCommands( contractArtifact: artifactPathPromise, contractAddress, from: parsedFromAddress, - rpcUrl, verbose, authWitness, - nodeUrl, } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const wallet = walletAndNodeWrapper.wallet; const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db); const authWitnesses = cleanupAuthWitnesses(authWitness); @@ -419,8 +373,6 @@ export function injectCommands( .command('profile') .description('Profiles a private function by counting the unconditional operations in its execution steps') .argument('', 'Name of function to simulate') - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createArgsOption(false, db)) .addOption(createContractAddressOption(db)) .addOption(createArtifactOption(db)) @@ -436,15 +388,11 @@ export function injectCommands( contractArtifact: artifactPathPromise, contractAddress, from: parsedFromAddress, - rpcUrl, debugExecutionStepsDir, authWitness, - nodeUrl, } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const wallet = walletAndNodeWrapper.wallet; const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db); const authWitnesses = cleanupAuthWitnesses(authWitness); @@ -482,8 +430,6 @@ export function injectCommands( ) .option('--mint', 'Mint the tokens on L1', false) .option('--l1-private-key ', 'The private key to the eth account bridging', PRIVATE_KEY) - .addOption(pxeOption) - .addOption(nodeOption) .addOption(l1ChainIdOption) .option('--json', 'Output the claim in JSON format') // `options.wait` is default true. Passing `--no-wait` will set it to false. @@ -496,25 +442,15 @@ export function injectCommands( ) .action(async (amount, recipient, options) => { const { bridgeL1FeeJuice } = await import('./bridge_fee_juice.js'); - const { - rpcUrl, - l1ChainId, - l1RpcUrls, - l1PrivateKey, - mnemonic, - mint, - json, - wait, - interval: intervalS, - nodeUrl, - } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); + const { l1ChainId, l1RpcUrls, l1PrivateKey, mnemonic, mint, json, wait, interval: intervalS } = options; + + const wallet = walletAndNodeWrapper.wallet; + const node = walletAndNodeWrapper.node; const [secret, messageLeafIndex] = await bridgeL1FeeJuice( amount, recipient, - client, + wallet, node, l1RpcUrls, l1ChainId, @@ -541,8 +477,6 @@ export function injectCommands( .argument('', 'Account to be authorized to perform the action', address => aliasedAddressParser('accounts', address, db), ) - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createArgsOption(false, db)) .addOption(createContractAddressOption(db)) .addOption(createArtifactOption(db)) @@ -553,19 +487,9 @@ export function injectCommands( .action(async (functionName, caller, _options, command) => { const { createAuthwit } = await import('./create_authwit.js'); const options = command.optsWithGlobals(); - const { - args, - contractArtifact: artifactPathPromise, - contractAddress, - from: parsedFromAddress, - rpcUrl, - alias, - nodeUrl, - } = options; - - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const { args, contractArtifact: artifactPathPromise, contractAddress, from: parsedFromAddress, alias } = options; + + const wallet = walletAndNodeWrapper.wallet; const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db); const witness = await createAuthwit( wallet, @@ -592,8 +516,6 @@ export function injectCommands( .argument('', 'Account to be authorized to perform the action', address => aliasedAddressParser('accounts', address, db), ) - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createArgsOption(false, db)) .addOption(createContractAddressOption(db)) .addOption(createArtifactOption(db)) @@ -601,18 +523,9 @@ export function injectCommands( .action(async (functionName, caller, _options, command) => { const { authorizeAction } = await import('./authorize_action.js'); const options = command.optsWithGlobals(); - const { - args, - contractArtifact: artifactPathPromise, - contractAddress, - from: parsedFromAddress, - rpcUrl, - nodeUrl, - } = options; + const { args, contractArtifact: artifactPathPromise, contractAddress, from: parsedFromAddress } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const wallet = walletAndNodeWrapper.wallet; const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db); await authorizeAction(wallet, parsedFromAddress, functionName, caller, args, artifactPath, contractAddress, log); @@ -622,8 +535,6 @@ export function injectCommands( .command('get-tx') .description('Gets the status of the recent txs, or a detailed view if a specific transaction hash is provided') .argument('[txHash]', 'A transaction hash to get the receipt for.', txHash => aliasedTxHashParser(txHash, db)) - .addOption(pxeOption) - .addOption(nodeOption) .option('-p, --page ', 'The page number to display', value => integerArgParser(value, '--page', 1), 1) .option( '-s, --page-size ', @@ -633,13 +544,14 @@ export function injectCommands( ) .action(async (txHash, options) => { const { checkTx } = await import('./check_tx.js'); - const { rpcUrl, nodeUrl, pageSize } = options; + const { pageSize } = options; let { page } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const aztecNode = createAztecNodeClient(nodeUrl); + + const wallet = walletAndNodeWrapper.wallet; + const node = walletAndNodeWrapper.node; if (txHash) { - await checkTx(client, aztecNode, txHash, false, log); + await checkTx(wallet, node, txHash, false, log); } else if (db) { const aliases = await db.listAliases('transactions'); const totalPages = Math.ceil(aliases.length / pageSize); @@ -649,7 +561,7 @@ export function injectCommands( alias: key, txHash: value, cancellable: (await db.retrieveTxData(TxHash.fromString(value))).cancellable, - status: await checkTx(client, aztecNode, TxHash.fromString(value), true, log), + status: await checkTx(wallet, node, TxHash.fromString(value), true, log), })), ); log(`Recent transactions:`); @@ -670,8 +582,6 @@ export function injectCommands( .command('cancel-tx') .description('Cancels a pending tx by reusing its nonce with a higher fee and an empty payload') .argument('', 'A transaction hash to cancel.', txHash => aliasedTxHashParser(txHash, db)) - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db)) .addOption(getPaymentMethodOption().default('method=fee_juice')) .option( @@ -685,10 +595,9 @@ export function injectCommands( ) .action(async (txHash, options) => { const { cancelTx } = await import('./cancel_tx.js'); - const { from: parsedFromAddress, rpcUrl, payment, increasedFees, maxFeesPerGas, nodeUrl } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const { from: parsedFromAddress, payment, increasedFees, maxFeesPerGas } = options; + + const wallet = walletAndNodeWrapper.wallet; const txData = await db?.retrieveTxData(txHash); if (!txData) { @@ -708,15 +617,12 @@ export function injectCommands( .argument('[address]', 'The address of the sender to register', address => aliasedAddressParser('accounts', address, db), ) - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createAliasOption('Alias for the sender. Used for easy reference in subsequent commands.', !db)) .action(async (address, options) => { const { registerSender } = await import('./register_sender.js'); - const { rpcUrl, alias, nodeUrl } = options; - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const { alias } = options; + + const wallet = walletAndNodeWrapper.wallet; await registerSender(wallet, address, log); @@ -747,15 +653,13 @@ export function injectCommands( aliasedAddressParser('accounts', address, db), ) .addOption(createArgsOption(true, db)) - .addOption(pxeOption) - .addOption(nodeOption) .addOption(createAliasOption('Alias for the contact. Used for easy reference in subsequent commands.', !db)) .action(async (address, artifactPathPromise, _options, command) => { const { registerContract } = await import('./register_contract.js'); - const { rpcUrl, nodeUrl, alias, init, publicKey, salt, deployer, args } = command.optsWithGlobals(); - const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger)); - const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl); - const wallet = new CLIWallet(client, node, log, db); + const { alias, init, publicKey, salt, deployer, args } = command.optsWithGlobals(); + + const wallet = walletAndNodeWrapper.wallet; + const node = walletAndNodeWrapper.node; const artifactPath = await artifactPathPromise; diff --git a/yarn-project/cli-wallet/src/cmds/send.ts b/yarn-project/cli-wallet/src/cmds/send.ts index 9762d951bfbb..ba44b1db82f5 100644 --- a/yarn-project/cli-wallet/src/cmds/send.ts +++ b/yarn-project/cli-wallet/src/cmds/send.ts @@ -3,9 +3,9 @@ import { prepTx } from '@aztec/cli/utils'; import type { LogFn } from '@aztec/foundation/log'; import { GasSettings } from '@aztec/stdlib/gas'; +import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js'; import { CLIFeeArgs } from '../utils/options/fees.js'; import { printProfileResult } from '../utils/profiling.js'; -import { DEFAULT_TX_TIMEOUT_S } from '../utils/pxe_wrapper.js'; export async function send( wallet: Wallet, diff --git a/yarn-project/cli-wallet/src/utils/cli_wallet_and_node_wrapper.ts b/yarn-project/cli-wallet/src/utils/cli_wallet_and_node_wrapper.ts new file mode 100644 index 000000000000..0292dba54ca4 --- /dev/null +++ b/yarn-project/cli-wallet/src/utils/cli_wallet_and_node_wrapper.ts @@ -0,0 +1,35 @@ +import type { AztecNode } from '@aztec/stdlib/interfaces/client'; + +import { CLIWallet } from './wallet.js'; + +export const DEFAULT_TX_TIMEOUT_S = 180; + +/* + * Wrapper class for CLIWallet and AztecNode, avoids initialization issues due to closures when providing CLIWallet + * and AztecNode to injected commander.js commands + */ +export class CliWalletAndNodeWrapper { + private _wallet: CLIWallet | undefined; + private _node: AztecNode | undefined; + + constructor() {} + + get wallet() { + if (!this._wallet) { + throw new Error('Wallet not initialized while it should have been initialized in preSubcommand'); + } + return this._wallet; + } + + get node() { + if (!this._node) { + throw new Error('Node not initialized while it should have been initialized in preSubcommand'); + } + return this._node; + } + + setNodeAndWallet(node: AztecNode, wallet: CLIWallet) { + this._node = node; + this._wallet = wallet; + } +} diff --git a/yarn-project/cli-wallet/src/utils/pxe_wrapper.ts b/yarn-project/cli-wallet/src/utils/pxe_wrapper.ts deleted file mode 100644 index 5d1a4c0601bd..000000000000 --- a/yarn-project/cli-wallet/src/utils/pxe_wrapper.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; -import { type AztecNode, type PXE, createAztecNodeClient } from '@aztec/stdlib/interfaces/client'; - -export const DEFAULT_TX_TIMEOUT_S = 180; - -/* - * Wrapper class for PXE service, avoids initialization issues due to - * closures when providing PXE service to injected commander.js commands - */ -export class PXEWrapper { - private static pxeConfig: PXEServiceConfig | undefined; - private static pxe: PXE | undefined; - private static node: AztecNode | undefined; - - async getPXE() { - if (!PXEWrapper.pxe) { - PXEWrapper.pxe = await createPXEService(PXEWrapper.node!, PXEWrapper.pxeConfig!); - } - return PXEWrapper.pxe; - } - - getNode(): AztecNode | undefined { - return PXEWrapper.node; - } - - prepare(nodeUrl: string, dataDir: string, overridePXEServiceConfig?: Partial) { - PXEWrapper.node = createAztecNodeClient(nodeUrl); - const pxeConfig = Object.assign(getPXEServiceConfig(), overridePXEServiceConfig); - pxeConfig.dataDirectory = dataDir; - PXEWrapper.pxeConfig = pxeConfig; - } -} diff --git a/yarn-project/cli-wallet/src/utils/wallet.ts b/yarn-project/cli-wallet/src/utils/wallet.ts index 8df33b9657a6..3c66a5ff1555 100644 --- a/yarn-project/cli-wallet/src/utils/wallet.ts +++ b/yarn-project/cli-wallet/src/utils/wallet.ts @@ -10,6 +10,7 @@ import { BaseWallet, SignerlessAccount, type SimulateMethodOptions, + UniqueNote, getContractInstanceFromInstantiationParams, getGasLimits, } from '@aztec/aztec.js'; @@ -18,9 +19,12 @@ import { DefaultMultiCallEntrypoint } from '@aztec/entrypoints/multicall'; import { ExecutionPayload } from '@aztec/entrypoints/payload'; import { Fr } from '@aztec/foundation/fields'; import type { LogFn } from '@aztec/foundation/log'; +import type { PXEServiceConfig } from '@aztec/pxe/config'; +import { createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { AztecNode, PXE } from '@aztec/stdlib/interfaces/client'; +import type { AztecNode, PXE, PXEInfo } from '@aztec/stdlib/interfaces/client'; import { deriveSigningKey } from '@aztec/stdlib/keys'; +import type { NotesFilter } from '@aztec/stdlib/note'; import type { TxExecutionRequest, TxProvingResult, TxSimulationResult } from '@aztec/stdlib/tx'; import type { WalletDB } from '../storage/wallet_db.js'; @@ -40,6 +44,17 @@ export class CLIWallet extends BaseWallet { super(pxe, node); } + static async create( + node: AztecNode, + log: LogFn, + db?: WalletDB, + overridePXEServiceConfig?: Partial, + ): Promise { + const pxeConfig = Object.assign(getPXEServiceConfig(), overridePXEServiceConfig); + const pxe = await createPXEService(node, pxeConfig); + return new CLIWallet(pxe, node, log, db); + } + override async getAccounts(): Promise[]> { const accounts = (await this.db?.listAliases('accounts')) ?? []; return Promise.resolve(accounts.map(({ key, value }) => ({ alias: value, item: AztecAddress.fromString(key) }))); @@ -208,4 +223,23 @@ export class CLIWallet extends BaseWallet { printGasEstimates(fee, limits, this.userLog); return simulationResults; } + + // Recently added when having the wallet instantiate PXE as PXE is now hidden. This forced me to expose this when + // refactoring `checkTx` cli-wallet command. + getContracts(): Promise { + return this.pxe.getContracts(); + } + + // Recently added when having the wallet instantiate PXE as PXE is now hidden. This forced me to expose this when + // refactoring `checkTx` cli-wallet command. + getNotes(filter: NotesFilter): Promise { + return this.pxe.getNotes(filter); + } + + // Recently added when having the wallet instantiate PXE as PXE is now hidden. This forced me to expose this when + // refactoring `bridge_fee_juice` cli-wallet command. + // TODO: This should most likely just be refactored to getProtocolContractAddresses. + getPXEInfo(): Promise { + return this.pxe.getPXEInfo(); + } } diff --git a/yarn-project/cli-wallet/test/test.sh b/yarn-project/cli-wallet/test/test.sh index eeb32e183a03..ef331cec1a93 100755 --- a/yarn-project/cli-wallet/test/test.sh +++ b/yarn-project/cli-wallet/test/test.sh @@ -15,10 +15,6 @@ while [[ $# -gt 0 ]]; do FILTER="$2" shift 2 ;; - -r|--remote-pxe) - REMOTE_PXE="1" - shift - ;; -*|--*) echo "Unknown option $1" exit 1 @@ -38,11 +34,6 @@ export PXE_PROVER="none" rm -rf $WALLET_DATA_DIRECTORY mkdir -p $WALLET_DATA_DIRECTORY -if [ "${REMOTE_PXE:-}" = "1" ]; then - echo "Using remote PXE" - export REMOTE_PXE="1" -fi - if [ "${USE_DOCKER:-}" = "1" ]; then echo "Using docker" # overwrite default command in flows diff --git a/yarn-project/cli/README.md b/yarn-project/cli/README.md index 49cae0ec75f7..4734cd61fcad 100644 --- a/yarn-project/cli/README.md +++ b/yarn-project/cli/README.md @@ -37,18 +37,8 @@ These options are: - `SECRET_KEY` -> `-sk, --secret-key` for all commands that require an Aztec secret key. - `PUBLIC_KEY` -> `-k, --public-key` for all commands that require a public key. -- `PXE_URL` -> `-u, --rpc-url` for commands that require a PXE - `ETHEREUM_HOSTS` -> `-u, --rpc-urls` or `--l1-rpc-urls` for `deploy-l1-contracts`. -So if for example you are running your Private eXecution Environment (PXE) remotely you can do: - -```shell -export PXE_URL=http://external.site/rpc:8080 -aztec-cli deploy my_contract.json -``` - -And this will send the request to `http://external.site/rpc:8080`. - **NOTE**: Entering an option value will override the environment variable. ## Available Commands diff --git a/yarn-project/cli/package.json b/yarn-project/cli/package.json index 3dba2da75fd6..7564d02f040a 100644 --- a/yarn-project/cli/package.json +++ b/yarn-project/cli/package.json @@ -7,7 +7,6 @@ "./devnet": "./dest/cmds/devnet/index.js", "./infrastructure": "./dest/cmds/infrastructure/index.js", "./l1": "./dest/cmds/l1/index.js", - "./pxe": "./dest/cmds/pxe/index.js", "./aztec_node": "./dest/cmds/aztec_node/index.js", "./cli-utils": "./dest/utils/index.js", "./misc": "./dest/cmds/misc/index.js", diff --git a/yarn-project/cli/src/cmds/aztec_node/get_block.ts b/yarn-project/cli/src/cmds/aztec_node/get_block.ts index cf59015cc2a3..e23b0f82d31c 100644 --- a/yarn-project/cli/src/cmds/aztec_node/get_block.ts +++ b/yarn-project/cli/src/cmds/aztec_node/get_block.ts @@ -1,17 +1,10 @@ -import { createAztecNodeClient, createCompatibleClient } from '@aztec/aztec.js'; -import type { LogFn, Logger } from '@aztec/foundation/log'; +import { createAztecNodeClient } from '@aztec/aztec.js'; +import type { LogFn } from '@aztec/foundation/log'; import { inspectBlock } from '../../utils/inspect.js'; -export async function getBlock( - pxeUrl: string, - nodeUrl: string, - maybeBlockNumber: number | undefined, - debugLogger: Logger, - log: LogFn, -) { - const client = await createCompatibleClient(pxeUrl, debugLogger); +export async function getBlock(nodeUrl: string, maybeBlockNumber: number | undefined, log: LogFn) { const aztecNode = createAztecNodeClient(nodeUrl); const blockNumber = maybeBlockNumber ?? (await aztecNode.getBlockNumber()); - await inspectBlock(client, aztecNode, blockNumber, log, { showTxs: true }); + await inspectBlock(aztecNode, blockNumber, log, { showTxs: true }); } diff --git a/yarn-project/cli/src/cmds/aztec_node/index.ts b/yarn-project/cli/src/cmds/aztec_node/index.ts index 4adffd621f9c..aa1d08b36e9f 100644 --- a/yarn-project/cli/src/cmds/aztec_node/index.ts +++ b/yarn-project/cli/src/cmds/aztec_node/index.ts @@ -11,7 +11,6 @@ import { parseOptionalInteger, parseOptionalLogId, parseOptionalTxHash, - pxeOption, } from '../../utils/commands.js'; export function injectCommands(program: Command, log: LogFn, debugLogger: Logger) { @@ -19,11 +18,10 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: Logger .command('get-block') .description('Gets info for a given block or latest.') .argument('[blockNumber]', 'Block height', parseOptionalInteger) - .addOption(pxeOption) .addOption(nodeOption) .action(async (blockNumber, options) => { const { getBlock } = await import('./get_block.js'); - await getBlock(options.rpcUrl, options.nodeUrl, blockNumber, debugLogger, log); + await getBlock(options.nodeUrl, blockNumber, log); }); program diff --git a/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts b/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts index f482b2cfc120..6cc6fa22cb08 100644 --- a/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts +++ b/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts @@ -10,7 +10,6 @@ import { type WaitOpts, type Wallet, createAztecNodeClient, - createCompatibleClient, retryUntil, waitForProven, } from '@aztec/aztec.js'; @@ -44,7 +43,6 @@ const provenWaitOpts: WaitForProvenOpts = { }; export async function bootstrapNetwork( - pxeUrl: string, nodeUrl: string, l1Urls: string[], l1ChainId: string, @@ -55,9 +53,8 @@ export async function bootstrapNetwork( log: LogFn, debugLog: Logger, ) { - const pxe = await createCompatibleClient(pxeUrl, debugLog); const node = createAztecNodeClient(nodeUrl); - const wallet = new TestWallet(pxe, node); + const wallet = await TestWallet.create(node); // We assume here that the initial test accounts were prefunded with deploy-l1-contracts, and deployed with setup-l2-contracts // so all we need to do is register them to our pxe. diff --git a/yarn-project/cli/src/cmds/devnet/index.ts b/yarn-project/cli/src/cmds/devnet/index.ts index 8fdbb8da7a1e..8e39dffe8871 100644 --- a/yarn-project/cli/src/cmds/devnet/index.ts +++ b/yarn-project/cli/src/cmds/devnet/index.ts @@ -2,13 +2,12 @@ import type { LogFn, Logger } from '@aztec/foundation/log'; import type { Command } from 'commander'; -import { ETHEREUM_HOSTS, l1ChainIdOption, nodeOption, parseEthereumAddress, pxeOption } from '../../utils/commands.js'; +import { ETHEREUM_HOSTS, l1ChainIdOption, nodeOption, parseEthereumAddress } from '../../utils/commands.js'; export function injectCommands(program: Command, log: LogFn, debugLogger: Logger) { program .command('bootstrap-network') .description('Bootstrap a new network') - .addOption(pxeOption) .addOption(nodeOption) .addOption(l1ChainIdOption) .requiredOption( @@ -33,7 +32,6 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: Logger .action(async options => { const { bootstrapNetwork } = await import('./bootstrap_network.js'); await bootstrapNetwork( - options[pxeOption.attributeName()], options[nodeOption.attributeName()], options.l1RpcUrls, options[l1ChainIdOption.attributeName()], diff --git a/yarn-project/cli/src/cmds/infrastructure/index.ts b/yarn-project/cli/src/cmds/infrastructure/index.ts index f79e0c1182ff..186a25d18c2a 100644 --- a/yarn-project/cli/src/cmds/infrastructure/index.ts +++ b/yarn-project/cli/src/cmds/infrastructure/index.ts @@ -2,27 +2,18 @@ import type { LogFn } from '@aztec/foundation/log'; import type { Command } from 'commander'; -import { ETHEREUM_HOSTS, l1ChainIdOption, nodeOption, parseOptionalInteger, pxeOption } from '../../utils/commands.js'; +import { ETHEREUM_HOSTS, l1ChainIdOption, nodeOption, parseOptionalInteger } from '../../utils/commands.js'; export function injectCommands(program: Command, log: LogFn) { program .command('setup-protocol-contracts') .description('Bootstrap the blockchain by initializing all the protocol contracts') - .addOption(pxeOption) .addOption(nodeOption) .option('--testAccounts', 'Deploy funded test accounts.') - .option('--sponsoredFPC', 'Deploy a sponsored FPC.') .option('--json', 'Output the contract addresses in JSON format') .action(async options => { const { setupL2Contracts } = await import('./setup_l2_contract.js'); - await setupL2Contracts( - options.rpcUrl, - options.nodeUrl, - options.testAccounts, - options.sponsoredFPC, - options.json, - log, - ); + await setupL2Contracts(options.nodeUrl, options.testAccounts, options.json, log); }); program diff --git a/yarn-project/cli/src/cmds/infrastructure/setup_l2_contract.ts b/yarn-project/cli/src/cmds/infrastructure/setup_l2_contract.ts index 5b408a094696..b2f59e8d8df9 100644 --- a/yarn-project/cli/src/cmds/infrastructure/setup_l2_contract.ts +++ b/yarn-project/cli/src/cmds/infrastructure/setup_l2_contract.ts @@ -1,36 +1,19 @@ import { getInitialTestAccountsData } from '@aztec/accounts/testing'; -import { - AccountManager, - type AztecAddress, - type WaitOpts, - createAztecNodeClient, - createPXEClient, - makeFetch, -} from '@aztec/aztec.js'; +import { AccountManager, type AztecAddress, type WaitOpts, createAztecNodeClient } from '@aztec/aztec.js'; import { jsonStringify } from '@aztec/foundation/json-rpc'; import type { LogFn } from '@aztec/foundation/log'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { TestWallet, deployFundedSchnorrAccounts } from '@aztec/test-wallet'; -import { setupSponsoredFPC } from '../../utils/setup_contracts.js'; - -export async function setupL2Contracts( - pxeUrl: string, - nodeUrl: string, - testAccounts: boolean, - sponsoredFPC: boolean, - json: boolean, - log: LogFn, -) { +export async function setupL2Contracts(nodeUrl: string, testAccounts: boolean, json: boolean, log: LogFn) { const waitOpts: WaitOpts = { timeout: 180, interval: 1, }; log('setupL2Contracts: Wait options' + jsonStringify(waitOpts)); log('setupL2Contracts: Creating PXE client...'); - const pxe = createPXEClient(pxeUrl, {}, makeFetch([1, 1, 1, 1, 1], false)); const node = createAztecNodeClient(nodeUrl); - const wallet = new TestWallet(pxe, node); + const wallet = await TestWallet.create(node); let deployedAccountManagers: AccountManager[] = []; if (testAccounts) { @@ -39,11 +22,6 @@ export async function setupL2Contracts( deployedAccountManagers = await deployFundedSchnorrAccounts(wallet, initialAccountsData, waitOpts); } - if (sponsoredFPC) { - log('setupL2Contracts: Setting up sponsored FPC...'); - await setupSponsoredFPC(pxe, log); - } - if (json) { const toPrint: Record = { ...ProtocolContractAddress }; deployedAccountManagers.forEach((a, i) => { diff --git a/yarn-project/cli/src/cmds/l1/index.ts b/yarn-project/cli/src/cmds/l1/index.ts index b10cae1598ba..1f1cf02eece7 100644 --- a/yarn-project/cli/src/cmds/l1/index.ts +++ b/yarn-project/cli/src/cmds/l1/index.ts @@ -13,7 +13,6 @@ import { parseAztecAddress, parseBigint, parseEthereumAddress, - pxeOption, } from '../../utils/commands.js'; export { addL1Validator } from './update_l1_validators.js'; @@ -518,10 +517,10 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: Logger .command('advance-epoch') .description('Use L1 cheat codes to warp time until the next epoch.') .addOption(l1RpcUrlsOption) - .addOption(pxeOption) + .addOption(nodeOption) .action(async options => { const { advanceEpoch } = await import('./advance_epoch.js'); - await advanceEpoch(options.l1RpcUrls, options.rpcUrl, log); + await advanceEpoch(options.l1RpcUrls, options.nodeUrl, log); }); program diff --git a/yarn-project/cli/src/cmds/pxe/add_contract.ts b/yarn-project/cli/src/cmds/pxe/add_contract.ts deleted file mode 100644 index fe47db0fced7..000000000000 --- a/yarn-project/cli/src/cmds/pxe/add_contract.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { AztecAddress, type ContractInstanceWithAddress, type Fr, getContractClassFromArtifact } from '@aztec/aztec.js'; -import { createCompatibleClient } from '@aztec/aztec.js'; -import type { LogFn, Logger } from '@aztec/foundation/log'; -import { computeContractAddressFromInstance } from '@aztec/stdlib/contract'; -import { PublicKeys } from '@aztec/stdlib/keys'; - -import { getContractArtifact } from '../../utils/aztec.js'; - -export async function addContract( - rpcUrl: string, - contractArtifactPath: string, - address: AztecAddress, - initializationHash: Fr, - salt: Fr, - publicKeys: PublicKeys, - deployer: AztecAddress | undefined, - debugLogger: Logger, - log: LogFn, -) { - const artifact = await getContractArtifact(contractArtifactPath, log); - const contractClass = await getContractClassFromArtifact(artifact); - const instance: ContractInstanceWithAddress = { - version: 1, - salt, - initializationHash, - currentContractClassId: contractClass.id, - originalContractClassId: contractClass.id, - publicKeys: publicKeys ?? PublicKeys.default(), - address, - deployer: deployer ?? AztecAddress.ZERO, - }; - const computed = await computeContractAddressFromInstance(instance); - if (!computed.equals(address)) { - throw new Error(`Contract address ${address.toString()} does not match computed address ${computed.toString()}`); - } - - const client = await createCompatibleClient(rpcUrl, debugLogger); - - await client.registerContract({ artifact, instance }); - log(`\nContract added to PXE at ${address.toString()} with class ${instance.currentContractClassId.toString()}\n`); -} diff --git a/yarn-project/cli/src/cmds/pxe/get_account.ts b/yarn-project/cli/src/cmds/pxe/get_account.ts deleted file mode 100644 index 2b65115528fa..000000000000 --- a/yarn-project/cli/src/cmds/pxe/get_account.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { AztecAddress } from '@aztec/aztec.js'; -import { createCompatibleClient } from '@aztec/aztec.js'; -import type { LogFn, Logger } from '@aztec/foundation/log'; - -export async function getAccount(aztecAddress: AztecAddress, rpcUrl: string, debugLogger: Logger, log: LogFn) { - const client = await createCompatibleClient(rpcUrl, debugLogger); - const account = (await client.getRegisteredAccounts()).find(completeAddress => - completeAddress.address.equals(aztecAddress), - ); - - if (!account) { - log(`Unknown account ${aztecAddress.toString()}`); - } else { - log(account.toReadableString()); - } -} diff --git a/yarn-project/cli/src/cmds/pxe/get_accounts.ts b/yarn-project/cli/src/cmds/pxe/get_accounts.ts deleted file mode 100644 index 4210d5c66e70..000000000000 --- a/yarn-project/cli/src/cmds/pxe/get_accounts.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { createCompatibleClient } from '@aztec/aztec.js'; -import type { LogFn, Logger } from '@aztec/foundation/log'; - -export async function getAccounts( - rpcUrl: string, - json: boolean, - debugLogger: Logger, - log: LogFn, - logJson: (output: any) => void, -) { - const client = await createCompatibleClient(rpcUrl, debugLogger); - const accounts = await client.getRegisteredAccounts(); - if (!accounts.length) { - if (json) { - logJson([]); - } else { - log('No accounts found.'); - } - return; - } - if (json) { - logJson( - accounts.map(a => ({ - address: a.address.toString(), - publicKeys: a.publicKeys.toString(), - partialAddress: a.partialAddress.toString(), - })), - ); - } else { - log(`Accounts found: \n`); - for (const account of accounts) { - log(account.toReadableString()); - } - } -} diff --git a/yarn-project/cli/src/cmds/pxe/get_contract_data.ts b/yarn-project/cli/src/cmds/pxe/get_contract_data.ts deleted file mode 100644 index 72fa4b41b118..000000000000 --- a/yarn-project/cli/src/cmds/pxe/get_contract_data.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { AztecAddress } from '@aztec/aztec.js'; -import { createCompatibleClient } from '@aztec/aztec.js'; -import type { LogFn, Logger } from '@aztec/foundation/log'; - -export async function getContractData( - rpcUrl: string, - contractAddress: AztecAddress, - includeBytecode: boolean, - debugLogger: Logger, - log: LogFn, -) { - const client = await createCompatibleClient(rpcUrl, debugLogger); - const { - contractInstance: instance, - isContractInitialized: isInitialized, - isContractPublished: isPubliclyDeployed, - } = await client.getContractMetadata(contractAddress); - const contractClass = - includeBytecode && - instance && - (await client.getContractClassMetadata(instance?.currentContractClassId)).contractClass; - - const isPrivatelyDeployed = !!instance; - const initStr = isInitialized ? 'initialized' : 'not initialized'; - const addrStr = contractAddress.toString(); - - if (isPubliclyDeployed && isPrivatelyDeployed) { - log(`Contract is ${initStr} and publicly deployed at ${addrStr}`); - } else if (isPrivatelyDeployed) { - log(`Contract is ${initStr} and registered in the local pxe at ${addrStr} but not publicly deployed`); - } else if (isPubliclyDeployed) { - log(`Contract is ${initStr} and publicly deployed at ${addrStr} but not registered in the local pxe`); - } else if (isInitialized) { - log(`Contract is initialized but not publicly deployed nor registered in the local pxe at ${addrStr}`); - } else { - log(`No contract found at ${addrStr}`); - } - - if (instance) { - log(``); - Object.entries(instance).forEach(([key, value]) => { - const capitalized = key.charAt(0).toUpperCase() + key.slice(1); - log(`${capitalized}: ${value.toString()}`); - }); - - if (contractClass) { - log(`\nBytecode: ${contractClass.packedBytecode.toString('base64')}`); - } - log(''); - } -} diff --git a/yarn-project/cli/src/cmds/pxe/get_pxe_info.ts b/yarn-project/cli/src/cmds/pxe/get_pxe_info.ts deleted file mode 100644 index b662b3dc874c..000000000000 --- a/yarn-project/cli/src/cmds/pxe/get_pxe_info.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { createCompatibleClient } from '@aztec/aztec.js'; -import type { LogFn, Logger } from '@aztec/foundation/log'; - -export async function getPXEInfo(rpcUrl: string, debugLogger: Logger, log: LogFn) { - const client = await createCompatibleClient(rpcUrl, debugLogger); - const info = await client.getPXEInfo(); - log(`PXE Version: ${info.pxeVersion}`); - log(`Protocol Contract Addresses:`); - log(` Class Registry: ${info.protocolContractAddresses.classRegistry.toString()}`); - log(` Fee Juice: ${info.protocolContractAddresses.feeJuice.toString()}`); - log(` Instance Deployer: ${info.protocolContractAddresses.instanceRegistry.toString()}`); - log(` Multi Call Entrypoint: ${info.protocolContractAddresses.multiCallEntrypoint.toString()}`); -} diff --git a/yarn-project/cli/src/cmds/pxe/index.ts b/yarn-project/cli/src/cmds/pxe/index.ts deleted file mode 100644 index 6322a86fbe2b..000000000000 --- a/yarn-project/cli/src/cmds/pxe/index.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Fr } from '@aztec/foundation/fields'; -import type { LogFn, Logger } from '@aztec/foundation/log'; - -import type { Command } from 'commander'; - -import { - logJson, - parseAztecAddress, - parseEthereumAddress, - parseFieldFromHexString, - parsePublicKey, - pxeOption, -} from '../../utils/commands.js'; - -export function injectCommands(program: Command, log: LogFn, debugLogger: Logger) { - program - .command('add-contract') - .description( - 'Adds an existing contract to the PXE. This is useful if you have deployed a contract outside of the PXE and want to use it with the PXE.', - ) - .requiredOption( - '-c, --contract-artifact ', - "A compiled Aztec.nr contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts.js", - ) - .requiredOption('-ca, --contract-address
', 'Aztec address of the contract.', parseAztecAddress) - .requiredOption('--init-hash ', 'Initialization hash', parseFieldFromHexString) - .option('--salt ', 'Optional deployment salt', parseFieldFromHexString) - .option('-p, --public-key ', 'Optional public key for this contract', parsePublicKey) - .option('--portal-address
', 'Optional address to a portal contract on L1', parseEthereumAddress) - .option('--deployer-address
', 'Optional address of the contract deployer', parseAztecAddress) - .addOption(pxeOption) - .action(async options => { - const { addContract } = await import('./add_contract.js'); - await addContract( - options.rpcUrl, - options.contractArtifact, - options.contractAddress, - options.initHash, - options.salt ?? Fr.ZERO, - options.publicKey, - options.deployerAddress, - debugLogger, - log, - ); - }); - - program - .command('get-contract-data') - .description('Gets information about the Aztec contract deployed at the specified address.') - .argument('', 'Aztec address of the contract.', parseAztecAddress) - .addOption(pxeOption) - .option('-b, --include-bytecode ', "Include the contract's public function bytecode, if any.", false) - .action(async (contractAddress, options) => { - const { getContractData } = await import('./get_contract_data.js'); - await getContractData(options.rpcUrl, contractAddress, options.includeBytecode, debugLogger, log); - }); - - program - .command('get-accounts') - .description('Gets all the Aztec accounts stored in the PXE.') - .addOption(pxeOption) - .option('--json', 'Emit output as json') - .action(async (options: any) => { - const { getAccounts } = await import('./get_accounts.js'); - await getAccounts(options.rpcUrl, options.json, debugLogger, log, logJson(log)); - }); - - program - .command('get-account') - .description('Gets an account given its Aztec address.') - .argument('
', 'The Aztec address to get account for', parseAztecAddress) - .addOption(pxeOption) - .action(async (address, options) => { - const { getAccount } = await import('./get_account.js'); - await getAccount(address, options.rpcUrl, debugLogger, log); - }); - - program - .command('get-pxe-info') - .description('Gets the information of a PXE at a URL.') - .addOption(pxeOption) - .action(async options => { - const { getPXEInfo } = await import('./get_pxe_info.js'); - await getPXEInfo(options.rpcUrl, debugLogger, log); - }); - - return program; -} diff --git a/yarn-project/cli/src/utils/commands.ts b/yarn-project/cli/src/utils/commands.ts index 43fef1946608..2b3f9f915781 100644 --- a/yarn-project/cli/src/utils/commands.ts +++ b/yarn-project/cli/src/utils/commands.ts @@ -29,19 +29,10 @@ export function addOptions(program: Command, options: Option[]) { return program; } -export const makePxeOption = (mandatory: boolean) => - new Option('-u, --rpc-url ', 'URL of the PXE') - .env('PXE_URL') - .default(`http://${LOCALHOST}:8080`) - .conflicts('remote-pxe') - .makeOptionMandatory(mandatory); - -export const pxeOption = makePxeOption(true); - export const makeNodeOption = (mandatory: boolean) => new Option('-n, --node-url ', 'URL of the Aztec node') .env('AZTEC_NODE_URL') - .default(`http://${LOCALHOST}:8079`) + .default(`http://${LOCALHOST}:8080`) .makeOptionMandatory(mandatory); export const nodeOption = makeNodeOption(true); diff --git a/yarn-project/cli/src/utils/inspect.ts b/yarn-project/cli/src/utils/inspect.ts index a0fdecff9f6c..b2fa2de75fda 100644 --- a/yarn-project/cli/src/utils/inspect.ts +++ b/yarn-project/cli/src/utils/inspect.ts @@ -1,13 +1,8 @@ -import type { AztecAddress, ContractArtifact, Fr } from '@aztec/aztec.js'; import type { LogFn } from '@aztec/foundation/log'; -import { ProtocolContractAddress } from '@aztec/protocol-contracts'; -import { siloNullifier } from '@aztec/stdlib/hash'; -import type { AztecNode, PXE } from '@aztec/stdlib/interfaces/client'; -import type { ExtendedNote } from '@aztec/stdlib/note'; +import type { AztecNode } from '@aztec/stdlib/interfaces/client'; import type { TxHash } from '@aztec/stdlib/tx'; export async function inspectBlock( - pxe: PXE, aztecNode: AztecNode, blockNumber: number, log: LogFn, @@ -31,9 +26,8 @@ export async function inspectBlock( log(` Timestamp: ${new Date(Number(block.header.globalVariables.timestamp) * 500)}`); if (opts.showTxs) { log(``); - const artifactMap = await getKnownArtifacts(pxe); for (const txHash of block.body.txEffects.map(tx => tx.txHash)) { - await inspectTx(pxe, aztecNode, txHash, log, { includeBlockInfo: false, artifactMap }); + await inspectTx(aztecNode, txHash, log, { includeBlockInfo: false }); } } else { log(` Transactions: ${block.body.txEffects.length}`); @@ -41,11 +35,10 @@ export async function inspectBlock( } export async function inspectTx( - pxe: PXE, aztecNode: AztecNode, txHash: TxHash, log: LogFn, - opts: { includeBlockInfo?: boolean; artifactMap?: ArtifactMap } = {}, + opts: { includeBlockInfo?: boolean } = {}, ) { const [receipt, effectsInBlock] = await Promise.all([aztecNode.getTxReceipt(txHash), aztecNode.getTxEffect(txHash)]); // Base tx data @@ -60,7 +53,6 @@ export async function inspectTx( } const effects = effectsInBlock.data; - const artifactMap = opts?.artifactMap ?? (await getKnownArtifacts(pxe)); if (opts.includeBlockInfo) { log(` Block: ${receipt.blockNumber} (${receipt.blockHash?.toString()})`); @@ -97,38 +89,12 @@ export async function inspectTx( } } - // Nullifiers - const nullifierCount = effects.nullifiers.length; - const { deployNullifiers, initNullifiers, classNullifiers } = await getKnownNullifiers(pxe, artifactMap); - if (nullifierCount > 0) { - log(' Nullifiers:'); - for (const nullifier of effects.nullifiers) { - const deployed = deployNullifiers[nullifier.toString()]; - const note = deployed - ? (await pxe.getNotes({ siloedNullifier: nullifier, contractAddress: deployed }))[0] - : undefined; - const initialized = initNullifiers[nullifier.toString()]; - const registered = classNullifiers[nullifier.toString()]; - if (nullifier.toBuffer().equals(txHash.toBuffer())) { - log(` Transaction hash nullifier ${nullifier.toShortString()}`); - } else if (note) { - inspectNote(note, artifactMap, log, `Nullifier ${nullifier.toShortString()} for note`); - } else if (deployed) { - log( - ` Contract ${toFriendlyAddress(deployed, artifactMap)} deployed via nullifier ${nullifier.toShortString()}`, - ); - } else if (initialized) { - log( - ` Contract ${toFriendlyAddress( - initialized, - artifactMap, - )} initialized via nullifier ${nullifier.toShortString()}`, - ); - } else if (registered) { - log(` Class ${registered} registered via nullifier ${nullifier.toShortString()}`); - } else { - log(` Unknown nullifier ${nullifier.toString()}`); - } + // Created nullifiers + const nullifiers = effects.nullifiers; + if (nullifiers.length > 0) { + log(' Created nullifiers:'); + for (const nullifier of nullifiers) { + log(` Nullifier: ${nullifier.toShortString()}`); } } @@ -140,69 +106,3 @@ export async function inspectTx( } } } - -function inspectNote(note: ExtendedNote, artifactMap: ArtifactMap, log: LogFn, text = 'Note') { - const artifact = artifactMap[note.contractAddress.toString()]; - const contract = artifact?.name ?? note.contractAddress.toString(); - log(` ${text} at ${contract}`); - log(` Recipient: ${toFriendlyAddress(note.recipient, artifactMap)}`); - for (const field of note.note.items) { - log(` ${field.toString()}`); - } -} - -function toFriendlyAddress(address: AztecAddress, artifactMap: ArtifactMap) { - const artifact = artifactMap[address.toString()]; - if (!artifact) { - return address.toString(); - } - - return `${artifact.name}<${address.toString()}>`; -} - -async function getKnownNullifiers(pxe: PXE, artifactMap: ArtifactMap) { - const knownContracts = await pxe.getContracts(); - const deployerAddress = ProtocolContractAddress.ContractInstanceRegistry; - const classRegistryAddress = ProtocolContractAddress.ContractClassRegistry; - const initNullifiers: Record = {}; - const deployNullifiers: Record = {}; - const classNullifiers: Record = {}; - for (const contract of knownContracts) { - initNullifiers[(await siloNullifier(contract, contract.toField())).toString()] = contract; - deployNullifiers[(await siloNullifier(deployerAddress, contract.toField())).toString()] = contract; - } - for (const artifact of Object.values(artifactMap)) { - classNullifiers[(await siloNullifier(classRegistryAddress, artifact.classId)).toString()] = - `${artifact.name}Class<${artifact.classId}>`; - } - return { initNullifiers, deployNullifiers, classNullifiers }; -} - -type ArtifactMap = Record; -type ContractArtifactWithClassId = ContractArtifact & { classId: Fr }; -async function getKnownArtifacts(pxe: PXE): Promise { - const knownContractAddresses = await pxe.getContracts(); - const knownContracts = ( - await Promise.all(knownContractAddresses.map(contractAddress => pxe.getContractMetadata(contractAddress))) - ).map(contractMetadata => contractMetadata.contractInstance); - const classIds = [...new Set(knownContracts.map(contract => contract?.currentContractClassId))]; - const knownArtifacts = ( - await Promise.all(classIds.map(classId => (classId ? pxe.getContractClassMetadata(classId) : undefined))) - ).map(contractClassMetadata => - contractClassMetadata - ? { ...contractClassMetadata.artifact, classId: contractClassMetadata.contractClass?.id } - : undefined, - ); - const map: Record = {}; - for (const instance of knownContracts) { - if (instance) { - const artifact = knownArtifacts.find(a => - a?.classId?.equals(instance.currentContractClassId), - ) as ContractArtifactWithClassId; - if (artifact) { - map[instance.address.toString()] = artifact; - } - } - } - return map; -} diff --git a/yarn-project/cli/src/utils/setup_contracts.ts b/yarn-project/cli/src/utils/setup_contracts.ts index 8c3ee5480c36..5b1a2d927457 100644 --- a/yarn-project/cli/src/utils/setup_contracts.ts +++ b/yarn-project/cli/src/utils/setup_contracts.ts @@ -1,6 +1,5 @@ -import { Fr, type PXE, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js'; +import { Fr, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js'; import { SPONSORED_FPC_SALT } from '@aztec/constants'; -import type { LogFn } from '@aztec/foundation/log'; async function getSponsoredFPCContract() { // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -16,13 +15,3 @@ export async function getSponsoredFPCAddress() { }); return sponsoredFPCInstance.address; } - -export async function setupSponsoredFPC(pxe: PXE, log: LogFn) { - const SponsoredFPCContract = await getSponsoredFPCContract(); - const sponsoredFPCInstance = await getContractInstanceFromInstantiationParams(SponsoredFPCContract.artifact, { - salt: new Fr(SPONSORED_FPC_SALT), - }); - await pxe.registerContract({ instance: sponsoredFPCInstance, artifact: SponsoredFPCContract.artifact }); - - log(`SponsoredFPC: ${sponsoredFPCInstance.address}`); -} diff --git a/yarn-project/end-to-end/scripts/docker-compose.yml b/yarn-project/end-to-end/scripts/docker-compose.yml index 7b1f2205d44b..386f98c536f1 100644 --- a/yarn-project/end-to-end/scripts/docker-compose.yml +++ b/yarn-project/end-to-end/scripts/docker-compose.yml @@ -47,7 +47,6 @@ services: ETHEREUM_HOSTS: http://fork:8545 L1_CHAIN_ID: 31337 FORCE_COLOR: ${FORCE_COLOR:-1} - PXE_URL: http://sandbox:8080 AZTEC_NODE_URL: http://sandbox:8080 # Allow git usage despite different ownership. Relevant for script tests. GIT_CONFIG_GLOBAL: /root/aztec-packages/build-images/src/home/.gitconfig diff --git a/yarn-project/end-to-end/scripts/native-network/deploy-l2-contracts.sh b/yarn-project/end-to-end/scripts/native-network/deploy-l2-contracts.sh index df5dbb05fa43..db15cb7e38a6 100755 --- a/yarn-project/end-to-end/scripts/native-network/deploy-l2-contracts.sh +++ b/yarn-project/end-to-end/scripts/native-network/deploy-l2-contracts.sh @@ -11,15 +11,6 @@ exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname set -eu -# Wait for PXE service to be ready -echo "Waiting for PXE service..." -until curl -s -X POST -H 'content-type: application/json' \ - -d '{"jsonrpc":"2.0","method":"pxe_getNodeInfo","params":[],"id":67}' \ - http://127.0.0.1:8079 | grep -q '"enr:-'; do - sleep 1 -done -echo "Done waiting." - # Get the chain ID from the Ethereum node export ETHEREUM_HOSTS=${ETHEREUM_HOSTS:-"http://127.0.0.1:8545"} source "$REPO"/yarn-project/end-to-end/scripts/native-network/utils/get-chain-id.sh @@ -30,7 +21,6 @@ ARGS="--skipProofWait --testAccounts" # Deploy L2 contracts export AZTEC_NODE_URL="http://127.0.0.1:8080" -export PXE_URL="http://127.0.0.1:8079" node --no-warnings "$REPO"/yarn-project/aztec/dest/bin/index.js setup-protocol-contracts $ARGS echo "Deployed L2 contracts" # Use file just as done signal diff --git a/yarn-project/end-to-end/scripts/native-network/pxe.sh b/yarn-project/end-to-end/scripts/native-network/pxe.sh deleted file mode 100755 index 581d0f2f705f..000000000000 --- a/yarn-project/end-to-end/scripts/native-network/pxe.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -set -eu - -# Get the name of the script without the path and extension -SCRIPT_NAME=$(basename "$0" .sh) -REPO=$(git rev-parse --show-toplevel) - -# Redirect stdout and stderr to .log while also printing to the console -exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log" >&2) - -# Starts the PXE (Private eXecution Environment) service -# Set environment variables -export ETHEREUM_HOSTS=${ETHEREUM_HOSTS:-"http://127.0.0.1:8545"} -export L1_CONSENSUS_HOST_URLS=${L1_CONSENSUS_HOST_URLS:-} -export AZTEC_NODE_URL=${AZTEC_NODE_URL:-"http://127.0.0.1:8080"} -export VALIDATOR_NODE_URL=${VALIDATOR_NODE_URL:-"http://127.0.0.1:8081"} -export LOG_LEVEL=${LOG_LEVEL:-"verbose"} - -echo "Waiting for Aztec Node..." -until curl -s $AZTEC_NODE_URL/status >/dev/null; do - sleep 1 -done - -# Get the chain ID from the Ethereum node -source "$REPO"/yarn-project/end-to-end/scripts/native-network/utils/get-chain-id.sh -export L1_CHAIN_ID=${L1_CHAIN_ID:-31337} - -# We need to also wait for the validator, as the initial node cannot -# Produce blocks on it's own -echo "Waiting for Validator 0..." -until curl -s $VALIDATOR_NODE_URL/status >/dev/null; do - sleep 1 -done -echo "Done waiting." - -function filter_noise() { - grep -v node_getProvenBlockNumber -} - -# Start the PXE service -node --no-warnings "$REPO"/yarn-project/aztec/dest/bin/index.js start --port=8079 --pxe 2>&1 | filter_noise diff --git a/yarn-project/end-to-end/scripts/native-network/test-4epochs.sh b/yarn-project/end-to-end/scripts/native-network/test-4epochs.sh index 19552d3ac9d9..b8949767d916 100755 --- a/yarn-project/end-to-end/scripts/native-network/test-4epochs.sh +++ b/yarn-project/end-to-end/scripts/native-network/test-4epochs.sh @@ -9,7 +9,6 @@ SCRIPT_NAME=$(basename "$0" .sh) exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log" >&2) export BOOTNODE_URL=${BOOTNODE_URL:-http://127.0.0.1:8080} -export PXE_URL=${PXE_URL:-http://127.0.0.1:8079} export ETHEREUM_HOSTS=${ETHEREUM_HOSTS:-http://127.0.0.1:8545} REPO=$(git rev-parse --show-toplevel) @@ -19,12 +18,6 @@ echo "Waiting for Aztec Node..." until curl -s $BOOTNODE_URL/status >/dev/null; do sleep 1 done -echo "Waiting for PXE service..." -until curl -s -X POST -H 'content-type: application/json' \ - -d '{"jsonrpc":"2.0","method":"pxe_getNodeInfo","params":[],"id":67}' \ - $PXE_URL | grep -q '"enr:-'; do - sleep 1 -done echo "Waiting for l2 contracts to be deployed..." until [ -f "$REPO"/yarn-project/end-to-end/scripts/native-network/state/l2-contracts.env ]; do sleep 1 diff --git a/yarn-project/end-to-end/scripts/native-network/test-transfer.sh b/yarn-project/end-to-end/scripts/native-network/test-transfer.sh index 34021df0ed94..d06c83377ccf 100755 --- a/yarn-project/end-to-end/scripts/native-network/test-transfer.sh +++ b/yarn-project/end-to-end/scripts/native-network/test-transfer.sh @@ -10,7 +10,6 @@ exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname export BOOTNODE_URL=${BOOTNODE_URL:-http://127.0.0.1:8080} export NODE_URL=${NODE_URL:-${BOOTNODE_URL:-http://127.0.0.1:8080}} -export PXE_URL=${PXE_URL:-http://127.0.0.1:8079} export ETHEREUM_HOSTS=${ETHEREUM_HOSTS:-http://127.0.0.1:8545} export K8S=${K8S:-false} @@ -21,12 +20,6 @@ echo "Waiting for Aztec Node..." until curl -s $BOOTNODE_URL/status >/dev/null; do sleep 1 done -echo "Waiting for PXE service..." -until curl -s -X POST -H 'content-type: application/json' \ - -d '{"jsonrpc":"2.0","method":"pxe_getNodeInfo","params":[],"id":67}' \ - $PXE_URL | grep -q '"enr:-'; do - sleep 1 -done echo "Waiting for l2 contracts to be deployed..." until [ -f "$REPO"/yarn-project/end-to-end/scripts/native-network/state/l2-contracts.env ]; do sleep 1 diff --git a/yarn-project/end-to-end/scripts/native-network/transaction-bot.sh b/yarn-project/end-to-end/scripts/native-network/transaction-bot.sh index 2aac51b85c17..75cb50e62822 100755 --- a/yarn-project/end-to-end/scripts/native-network/transaction-bot.sh +++ b/yarn-project/end-to-end/scripts/native-network/transaction-bot.sh @@ -6,7 +6,6 @@ SCRIPT_NAME=$(basename "$0" .sh) # Set the token contract to use export BOT_TOKEN_CONTRACT=${BOT_TOKEN_CONTRACT:-"TokenContract"} -export BOT_PXE_URL=${BOT_PXE_URL:-"http://127.0.0.1:8079"} # Redirect stdout and stderr to .log while also printing to the console exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log" >&2) @@ -18,12 +17,6 @@ echo "Waiting for Aztec Node..." until curl -s http://127.0.0.1:8080/status >/dev/null; do sleep 1 done -echo "Waiting for PXE service..." -until curl -s -X POST -H 'content-type: application/json' \ - -d '{"jsonrpc":"2.0","method":"pxe_getNodeInfo","params":[],"id":67}' \ - $BOT_PXE_URL | grep -q '"enr:-'; do - sleep 1 -done echo "Waiting for l2 contracts to be deployed..." until [ -f "$REPO"/yarn-project/end-to-end/scripts/native-network/state/l2-contracts.env ]; do sleep 1 diff --git a/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts b/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts index 6ea5a9216116..e7dcd79bd694 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts @@ -1,7 +1,7 @@ import { EcdsaRAccountContractArtifact } from '@aztec/accounts/ecdsa'; import { AztecAddress, type DeployOptions, Fr, type Wallet, publishContractClass } from '@aztec/aztec.js'; import type { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts b/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts index 58cd01f80471..485ebdaf323f 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts @@ -3,7 +3,7 @@ import type { AMMContract } from '@aztec/noir-contracts.js/AMM'; import type { FPCContract } from '@aztec/noir-contracts.js/FPC'; import type { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts b/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts index 3370cab528f5..9d5eae0f6f6f 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts @@ -26,9 +26,9 @@ import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC'; import { TokenContract as BananaCoin, TokenContract } from '@aztec/noir-contracts.js/Token'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; -import { type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; +import { type PXEServiceConfig, getPXEServiceConfig } from '@aztec/pxe/server'; import { deriveSigningKey } from '@aztec/stdlib/keys'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { MNEMONIC } from '../../fixtures/fixtures.js'; import { @@ -215,19 +215,16 @@ export class ClientFlowsBenchmark { this.coinbase = EthAddress.random(); const userPXEConfig = getPXEServiceConfig(); - const l1Contracts = await aztecNode.getL1ContractAddresses(); const userPXEConfigWithContracts = { ...userPXEConfig, proverEnabled: this.realProofs, - l1Contracts, } as PXEServiceConfig; - this.userPXE = await createPXEService(this.aztecNode, userPXEConfigWithContracts, { + this.userWallet = await TestWallet.create(this.aztecNode, userPXEConfigWithContracts, { loggers: { prover: this.proxyLogger.createLogger('pxe:bb:wasm:bundle:proxied'), }, }); - this.userWallet = new TestWallet(this.userPXE, this.aztecNode); }, ); } diff --git a/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts b/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts index daee346c698b..c5f70cdbb66d 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts @@ -2,7 +2,7 @@ import { AztecAddress, type AztecNode, Fr, type SimulateMethodOptions, type Wall import type { FPCContract } from '@aztec/noir-contracts.js/FPC'; import type { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/composed/docs_examples.test.ts b/yarn-project/end-to-end/src/composed/docs_examples.test.ts index cdcb0d750869..bd233d00df2b 100644 --- a/yarn-project/end-to-end/src/composed/docs_examples.test.ts +++ b/yarn-project/end-to-end/src/composed/docs_examples.test.ts @@ -1,32 +1,41 @@ /* eslint-disable import/no-duplicates */ // docs:start:create_account_imports import { getInitialTestAccountsData } from '@aztec/accounts/testing'; -import { Fr, GrumpkinScalar, createAztecNodeClient, createPXEClient } from '@aztec/aztec.js'; +import { Fr, GrumpkinScalar, createAztecNodeClient } from '@aztec/aztec.js'; // docs:end:create_account_imports // docs:start:import_contract import { Contract } from '@aztec/aztec.js'; // docs:end:import_contract // docs:start:import_token_contract import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js/Token'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; // docs:end:import_token_contract +// To run these tests against a local sandbox: +// 1. Start a local Ethereum node (Anvil): +// anvil --host 127.0.0.1 --port 8545 +// +// 2. Start the Aztec sandbox: +// cd yarn-project/aztec +// NODE_NO_WARNINGS=1 ETHEREUM_HOSTS=http://127.0.0.1:8545 node ./dest/bin/index.js start --sandbox +// +// 3. Run the tests: +// yarn test:e2e docs_examples.test.ts describe('docs_examples', () => { it('deploys and interacts with a token contract', async () => { // docs:start:full_deploy // docs:start:define_account_vars - const PXE_URL = process.env.PXE_URL || 'http://localhost:8080'; - const AZTEC_NODE_URL = process.env.AZTEC_NODE_URL || 'http://localhost:8079'; + const AZTEC_NODE_URL = process.env.AZTEC_NODE_URL || 'http://localhost:8080'; const node = createAztecNodeClient(AZTEC_NODE_URL); - const pxe = createPXEClient(PXE_URL); + + const wallet = await TestWallet.create(node); const secretKey = Fr.random(); const signingPrivateKey = GrumpkinScalar.random(); // docs:end:define_account_vars // docs:start:create_wallet // Use a pre-funded wallet to pay for the fees for the deployments. - const wallet = new TestWallet(pxe, node); const [accountData] = await getInitialTestAccountsData(); const prefundedAccount = await wallet.createSchnorrAccount(accountData.secret, accountData.salt); const newAccount = await wallet.createSchnorrAccount(secretKey, Fr.random(), signingPrivateKey); diff --git a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts index 7278dd9b7cd1..5e6592083cab 100644 --- a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts @@ -6,7 +6,7 @@ import { Fr } from '@aztec/foundation/fields'; // implements TransparentNote shield flow. import { TokenBlacklistContract } from '@aztec/noir-contracts.js/TokenBlacklist'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import { mkdtemp } from 'fs/promises'; diff --git a/yarn-project/end-to-end/src/composed/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/composed/e2e_sandbox_example.test.ts index 89cd6388b652..061e2e673e0f 100644 --- a/yarn-project/end-to-end/src/composed/e2e_sandbox_example.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_sandbox_example.test.ts @@ -1,8 +1,7 @@ -import { getDeployedTestAccounts } from '@aztec/accounts/testing'; import { - getDeployedBananaCoinAddress, - getDeployedBananaFPCAddress, - getDeployedSponsoredFPCAddress, + registerDeployedBananaCoinInWalletAndGetAddress, + registerDeployedBananaFPCInWalletAndGetAddress, + registerDeployedSponsoredFPCInWalletAndGetAddress, } from '@aztec/aztec'; // docs:start:imports2 import { @@ -11,24 +10,34 @@ import { PrivateFeePaymentMethod, createAztecNodeClient, createLogger, - createPXEClient, getFeeJuiceBalance, - waitForPXE, + waitForNode, } from '@aztec/aztec.js'; // docs:end:imports2 import { SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee/testing'; import { timesParallel } from '@aztec/foundation/collection'; // docs:start:imports3 import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import { TestWallet } from '@aztec/test-wallet'; +import { registerInitialSandboxAccountsInWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { format } from 'util'; // docs:end:imports3 import { deployToken, mintTokensToPrivate } from '../fixtures/token_utils.js'; -const { PXE_URL = 'http://localhost:8080', AZTEC_NODE_URL = 'http://localhost:8079' } = process.env; - +const { AZTEC_NODE_URL = 'http://localhost:8080' } = process.env; + +// To run these tests against a local sandbox: +// 1. Start a local Ethereum node (Anvil): +// anvil --host 127.0.0.1 --port 8545 +// +// 2. Start the Aztec sandbox: +// cd yarn-project/aztec +// NODE_NO_WARNINGS=1 ETHEREUM_HOSTS=http://127.0.0.1:8545 node ./dest/bin/index.js start --sandbox +// +// 3. Run the tests: +// yarn test:e2e e2e_sandbox_example.test.ts describe('e2e_sandbox_example', () => { it('sandbox example works', async () => { // docs:start:setup @@ -36,16 +45,15 @@ describe('e2e_sandbox_example', () => { const logger = createLogger('e2e:token'); // We create PXE client connected to the sandbox URL - const pxe = createPXEClient(PXE_URL); const node = createAztecNodeClient(AZTEC_NODE_URL); // Wait for sandbox to be ready - await waitForPXE(pxe, logger); + await waitForNode(node, logger); + const wallet = await TestWallet.create(node); const nodeInfo = await node.getNodeInfo(); logger.info(format('Aztec Sandbox Info ', nodeInfo)); - const wallet = new TestWallet(pxe, node); // docs:end:setup expect(typeof nodeInfo.rollupVersion).toBe('number'); @@ -58,12 +66,8 @@ describe('e2e_sandbox_example', () => { // docs:start:load_accounts ////////////// LOAD SOME ACCOUNTS FROM THE SANDBOX ////////////// // The sandbox comes with a set of created accounts. Load them - const [aliceAccount, bobAccount] = await getDeployedTestAccounts(wallet); - await wallet.createSchnorrAccount(aliceAccount.secret, aliceAccount.salt); - await wallet.createSchnorrAccount(bobAccount.secret, bobAccount.salt); + const [alice, bob] = await registerInitialSandboxAccountsInWallet(wallet); - const alice = aliceAccount.address; - const bob = bobAccount.address; logger.info(`Loaded alice's account at ${alice.toString()}`); logger.info(`Loaded bob's account at ${bob.toString()}`); // docs:end:load_accounts @@ -139,18 +143,16 @@ describe('e2e_sandbox_example', () => { it('can create accounts on the sandbox', async () => { const logger = createLogger('e2e:token'); // We create PXE client connected to the sandbox URL - const pxe = createPXEClient(PXE_URL); const node = createAztecNodeClient(AZTEC_NODE_URL); // Wait for sandbox to be ready - await waitForPXE(pxe, logger); + await waitForNode(node, logger); + const wallet = await TestWallet.create(node); // docs:start:create_accounts ////////////// CREATE SOME ACCOUNTS WITH SCHNORR SIGNERS ////////////// // Use one of the pre-funded accounts to pay for the deployments. - const wallet = new TestWallet(pxe, node); - const [fundedAccount] = await getDeployedTestAccounts(wallet); - await wallet.createSchnorrAccount(fundedAccount.secret, fundedAccount.salt); + const [fundedAccount] = await registerInitialSandboxAccountsInWallet(wallet); // Creates new accounts using an account contract that verifies schnorr signatures // Returns once the deployment transactions have settled @@ -165,7 +167,7 @@ describe('e2e_sandbox_example', () => { return await Promise.all( accountManagers.map(async x => { - await x.deploy({ deployAccount: fundedAccount.address }).wait(); + await x.deploy({ deployAccount: fundedAccount }).wait(); return x; }), ); @@ -195,14 +197,14 @@ describe('e2e_sandbox_example', () => { expect(registeredAccounts.find(acc => acc.equals(bob))).toBeTruthy(); ////////////// FUND A NEW ACCOUNT WITH BANANA COIN ////////////// - const bananaCoinAddress = await getDeployedBananaCoinAddress(wallet); + const bananaCoinAddress = await registerDeployedBananaCoinInWalletAndGetAddress(wallet); const bananaCoin = await TokenContract.at(bananaCoinAddress, wallet); const mintAmount = 10n ** 20n; - await bananaCoin.methods.mint_to_private(alice, mintAmount).send({ from: fundedAccount.address }).wait(); + await bananaCoin.methods.mint_to_private(alice, mintAmount).send({ from: fundedAccount }).wait(); ////////////// USE A NEW ACCOUNT TO SEND A TX AND PAY WITH BANANA COIN ////////////// const amountTransferToBob = 100n; - const bananaFPCAddress = await getDeployedBananaFPCAddress(wallet); + const bananaFPCAddress = await registerDeployedBananaFPCInWalletAndGetAddress(wallet); const paymentMethod = new PrivateFeePaymentMethod(bananaFPCAddress, alice, wallet); const receiptForAlice = await bananaCoin.methods .transfer(bob, amountTransferToBob) @@ -223,7 +225,7 @@ describe('e2e_sandbox_example', () => { ////////////// USE A NEW ACCOUNT TO SEND A TX AND PAY VIA SPONSORED FPC ////////////// const amountTransferToAlice = 48n; - const sponsoredFPC = await getDeployedSponsoredFPCAddress(wallet); + const sponsoredFPC = await registerDeployedSponsoredFPCInWalletAndGetAddress(wallet); const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(sponsoredFPC); // The payment method can also be initialized as follows: // const sponsoredPaymentMethod = await SponsoredFeePaymentMethod.new(pxe); diff --git a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts index 99e46cef954b..2bbb0c81b16f 100644 --- a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts @@ -1,6 +1,5 @@ // This test should only use packages that are published to npm // docs:start:imports -import { getDeployedTestAccounts } from '@aztec/accounts/testing'; import { EthAddress, Fr, @@ -8,8 +7,7 @@ import { L1TokenPortalManager, createAztecNodeClient, createLogger, - createPXEClient, - waitForPXE, + waitForNode, } from '@aztec/aztec.js'; import { createExtendedL1Client, deployL1Contract } from '@aztec/ethereum'; import { @@ -23,7 +21,8 @@ import { import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; -import { TestWallet } from '@aztec/test-wallet'; +import { registerInitialSandboxAccountsInWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { getContract } from 'viem'; @@ -38,12 +37,11 @@ const ownerEthAddress = l1Client.account.address; const MINT_AMOUNT = BigInt(1e15); const setupSandbox = async () => { - const { AZTEC_NODE_URL = 'http://localhost:8079', PXE_URL = 'http://localhost:8080' } = process.env; - // eslint-disable-next-line @typescript-eslint/await-thenable - const pxe = await createPXEClient(PXE_URL); - await waitForPXE(pxe); + const { AZTEC_NODE_URL = 'http://localhost:8080' } = process.env; + const node = createAztecNodeClient(AZTEC_NODE_URL); - const wallet = new TestWallet(pxe, node); + await waitForNode(node); + const wallet = await TestWallet.create(node); return { node, wallet }; }; @@ -76,14 +74,22 @@ async function addMinter(l1TokenContract: EthAddress, l1TokenHandler: EthAddress } // docs:end:utils +// To run these tests against a local sandbox: +// 1. Start a local Ethereum node (Anvil): +// anvil --host 127.0.0.1 --port 8545 +// +// 2. Start the Aztec sandbox: +// cd yarn-project/aztec +// NODE_NO_WARNINGS=1 ETHEREUM_HOSTS=http://127.0.0.1:8545 node ./dest/bin/index.js start --sandbox +// +// 3. Run the tests: +// yarn test:e2e e2e_token_bridge_tutorial_test.test.ts describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => { it('Deploys tokens & bridges to L1 & L2, mints & publicly bridges tokens', async () => { // docs:start:setup const logger = createLogger('aztec:token-bridge-tutorial'); const { wallet, node } = await setupSandbox(); - const [ownerAccount] = await getDeployedTestAccounts(wallet); - await wallet.createSchnorrAccount(ownerAccount.secret, ownerAccount.salt, ownerAccount.signingKey); - const { address: ownerAztecAddress } = ownerAccount; + const [ownerAztecAddress] = await registerInitialSandboxAccountsInWallet(wallet); const l1ContractAddresses = (await node.getNodeInfo()).l1ContractAddresses; logger.info('L1 Contract Addresses:'); logger.info(`Registry Address: ${l1ContractAddresses.registryAddress}`); diff --git a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts index 080f3ca3250f..b6557e904d4a 100644 --- a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts +++ b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts @@ -1,4 +1,3 @@ -import { getDeployedTestAccounts } from '@aztec/accounts/testing'; import { type EthAddress, FeeJuicePaymentMethodWithClaim, @@ -6,20 +5,18 @@ import { TxStatus, type WaitOpts, createAztecNodeClient, - createPXEClient, fileURLToPath, retryUntil, } from '@aztec/aztec.js'; -import { createNamespacedSafeJsonRpcServer, startHttpRpcServer } from '@aztec/foundation/json-rpc/server'; import type { Logger } from '@aztec/foundation/log'; import { promiseWithResolvers } from '@aztec/foundation/promise'; import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; -import { type AztecNode, PXESchema } from '@aztec/stdlib/interfaces/client'; +import type { AztecNode } from '@aztec/stdlib/interfaces/client'; import { deriveSigningKey } from '@aztec/stdlib/keys'; -import { TestWallet } from '@aztec/test-wallet'; +import { registerInitialSandboxAccountsInWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; -import getPort from 'get-port'; import { exec } from 'node:child_process'; import { lookup } from 'node:dns/promises'; import { tmpdir } from 'node:os'; @@ -31,7 +28,6 @@ import { getLogger, setupPXEServiceAndGetWallet } from '../fixtures/utils.js'; const { AZTEC_NODE_URL, - PXE_URL, FAUCET_URL, AZTEC_CLI = `node ${resolve(fileURLToPath(import.meta.url), '../../../../aztec/dest/bin/index.js')}`, ETHEREUM_HOSTS, @@ -53,7 +49,6 @@ export const getLocalhost = () => .catch(() => 'localhost'); describe('End-to-end tests for devnet', () => { - let pxeUrl: string; // needed for the CLI let node: AztecNode; let wallet: TestWallet; let logger: Logger; @@ -76,58 +71,40 @@ describe('End-to-end tests for devnet', () => { throw new Error('FAUCET_URL must be set'); } - logger.info(`Using AZTEC_CLI: ${AZTEC_CLI}`); + if (!AZTEC_NODE_URL) { + throw new Error('AZTEC_NODE_URL must be set'); + } - if (AZTEC_NODE_URL) { - logger.info(`Using AZTEC_NODE_URL: ${AZTEC_NODE_URL}`); - node = createAztecNodeClient(AZTEC_NODE_URL); - const bbConfig = await getBBConfig(logger); - const acvmConfig = await getACVMConfig(logger); - const svc = await setupPXEServiceAndGetWallet(node, { - ...bbConfig, - ...acvmConfig, - proverEnabled: ['1', 'true'].includes(PXE_PROVER_ENABLED!), - }); - wallet = svc.wallet; - - const nodeInfo = await node.getNodeInfo(); - const pxeInfo = await wallet.getPXEInfo(); - - expect(nodeInfo.protocolContractAddresses.classRegistry).toEqual(pxeInfo.protocolContractAddresses.classRegistry); - expect(nodeInfo.protocolContractAddresses.instanceRegistry).toEqual( - pxeInfo.protocolContractAddresses.instanceRegistry, - ); - expect(nodeInfo.protocolContractAddresses.feeJuice).toEqual(pxeInfo.protocolContractAddresses.feeJuice); - expect(nodeInfo.protocolContractAddresses.multiCallEntrypoint).toEqual( - pxeInfo.protocolContractAddresses.multiCallEntrypoint, - ); + logger.info(`Using AZTEC_CLI: ${AZTEC_CLI}`); - const port = await getPort(); - const localhost = await getLocalhost(); - pxeUrl = `http://${localhost}:${port}`; - // start a server for the CLI to talk to - const jsonRpcServer = createNamespacedSafeJsonRpcServer({ pxe: [wallet.getPxe(), PXESchema] }); - const server = await startHttpRpcServer(jsonRpcServer, { port }); - - teardown = async () => { - const { promise, resolve, reject } = promiseWithResolvers(); - server.close(e => (e ? reject(e) : resolve())); - await promise; - - await svc.teardown(); - await bbConfig?.cleanup(); - await acvmConfig?.cleanup(); - }; - } else if (PXE_URL) { - logger.info(`Using PXE_URL: ${PXE_URL}`); - const pxe = createPXEClient(PXE_URL); - node = createAztecNodeClient(PXE_URL); - pxeUrl = PXE_URL; - teardown = () => {}; - wallet = new TestWallet(pxe, node); - } else { - throw new Error('AZTEC_NODE_URL or PXE_URL must be set'); - } + logger.info(`Using AZTEC_NODE_URL: ${AZTEC_NODE_URL}`); + node = createAztecNodeClient(AZTEC_NODE_URL); + const bbConfig = await getBBConfig(logger); + const acvmConfig = await getACVMConfig(logger); + const svc = await setupPXEServiceAndGetWallet(node, { + ...bbConfig, + ...acvmConfig, + proverEnabled: ['1', 'true'].includes(PXE_PROVER_ENABLED!), + }); + wallet = svc.wallet; + + const nodeInfo = await node.getNodeInfo(); + const pxeInfo = await wallet.getPXEInfo(); + + expect(nodeInfo.protocolContractAddresses.classRegistry).toEqual(pxeInfo.protocolContractAddresses.classRegistry); + expect(nodeInfo.protocolContractAddresses.instanceRegistry).toEqual( + pxeInfo.protocolContractAddresses.instanceRegistry, + ); + expect(nodeInfo.protocolContractAddresses.feeJuice).toEqual(pxeInfo.protocolContractAddresses.feeJuice); + expect(nodeInfo.protocolContractAddresses.multiCallEntrypoint).toEqual( + pxeInfo.protocolContractAddresses.multiCallEntrypoint, + ); + + teardown = async () => { + await svc.teardown(); + await bbConfig?.cleanup(); + await acvmConfig?.cleanup(); + }; ({ l1ChainId, @@ -164,7 +141,6 @@ describe('End-to-end tests for devnet', () => { 'l1-rpc-urls': ETHEREUM_HOSTS!, 'l1-chain-id': l1ChainId.toString(), 'l1-private-key': l1Account.privateKey, - 'rpc-url': pxeUrl, mint: true, }); @@ -289,20 +265,15 @@ describe('End-to-end tests for devnet', () => { } async function advanceChainWithEmptyBlocks(wallet: TestWallet) { - const [fundedAccount] = await getDeployedTestAccounts(wallet); - if (!fundedAccount) { - throw new Error('A funded wallet is required to create dummy txs.'); - } - - await wallet.createSchnorrAccount(fundedAccount.secret, fundedAccount.salt); + const [fundedAccountAddress] = await registerInitialSandboxAccountsInWallet(wallet); const test = await TestContract.deploy(wallet) - .send({ from: fundedAccount.address, universalDeploy: true, skipClassPublication: true }) + .send({ from: fundedAccountAddress, universalDeploy: true, skipClassPublication: true }) .deployed(); // start at 1 because deploying the contract has already mined a block for (let i = 1; i < MIN_BLOCKS_FOR_BRIDGING; i++) { - await test.methods.get_this_address().send({ from: fundedAccount.address }).wait(waitOpts); + await test.methods.get_this_address().send({ from: fundedAccountAddress }).wait(waitOpts); } } }); diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index 66cf55e48197..ceccaa4489cc 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -4,7 +4,7 @@ import { type AztecAddress, type AztecNode, Fr, type Logger, sleep } from '@azte import { TokenContract } from '@aztec/noir-contracts.js/Token'; // docs:end:import_aztecjs import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { expect, jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index 58d1c9f1b0f7..5a83824b36d2 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -18,12 +18,20 @@ import { } from '@aztec/aztec.js'; import { randomBytes } from '@aztec/foundation/crypto'; import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; +import { createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; import { deriveSigningKey } from '@aztec/stdlib/keys'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { setup } from './fixtures/utils.js'; export class TestWalletInternals extends TestWallet { + static override async create(node: AztecNode): Promise { + const pxeConfig = getPXEServiceConfig(); + pxeConfig.proverEnabled = false; + const pxe = await createPXEService(node, pxeConfig); + return new TestWalletInternals(pxe, node); + } + replaceAccountAt(account: Account, address: AztecAddress) { this.accounts.set(address.toString(), account); } @@ -36,7 +44,7 @@ const itShouldBehaveLikeAnAccountContract = ( let aztecNode: AztecNode; let logger: Logger; let teardown: () => Promise; - let wallet: TestWallet; + let wallet: TestWalletInternals; let completeAddress: CompleteAddress; let child: ChildContract; @@ -53,8 +61,8 @@ const itShouldBehaveLikeAnAccountContract = ( address, }; - ({ logger, wallet, teardown, aztecNode } = await setup(0, { initialFundedAccounts: [accountData] })); - wallet = new TestWalletInternals(wallet.getPxe(), aztecNode); + ({ logger, teardown, aztecNode } = await setup(0, { initialFundedAccounts: [accountData] })); + wallet = await TestWalletInternals.create(aztecNode); const accountManager = await AccountManager.create(wallet, wallet.getPxe(), secret, accountContract, salt); completeAddress = await accountManager.getCompleteAddress(); @@ -66,7 +74,7 @@ const itShouldBehaveLikeAnAccountContract = ( await accountManager.register(); } - (wallet as TestWalletInternals).replaceAccountAt(await accountManager.getAccount(), address); + wallet.replaceAccountAt(await accountManager.getAccount(), address); child = await ChildContract.deploy(wallet).send({ from: address }).deployed(); }); @@ -93,7 +101,7 @@ const itShouldBehaveLikeAnAccountContract = ( await wallet.getChainInfo(), ); const account = new BaseAccount(accountInterface); - (wallet as TestWalletInternals).replaceAccountAt(account, completeAddress.address); + wallet.replaceAccountAt(account, completeAddress.address); await expect(child.methods.value(42).simulate({ from: completeAddress.address })).rejects.toThrow( 'Cannot satisfy constraint', ); diff --git a/yarn-project/end-to-end/src/e2e_amm.test.ts b/yarn-project/end-to-end/src/e2e_amm.test.ts index 7a6058345fbe..daaebd1f94e1 100644 --- a/yarn-project/end-to-end/src/e2e_amm.test.ts +++ b/yarn-project/end-to-end/src/e2e_amm.test.ts @@ -1,7 +1,7 @@ import { AztecAddress, Fr, type Logger } from '@aztec/aztec.js'; import { AMMContract } from '@aztec/noir-contracts.js/AMM'; import type { TokenContract } from '@aztec/noir-contracts.js/Token'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_authwit.test.ts b/yarn-project/end-to-end/src/e2e_authwit.test.ts index 099ec68c1b4c..a52ac0bb04d2 100644 --- a/yarn-project/end-to-end/src/e2e_authwit.test.ts +++ b/yarn-project/end-to-end/src/e2e_authwit.test.ts @@ -2,7 +2,7 @@ import { AztecAddress, Fr, computeAuthWitMessageHash, computeInnerAuthWitHash } import { AuthRegistryContract } from '@aztec/noir-contracts.js/AuthRegistry'; import { AuthWitTestContract } from '@aztec/noir-test-contracts.js/AuthWitTest'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts index 7183e678baaf..75a79c843622 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts @@ -12,7 +12,7 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { TokenBlacklistContract } from '@aztec/noir-contracts.js/TokenBlacklist'; import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount'; import type { SequencerClient } from '@aztec/sequencer-client'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index 0bd738864ab8..8a8b696f88ba 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -26,7 +26,7 @@ import { type PublicTxResult, PublicTxSimulator } from '@aztec/simulator/server' import { getProofSubmissionDeadlineEpoch } from '@aztec/stdlib/epoch-helpers'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { TX_ERROR_EXISTING_NULLIFIER, type Tx } from '@aztec/stdlib/tx'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import 'jest-extended'; diff --git a/yarn-project/end-to-end/src/e2e_bot.test.ts b/yarn-project/end-to-end/src/e2e_bot.test.ts index 1f70bdb8ae9b..705109975e90 100644 --- a/yarn-project/end-to-end/src/e2e_bot.test.ts +++ b/yarn-project/end-to-end/src/e2e_bot.test.ts @@ -7,7 +7,7 @@ import { SecretValue } from '@aztec/foundation/config'; import { bufferToHex } from '@aztec/foundation/string'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts index 09ed0e51ca47..82dd09968619 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts @@ -12,7 +12,7 @@ import { InboxAbi, OutboxAbi, TestERC20Abi, TestERC20Bytecode } from '@aztec/l1- import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { getContract } from 'viem'; diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts index 537c0625cad9..595c65696e8f 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts @@ -4,7 +4,7 @@ import { RollupContract } from '@aztec/ethereum'; import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index bbf8324d1c74..714a7379f289 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -6,7 +6,7 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { computePartialAddress } from '@aztec/stdlib/contract'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts index 860b1585f853..22e31a15e3ab 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts @@ -6,15 +6,13 @@ import { type Logger, type Wallet, createAztecNodeClient, - createPXEClient, - makeFetch, } from '@aztec/aztec.js'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { CounterContract } from '@aztec/noir-test-contracts.js/Counter'; import { NoConstructorContract } from '@aztec/noir-test-contracts.js/NoConstructor'; import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import { GasFees } from '@aztec/stdlib/gas'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { DeployTest } from './deploy_test.js'; @@ -161,13 +159,12 @@ describe('e2e_deploy_contract deploy method', () => { describe('regressions', () => { it('fails properly when trying to deploy a contract with a failing constructor with a pxe client with retries', async () => { - const { PXE_URL, AZTEC_NODE_URL } = process.env; - if (!PXE_URL || !AZTEC_NODE_URL) { + const { AZTEC_NODE_URL } = process.env; + if (!AZTEC_NODE_URL) { return; } - const pxeClient = createPXEClient(PXE_URL, {}, makeFetch([1, 2, 3], false)); const aztecNode = createAztecNodeClient(AZTEC_NODE_URL); - const retryingWallet = new TestWallet(pxeClient, aztecNode); + const retryingWallet = await TestWallet.create(aztecNode); await expect( StatefulTestContract.deployWithOpts({ wallet: retryingWallet, method: 'wrong_constructor' }) .send({ from: defaultAccountAddress }) diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts index 8c29a8e86a5c..77825274a3ad 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts @@ -12,7 +12,7 @@ import { } from '@aztec/aztec.js'; import type { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { type ISnapshotManager, createSnapshotManager, deployAccounts } from '../fixtures/snapshot_manager.js'; diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts index 19d4cfe27e21..250bfab6d541 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts @@ -11,7 +11,7 @@ import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token'; import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import { TestContractArtifact } from '@aztec/noir-test-contracts.js/Test'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { DeployTest } from './deploy_test.js'; diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index 907ec8fb2bec..ff5cf6ec6174 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -3,7 +3,7 @@ import { EscrowContract } from '@aztec/noir-contracts.js/Escrow'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { computePartialAddress } from '@aztec/stdlib/contract'; import type { PublicKeys } from '@aztec/stdlib/keys'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { expectTokenBalance, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index fe51df420886..fd8f0ca160ec 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -16,7 +16,7 @@ import type { FPCContract } from '@aztec/noir-contracts.js/FPC'; import { SchnorrAccountContract as SchnorrAccountContractInterface } from '@aztec/noir-contracts.js/SchnorrAccount'; import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_fees/bridging_race.notest.ts b/yarn-project/end-to-end/src/e2e_fees/bridging_race.notest.ts index 35b1f6d7d7a2..44bdd2f8a419 100644 --- a/yarn-project/end-to-end/src/e2e_fees/bridging_race.notest.ts +++ b/yarn-project/end-to-end/src/e2e_fees/bridging_race.notest.ts @@ -2,7 +2,7 @@ import { SchnorrAccountContract } from '@aztec/accounts/schnorr'; import { Fr, type Logger, sleep } from '@aztec/aztec.js'; import { Fq } from '@aztec/foundation/fields'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import type { Hex } from 'viem'; diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts index cc31877ccc52..0bd726b0e601 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts @@ -4,7 +4,7 @@ import { type AztecAddress, FeeJuicePaymentMethod, FeeJuicePaymentMethodWithClai import type { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token'; import type { GasSettings } from '@aztec/stdlib/gas'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { FeesTest } from './fees_test.js'; diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts index 5870bd566316..84b9fbde0cae 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts @@ -4,7 +4,7 @@ import { Fr } from '@aztec/foundation/fields'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import type { GasSettings } from '@aztec/stdlib/gas'; import { TX_ERROR_INSUFFICIENT_FEE_PER_GAS } from '@aztec/stdlib/tx'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { inspect } from 'util'; diff --git a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts index 17fc1c6bca0b..c6fbd62d954f 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts @@ -14,7 +14,7 @@ import { CounterContract } from '@aztec/noir-test-contracts.js/Counter'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; import { GasSettings } from '@aztec/stdlib/gas'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { getContract } from 'viem'; diff --git a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts index 4c57bd4b50c9..ed2db64267c6 100644 --- a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts +++ b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts @@ -3,7 +3,7 @@ import { AMMContract } from '@aztec/noir-contracts.js/AMM'; import { type TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js/Token'; import { type AbiDecoded, decodeFromAbi, getFunctionArtifact } from '@aztec/stdlib/abi'; import { computeOuterAuthWitHash } from '@aztec/stdlib/auth-witness'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; diff --git a/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts b/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts index e9440dc0b659..8a65e4a1ca2b 100644 --- a/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts +++ b/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts @@ -1,7 +1,7 @@ import { AztecAddress, EthAddress, Fr, type Logger } from '@aztec/aztec.js'; import { getL1ContractsConfigEnvVars } from '@aztec/ethereum'; import { SecretValue } from '@aztec/foundation/config'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 9209ae298570..ddb2db7bd237 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -5,7 +5,7 @@ import type { TestDateProvider } from '@aztec/foundation/timer'; import { LendingContract } from '@aztec/noir-contracts.js/Lending'; import { PriceFeedContract } from '@aztec/noir-contracts.js/PriceFeed'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { afterAll, jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_orderbook.test.ts b/yarn-project/end-to-end/src/e2e_orderbook.test.ts index d894cf01e00d..5aef2e61435f 100644 --- a/yarn-project/end-to-end/src/e2e_orderbook.test.ts +++ b/yarn-project/end-to-end/src/e2e_orderbook.test.ts @@ -1,7 +1,7 @@ import { AztecAddress, type AztecNode, type FieldLike, Fr, type Logger, getDecodedPublicEvents } from '@aztec/aztec.js'; import { type OrderCreated, type OrderFulfilled, OrderbookContract } from '@aztec/noir-contracts.js/Orderbook'; import type { TokenContract } from '@aztec/noir-contracts.js/Token'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts index 67a4636de7a0..2f3dd09e1a71 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts @@ -25,10 +25,10 @@ import { import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; -import { createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; +import { getPXEServiceConfig } from '@aztec/pxe/server'; import { computeL2ToL1MessageHash } from '@aztec/stdlib/hash'; import { computeL2ToL1MembershipWitness, getL2ToL1MessageLeafId } from '@aztec/stdlib/messaging'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { getGenesisValues } from '@aztec/world-state/testing'; import { jest } from '@jest/globals'; @@ -237,12 +237,11 @@ describe('e2e_p2p_add_rollup', () => { ) => { // Bridge assets into the rollup, and consume the message. // We are doing some of the things that are in the crosschain harness, but we don't actually want the full thing - const pxeService = await createPXEService( + const wallet = await TestWallet.create( node, { ...getPXEServiceConfig(), proverEnabled: false }, { useLogSuffix: true }, ); - const wallet = new TestWallet(pxeService, node); const aliceAccountManager = await wallet.createSchnorrAccount(aliceAccount.secret, aliceAccount.salt); await aliceAccountManager.deploy().wait(); diff --git a/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts b/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts index 1ca696ff3acf..b2c2881e58aa 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts @@ -1,6 +1,6 @@ import type { Archiver } from '@aztec/archiver'; import type { AztecNodeService } from '@aztec/aztec-node'; -import { retryUntil, sleep } from '@aztec/aztec.js'; +import { SentTx, retryUntil, sleep } from '@aztec/aztec.js'; import type { ProverNode } from '@aztec/prover-node'; import type { SequencerClient } from '@aztec/sequencer-client'; import { tryStop } from '@aztec/stdlib/interfaces/server'; @@ -12,15 +12,10 @@ import os from 'os'; import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; -import { - ATTESTER_PRIVATE_KEYS_START_INDEX, - type NodeContext, - createNodes, - createProverNode, -} from '../fixtures/setup_p2p_test.js'; +import { ATTESTER_PRIVATE_KEYS_START_INDEX, createNodes, createProverNode } from '../fixtures/setup_p2p_test.js'; import { AlertChecker, type AlertConfig } from '../quality_of_service/alert_checker.js'; import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { createPXEServiceAndSubmitTransactions } from './shared.js'; +import { submitTransactions } from './shared.js'; const CHECK_ALERTS = process.env.CHECK_ALERTS === 'true'; @@ -97,7 +92,7 @@ describe('e2e_p2p_network', () => { // the number of txs per node and the number of txs per rollup // should be set so that the only way for rollups to be built // is if the txs are successfully gossiped around the nodes. - const contexts: NodeContext[] = []; + const txsSentViaDifferentNodes: SentTx[][] = []; t.logger.info('Creating nodes'); nodes = await createNodes( t.ctx.aztecNodeConfig, @@ -134,15 +129,15 @@ describe('e2e_p2p_network', () => { t.logger.info('Submitting transactions'); for (const node of nodes) { - const context = await createPXEServiceAndSubmitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); - contexts.push(context); + const context = await submitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); + txsSentViaDifferentNodes.push(context); } t.logger.info('Waiting for transactions to be mined'); // now ensure that all txs were successfully mined await Promise.all( - contexts.flatMap((context, i) => - context.txs.map(async (tx, j) => { + txsSentViaDifferentNodes.flatMap((txs, i) => + txs.map(async (tx, j) => { t.logger.info(`Waiting for tx ${i}-${j}: ${(await tx.getTxHash()).toString()} to be mined`); return tx.wait({ timeout: WAIT_FOR_TX_TIMEOUT }); }), @@ -151,7 +146,7 @@ describe('e2e_p2p_network', () => { t.logger.info('All transactions mined'); // Gather signers from attestations downloaded from L1 - const blockNumber = await contexts[0].txs[0].getReceipt().then(r => r.blockNumber!); + const blockNumber = await txsSentViaDifferentNodes[0][0].getReceipt().then(r => r.blockNumber!); const dataStore = ((nodes[0] as AztecNodeService).getBlockSource() as Archiver).dataStore; const [block] = await dataStore.getPublishedBlocks(blockNumber, blockNumber); const payload = ConsensusPayload.fromBlock(block.block); diff --git a/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts b/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts index 8bde293b6c12..8959719a0b15 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts @@ -1,6 +1,6 @@ import type { Archiver } from '@aztec/archiver'; import type { AztecNodeService } from '@aztec/aztec-node'; -import { EthAddress, Fr, sleep } from '@aztec/aztec.js'; +import { EthAddress, Fr, SentTx, sleep } from '@aztec/aztec.js'; import { addL1Validator } from '@aztec/cli/l1'; import { RollupContract } from '@aztec/ethereum'; import { MockZKPassportVerifierAbi } from '@aztec/l1-artifacts/MockZKPassportVerifierAbi'; @@ -17,10 +17,10 @@ import path from 'path'; import { getContract } from 'viem'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; -import { type NodeContext, createNodes } from '../fixtures/setup_p2p_test.js'; +import { createNodes } from '../fixtures/setup_p2p_test.js'; import { AlertChecker, type AlertConfig } from '../quality_of_service/alert_checker.js'; import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { createPXEServiceAndSubmitTransactions } from './shared.js'; +import { submitTransactions } from './shared.js'; const CHECK_ALERTS = process.env.CHECK_ALERTS === 'true'; @@ -178,7 +178,7 @@ describe('e2e_p2p_network', () => { // the number of txs per node and the number of txs per rollup // should be set so that the only way for rollups to be built // is if the txs are successfully gossiped around the nodes. - const contexts: NodeContext[] = []; + const txsSentViaDifferentNodes: SentTx[][] = []; t.logger.info('Creating nodes'); nodes = await createNodes( t.ctx.aztecNodeConfig, @@ -202,15 +202,15 @@ describe('e2e_p2p_network', () => { t.logger.info('Submitting transactions'); for (const node of nodes) { - const context = await createPXEServiceAndSubmitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); - contexts.push(context); + const txs = await submitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); + txsSentViaDifferentNodes.push(txs); } t.logger.info('Waiting for transactions to be mined'); // now ensure that all txs were successfully mined await Promise.all( - contexts.flatMap((context, i) => - context.txs.map(async (tx, j) => { + txsSentViaDifferentNodes.flatMap((txs, i) => + txs.map(async (tx, j) => { t.logger.info(`Waiting for tx ${i}-${j}: ${(await tx.getTxHash()).toString()} to be mined`); return tx.wait({ timeout: WAIT_FOR_TX_TIMEOUT }); }), @@ -219,7 +219,7 @@ describe('e2e_p2p_network', () => { t.logger.info('All transactions mined'); // Gather signers from attestations downloaded from L1 - const blockNumber = await contexts[0].txs[0].getReceipt().then(r => r.blockNumber!); + const blockNumber = await txsSentViaDifferentNodes[0][0].getReceipt().then(r => r.blockNumber!); const dataStore = ((nodes[0] as AztecNodeService).getBlockSource() as Archiver).dataStore; const [block] = await dataStore.getPublishedBlocks(blockNumber, blockNumber); const payload = ConsensusPayload.fromBlock(block.block); diff --git a/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts b/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts index a9764cd510fb..5ea31f8fdd8a 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts @@ -25,7 +25,7 @@ import { tryStop } from '@aztec/stdlib/interfaces/server'; import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts'; import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { getGenesisValues } from '@aztec/world-state/testing'; import getPort from 'get-port'; diff --git a/yarn-project/end-to-end/src/e2e_p2p/preferred_gossip_network.test.ts b/yarn-project/end-to-end/src/e2e_p2p/preferred_gossip_network.test.ts index 0b2d94e02845..3f01e7665b95 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/preferred_gossip_network.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/preferred_gossip_network.test.ts @@ -1,6 +1,6 @@ import type { Archiver } from '@aztec/archiver'; import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; -import { retryUntil } from '@aztec/aztec.js'; +import { SentTx, retryUntil } from '@aztec/aztec.js'; import { ENR, type P2PClient, type P2PService, type PeerId } from '@aztec/p2p'; import type { SequencerClient } from '@aztec/sequencer-client'; import { BlockAttestation, ConsensusPayload } from '@aztec/stdlib/p2p'; @@ -11,10 +11,10 @@ import os from 'os'; import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; -import { type NodeContext, createNodes } from '../fixtures/setup_p2p_test.js'; +import { createNodes } from '../fixtures/setup_p2p_test.js'; import { AlertChecker, type AlertConfig } from '../quality_of_service/alert_checker.js'; import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { createPXEServiceAndSubmitTransactions } from './shared.js'; +import { submitTransactions } from './shared.js'; const CHECK_ALERTS = process.env.CHECK_ALERTS === 'true'; @@ -178,7 +178,7 @@ describe('e2e_p2p_preferred_network', () => { // the number of txs per node and the number of txs per rollup // should be set so that the only way for rollups to be built // is if the txs are successfully gossiped around the nodes. - const contexts: NodeContext[] = []; + const txsSentViaDifferentNodes: SentTx[][] = []; let indexOffset = 0; t.logger.info('Creating preferred nodes'); @@ -334,15 +334,15 @@ describe('e2e_p2p_preferred_network', () => { // Send the required number of transactions to each node t.logger.info('Submitting transactions'); for (const node of nodes) { - const context = await createPXEServiceAndSubmitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); - contexts.push(context); + const txs = await submitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); + txsSentViaDifferentNodes.push(txs); } t.logger.info('Waiting for transactions to be mined'); // now ensure that all txs were successfully mined await Promise.all( - contexts.flatMap((context, i) => - context.txs.map(async (tx, j) => { + txsSentViaDifferentNodes.flatMap((txs, i) => + txs.map(async (tx, j) => { t.logger.info(`Waiting for tx ${i}-${j}: ${await tx.getTxHash()} to be mined`); return tx.wait({ timeout: WAIT_FOR_TX_TIMEOUT }); }), @@ -351,7 +351,7 @@ describe('e2e_p2p_preferred_network', () => { t.logger.info('All transactions mined'); // Gather signers from attestations downloaded from L1 - const blockNumber = await contexts[0].txs[0].getReceipt().then(r => r.blockNumber!); + const blockNumber = await txsSentViaDifferentNodes[0][0].getReceipt().then(r => r.blockNumber!); const dataStore = ((nodes[0] as AztecNodeService).getBlockSource() as Archiver).dataStore; const [block] = await dataStore.getPublishedBlocks(blockNumber, blockNumber); const payload = ConsensusPayload.fromBlock(block.block); diff --git a/yarn-project/end-to-end/src/e2e_p2p/rediscovery.test.ts b/yarn-project/end-to-end/src/e2e_p2p/rediscovery.test.ts index 7efcd41df2ce..566884cb2171 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/rediscovery.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/rediscovery.test.ts @@ -1,14 +1,14 @@ import type { AztecNodeService } from '@aztec/aztec-node'; -import { sleep } from '@aztec/aztec.js'; +import { SentTx, sleep } from '@aztec/aztec.js'; import fs from 'fs'; import os from 'os'; import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; -import { type NodeContext, createNode, createNodes } from '../fixtures/setup_p2p_test.js'; +import { createNode, createNodes } from '../fixtures/setup_p2p_test.js'; import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { createPXEServiceAndSubmitTransactions } from './shared.js'; +import { submitTransactions } from './shared.js'; // Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds const NUM_VALIDATORS = 4; @@ -48,7 +48,7 @@ describe('e2e_p2p_rediscovery', () => { }); it('should re-discover stored peers without bootstrap node', async () => { - const contexts: NodeContext[] = []; + const txsSentViaDifferentNodes: SentTx[][] = []; nodes = await createNodes( t.ctx.aztecNodeConfig, t.ctx.dateProvider, @@ -100,14 +100,14 @@ describe('e2e_p2p_rediscovery', () => { await sleep(2000); for (const node of newNodes) { - const context = await createPXEServiceAndSubmitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); - contexts.push(context); + const txs = await submitTransactions(t.logger, node, NUM_TXS_PER_NODE, t.fundedAccount); + txsSentViaDifferentNodes.push(txs); } // now ensure that all txs were successfully mined await Promise.all( - contexts.flatMap((context, i) => - context.txs.map(async (tx, j) => { + txsSentViaDifferentNodes.flatMap((txs, i) => + txs.map(async (tx, j) => { const txHash = await tx.getTxHash(); t.logger.info(`Waiting for tx ${i}-${j} ${txHash} to be mined`, { txHash }); return tx diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp.test.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp.test.ts index 8bbe5f95d762..99b34518b1f9 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp.test.ts @@ -11,7 +11,7 @@ import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; import { createNodes } from '../fixtures/setup_p2p_test.js'; import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { createPXEServiceAndPrepareTransactions } from './shared.js'; +import { prepareTransactions } from './shared.js'; // Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds const NUM_VALIDATORS = 6; @@ -88,8 +88,8 @@ describe('e2e_p2p_reqresp_tx', () => { await t.setupAccount(); t.logger.info('Preparing transactions to send'); - const contexts = await timesAsync(2, () => - createPXEServiceAndPrepareTransactions(t.logger, t.ctx.aztecNode, NUM_TXS_PER_NODE, t.fundedAccount), + const txss = await timesAsync(2, () => + prepareTransactions(t.logger, t.ctx.aztecNode, NUM_TXS_PER_NODE, t.fundedAccount), ); t.logger.info('Removing initial node'); @@ -120,8 +120,8 @@ describe('e2e_p2p_reqresp_tx', () => { // We send the tx to the proposer nodes directly, ignoring the pxe and node in each context // We cannot just call tx.send since they were created using a pxe wired to the first node which is now stopped t.logger.info('Sending transactions through proposer nodes'); - const sentTxs = contexts.map((c, i) => - c.txs.map(tx => { + const sentTxs = txss.map((txs, i) => + txs.map(tx => { const node = nodes[proposerIndexes[i]]; void node.sendTx(tx).catch(err => t.logger.error(`Error sending tx: ${err}`)); return new SentTx(node, () => Promise.resolve(tx.getTxHash())); diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp_no_handshake.test.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp_no_handshake.test.ts index d15186aa4dc8..11d22ea356f4 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp_no_handshake.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp_no_handshake.test.ts @@ -11,7 +11,7 @@ import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; import { createNodes } from '../fixtures/setup_p2p_test.js'; import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { createPXEServiceAndPrepareTransactions } from './shared.js'; +import { prepareTransactions } from './shared.js'; // TODO: DELETE THIS FILE // This is a temporary copy of reqresp.test.ts with status handshake disabled @@ -93,8 +93,8 @@ describe('e2e_p2p_reqresp_tx_no_handshake', () => { await t.setupAccount(); t.logger.info('Preparing transactions to send'); - const contexts = await timesAsync(2, () => - createPXEServiceAndPrepareTransactions(t.logger, t.ctx.aztecNode, NUM_TXS_PER_NODE, t.fundedAccount), + const txss = await timesAsync(2, () => + prepareTransactions(t.logger, t.ctx.aztecNode, NUM_TXS_PER_NODE, t.fundedAccount), ); t.logger.info('Removing initial node'); @@ -125,8 +125,8 @@ describe('e2e_p2p_reqresp_tx_no_handshake', () => { // We send the tx to the proposer nodes directly, ignoring the pxe and node in each context // We cannot just call tx.send since they were created using a pxe wired to the first node which is now stopped t.logger.info('Sending transactions through proposer nodes'); - const sentTxs = contexts.map((c, i) => - c.txs.map(tx => { + const sentTxs = txss.map((txs, i) => + txs.map(tx => { const node = nodes[proposerIndexes[i]]; void node.sendTx(tx).catch(err => t.logger.error(`Error sending tx: ${err}`)); return new SentTx(node, () => Promise.resolve(tx.getTxHash())); diff --git a/yarn-project/end-to-end/src/e2e_p2p/shared.ts b/yarn-project/end-to-end/src/e2e_p2p/shared.ts index ffa6076c041a..c062388121cf 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/shared.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/shared.ts @@ -16,13 +16,12 @@ import { timesAsync, unique } from '@aztec/foundation/collection'; import { pluralize } from '@aztec/foundation/string'; import type { SpamContract } from '@aztec/noir-test-contracts.js/Spam'; import { TestContract, TestContractArtifact } from '@aztec/noir-test-contracts.js/Test'; -import { PXEService, createPXEService, getPXEServiceConfig as getRpcConfig } from '@aztec/pxe/server'; +import { getPXEServiceConfig, getPXEServiceConfig as getRpcConfig } from '@aztec/pxe/server'; import { getRoundForOffense } from '@aztec/slasher'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; -import type { NodeContext } from '../fixtures/setup_p2p_test.js'; import { submitTxsTo } from '../shared/submit-transactions.js'; // submits a set of transactions to the provided Private eXecution Environment (PXE) @@ -55,33 +54,38 @@ export const submitComplexTxsTo = async ( return txs; }; -// creates an instance of the PXE and submit a given number of transactions to it. -export const createPXEServiceAndSubmitTransactions = async ( +// creates a wallet and submit a given number of transactions through it. +export const submitTransactions = async ( logger: Logger, node: AztecNodeService, numTxs: number, fundedAccount: InitialAccountData, -): Promise => { +): Promise => { const rpcConfig = getRpcConfig(); rpcConfig.proverEnabled = false; - const pxeService = await createPXEService(node, rpcConfig, { useLogSuffix: true }); - const wallet = new TestWallet(pxeService, node); + const wallet = await TestWallet.create( + node, + { ...getPXEServiceConfig(), proverEnabled: false }, + { useLogSuffix: true }, + ); const fundedAccountManager = await wallet.createSchnorrAccount(fundedAccount.secret, fundedAccount.salt); - const txs = await submitTxsTo(wallet, fundedAccountManager.getAddress(), numTxs, logger); - return { txs, pxeService, node }; + return submitTxsTo(wallet, fundedAccountManager.getAddress(), numTxs, logger); }; -export async function createPXEServiceAndPrepareTransactions( +export async function prepareTransactions( logger: Logger, node: AztecNodeService, numTxs: number, fundedAccount: InitialAccountData, -): Promise<{ pxeService: PXEService; txs: ProvenTx[]; node: AztecNodeService }> { +): Promise { const rpcConfig = getRpcConfig(); rpcConfig.proverEnabled = false; - const pxe = await createPXEService(node, rpcConfig, { useLogSuffix: true }); - const wallet = new TestWallet(pxe, node); + const wallet = await TestWallet.create( + node, + { ...getPXEServiceConfig(), proverEnabled: false }, + { useLogSuffix: true }, + ); const fundedAccountManager = await wallet.createSchnorrAccount(fundedAccount.secret, fundedAccount.salt); const testContractInstance = await getContractInstanceFromInstantiationParams(TestContractArtifact, { @@ -90,14 +94,12 @@ export async function createPXEServiceAndPrepareTransactions( await wallet.registerContract(testContractInstance, TestContractArtifact); const contract = await TestContract.at(testContractInstance.address, wallet); - const txs = await timesAsync(numTxs, async () => { + return timesAsync(numTxs, async () => { const tx = await contract.methods.emit_nullifier(Fr.random()).prove({ from: fundedAccountManager.getAddress() }); const txHash = tx.getTxHash(); logger.info(`Tx prepared with hash ${txHash}`); return tx; }); - - return { txs, pxeService: pxe, node }; } export function awaitProposalExecution( diff --git a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts index 867e4e29be2e..2145d91ea8dd 100644 --- a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts @@ -6,7 +6,7 @@ import { MAX_NOTE_HASH_READ_REQUESTS_PER_TX, } from '@aztec/constants'; import { PendingNoteHashesContract } from '@aztec/noir-test-contracts.js/PendingNoteHashes'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { setup } from './fixtures/utils.js'; diff --git a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts index bed4fb67180f..82b3695f2e8c 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts @@ -4,7 +4,7 @@ import { Bot, type BotConfig, BotStore, getBotDefaultConfig } from '@aztec/bot'; import type { Logger } from '@aztec/foundation/log'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import type { SequencerClient } from '@aztec/sequencer-client'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import 'jest-extended'; diff --git a/yarn-project/end-to-end/src/e2e_synching.test.ts b/yarn-project/end-to-end/src/e2e_synching.test.ts index 8e37614a8ce0..5f870d565cd0 100644 --- a/yarn-project/end-to-end/src/e2e_synching.test.ts +++ b/yarn-project/end-to-end/src/e2e_synching.test.ts @@ -56,7 +56,7 @@ import { SequencerPublisher, SequencerPublisherMetrics } from '@aztec/sequencer- import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { CommitteeAttestationsAndSigners, L2Block } from '@aztec/stdlib/block'; import { tryStop } from '@aztec/stdlib/interfaces/server'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { createWorldStateSynchronizer } from '@aztec/world-state'; import * as fs from 'fs'; diff --git a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts index 61671ac0890d..31c2459bbb2a 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts @@ -1,7 +1,7 @@ import { AztecAddress, type AztecNode, type Logger, createLogger } from '@aztec/aztec.js'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; diff --git a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts index fe34ef93a642..e94a08390ea1 100644 --- a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts @@ -17,7 +17,7 @@ import { FeeAssetHandlerAbi } from '@aztec/l1-artifacts'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { type ProverNode, type ProverNodeConfig, createProverNode } from '@aztec/prover-node'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { getGenesisValues } from '@aztec/world-state/testing'; import { type Hex, getContract } from 'viem'; diff --git a/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts b/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts index e1943b051a0b..fc20439c5752 100644 --- a/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts +++ b/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts @@ -2,13 +2,11 @@ * Test fixtures and utilities to set up and run a test using multiple validators */ import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; -import type { SentTx } from '@aztec/aztec.js'; import { SecretValue } from '@aztec/foundation/config'; import { addLogNameHandler, removeLogNameHandler } from '@aztec/foundation/log'; import { bufferToHex } from '@aztec/foundation/string'; import type { DateProvider } from '@aztec/foundation/timer'; import type { ProverNodeConfig, ProverNodeDeps } from '@aztec/prover-node'; -import type { PXEService } from '@aztec/pxe/server'; import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; import getPort from 'get-port'; @@ -23,12 +21,6 @@ import { getEndToEndTestTelemetryClient } from './with_telemetry_utils.js'; // to avoid running validators with the same key export const ATTESTER_PRIVATE_KEYS_START_INDEX = 3; -export interface NodeContext { - node: AztecNodeService; - pxeService: PXEService; - txs: SentTx[]; -} - export function generatePrivateKeys(startIndex: number, numberOfKeys: number): `0x${string}`[] { const privateKeys: `0x${string}`[] = []; // Do not start from 0 as it is used during setup diff --git a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts index e9d475d21fd3..d167f1123d96 100644 --- a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts +++ b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts @@ -31,11 +31,11 @@ import { createLogger } from '@aztec/foundation/log'; import { resolver, reviver } from '@aztec/foundation/serialize'; import { TestDateProvider } from '@aztec/foundation/timer'; import type { ProverNode } from '@aztec/prover-node'; -import { createPXEService, getPXEServiceConfig } from '@aztec/pxe/server'; +import { getPXEServiceConfig } from '@aztec/pxe/server'; import type { SequencerClient } from '@aztec/sequencer-client'; import { tryStop } from '@aztec/stdlib/interfaces/server'; import { getConfigEnvVars as getTelemetryConfig, initTelemetryClient } from '@aztec/telemetry-client'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { getGenesisValues } from '@aztec/world-state/testing'; import type { Anvil } from '@viem/anvil'; @@ -446,8 +446,7 @@ async function setupFromFresh( pxeConfig.dataDirectory = statePath ?? path.join(directoryToCleanup, randomBytes(8).toString('hex')); // Only enable proving if specifically requested. pxeConfig.proverEnabled = !!opts.realProofs; - const pxe = await createPXEService(aztecNode, pxeConfig); - const wallet = new TestWallet(pxe, aztecNode); + const wallet = await TestWallet.create(aztecNode, pxeConfig); const cheatCodes = await CheatCodes.create(aztecNodeConfig.l1RpcUrls, wallet, aztecNode, dateProvider); if (statePath) { @@ -575,8 +574,7 @@ async function setupFromState(statePath: string, logger: Logger): Promise PXE_URL; +const { AZTEC_NODE_URL = '' } = process.env; +const getAztecUrl = () => AZTEC_NODE_URL; let telemetry: TelemetryClient | undefined = undefined; function getTelemetryClient(partialConfig: Partial & { benchmark?: boolean } = {}) { @@ -178,18 +174,11 @@ export async function setupPXEServiceAndGetWallet( pxeServiceConfig.dataDirectory = path.join(tmpdir(), randomBytes(8).toString('hex')); } - const simulator = new WASMSimulator(); - const recorder = process.env.CIRCUIT_RECORD_DIR - ? new FileCircuitRecorder(process.env.CIRCUIT_RECORD_DIR) - : new MemoryCircuitRecorder(); - const simulatorWithRecorder = new SimulatorRecorderWrapper(simulator, recorder); - const pxe = await createPXEServiceWithSimulator(aztecNode, simulatorWithRecorder, pxeServiceConfig, { - useLogSuffix, - }); - const teardown = configuredDataDirectory ? () => Promise.resolve() : () => tryRmDir(pxeServiceConfig.dataDirectory!); - const wallet = new TestWallet(pxe, aztecNode); + const wallet = await TestWallet.create(aztecNode, pxeServiceConfig, { + useLogSuffix, + }); return { wallet, @@ -217,11 +206,9 @@ async function setupWithRemoteEnvironment( const aztecNodeUrl = getAztecUrl(); logger.verbose(`Creating Aztec Node client to remote host ${aztecNodeUrl}`); const aztecNode = createAztecNodeClient(aztecNodeUrl); - logger.verbose(`Creating PXE client to remote host ${PXE_URL}`); - const pxeClient = createPXEClient(PXE_URL, {}, makeFetch([1, 2, 3], true)); - await waitForPXE(pxeClient, logger); - logger.verbose('JSON RPC client connected to PXE'); - logger.verbose(`Retrieving contract addresses from ${PXE_URL}`); + await waitForNode(aztecNode, logger); + logger.verbose('JSON RPC client connected to Aztec Node'); + logger.verbose(`Retrieving contract addresses from ${aztecNodeUrl}`); const { l1ContractAddresses, rollupVersion } = await aztecNode.getNodeInfo(); const l1Client = createExtendedL1Client(config.l1RpcUrls, account, foundry); @@ -232,12 +219,12 @@ async function setupWithRemoteEnvironment( rollupVersion, }; const ethCheatCodes = new EthCheatCodes(config.l1RpcUrls, new DateProvider()); - const wallet = new TestWallet(pxeClient, aztecNode); + const wallet = await TestWallet.create(aztecNode); const cheatCodes = await CheatCodes.create(config.l1RpcUrls, wallet, aztecNode, new DateProvider()); const teardown = () => Promise.resolve(); logger.verbose('Populating wallet from already registered accounts...'); - const initialFundedAccounts = await getDeployedTestAccounts(wallet); + const initialFundedAccounts = await getInitialTestAccountsData(); if (initialFundedAccounts.length < numberOfAccounts) { throw new Error(`Required ${numberOfAccounts} accounts. Found ${initialFundedAccounts.length}.`); @@ -404,9 +391,9 @@ export async function setup( if (!isAnvilTestChain(chain.id)) { throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`); } - if (PXE_URL) { + if (AZTEC_NODE_URL) { throw new Error( - `PXE_URL provided but no ETHEREUM_HOSTS set. Refusing to run, please set both variables so tests can deploy L1 contracts to the same Anvil instance`, + `AZTEC_NODE_URL provided but no ETHEREUM_HOSTS set. Refusing to run, please set both variables so tests can deploy L1 contracts to the same Anvil instance`, ); } @@ -459,7 +446,7 @@ export async function setup( config.coinbase = EthAddress.fromString(publisherHdAccount.address); - if (PXE_URL) { + if (AZTEC_NODE_URL) { // we are setting up against a remote environment, l1 contracts are assumed to already be deployed return await setupWithRemoteEnvironment(publisherHdAccount!, config, logger, numberOfAccounts); } diff --git a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts index d2cba8db8cbe..51a68217de79 100644 --- a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts +++ b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts @@ -1,43 +1,31 @@ // docs:start:imports -import { getDeployedTestAccounts } from '@aztec/accounts/testing'; -import { - AztecAddress, - type AztecNode, - Fr, - TxStatus, - createAztecNodeClient, - createPXEClient, - waitForPXE, -} from '@aztec/aztec.js'; +import { AztecAddress, type AztecNode, Fr, TxStatus, createAztecNodeClient, waitForNode } from '@aztec/aztec.js'; import { CheatCodes } from '@aztec/aztec/testing'; import { TestDateProvider } from '@aztec/foundation/timer'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; // docs:end:imports // docs:start:import_contract import { TestContract } from '@aztec/noir-test-contracts.js/Test'; -import { TestWallet } from '@aztec/test-wallet'; +import { registerInitialSandboxAccountsInWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; // docs:end:import_contract import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { mintTokensToPrivate } from '../fixtures/token_utils.js'; -const { - AZTEC_NODE_URL = 'http://localhost:8080', - PXE_URL = 'http://localhost:8080', - ETHEREUM_HOSTS = 'http://localhost:8545', -} = process.env; +const { AZTEC_NODE_URL = 'http://localhost:8080', ETHEREUM_HOSTS = 'http://localhost:8545' } = process.env; describe('guides/dapp/testing', () => { describe('on local sandbox', () => { + let aztecNode: AztecNode; beforeAll(async () => { // docs:start:create_pxe_client - const pxe = createPXEClient(PXE_URL); - await waitForPXE(pxe); + aztecNode = createAztecNodeClient(AZTEC_NODE_URL); + await waitForNode(aztecNode); // docs:end:create_pxe_client }); describe('token contract with initial accounts', () => { - let aztecNode: AztecNode; let wallet: TestWallet; let ownerAddress: AztecAddress; let recipientAddress: AztecAddress; @@ -45,14 +33,8 @@ describe('guides/dapp/testing', () => { beforeEach(async () => { // docs:start:use-existing-wallets - const pxe = createPXEClient(PXE_URL); - aztecNode = createAztecNodeClient(AZTEC_NODE_URL); - wallet = new TestWallet(pxe, aztecNode); - const [owner, recipient] = await getDeployedTestAccounts(wallet); - await wallet.createSchnorrAccount(owner.secret, owner.salt); - await wallet.createSchnorrAccount(recipient.secret, recipient.salt); - ownerAddress = owner.address; - recipientAddress = recipient.address; + wallet = await TestWallet.create(aztecNode); + [ownerAddress, recipientAddress] = await registerInitialSandboxAccountsInWallet(wallet); token = await TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18) .send({ from: ownerAddress }) .deployed(); @@ -74,7 +56,6 @@ describe('guides/dapp/testing', () => { }); describe('assertions', () => { - let aztecNode: AztecNode; let wallet: TestWallet; let ownerAddress: AztecAddress; let recipientAddress: AztecAddress; @@ -84,14 +65,8 @@ describe('guides/dapp/testing', () => { let ownerSlot: Fr; beforeAll(async () => { - const pxe = createPXEClient(PXE_URL); - aztecNode = createAztecNodeClient(AZTEC_NODE_URL); - wallet = new TestWallet(pxe, aztecNode); - const [owner, recipient] = await getDeployedTestAccounts(wallet); - await wallet.createSchnorrAccount(owner.secret, owner.salt); - await wallet.createSchnorrAccount(recipient.secret, recipient.salt); - ownerAddress = owner.address; - recipientAddress = recipient.address; + wallet = await TestWallet.create(aztecNode); + [ownerAddress, recipientAddress] = await registerInitialSandboxAccountsInWallet(wallet); testContract = await TestContract.deploy(wallet).send({ from: ownerAddress }).deployed(); token = await TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18) .send({ from: ownerAddress }) diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index 0ef0a511a0cd..7a5ad1f0ee2c 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -10,7 +10,7 @@ import { } from '@aztec/aztec.js'; import { SchnorrHardcodedAccountContractArtifact } from '@aztec/noir-contracts.js/SchnorrHardcodedAccount'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { setup } from '../fixtures/utils.js'; diff --git a/yarn-project/end-to-end/src/shared/submit-transactions.ts b/yarn-project/end-to-end/src/shared/submit-transactions.ts index 9d8f9bde9d58..4946eeace437 100644 --- a/yarn-project/end-to-end/src/shared/submit-transactions.ts +++ b/yarn-project/end-to-end/src/shared/submit-transactions.ts @@ -1,6 +1,6 @@ import { AztecAddress, Fr, GrumpkinScalar, type Logger, type SentTx, TxStatus } from '@aztec/aztec.js'; import { times } from '@aztec/foundation/collection'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; // submits a set of transactions to the provided Wallet export const submitTxsTo = async ( diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index 345e848855f4..de5b50f9257c 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -20,7 +20,7 @@ import { InboxAbi, UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-art import { UniswapContract } from '@aztec/noir-contracts.js/Uniswap'; import { computeL2ToL1MessageHash } from '@aztec/stdlib/hash'; import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; -import type { TestWallet } from '@aztec/test-wallet'; +import type { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import { type GetContractReturnType, getContract, parseEther, toFunctionSelector } from 'viem'; diff --git a/yarn-project/end-to-end/src/spartan/4epochs.test.ts b/yarn-project/end-to-end/src/spartan/4epochs.test.ts index 807623afc522..7c0d3a79e7c6 100644 --- a/yarn-project/end-to-end/src/spartan/4epochs.test.ts +++ b/yarn-project/end-to-end/src/spartan/4epochs.test.ts @@ -4,7 +4,7 @@ import { getL1ContractsConfigEnvVars } from '@aztec/ethereum'; import { EthCheatCodesWithState } from '@aztec/ethereum/test'; import { createLogger } from '@aztec/foundation/log'; import { DateProvider } from '@aztec/foundation/timer'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import type { ChildProcess } from 'child_process'; diff --git a/yarn-project/end-to-end/src/spartan/n_tps.test.ts b/yarn-project/end-to-end/src/spartan/n_tps.test.ts index 8e442bb563a5..a5a31747e195 100644 --- a/yarn-project/end-to-end/src/spartan/n_tps.test.ts +++ b/yarn-project/end-to-end/src/spartan/n_tps.test.ts @@ -1,6 +1,6 @@ import { type AztecNode, Fr, ProvenTx, Tx, readFieldCompressedString, sleep } from '@aztec/aztec.js'; import { createLogger } from '@aztec/foundation/log'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import type { ChildProcess } from 'child_process'; diff --git a/yarn-project/end-to-end/src/spartan/reorg.test.ts b/yarn-project/end-to-end/src/spartan/reorg.test.ts index 90df2642250a..4252d746179e 100644 --- a/yarn-project/end-to-end/src/spartan/reorg.test.ts +++ b/yarn-project/end-to-end/src/spartan/reorg.test.ts @@ -4,7 +4,7 @@ import { RollupCheatCodes } from '@aztec/aztec/testing'; import { EthCheatCodesWithState } from '@aztec/ethereum/test'; import { createLogger } from '@aztec/foundation/log'; import { DateProvider } from '@aztec/foundation/timer'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { expect, jest } from '@jest/globals'; import type { ChildProcess } from 'child_process'; diff --git a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts index 300ac3ecd8ee..26e6cdfb4dbc 100644 --- a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts +++ b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts @@ -1,4 +1,4 @@ -import { generateSchnorrAccounts, getDeployedTestAccounts } from '@aztec/accounts/testing'; +import { generateSchnorrAccounts } from '@aztec/accounts/testing'; import { type AztecAddress, type AztecNode, @@ -9,15 +9,14 @@ import { SponsoredFeePaymentMethod, type Wallet, createAztecNodeClient, - createCompatibleClient, retryUntil, } from '@aztec/aztec.js'; import { createEthereumChain, createExtendedL1Client } from '@aztec/ethereum'; import type { Logger } from '@aztec/foundation/log'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import { createPXEService } from '@aztec/pxe/server'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; -import { TestWallet } from '@aztec/test-wallet'; +import { registerInitialSandboxAccountsInWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { getACVMConfig } from '../fixtures/get_acvm_config.js'; import { getBBConfig } from '../fixtures/get_bb_config.js'; @@ -39,39 +38,33 @@ const TOKEN_SYMBOL = 'USD'; const TOKEN_DECIMALS = 18n; export async function setupTestAccountsWithTokens( - pxeUrl: string, nodeUrl: string, mintAmount: bigint, logger: Logger, ): Promise { const ACCOUNT_COUNT = 1; // TODO fix this to allow for 16 wallets again - const pxe = await createCompatibleClient(pxeUrl, logger); const aztecNode = createAztecNodeClient(nodeUrl); - const wallet = new TestWallet(pxe, aztecNode); + const wallet = await TestWallet.create(aztecNode); - const [recipientAccount, ...accounts] = (await getDeployedTestAccounts(wallet)).slice(0, ACCOUNT_COUNT + 1); + const [recipientAccount, ...accounts] = (await registerInitialSandboxAccountsInWallet(wallet)).slice( + 0, + ACCOUNT_COUNT + 1, + ); const tokenAdmin = accounts[0]; - const tokenAddress = await deployTokenAndMint( - wallet, - accounts.map(acc => acc.address), - tokenAdmin.address, - mintAmount, - undefined, - logger, - ); + const tokenAddress = await deployTokenAndMint(wallet, accounts, tokenAdmin, mintAmount, undefined, logger); const tokenContract = await TokenContract.at(tokenAddress, wallet); return { aztecNode, - accounts: accounts.map(acc => acc.address), + accounts, wallet, - tokenAdminAddress: tokenAdmin.address, + tokenAdminAddress: tokenAdmin, tokenName: TOKEN_NAME, tokenAddress, tokenContract, - recipientAddress: recipientAccount.address, + recipientAddress: recipientAccount, }; } @@ -121,7 +114,6 @@ export async function deploySponsoredTestAccounts( } export async function deployTestAccountsWithTokens( - pxeUrl: string, nodeUrl: string, l1RpcUrls: string[], mnemonicOrPrivateKey: string, @@ -129,9 +121,8 @@ export async function deployTestAccountsWithTokens( logger: Logger, numberOfFundedWallets = 1, ): Promise { - const pxe = await createCompatibleClient(pxeUrl, logger); const aztecNode = createAztecNodeClient(nodeUrl); - const wallet = new TestWallet(pxe, aztecNode); + const wallet = await TestWallet.create(aztecNode); const [recipient, ...funded] = await generateSchnorrAccounts(numberOfFundedWallets + 1); const recipientAccount = await wallet.createSchnorrAccount(recipient.secret, recipient.salt); @@ -294,20 +285,20 @@ export async function createWalletAndAztecNodeClient( ): Promise<{ wallet: TestWallet; aztecNode: AztecNode; cleanup: () => Promise }> { const aztecNode = createAztecNodeClient(nodeUrl); const [bbConfig, acvmConfig] = await Promise.all([getBBConfig(logger), getACVMConfig(logger)]); - const pxe = await createPXEService(aztecNode, { + const pxeConfig = { dataDirectory: undefined, dataStoreMapSizeKB: 1024 * 1024, ...bbConfig, ...acvmConfig, proverEnabled, - }); - const wallet = new TestWallet(pxe, aztecNode); + }; + const wallet = await TestWallet.create(aztecNode, pxeConfig); return { wallet, aztecNode, async cleanup() { - await pxe.stop(); + await wallet.stop(); await bbConfig?.cleanup(); await acvmConfig?.cleanup(); }, diff --git a/yarn-project/end-to-end/src/spartan/transfer.test.ts b/yarn-project/end-to-end/src/spartan/transfer.test.ts index 3e102d22cae1..a2c176de43cb 100644 --- a/yarn-project/end-to-end/src/spartan/transfer.test.ts +++ b/yarn-project/end-to-end/src/spartan/transfer.test.ts @@ -1,7 +1,7 @@ import { type AztecNode, SponsoredFeePaymentMethod, readFieldCompressedString } from '@aztec/aztec.js'; import { createLogger } from '@aztec/foundation/log'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import { TestWallet } from '@aztec/test-wallet'; +import { TestWallet } from '@aztec/test-wallet/server'; import { jest } from '@jest/globals'; import type { ChildProcess } from 'child_process'; diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 91b3e3ea53f2..8fa354247c93 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -38,7 +38,6 @@ export type EnvVar = | 'BOT_ACCOUNT_SALT' | 'BOT_PRIVATE_TRANSFERS_PER_TX' | 'BOT_PUBLIC_TRANSFERS_PER_TX' - | 'BOT_PXE_URL' | 'BOT_RECIPIENT_ENCRYPTION_SECRET' | 'BOT_TOKEN_CONTRACT' | 'BOT_TOKEN_SALT' diff --git a/yarn-project/pxe/package.json b/yarn-project/pxe/package.json index 0b61ad778283..fc13fe746603 100644 --- a/yarn-project/pxe/package.json +++ b/yarn-project/pxe/package.json @@ -7,8 +7,7 @@ "./client/lazy": "./dest/entrypoints/client/lazy/index.js", "./client/bundle": "./dest/entrypoints/client/bundle/index.js", "./simulator": "./dest/contract_function_simulator/index.js", - "./config": "./dest/config/index.js", - "./testing": "./dest/test/pxe_test_suite.js" + "./config": "./dest/config/index.js" }, "bin": "./dest/bin/index.js", "scripts": { @@ -16,7 +15,6 @@ "build:dev": "tsc -b --watch", "clean": "rm -rf ./dest .tsbuildinfo ./src/config/package_info.ts", "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}", - "start": "LOG_LEVEL=${LOG_LEVEL:-debug} && node ./dest/bin/index.js", "generate": "node ./scripts/generate_package_info.js", "check_oracle_version": "node ./dest/bin/check_oracle_version.js" }, diff --git a/yarn-project/pxe/src/bin/index.ts b/yarn-project/pxe/src/bin/index.ts deleted file mode 100644 index 3379aa05bfc0..000000000000 --- a/yarn-project/pxe/src/bin/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env -S node --no-warnings -import { type SafeJsonRpcServerOptions, createNamespacedSafeJsonRpcServer } from '@aztec/foundation/json-rpc/server'; -import { createLogger } from '@aztec/foundation/log'; -import { type PXE, PXESchema, createAztecNodeClient } from '@aztec/stdlib/interfaces/client'; - -import http from 'http'; - -import { getPXEServiceConfig } from '../config/index.js'; -import { createPXEService } from '../entrypoints/server/utils.js'; - -const { PXE_PORT = 8080, AZTEC_NODE_URL = 'http://localhost:8079' } = process.env; - -const logger = createLogger('pxe:service'); - -/** - * Creates an http server that forwards calls to the PXE and starts it on the given port. - * @param pxeService - PXE that answers queries to the created HTTP server. - * @param port - Port to listen in. - * @param maxBatchSize - Maximum allowed batch size for JSON RPC batch requests. - * @returns A running http server. - */ -function startPXEHttpServer( - pxeService: PXE, - port: string | number, - opts: Pick = {}, -): http.Server { - const rpcServer = createNamespacedSafeJsonRpcServer({ pxe: [pxeService, PXESchema] }, opts); - - const app = rpcServer.getApp(); - // eslint-disable-next-line @typescript-eslint/no-misused-promises - const httpServer = http.createServer(app.callback()); - httpServer.listen(port); - - return httpServer; -} - -/** - * Create and start a new PXE HTTP Server - */ -async function main() { - logger.info(`Setting up PXE...`); - - const pxeConfig = getPXEServiceConfig(); - const nodeRpcClient = createAztecNodeClient(AZTEC_NODE_URL, {}); - const pxeService = await createPXEService(nodeRpcClient, pxeConfig); - - const shutdown = () => { - logger.info('Shutting down...'); - process.exit(0); - }; - - process.once('SIGINT', shutdown); - process.once('SIGTERM', shutdown); - - startPXEHttpServer(pxeService, PXE_PORT); - logger.info(`PXE listening on port ${PXE_PORT}`); -} - -main().catch(err => { - logger.error(err); - process.exit(1); -}); diff --git a/yarn-project/pxe/src/entrypoints/client/bundle/index.ts b/yarn-project/pxe/src/entrypoints/client/bundle/index.ts index bdf6dcfcb8e4..9fa3e13f5580 100644 --- a/yarn-project/pxe/src/entrypoints/client/bundle/index.ts +++ b/yarn-project/pxe/src/entrypoints/client/bundle/index.ts @@ -3,3 +3,4 @@ export * from '../../../config/index.js'; export * from '../../../storage/index.js'; export * from './utils.js'; export { PXEOracleInterface } from '../../../contract_function_simulator/pxe_oracle_interface.js'; +export type { PXECreationOptions } from '../../pxe_creation_options.js'; diff --git a/yarn-project/pxe/src/entrypoints/client/lazy/index.ts b/yarn-project/pxe/src/entrypoints/client/lazy/index.ts index bdf6dcfcb8e4..7a9618034812 100644 --- a/yarn-project/pxe/src/entrypoints/client/lazy/index.ts +++ b/yarn-project/pxe/src/entrypoints/client/lazy/index.ts @@ -3,3 +3,4 @@ export * from '../../../config/index.js'; export * from '../../../storage/index.js'; export * from './utils.js'; export { PXEOracleInterface } from '../../../contract_function_simulator/pxe_oracle_interface.js'; +export { type PXECreationOptions } from '../../pxe_creation_options.js'; diff --git a/yarn-project/pxe/src/entrypoints/server/index.ts b/yarn-project/pxe/src/entrypoints/server/index.ts index 80640fd5ec6a..7a63712edbbb 100644 --- a/yarn-project/pxe/src/entrypoints/server/index.ts +++ b/yarn-project/pxe/src/entrypoints/server/index.ts @@ -4,3 +4,4 @@ export * from '../../storage/index.js'; export * from './utils.js'; export { PXEOracleInterface } from '../../contract_function_simulator/pxe_oracle_interface.js'; export { ORACLE_VERSION } from '../../oracle_version.js'; +export { type PXECreationOptions } from '../pxe_creation_options.js'; diff --git a/yarn-project/pxe/src/entrypoints/server/utils.ts b/yarn-project/pxe/src/entrypoints/server/utils.ts index 9478b9164183..13c5232aa8e4 100644 --- a/yarn-project/pxe/src/entrypoints/server/utils.ts +++ b/yarn-project/pxe/src/entrypoints/server/utils.ts @@ -30,34 +30,16 @@ type PXEConfigWithoutDefaults = Omit< * @param useLogSuffix - Whether to add a randomly generated suffix to the PXE debug logs. * @returns A Promise that resolves to the started PXEService instance. */ -export function createPXEService( +export async function createPXEService( aztecNode: AztecNode, config: PXEConfigWithoutDefaults, options: PXECreationOptions = { loggers: {} }, ) { - const simulator = new WASMSimulator(); const recorder = process.env.CIRCUIT_RECORD_DIR ? new FileCircuitRecorder(process.env.CIRCUIT_RECORD_DIR) : new MemoryCircuitRecorder(); - const simulatorWithRecorder = new SimulatorRecorderWrapper(simulator, recorder); - return createPXEServiceWithSimulator(aztecNode, simulatorWithRecorder, config, options); -} + const simulator = new SimulatorRecorderWrapper(new WASMSimulator(), recorder); -/** - * Create and start an PXEService instance with the given AztecNode, Simulator and config. - * - * @param aztecNode - The AztecNode instance to be used by the server. - * @param simulator - The Simulator to use - * @param config - The PXE Service Config to use - * @param useLogSuffix - Whether to add a randomly generated suffix to the PXE debug logs. - * @returns A Promise that resolves to the started PXEService instance. - */ -export async function createPXEServiceWithSimulator( - aztecNode: AztecNode, - simulator: CircuitSimulator, - config: PXEConfigWithoutDefaults, - options: PXECreationOptions = { loggers: {} }, -) { const logSuffix = typeof options.useLogSuffix === 'boolean' ? options.useLogSuffix diff --git a/yarn-project/pxe/src/test/pxe_service.test.ts b/yarn-project/pxe/src/test/pxe_service.test.ts index bc38eae45adf..d69b26a3ab76 100644 --- a/yarn-project/pxe/src/test/pxe_service.test.ts +++ b/yarn-project/pxe/src/test/pxe_service.test.ts @@ -1,63 +1,146 @@ import { BBWASMBundlePrivateKernelProver } from '@aztec/bb-prover/client/wasm/bundle'; import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses'; +import { omit } from '@aztec/foundation/collection'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { Fr } from '@aztec/foundation/fields'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle'; import { WASMSimulator } from '@aztec/simulator/client'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; +import { getContractClassFromArtifact } from '@aztec/stdlib/contract'; import type { AztecNode, PXE } from '@aztec/stdlib/interfaces/client'; +import { + randomContractArtifact, + randomContractInstanceWithAddress, + randomDeployedContract, +} from '@aztec/stdlib/testing'; import { mock } from 'jest-mock-extended'; import type { PXEServiceConfig } from '../config/index.js'; import { PXEService } from '../pxe_service/pxe_service.js'; -import { pxeTestSuite } from './pxe_test_suite.js'; - -async function createPXEService(): Promise { - const kvStore = await openTmpStore('test'); - const node = mock(); - const simulator = new WASMSimulator(); - const kernelProver = new BBWASMBundlePrivateKernelProver(simulator); - const protocolContractsProvider = new BundledProtocolContractsProvider(); - const config: PXEServiceConfig = { - l2BlockBatchSize: 50, - dataDirectory: undefined, - dataStoreMapSizeKB: 1024 * 1024, - l1Contracts: { rollupAddress: EthAddress.random() }, - l1ChainId: 31337, - rollupVersion: 1, - }; - - // Mock getNodeInfo which is called during PXE service creation - const mockedContracts: L1ContractAddresses = { - rollupAddress: EthAddress.random(), - registryAddress: EthAddress.random(), - inboxAddress: EthAddress.random(), - outboxAddress: EthAddress.random(), - feeJuiceAddress: EthAddress.random(), - stakingAssetAddress: EthAddress.random(), - feeJuicePortalAddress: EthAddress.random(), - governanceAddress: EthAddress.random(), - coinIssuerAddress: EthAddress.random(), - rewardDistributorAddress: EthAddress.random(), - governanceProposerAddress: EthAddress.random(), - slashFactoryAddress: EthAddress.random(), - }; - node.getNodeInfo.mockResolvedValue({ - nodeVersion: '1.0.0', - l1ChainId: 31337, - rollupVersion: 1, - enr: undefined, - l1ContractAddresses: mockedContracts, - protocolContractAddresses: { - classRegistry: await AztecAddress.random(), - feeJuice: await AztecAddress.random(), - instanceRegistry: await AztecAddress.random(), - multiCallEntrypoint: await AztecAddress.random(), - }, + +describe('PXEService', () => { + let pxe: PXE; + + beforeAll(async () => { + const kvStore = await openTmpStore('test'); + const node = mock(); + const simulator = new WASMSimulator(); + const kernelProver = new BBWASMBundlePrivateKernelProver(simulator); + const protocolContractsProvider = new BundledProtocolContractsProvider(); + const config: PXEServiceConfig = { + l2BlockBatchSize: 50, + dataDirectory: undefined, + dataStoreMapSizeKB: 1024 * 1024, + l1Contracts: { rollupAddress: EthAddress.random() }, + l1ChainId: 31337, + rollupVersion: 1, + }; + + // Mock getNodeInfo which is called during PXE service creation + const mockedContracts: L1ContractAddresses = { + rollupAddress: EthAddress.random(), + registryAddress: EthAddress.random(), + inboxAddress: EthAddress.random(), + outboxAddress: EthAddress.random(), + feeJuiceAddress: EthAddress.random(), + stakingAssetAddress: EthAddress.random(), + feeJuicePortalAddress: EthAddress.random(), + governanceAddress: EthAddress.random(), + coinIssuerAddress: EthAddress.random(), + rewardDistributorAddress: EthAddress.random(), + governanceProposerAddress: EthAddress.random(), + slashFactoryAddress: EthAddress.random(), + }; + node.getNodeInfo.mockResolvedValue({ + nodeVersion: '1.0.0', + l1ChainId: 31337, + rollupVersion: 1, + enr: undefined, + l1ContractAddresses: mockedContracts, + protocolContractAddresses: { + classRegistry: await AztecAddress.random(), + feeJuice: await AztecAddress.random(), + instanceRegistry: await AztecAddress.random(), + multiCallEntrypoint: await AztecAddress.random(), + }, + }); + + pxe = await PXEService.create(node, kvStore, kernelProver, simulator, protocolContractsProvider, config); + }, 120_000); + + it('registers an account and returns it as an account only and not as a recipient', async () => { + const randomSecretKey = Fr.random(); + const randomPartialAddress = Fr.random(); + const completeAddress = await pxe.registerAccount(randomSecretKey, randomPartialAddress); + + // Check that the account is correctly registered using the getAccounts and getRecipients methods + const accounts = await pxe.getRegisteredAccounts(); + expect(accounts).toContainEqual(completeAddress); }); - return await PXEService.create(node, kvStore, kernelProver, simulator, protocolContractsProvider, config); -} + it('does not throw when registering the same account twice (just ignores the second attempt)', async () => { + const randomSecretKey = Fr.random(); + const randomPartialAddress = Fr.random(); + + await pxe.registerAccount(randomSecretKey, randomPartialAddress); + await pxe.registerAccount(randomSecretKey, randomPartialAddress); + }); + + it('successfully adds a contract', async () => { + const contracts = await Promise.all([randomDeployedContract(), randomDeployedContract()]); + for (const contract of contracts) { + await pxe.registerContract(contract); + } + + const expectedContractAddresses = contracts.map(contract => contract.instance.address); + const contractAddresses = await pxe.getContracts(); + expect(contractAddresses).toEqual(expect.arrayContaining(expectedContractAddresses)); + }); + + it('registers a class and adds a contract for it', async () => { + const artifact = randomContractArtifact(); + const contractClass = await getContractClassFromArtifact(artifact); + const contractClassId = contractClass.id; + const instance = await randomContractInstanceWithAddress({ contractClassId }); + + await pxe.registerContractClass(artifact); + expect((await pxe.getContractClassMetadata(contractClassId)).contractClass).toMatchObject( + omit(contractClass, 'privateFunctionsRoot', 'publicBytecodeCommitment'), + ); + + await pxe.registerContract({ instance }); + expect((await pxe.getContractMetadata(instance.address)).contractInstance).toEqual(instance); + }); + + it('refuses to register a class with a mismatched address', async () => { + const artifact = randomContractArtifact(); + const contractClass = await getContractClassFromArtifact(artifact); + const contractClassId = contractClass.id; + const instance = await randomContractInstanceWithAddress({ contractClassId }); + await expect( + pxe.registerContract({ + instance: { + ...instance, + address: await AztecAddress.random(), + }, + artifact, + }), + ).rejects.toThrow(/Added a contract in which the address does not match the contract instance./); + }); + + it('refuses to register a contract with a class that has not been registered', async () => { + const instance = await randomContractInstanceWithAddress(); + await expect(pxe.registerContract({ instance })).rejects.toThrow(/Artifact not found when registering an instance/); + }); + + it('refuses to register a contract with an artifact with mismatching class id', async () => { + const artifact = randomContractArtifact(); + const instance = await randomContractInstanceWithAddress(); + await expect(pxe.registerContract({ instance, artifact })).rejects.toThrow(/Artifact does not match/i); + }); -pxeTestSuite('PXEService', createPXEService); + // Note: Not testing a successful run of `proveTx`, `sendTx`, `getTxReceipt` and `simulateUtility` here as it + // requires a larger setup and it's sufficiently tested in the e2e tests. +}); diff --git a/yarn-project/pxe/src/test/pxe_test_suite.ts b/yarn-project/pxe/src/test/pxe_test_suite.ts deleted file mode 100644 index 67ef30648c56..000000000000 --- a/yarn-project/pxe/src/test/pxe_test_suite.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Fr } from '@aztec/foundation/fields'; -import { AztecAddress } from '@aztec/stdlib/aztec-address'; -import { getContractClassFromArtifact } from '@aztec/stdlib/contract'; -import type { PXE } from '@aztec/stdlib/interfaces/client'; -import { - randomContractArtifact, - randomContractInstanceWithAddress, - randomDeployedContract, -} from '@aztec/stdlib/testing'; - -import omit from 'lodash.omit'; - -export const pxeTestSuite = (testName: string, pxeSetup: () => Promise) => { - describe(testName, () => { - let pxe: PXE; - - beforeAll(async () => { - pxe = await pxeSetup(); - }, 120_000); - - it('registers an account and returns it as an account only and not as a recipient', async () => { - const randomSecretKey = Fr.random(); - const randomPartialAddress = Fr.random(); - const completeAddress = await pxe.registerAccount(randomSecretKey, randomPartialAddress); - - // Check that the account is correctly registered using the getAccounts and getRecipients methods - const accounts = await pxe.getRegisteredAccounts(); - expect(accounts).toContainEqual(completeAddress); - }); - - it('does not throw when registering the same account twice (just ignores the second attempt)', async () => { - const randomSecretKey = Fr.random(); - const randomPartialAddress = Fr.random(); - - await pxe.registerAccount(randomSecretKey, randomPartialAddress); - await pxe.registerAccount(randomSecretKey, randomPartialAddress); - }); - - it('successfully adds a contract', async () => { - const contracts = await Promise.all([randomDeployedContract(), randomDeployedContract()]); - for (const contract of contracts) { - await pxe.registerContract(contract); - } - - const expectedContractAddresses = contracts.map(contract => contract.instance.address); - const contractAddresses = await pxe.getContracts(); - expect(contractAddresses).toEqual(expect.arrayContaining(expectedContractAddresses)); - }); - - it('registers a class and adds a contract for it', async () => { - const artifact = randomContractArtifact(); - const contractClass = await getContractClassFromArtifact(artifact); - const contractClassId = contractClass.id; - const instance = await randomContractInstanceWithAddress({ contractClassId }); - - await pxe.registerContractClass(artifact); - expect((await pxe.getContractClassMetadata(contractClassId)).contractClass).toMatchObject( - omit(contractClass, 'privateFunctionsRoot', 'publicBytecodeCommitment'), - ); - - await pxe.registerContract({ instance }); - expect((await pxe.getContractMetadata(instance.address)).contractInstance).toEqual(instance); - }); - - it('refuses to register a class with a mismatched address', async () => { - const artifact = randomContractArtifact(); - const contractClass = await getContractClassFromArtifact(artifact); - const contractClassId = contractClass.id; - const instance = await randomContractInstanceWithAddress({ contractClassId }); - await expect( - pxe.registerContract({ - instance: { - ...instance, - address: await AztecAddress.random(), - }, - artifact, - }), - ).rejects.toThrow(/Added a contract in which the address does not match the contract instance./); - }); - - it('refuses to register a contract with a class that has not been registered', async () => { - const instance = await randomContractInstanceWithAddress(); - await expect(pxe.registerContract({ instance })).rejects.toThrow( - /Artifact not found when registering an instance/, - ); - }); - - it('refuses to register a contract with an artifact with mismatching class id', async () => { - const artifact = randomContractArtifact(); - const instance = await randomContractInstanceWithAddress(); - await expect(pxe.registerContract({ instance, artifact })).rejects.toThrow(/Artifact does not match/i); - }); - - // Note: Not testing a successful run of `proveTx`, `sendTx`, `getTxReceipt` and `simulateUtility` here as it - // requires a larger setup and it's sufficiently tested in the e2e tests. - }); -}; diff --git a/yarn-project/stdlib/src/interfaces/pxe.test.ts b/yarn-project/stdlib/src/interfaces/pxe.test.ts deleted file mode 100644 index a53f221ee146..000000000000 --- a/yarn-project/stdlib/src/interfaces/pxe.test.ts +++ /dev/null @@ -1,422 +0,0 @@ -import { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants'; -import { randomInt } from '@aztec/foundation/crypto'; -import { memoize } from '@aztec/foundation/decorators'; -import { Fr } from '@aztec/foundation/fields'; -import { type JsonRpcTestContext, createJsonRpcTestSetup } from '@aztec/foundation/json-rpc/test'; -import { SiblingPath } from '@aztec/foundation/trees'; - -import { jest } from '@jest/globals'; -import { deepStrictEqual } from 'assert'; -import omit from 'lodash.omit'; - -import type { ContractArtifact } from '../abi/abi.js'; -import { EventSelector } from '../abi/event_selector.js'; -import { AuthWitness } from '../auth_witness/auth_witness.js'; -import { AztecAddress } from '../aztec-address/index.js'; -import { L2BlockHash } from '../block/block_hash.js'; -import { L2Block } from '../block/l2_block.js'; -import { - CompleteAddress, - type ContractInstanceWithAddress, - type ProtocolContractAddresses, - ProtocolContractsNames, - getContractClassFromArtifact, -} from '../contract/index.js'; -import { GasFees } from '../gas/gas_fees.js'; -import { PrivateKernelTailCircuitPublicInputs } from '../kernel/private_kernel_tail_circuit_public_inputs.js'; -import { PublicKeys } from '../keys/public_keys.js'; -import { UniqueNote } from '../note/index.js'; -import type { NotesFilter } from '../note/notes_filter.js'; -import { ClientIvcProof } from '../proofs/client_ivc_proof.js'; -import { getTokenContractArtifact } from '../tests/fixtures.js'; -import { - type IndexedTxEffect, - PrivateExecutionResult, - SimulationOverrides, - TxHash, - TxReceipt, - TxSimulationResult, -} from '../tx/index.js'; -import { TxProfileResult, UtilitySimulationResult } from '../tx/profiling.js'; -import { TxProvingResult } from '../tx/proven_tx.js'; -import { TxEffect } from '../tx/tx_effect.js'; -import { TxExecutionRequest } from '../tx/tx_execution_request.js'; -import { - type ContractClassMetadata, - type ContractMetadata, - type EventMetadataDefinition, - type PXE, - type PXEInfo, - PXESchema, -} from './pxe.js'; - -jest.setTimeout(12_000); - -describe('PXESchema', () => { - let handler: MockPXE; - let context: JsonRpcTestContext; - - let address: AztecAddress; - let artifact: ContractArtifact; - let instance: ContractInstanceWithAddress; - - const tested = new Set(); - - beforeAll(() => { - artifact = getTokenContractArtifact(); - }); - - beforeEach(async () => { - address = await AztecAddress.random(); - instance = { - version: 1, - currentContractClassId: Fr.random(), - originalContractClassId: Fr.random(), - deployer: await AztecAddress.random(), - initializationHash: Fr.random(), - publicKeys: await PublicKeys.random(), - salt: Fr.random(), - address, - }; - handler = new MockPXE(address, artifact, instance); - context = await createJsonRpcTestSetup(handler, PXESchema); - }); - - afterEach(() => { - tested.add(/^PXESchema\s+([^(]+)/.exec(expect.getState().currentTestName!)![1]); - context.httpServer.close(); - }); - - afterAll(() => { - const all = Object.keys(PXESchema); - expect([...tested].sort()).toEqual(all.sort()); - }); - - it('registerAccount', async () => { - const result = await context.client.registerAccount(Fr.random(), Fr.random()); - expect(result).toBeInstanceOf(CompleteAddress); - }); - - it('getRegisteredAccounts', async () => { - const result = await context.client.getRegisteredAccounts(); - expect(result).toEqual([expect.any(CompleteAddress)]); - }); - - it('registerSender', async () => { - const result = await context.client.registerSender(address); - expect(result).toEqual(address); - }); - - it('getSenders', async () => { - const result = await context.client.getSenders(); - expect(result).toEqual([address]); - }); - - it('removeSender', async () => { - await context.client.removeSender(address); - }); - - it('registerContractClass', async () => { - await context.client.registerContractClass(artifact); - }); - - it('registerContract', async () => { - await context.client.registerContract({ instance, artifact }); - }); - - it('updateContract', async () => { - await context.client.updateContract(instance.address, artifact); - }); - - it('getContracts', async () => { - const result = await context.client.getContracts(); - expect(result).toEqual([address]); - }); - - it('profileTx', async () => { - const result = await context.client.profileTx(await TxExecutionRequest.random(), 'gates'); - expect(result).toBeInstanceOf(TxProfileResult); - }); - - it('proveTx', async () => { - const result = await context.client.proveTx(await TxExecutionRequest.random()); - expect(result).toBeInstanceOf(TxProvingResult); - }); - - it('simulateTx(all)', async () => { - const result = await context.client.simulateTx( - await TxExecutionRequest.random(), - true, - false, - true, - { contracts: {} }, - [], - ); - expect(result).toBeInstanceOf(TxSimulationResult); - }); - - it('simulateTx(required)', async () => { - const result = await context.client.simulateTx(await TxExecutionRequest.random(), true); - expect(result).toBeInstanceOf(TxSimulationResult); - }); - - it('simulateTx(undefined)', async () => { - const result = await context.client.simulateTx( - await TxExecutionRequest.random(), - true, - undefined, - undefined, - undefined, - undefined, - ); - expect(result).toBeInstanceOf(TxSimulationResult); - }); - - it('getNotes', async () => { - const result = await context.client.getNotes({ contractAddress: address }); - expect(result).toEqual([expect.any(UniqueNote)]); - }); - - it('simulateUtility', async () => { - const result = await context.client.simulateUtility('function', [], address, [], address, [address]); - expect(result).toEqual({ result: 10n }); - }); - - it('getContractMetadata', async () => { - const { contractInstance, isContractInitialized, isContractPublished } = - await context.client.getContractMetadata(address); - expect(contractInstance).toEqual(instance); - expect(isContractInitialized).toEqual(true); - expect(isContractPublished).toEqual(true); - }); - - it('getContractClassMetadata', async () => { - const { - contractClass, - isContractClassPubliclyRegistered, - artifact: contractArtifact, - } = await context.client.getContractClassMetadata(Fr.random(), true); - const expected = omit( - await getContractClassFromArtifact(artifact), - 'privateFunctionsRoot', - 'publicBytecodeCommitment', - ); - expect(contractClass).toEqual(expected); - expect(isContractClassPubliclyRegistered).toEqual(true); - deepStrictEqual(contractArtifact, artifact); - }); - - it('getPrivateEvents', async () => { - const result = await context.client.getPrivateEvents<{ value: bigint }>( - address, - { abiType: { kind: 'boolean' }, eventSelector: EventSelector.random(), fieldNames: ['name'] }, - 1, - 1, - [await AztecAddress.random()], - ); - expect(result).toEqual([{ value: 1n }]); - }); - - it('getPXEInfo', async () => { - const result = await context.client.getPXEInfo(); - expect(result).toEqual({ - pxeVersion: '1.0', - protocolContractAddresses: expect.any(Object), - }); - }); -}); - -class MockPXE implements PXE { - constructor( - private address: AztecAddress, - private artifact: ContractArtifact, - private instance: ContractInstanceWithAddress, - ) {} - - registerAccount(secretKey: Fr, partialAddress: Fr): Promise { - expect(secretKey).toBeInstanceOf(Fr); - expect(partialAddress).toBeInstanceOf(Fr); - return Promise.resolve(CompleteAddress.random()); - } - async getRegisteredAccounts(): Promise { - return [await CompleteAddress.random()]; - } - getRegisteredAccount(address: AztecAddress): Promise { - expect(address).toBeInstanceOf(AztecAddress); - return Promise.resolve(CompleteAddress.random()); - } - registerSender(address: AztecAddress): Promise { - expect(address).toBeInstanceOf(AztecAddress); - return Promise.resolve(this.address); - } - getSenders(): Promise { - return Promise.resolve([this.address]); - } - removeSender(address: AztecAddress): Promise { - expect(address).toBeInstanceOf(AztecAddress); - return Promise.resolve(); - } - registerContractClass(artifact: ContractArtifact): Promise { - deepStrictEqual(artifact, this.artifact); - return Promise.resolve(); - } - registerContract(contract: { - instance: ContractInstanceWithAddress; - artifact?: ContractArtifact | undefined; - }): Promise { - expect(contract.instance).toEqual(this.instance); - deepStrictEqual(contract.artifact, this.artifact); - return Promise.resolve(); - } - updateContract(contractAddress: AztecAddress, _artifact: ContractArtifact): Promise { - expect(contractAddress).toEqual(this.address); - return Promise.resolve(); - } - getContracts(): Promise { - return Promise.resolve([this.address]); - } - profileTx( - txRequest: TxExecutionRequest, - profileMode: 'gates' | 'full' | 'execution-steps' | 'none', - skipProofGeneration = true, - msgSender?: AztecAddress, - ): Promise { - expect(txRequest).toBeInstanceOf(TxExecutionRequest); - expect(profileMode).toMatch(/gates|debug/); - if (msgSender) { - expect(msgSender).toBeInstanceOf(AztecAddress); - } - const provingTime = skipProofGeneration ? 1 : undefined; - return Promise.resolve( - new TxProfileResult([], { - nodeRPCCalls: { getBlockNumber: { times: [1] } }, - timings: { - perFunction: [{ functionName: 'something', time: 1 }], - proving: provingTime, - unaccounted: 1, - total: 2, - }, - }), - ); - } - async proveTx(txRequest: TxExecutionRequest): Promise { - expect(txRequest).toBeInstanceOf(TxExecutionRequest); - return Promise.resolve( - new TxProvingResult( - await PrivateExecutionResult.random(), - PrivateKernelTailCircuitPublicInputs.empty(), - ClientIvcProof.empty(), - ), - ); - } - async simulateTx( - txRequest: TxExecutionRequest, - _simulatePublic: boolean, - _skipTxValidation?: boolean, - _skipFeeEnforcement?: boolean, - _overrides?: SimulationOverrides, - scopes?: AztecAddress[], - ): Promise { - expect(txRequest).toBeInstanceOf(TxExecutionRequest); - if (scopes) { - expect(scopes).toEqual([]); - } - return new TxSimulationResult(await PrivateExecutionResult.random(), PrivateKernelTailCircuitPublicInputs.empty()); - } - getTxReceipt(txHash: TxHash): Promise { - expect(txHash).toBeInstanceOf(TxHash); - return Promise.resolve(TxReceipt.empty()); - } - async getTxEffect(txHash: TxHash): Promise { - expect(txHash).toBeInstanceOf(TxHash); - return { - data: await TxEffect.random(), - l2BlockHash: L2BlockHash.random(), - l2BlockNumber: 1, - txIndexInBlock: randomInt(10), - }; - } - getPublicStorageAt(contract: AztecAddress, slot: Fr): Promise { - expect(contract).toBeInstanceOf(AztecAddress); - expect(slot).toBeInstanceOf(Fr); - return Promise.resolve(Fr.random()); - } - async getNotes(filter: NotesFilter): Promise { - expect(filter.contractAddress).toEqual(this.address); - const uniqueNote = await UniqueNote.random(); - return [uniqueNote]; - } - getL1ToL2MembershipWitness( - contractAddress: AztecAddress, - messageHash: Fr, - secret: Fr, - ): Promise<[bigint, SiblingPath]> { - expect(contractAddress).toBeInstanceOf(AztecAddress); - expect(messageHash).toBeInstanceOf(Fr); - expect(secret).toBeInstanceOf(Fr); - return Promise.resolve([1n, SiblingPath.random(L1_TO_L2_MSG_TREE_HEIGHT)]); - } - getL2ToL1Messages(blockNumber: number): Promise { - expect(typeof blockNumber).toEqual('number'); - return Promise.resolve([[Fr.random()], [Fr.random(), Fr.random()]]); - } - getBlock(number: number): Promise { - return Promise.resolve(L2Block.random(number)); - } - getCurrentBaseFees(): Promise { - return Promise.resolve(GasFees.empty()); - } - simulateUtility( - _functionName: string, - _args: any[], - to: AztecAddress, - authwits?: AuthWitness[], - from?: AztecAddress, - scopes?: AztecAddress[], - ): Promise { - expect(to).toEqual(this.address); - expect(from).toEqual(this.address); - expect(scopes).toEqual([this.address]); - expect(authwits).toEqual([]); - return Promise.resolve(new UtilitySimulationResult(10n)); - } - @memoize - async getPXEInfo(): Promise { - const protocolContracts = await Promise.all( - ProtocolContractsNames.map(async name => [name, await AztecAddress.random()]), - ); - return Promise.resolve({ - protocolContractAddresses: Object.fromEntries(protocolContracts) as ProtocolContractAddresses, - pxeVersion: '1.0', - }); - } - async getContractClassMetadata(id: Fr, includeArtifact: boolean = false): Promise { - expect(id).toBeInstanceOf(Fr); - const contractClass = await getContractClassFromArtifact(this.artifact); - return Promise.resolve({ - contractClass, - isContractClassPubliclyRegistered: true, - artifact: includeArtifact ? this.artifact : undefined, - }); - } - getContractMetadata(address: AztecAddress): Promise { - expect(address).toEqual(this.address); - return Promise.resolve({ - contractInstance: this.instance, - isContractInitialized: true, - isContractPublished: true, - }); - } - getPrivateEvents( - _contractAddress: AztecAddress, - _eventMetadata: EventMetadataDefinition, - from: number, - limit: number, - _recipients: AztecAddress[], - ): Promise { - expect(from).toBe(1); - expect(limit).toBe(1); - expect(_recipients[0]).toBeInstanceOf(AztecAddress); - return Promise.resolve([{ value: 1n } as T]); - } -} diff --git a/yarn-project/stdlib/src/interfaces/pxe.ts b/yarn-project/stdlib/src/interfaces/pxe.ts index 2aa47c6c3cf8..a14332f339fd 100644 --- a/yarn-project/stdlib/src/interfaces/pxe.ts +++ b/yarn-project/stdlib/src/interfaces/pxe.ts @@ -1,25 +1,21 @@ import type { Fr } from '@aztec/foundation/fields'; -import type { ApiSchemaFor, ZodFor } from '@aztec/foundation/schemas'; import { z } from 'zod'; -import { type AbiType, AbiTypeSchema, type ContractArtifact, ContractArtifactSchema } from '../abi/abi.js'; +import { type AbiType, AbiTypeSchema, type ContractArtifact } from '../abi/abi.js'; import type { EventSelector } from '../abi/event_selector.js'; import { AuthWitness } from '../auth_witness/auth_witness.js'; import type { AztecAddress } from '../aztec-address/index.js'; import { CompleteAddress, type ContractClassWithId, - ContractClassWithIdSchema, type ContractInstanceWithAddress, - ContractInstanceWithAddressSchema, type PartialAddress, type ProtocolContractAddresses, - ProtocolContractAddressesSchema, } from '../contract/index.js'; import { UniqueNote } from '../note/extended_note.js'; -import { type NotesFilter, NotesFilterSchema } from '../note/notes_filter.js'; -import { AbiDecodedSchema, optional, schemas } from '../schemas/schemas.js'; +import type { NotesFilter } from '../note/notes_filter.js'; +import { schemas } from '../schemas/schemas.js'; import { SimulationOverrides, TxExecutionRequest, TxSimulationResult } from '../tx/index.js'; import { TxProfileResult, UtilitySimulationResult } from '../tx/profiling.js'; import { TxProvingResult } from '../tx/proven_tx.js'; @@ -241,6 +237,11 @@ export interface PXE { numBlocks: number, recipients: AztecAddress[], ): Promise; + + /** + * Stops the PXE's job queue. + */ + stop(): Promise; } // docs:end:pxe-interface @@ -281,76 +282,3 @@ export interface ContractClassMetadata { isContractClassPubliclyRegistered: boolean; artifact?: ContractArtifact | undefined; } - -export const ContractMetadataSchema = z.object({ - contractInstance: z.union([ContractInstanceWithAddressSchema, z.undefined()]), - isContractInitialized: z.boolean(), - isContractPublished: z.boolean(), -}) satisfies ZodFor; - -export const ContractClassMetadataSchema = z.object({ - contractClass: z.union([ContractClassWithIdSchema, z.undefined()]), - isContractClassPubliclyRegistered: z.boolean(), - artifact: z.union([ContractArtifactSchema, z.undefined()]), -}) satisfies ZodFor; - -const PXEInfoSchema = z.object({ - pxeVersion: z.string(), - protocolContractAddresses: ProtocolContractAddressesSchema, -}) satisfies ZodFor; - -export const PXESchema: ApiSchemaFor = { - registerAccount: z.function().args(schemas.Fr, schemas.Fr).returns(CompleteAddress.schema), - getRegisteredAccounts: z.function().returns(z.array(CompleteAddress.schema)), - registerSender: z.function().args(schemas.AztecAddress).returns(schemas.AztecAddress), - getSenders: z.function().returns(z.array(schemas.AztecAddress)), - removeSender: z.function().args(schemas.AztecAddress).returns(z.void()), - registerContractClass: z.function().args(ContractArtifactSchema).returns(z.void()), - registerContract: z - .function() - .args(z.object({ instance: ContractInstanceWithAddressSchema, artifact: z.optional(ContractArtifactSchema) })) - .returns(z.void()), - updateContract: z.function().args(schemas.AztecAddress, ContractArtifactSchema).returns(z.void()), - getContracts: z.function().returns(z.array(schemas.AztecAddress)), - proveTx: z.function().args(TxExecutionRequest.schema).returns(TxProvingResult.schema), - profileTx: z - .function() - .args( - TxExecutionRequest.schema, - z.union([z.literal('gates'), z.literal('full'), z.literal('execution-steps')]), - optional(z.boolean()), - optional(schemas.AztecAddress), - ) - .returns(TxProfileResult.schema), - simulateTx: z - .function() - .args( - TxExecutionRequest.schema, - z.boolean(), - optional(z.boolean()), - optional(z.boolean()), - optional(SimulationOverrides.schema), - optional(z.array(schemas.AztecAddress)), - ) - .returns(TxSimulationResult.schema), - getNotes: z.function().args(NotesFilterSchema).returns(z.array(UniqueNote.schema)), - - simulateUtility: z - .function() - .args( - z.string(), - z.array(z.any()), - schemas.AztecAddress, - optional(z.array(AuthWitness.schema)), - optional(schemas.AztecAddress), - optional(z.array(schemas.AztecAddress)), - ) - .returns(UtilitySimulationResult.schema), - getPXEInfo: z.function().returns(PXEInfoSchema), - getContractMetadata: z.function().args(schemas.AztecAddress).returns(ContractMetadataSchema), - getContractClassMetadata: z.function().args(schemas.Fr, optional(z.boolean())).returns(ContractClassMetadataSchema), - getPrivateEvents: z - .function() - .args(schemas.AztecAddress, EventMetadataDefinitionSchema, z.number(), z.number(), z.array(schemas.AztecAddress)) - .returns(z.array(AbiDecodedSchema)), -}; diff --git a/yarn-project/test-wallet/package.json b/yarn-project/test-wallet/package.json index 53413412327c..8924ad2923f9 100644 --- a/yarn-project/test-wallet/package.json +++ b/yarn-project/test-wallet/package.json @@ -5,7 +5,8 @@ "type": "module", "exports": { ".": "./dest/index.js", - "./lazy": "./dest/lazy.js" + "./lazy": "./dest/lazy.js", + "./server": "./dest/server.js" }, "typedocOptions": { "entryPoints": [ @@ -66,6 +67,7 @@ "@aztec/entrypoints": "workspace:^", "@aztec/foundation": "workspace:^", "@aztec/noir-contracts.js": "workspace:^", + "@aztec/pxe": "workspace:^", "@aztec/stdlib": "workspace:^" }, "devDependencies": { diff --git a/yarn-project/test-wallet/src/index.ts b/yarn-project/test-wallet/src/index.ts index fbfdc7bcfbc4..75cb682f4deb 100644 --- a/yarn-project/test-wallet/src/index.ts +++ b/yarn-project/test-wallet/src/index.ts @@ -1,3 +1,3 @@ export { TestWallet } from './wallet/bundle.js'; export { type AccountData } from './wallet/test_wallet.js'; -export { deployFundedSchnorrAccounts } from './utils.js'; +export { deployFundedSchnorrAccounts, registerInitialSandboxAccountsInWallet } from './utils.js'; diff --git a/yarn-project/test-wallet/src/server.ts b/yarn-project/test-wallet/src/server.ts new file mode 100644 index 000000000000..38c0bac129d2 --- /dev/null +++ b/yarn-project/test-wallet/src/server.ts @@ -0,0 +1,3 @@ +export { TestWallet } from './wallet/server.js'; +export { type AccountData } from './wallet/test_wallet.js'; +export { deployFundedSchnorrAccounts } from './utils.js'; diff --git a/yarn-project/test-wallet/src/utils.ts b/yarn-project/test-wallet/src/utils.ts index 302520795b77..af024fd4ce26 100644 --- a/yarn-project/test-wallet/src/utils.ts +++ b/yarn-project/test-wallet/src/utils.ts @@ -1,5 +1,6 @@ import type { InitialAccountData } from '@aztec/accounts/testing'; -import type { WaitOpts } from '@aztec/aztec.js'; +import { getInitialTestAccountsData } from '@aztec/accounts/testing/lazy'; +import type { AztecAddress, WaitOpts } from '@aztec/aztec.js'; import type { BaseTestWallet } from './wallet/test_wallet.js'; @@ -26,3 +27,17 @@ export async function deployFundedSchnorrAccounts( } return accountManagers; } + +/** + * Registers the initial sandbox accounts in the wallet. + * @param wallet - Test wallet to use to register the accounts. + * @returns Addresses of the registered accounts. + */ +export async function registerInitialSandboxAccountsInWallet(wallet: BaseTestWallet): Promise { + const testAccounts = await getInitialTestAccountsData(); + return Promise.all( + testAccounts.map(async account => { + return (await wallet.createSchnorrAccount(account.secret, account.salt, account.signingKey)).getAddress(); + }), + ); +} diff --git a/yarn-project/test-wallet/src/wallet/bundle.ts b/yarn-project/test-wallet/src/wallet/bundle.ts index 2b4f1292ed72..be2176a81897 100644 --- a/yarn-project/test-wallet/src/wallet/bundle.ts +++ b/yarn-project/test-wallet/src/wallet/bundle.ts @@ -1,15 +1,43 @@ import { EcdsaKAccountContract, EcdsaRAccountContract } from '@aztec/accounts/ecdsa'; import { SchnorrAccountContract } from '@aztec/accounts/schnorr'; import { StubAccountContractArtifact, createStubAccount } from '@aztec/accounts/stub'; -import { AccountManager, type AztecAddress, Fq, Fr, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js'; +import { + AccountManager, + type AztecAddress, + type AztecNode, + Fq, + Fr, + getContractInstanceFromInstantiationParams, +} from '@aztec/aztec.js'; +import { + type PXECreationOptions, + type PXEServiceConfig, + createPXEService, + getPXEServiceConfig, +} from '@aztec/pxe/client/bundle'; import { deriveSigningKey } from '@aztec/stdlib/keys'; import { BaseTestWallet } from './test_wallet.js'; /** * A TestWallet implementation that loads the account contract artifacts eagerly + * Note that the only difference from `lazy` and `server` test wallets is that it uses the `createPXEService` function + * from the `pxe/client/bundle` package. */ export class TestWallet extends BaseTestWallet { + static async create( + node: AztecNode, + overridePXEServiceConfig?: Partial, + options: PXECreationOptions = { loggers: {} }, + ): Promise { + const pxeConfig = Object.assign(getPXEServiceConfig(), { + proverEnabled: overridePXEServiceConfig?.proverEnabled ?? false, + ...overridePXEServiceConfig, + }); + const pxe = await createPXEService(node, pxeConfig, options); + return new TestWallet(pxe, node); + } + createSchnorrAccount(secret: Fr, salt: Fr, signingKey?: Fq): Promise { signingKey = signingKey ?? deriveSigningKey(secret); const accountData = { diff --git a/yarn-project/test-wallet/src/wallet/lazy.ts b/yarn-project/test-wallet/src/wallet/lazy.ts index d51e528328bd..cfc1ad2b680a 100644 --- a/yarn-project/test-wallet/src/wallet/lazy.ts +++ b/yarn-project/test-wallet/src/wallet/lazy.ts @@ -1,15 +1,43 @@ import { EcdsaKAccountContract, EcdsaRAccountContract } from '@aztec/accounts/ecdsa/lazy'; import { SchnorrAccountContract } from '@aztec/accounts/schnorr/lazy'; import { createStubAccount, getStubAccountContractArtifact } from '@aztec/accounts/stub/lazy'; -import { AccountManager, type AztecAddress, Fq, Fr, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js'; +import { + AccountManager, + type AztecAddress, + type AztecNode, + Fq, + Fr, + getContractInstanceFromInstantiationParams, +} from '@aztec/aztec.js'; +import { + type PXECreationOptions, + type PXEServiceConfig, + createPXEService, + getPXEServiceConfig, +} from '@aztec/pxe/client/lazy'; import { deriveSigningKey } from '@aztec/stdlib/keys'; import { BaseTestWallet } from './test_wallet.js'; /** * A TestWallet implementation that loads the account contract artifacts lazily + * Note that the only difference from `server` and `bundle` test wallets is that it uses the `createPXEService` function + * from the `pxe/client/lazy` package. */ export class TestWallet extends BaseTestWallet { + static async create( + node: AztecNode, + overridePXEServiceConfig?: Partial, + options: PXECreationOptions = { loggers: {} }, + ): Promise { + const pxeConfig = Object.assign(getPXEServiceConfig(), { + proverEnabled: overridePXEServiceConfig?.proverEnabled ?? false, + ...overridePXEServiceConfig, + }); + const pxe = await createPXEService(node, pxeConfig, options); + return new TestWallet(pxe, node); + } + createSchnorrAccount(secret: Fr, salt: Fr, signingKey?: Fq): Promise { signingKey = signingKey ?? deriveSigningKey(secret); const accountData = { diff --git a/yarn-project/test-wallet/src/wallet/server.ts b/yarn-project/test-wallet/src/wallet/server.ts new file mode 100644 index 000000000000..28781a9592ec --- /dev/null +++ b/yarn-project/test-wallet/src/wallet/server.ts @@ -0,0 +1,87 @@ +import { EcdsaKAccountContract, EcdsaRAccountContract } from '@aztec/accounts/ecdsa'; +import { SchnorrAccountContract } from '@aztec/accounts/schnorr'; +import { StubAccountContractArtifact, createStubAccount } from '@aztec/accounts/stub'; +import { + AccountManager, + type AztecAddress, + type AztecNode, + Fq, + Fr, + getContractInstanceFromInstantiationParams, +} from '@aztec/aztec.js'; +import { + type PXECreationOptions, + type PXEServiceConfig, + createPXEService, + getPXEServiceConfig, +} from '@aztec/pxe/server'; +import { deriveSigningKey } from '@aztec/stdlib/keys'; + +import { BaseTestWallet } from './test_wallet.js'; + +/** + * A TestWallet implementation to be used in server settings (e.g. e2e tests). + * Note that the only difference from `lazy` and `bundle` test wallets is that it uses the `createPXEService` function + * from the `pxe/server` package. + */ +export class TestWallet extends BaseTestWallet { + static async create( + node: AztecNode, + overridePXEServiceConfig?: Partial, + options: PXECreationOptions = { loggers: {} }, + ): Promise { + const pxeConfig = Object.assign(getPXEServiceConfig(), { + proverEnabled: overridePXEServiceConfig?.proverEnabled ?? false, + ...overridePXEServiceConfig, + }); + const pxe = await createPXEService(node, pxeConfig, options); + return new TestWallet(pxe, node); + } + + createSchnorrAccount(secret: Fr, salt: Fr, signingKey?: Fq): Promise { + signingKey = signingKey ?? deriveSigningKey(secret); + const accountData = { + secret, + salt, + contract: new SchnorrAccountContract(signingKey), + }; + return this.createAccount(accountData); + } + + createECDSARAccount(secret: Fr, salt: Fr, signingKey: Buffer): Promise { + const accountData = { + secret, + salt, + contract: new EcdsaRAccountContract(signingKey), + }; + return this.createAccount(accountData); + } + + createECDSAKAccount(secret: Fr, salt: Fr, signingKey: Buffer): Promise { + const accountData = { + secret, + salt, + contract: new EcdsaKAccountContract(signingKey), + }; + return this.createAccount(accountData); + } + + async getFakeAccountDataFor(address: AztecAddress) { + const chainInfo = await this.getChainInfo(); + const originalAccount = await this.getAccountFromAddress(address); + const originalAddress = originalAccount.getCompleteAddress(); + const { contractInstance } = await this.pxe.getContractMetadata(originalAddress.address); + if (!contractInstance) { + throw new Error(`No contract instance found for address: ${originalAddress.address}`); + } + const stubAccount = createStubAccount(originalAddress, chainInfo); + const instance = await getContractInstanceFromInstantiationParams(StubAccountContractArtifact, { + salt: Fr.random(), + }); + return { + account: stubAccount, + instance, + artifact: StubAccountContractArtifact, + }; + } +} diff --git a/yarn-project/test-wallet/src/wallet/test_wallet.ts b/yarn-project/test-wallet/src/wallet/test_wallet.ts index 6ddf0df6f805..70bf0ed1e29a 100644 --- a/yarn-project/test-wallet/src/wallet/test_wallet.ts +++ b/yarn-project/test-wallet/src/wallet/test_wallet.ts @@ -216,4 +216,8 @@ export abstract class BaseTestWallet extends BaseWallet { getContracts(): Promise { return this.pxe.getContracts(); } + + stop(): Promise { + return this.pxe.stop(); + } } diff --git a/yarn-project/test-wallet/tsconfig.json b/yarn-project/test-wallet/tsconfig.json index 7e949788af9b..3f33f4fe5769 100644 --- a/yarn-project/test-wallet/tsconfig.json +++ b/yarn-project/test-wallet/tsconfig.json @@ -21,6 +21,9 @@ { "path": "../noir-contracts.js" }, + { + "path": "../pxe" + }, { "path": "../stdlib" } diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index e5ede5284d46..db994adcff98 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -249,7 +249,6 @@ __metadata: "@aztec/bot": "workspace:^" "@aztec/builder": "workspace:^" "@aztec/cli": "workspace:^" - "@aztec/cli-wallet": "workspace:^" "@aztec/constants": "workspace:^" "@aztec/entrypoints": "workspace:^" "@aztec/ethereum": "workspace:^" @@ -438,7 +437,7 @@ __metadata: languageName: unknown linkType: soft -"@aztec/cli-wallet@workspace:^, @aztec/cli-wallet@workspace:cli-wallet": +"@aztec/cli-wallet@workspace:cli-wallet": version: 0.0.0-use.local resolution: "@aztec/cli-wallet@workspace:cli-wallet" dependencies: @@ -1492,6 +1491,7 @@ __metadata: "@aztec/entrypoints": "workspace:^" "@aztec/foundation": "workspace:^" "@aztec/noir-contracts.js": "workspace:^" + "@aztec/pxe": "workspace:^" "@aztec/stdlib": "workspace:^" "@jest/globals": "npm:^30.0.0" "@types/jest": "npm:^30.0.0"