diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp index 688a63351cc..663042da858 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp @@ -360,7 +360,7 @@ WASM_EXPORT void abis__compute_contract_address_from_partial(uint8_t const* poin * @param constructor_hash_buf the hash of the contract constructor's verification key * @param output buffer that will contain the output. The serialized contract address. * See the link bellow for more details: - * https://github.com/AztecProtocol/aztec-packages/blob/janb/rpc-interface-cleanup/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys + * https://github.com/AztecProtocol/aztec-packages/blob/master/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys */ WASM_EXPORT void abis__compute_partial_address(uint8_t const* contract_address_salt_buf, uint8_t const* function_tree_root_buf, diff --git a/docs/src/code_examples/sandbox_example.ts b/docs/src/code_examples/sandbox_example.ts index f9be30abfab..cf6dcff2aca 100644 --- a/docs/src/code_examples/sandbox_example.ts +++ b/docs/src/code_examples/sandbox_example.ts @@ -1,5 +1,4 @@ // docs:start:index -import { PrivateTokenContract } from "@aztec/noir-contracts/types"; import { AztecRPC, L2BlockL2Logs, @@ -8,41 +7,39 @@ import { createDebugLogger, getSchnorrAccount, mustSucceedFetch, -} from "@aztec/aztec.js"; +} from '@aztec/aztec.js'; +import { PrivateTokenContract } from '@aztec/noir-contracts/types'; ////////////// CREATE THE CLIENT INTERFACE AND CONTACT THE SANDBOX ////////////// -const logger = createDebugLogger("private-token"); -const sandboxUrl = "http://localhost:8080"; +const logger = createDebugLogger('private-token'); +const sandboxUrl = 'http://localhost:8080'; const aztecRpc = createAztecRpcClient(sandboxUrl, mustSucceedFetch); const nodeInfo = await aztecRpc.getNodeInfo(); -logger("Aztec Sandbox Info ", nodeInfo); +logger('Aztec Sandbox Info ', nodeInfo); // docs:end:index // docs:start:Accounts ////////////// CREATE SOME ACCOUNTS WITH SCHNORR SIGNERS ////////////// // Creates new accounts using an account contract that verifies schnorr signatures // Returns once the deployment transactions have settled -const createSchnorrAccounts = async ( - numAccounts: number, - aztecRpc: AztecRPC -) => { +const createSchnorrAccounts = async (numAccounts: number, aztecRpc: AztecRPC) => { const accountManagers = Array(numAccounts) .fill(0) - .map((x) => + .map(x => getSchnorrAccount( aztecRpc, PrivateKey.random(), // encryption private key - PrivateKey.random() // signing private key - ) + PrivateKey.random(), // signing private key + ), ); return await Promise.all( - accountManagers.map(async (x) => { + accountManagers.map(async x => { await x.waitDeploy({}); return x; - }) + }), ); }; @@ -52,17 +49,15 @@ const accounts = await createSchnorrAccounts(2, aztecRpc); ////////////// VERIFY THE ACCOUNTS WERE CREATED SUCCESSFULLY ////////////// -const [alice, bob] = ( - await Promise.all(accounts.map((x) => x.getCompleteAddress())) -).map((x) => x.address); +const [alice, bob] = (await Promise.all(accounts.map(x => x.getCompleteAddress()))).map(x => x.address); // Verify that the accounts were deployed -const registeredAccounts = await aztecRpc.getAccounts(); +const registeredAccounts = (await aztecRpc.getAccounts()).map(x => x.address); for (const [account, name] of [ - [alice, "Alice"], - [bob, "Bob"], + [alice, 'Alice'], + [bob, 'Bob'], ] as const) { - if (registeredAccounts.find((acc) => acc.equals(account))) { + if (registeredAccounts.find(acc => acc.equals(account))) { logger(`Created ${name}'s account at ${account.toShortString()}`); continue; } @@ -76,23 +71,19 @@ for (const [account, name] of [ // Deploy a private token contract, create a contract abstraction object and link it to the owner's wallet // The contract's constructor takes 2 arguments, the initial supply and the owner of that initial supply const initialSupply = 1_000_000; -logger( - `Deploying private token contract minting an initial ${initialSupply} tokens to Alice...` -); +logger(`Deploying private token contract minting an initial ${initialSupply} tokens to Alice...`); const tokenContractTx = PrivateTokenContract.deploy( aztecRpc, initialSupply, // the initial supply - alice // the owner of the initial supply + alice, // the owner of the initial supply ).send(); // wait for the tx to settle await tokenContractTx.isMined(); const receipt = await tokenContractTx.getReceipt(); logger(`Transaction status is ${receipt.status}`); -const contractInfo = await aztecRpc.getContractInfo(receipt.contractAddress!); -if (contractInfo) { - logger( - `Contract successfully deployed at address ${receipt.contractAddress!.toShortString()}` - ); +const contractData = await aztecRpc.getContractData(receipt.contractAddress!); +if (contractData) { + logger(`Contract successfully deployed at address ${receipt.contractAddress!.toShortString()}`); } // docs:end:Deployment // docs:start:Logs @@ -105,7 +96,7 @@ const viewUnencryptedLogs = async () => { logger(`Retrieving unencrypted logs for block ${lastBlock}`); const logs = await aztecRpc.getUnencryptedLogs(lastBlock, 1); const unrolledLogs = L2BlockL2Logs.unrollLogs(logs); - const asciiLogs = unrolledLogs.map((log) => log.toString("ascii")); + const asciiLogs = unrolledLogs.map(log => log.toString('ascii')); logger(`Emitted logs: `, asciiLogs); }; await viewUnencryptedLogs(); @@ -116,28 +107,16 @@ await viewUnencryptedLogs(); ////////////// QUERYING THE TOKEN BALANCE FOR EACH ACCOUNT ////////////// // Create the contract abstraction and link to Alice's wallet for future signing -const tokenContractAlice = await PrivateTokenContract.create( - receipt.contractAddress!, - await accounts[0].getWallet() -); +const tokenContractAlice = await PrivateTokenContract.create(receipt.contractAddress!, await accounts[0].getWallet()); // Bob wants to mint some funds, the contract is already deployed, create an abstraction and link it his wallet -const tokenContractBob = await PrivateTokenContract.create( - receipt.contractAddress!, - await accounts[1].getWallet() -); +const tokenContractBob = await PrivateTokenContract.create(receipt.contractAddress!, await accounts[1].getWallet()); const checkBalances = async () => { // Check Alice's balance - logger( - `Alice's balance ${await tokenContractAlice.methods - .getBalance(alice) - .view()}` - ); + logger(`Alice's balance ${await tokenContractAlice.methods.getBalance(alice).view()}`); // Check Bob's balance - logger( - `Bob's balance ${await tokenContractBob.methods.getBalance(bob).view()}` - ); + logger(`Bob's balance ${await tokenContractBob.methods.getBalance(bob).view()}`); }; // Check the initial balances await checkBalances(); @@ -148,10 +127,7 @@ await checkBalances(); // We will now transfer tokens from ALice to Bob const transferQuantity = 543; logger(`Transferring ${transferQuantity} tokens from Alice to Bob...`); -await tokenContractAlice.methods - .transfer(transferQuantity, alice, bob) - .send() - .wait(); +await tokenContractAlice.methods.transfer(transferQuantity, alice, bob).send().wait(); // See if any logs were emitted await viewUnencryptedLogs(); diff --git a/yarn-project/acir-simulator/src/client/db_oracle.ts b/yarn-project/acir-simulator/src/client/db_oracle.ts index ac3c1fc940f..b46bb9678c8 100644 --- a/yarn-project/acir-simulator/src/client/db_oracle.ts +++ b/yarn-project/acir-simulator/src/client/db_oracle.ts @@ -1,4 +1,4 @@ -import { HistoricBlockData, PartialAddress, PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { CompleteAddress, HistoricBlockData, PrivateKey, PublicKey } from '@aztec/circuits.js'; import { FunctionAbi } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -72,11 +72,11 @@ export interface CommitmentDataOracleInputs { */ export interface DBOracle extends CommitmentsDB { /** - * Retrieve the public key associated to a given address. + * Retrieve the complete address associated to a given address. * @param address - Address to fetch the pubkey for. - * @returns A public key and the corresponding partial address, such that the hash of the two resolves to the input address. + * @returns A complete address associated with the input address. */ - getPublicKey(address: AztecAddress): Promise<[PublicKey, PartialAddress]>; + getCompleteAddress(address: AztecAddress): Promise; /** * Retrieve the secret key associated with a specific public key. diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 794313e2616..be3318b908e 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -1,6 +1,7 @@ import { CallContext, CircuitsWasm, + CompleteAddress, ContractDeploymentData, FieldsOf, FunctionData, @@ -15,20 +16,19 @@ import { import { computeCallStackItemHash, computeCommitmentNonce, - computeContractAddressFromPartial, computeSecretMessageHash, computeUniqueCommitment, computeVarArgsHash, siloCommitment, } from '@aztec/circuits.js/abis'; import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg'; -import { makeAddressWithPreimagesFromPrivateKey, makeContractDeploymentData } from '@aztec/circuits.js/factories'; +import { makeContractDeploymentData } from '@aztec/circuits.js/factories'; import { FunctionAbi, encodeArguments, generateFunctionSelector } from '@aztec/foundation/abi'; import { asyncMap } from '@aztec/foundation/async-map'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { Fr, Point } from '@aztec/foundation/fields'; +import { Fr } from '@aztec/foundation/fields'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { AppendOnlyTree, Pedersen, StandardTree, newTree } from '@aztec/merkle-tree'; import { @@ -196,24 +196,15 @@ describe('Private Execution test suite', () => { }; beforeEach(async () => { - const { - address: ownerAddress, - partialAddress: ownerPartialAddress, - publicKey: ownerPubKey, - } = await makeAddressWithPreimagesFromPrivateKey(ownerPk); - - const { - address: recipientAddress, - partialAddress: recipientPartialAddress, - publicKey: recipientPubKey, - } = await makeAddressWithPreimagesFromPrivateKey(recipientPk); - - owner = ownerAddress; - recipient = recipientAddress; - - oracle.getPublicKey.mockImplementation((address: AztecAddress) => { - if (address.equals(owner)) return Promise.resolve([ownerPubKey, ownerPartialAddress]); - if (address.equals(recipient)) return Promise.resolve([recipientPubKey, recipientPartialAddress]); + const ownerCompleteAddress = await CompleteAddress.fromPrivateKey(ownerPk); + const recipientCompleteAddress = await CompleteAddress.fromPrivateKey(recipientPk); + + owner = ownerCompleteAddress.address; + recipient = recipientCompleteAddress.address; + + oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { + if (address.equals(owner)) return Promise.resolve(ownerCompleteAddress); + if (address.equals(recipient)) return Promise.resolve(recipientCompleteAddress); throw new Error(`Unknown address ${address}`); }); @@ -435,24 +426,15 @@ describe('Private Execution test suite', () => { }; beforeEach(async () => { - const { - address: ownerAddress, - partialAddress: ownerPartialAddress, - publicKey: ownerPubKey, - } = await makeAddressWithPreimagesFromPrivateKey(ownerPk); - - const { - address: recipientAddress, - partialAddress: recipientPartialAddress, - publicKey: recipientPubKey, - } = await makeAddressWithPreimagesFromPrivateKey(recipientPk); - - owner = ownerAddress; - recipient = recipientAddress; - - oracle.getPublicKey.mockImplementation((address: AztecAddress) => { - if (address.equals(owner)) return Promise.resolve([ownerPubKey, ownerPartialAddress]); - if (address.equals(recipient)) return Promise.resolve([recipientPubKey, recipientPartialAddress]); + const ownerCompleteAddress = await CompleteAddress.fromPrivateKey(ownerPk); + const recipientCompleteAddress = await CompleteAddress.fromPrivateKey(recipientPk); + + owner = ownerCompleteAddress.address; + recipient = recipientCompleteAddress.address; + + oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { + if (address.equals(owner)) return Promise.resolve(ownerCompleteAddress); + if (address.equals(recipient)) return Promise.resolve(recipientCompleteAddress); throw new Error(`Unknown address ${address}`); }); @@ -694,10 +676,10 @@ describe('Private Execution test suite', () => { let recipient: AztecAddress; beforeEach(async () => { - const { address, partialAddress, publicKey } = await makeAddressWithPreimagesFromPrivateKey(recipientPk); - recipient = address; - oracle.getPublicKey.mockImplementation((address: AztecAddress) => { - if (address.equals(recipient)) return Promise.resolve([publicKey, partialAddress]); + const recipientCompleteAddress = await CompleteAddress.fromPrivateKey(recipientPk); + recipient = recipientCompleteAddress.address; + oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { + if (address.equals(recipient)) return Promise.resolve(recipientCompleteAddress); throw new Error(`Unknown address ${address}`); }); }); @@ -833,10 +815,12 @@ describe('Private Execution test suite', () => { let owner: AztecAddress; beforeEach(async () => { - const { address, partialAddress, publicKey } = await makeAddressWithPreimagesFromPrivateKey(ownerPk); - owner = address; - oracle.getPublicKey.mockImplementation((address: AztecAddress) => { - if (address.equals(owner)) return Promise.resolve([publicKey, partialAddress]); + const ownerCompleteAddress = await CompleteAddress.fromPrivateKey(ownerPk); + + owner = ownerCompleteAddress.address; + + oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { + if (address.equals(owner)) return Promise.resolve(ownerCompleteAddress); throw new Error(`Unknown address ${address}`); }); }); @@ -1017,13 +1001,11 @@ describe('Private Execution test suite', () => { abi.returnTypes = [{ kind: 'array', length: 2, type: { kind: 'field' } }]; // Generate a partial address, pubkey, and resulting address - const partialAddress = Fr.random(); - const pubKey = Point.random(); - const wasm = await CircuitsWasm.get(); - const address = computeContractAddressFromPartial(wasm, pubKey, partialAddress); - const args = [address]; + const completeAddress = await CompleteAddress.random(); + const args = [completeAddress.address]; + const pubKey = completeAddress.publicKey; - oracle.getPublicKey.mockResolvedValue([pubKey, partialAddress]); + oracle.getCompleteAddress.mockResolvedValue(completeAddress); const result = await runSimulator({ origin: AztecAddress.random(), abi, args }); expect(result.returnValues).toEqual([pubKey.x.value, pubKey.y.value]); }); diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index 03da34d109d..233490c52d6 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -70,8 +70,8 @@ export class PrivateFunctionExecution { getSecretKey: ([ownerX], [ownerY]) => this.context.getSecretKey(this.contractAddress, ownerX, ownerY), getPublicKey: async ([acvmAddress]) => { const address = frToAztecAddress(fromACVMField(acvmAddress)); - const [pubKey, partialAddress] = await this.context.db.getPublicKey(address); - return [pubKey.x, pubKey.y, partialAddress].map(toACVMField); + const { publicKey, partialAddress } = await this.context.db.getCompleteAddress(address); + return [publicKey.x, publicKey.y, partialAddress].map(toACVMField); }, getNotes: ([slot], sortBy, sortOrder, [limit], [offset], [returnSize]) => this.context.getNotes(this.contractAddress, slot, sortBy, sortOrder, +limit, +offset, +returnSize), diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts index 3e65e468505..868fadc6382 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts @@ -1,6 +1,4 @@ -import { CircuitsWasm, FunctionData, HistoricBlockData, PrivateKey } from '@aztec/circuits.js'; -import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis'; -import { Grumpkin } from '@aztec/circuits.js/barretenberg'; +import { CompleteAddress, FunctionData, HistoricBlockData, PrivateKey } from '@aztec/circuits.js'; import { encodeArguments } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -14,14 +12,9 @@ import { DBOracle } from './db_oracle.js'; import { AcirSimulator } from './simulator.js'; describe('Unconstrained Execution test suite', () => { - let bbWasm: CircuitsWasm; let oracle: ReturnType>; let acirSimulator: AcirSimulator; - beforeAll(async () => { - bbWasm = await CircuitsWasm.get(); - }); - beforeEach(() => { oracle = mock(); acirSimulator = new AcirSimulator(oracle); @@ -36,20 +29,12 @@ describe('Unconstrained Execution test suite', () => { return [new Fr(amount), owner, Fr.random()]; }; - const calculateAddress = (privateKey: PrivateKey) => { - const grumpkin = new Grumpkin(bbWasm); - const pubKey = grumpkin.mul(Grumpkin.generator, privateKey); - const partialAddress = Fr.random(); - const address = computeContractAddressFromPartial(bbWasm, pubKey, partialAddress); - return [address, partialAddress, pubKey] as const; - }; - - beforeEach(() => { - const [ownerAddress, ownerPartialAddress, ownerPubKey] = calculateAddress(ownerPk); - owner = ownerAddress; + beforeEach(async () => { + const ownerCompleteAddress = await CompleteAddress.fromPrivateKey(ownerPk); + owner = ownerCompleteAddress.address; - oracle.getPublicKey.mockImplementation((address: AztecAddress) => { - if (address.equals(owner)) return Promise.resolve([ownerPubKey, ownerPartialAddress]); + oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { + if (address.equals(owner)) return Promise.resolve(ownerCompleteAddress); throw new Error(`Unknown address ${address}`); }); }); diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts index b23ba07763a..bc5d36b3fe0 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts @@ -44,8 +44,8 @@ export class UnconstrainedFunctionExecution { getSecretKey: ([ownerX], [ownerY]) => this.context.getSecretKey(this.contractAddress, ownerX, ownerY), getPublicKey: async ([acvmAddress]) => { const address = frToAztecAddress(fromACVMField(acvmAddress)); - const [pubKey, partialAddress] = await this.context.db.getPublicKey(address); - return [pubKey.x, pubKey.y, partialAddress].map(toACVMField); + const { publicKey, partialAddress } = await this.context.db.getCompleteAddress(address); + return [publicKey.x, publicKey.y, partialAddress].map(toACVMField); }, getNotes: ([slot], sortBy, sortOrder, [limit], [offset], [returnSize]) => this.context.getNotes(this.contractAddress, slot, sortBy, sortOrder, +limit, +offset, +returnSize), diff --git a/yarn-project/aztec-cli/README.md b/yarn-project/aztec-cli/README.md index 7f7af031c01..a6992d657aa 100644 --- a/yarn-project/aztec-cli/README.md +++ b/yarn-project/aztec-cli/README.md @@ -236,15 +236,15 @@ Example usage: aztec-cli get-contract-data 0x123456789abcdef123456789abcdef12345678 ``` -### register-public-key +### register-recipient -Register an account's public key to the RPC server. +Register a recipient account on the RPC server (called recipient because we can only send notes to this account and not receive them via this RPC server). To read about how keys are generated and used, head to our docs [here](https://github.com/AztecProtocol/aztec-packages/blob/master/docs/docs/aztec/developer/wallet-providers/keys.md#addresses-partial-addresses-and-public-keys). Syntax: ```shell -aztec-cli register-public-key [options] +aztec-cli register-recipient [options] ``` Options: @@ -257,7 +257,7 @@ Options: Example usage: ```shell -aztec-cli register-public-key -p 0x20d9d93c4a9eb2b4bdb70ead07d28d1edb74bfd78443a8c36b098b024cd26f0e0647f5dbe3619453f42eb788c2beed0294c84676425047aadac23294605c4af9 -a 0x111fdc0f6bf831ca59f05863199762d643b782699d7ce6feaae40a923baf60af -pa 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed +aztec-cli register-recipient -p 0x20d9d93c4a9eb2b4bdb70ead07d28d1edb74bfd78443a8c36b098b024cd26f0e0647f5dbe3619453f42eb788c2beed0294c84676425047aadac23294605c4af9 -a 0x111fdc0f6bf831ca59f05863199762d643b782699d7ce6feaae40a923baf60af -pa 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed ``` ### get-accounts @@ -282,14 +282,14 @@ Example usage: aztec-cli get-accounts ``` -### get-account-public-key +### get-account -Gets an account's public key, given its Aztec address. +Gets an account given its Aztec address. Syntax: ```shell -aztec-cli get-account-public-key
[options] +aztec-cli get-account
[options] ``` - `address`: The Aztec address to get the public key for. @@ -303,7 +303,7 @@ This command retrieves and displays the public key of an account given its Aztec Example usage: ```shell -aztec-cli get-account-public-key 0x123456789abcdef123456789abcdef12345678 +aztec-cli get-account 0x123456789abcdef123456789abcdef12345678 ``` ### send diff --git a/yarn-project/aztec-cli/src/index.ts b/yarn-project/aztec-cli/src/index.ts index e98b5e10724..d2eaff4653d 100644 --- a/yarn-project/aztec-cli/src/index.ts +++ b/yarn-project/aztec-cli/src/index.ts @@ -15,7 +15,7 @@ import { StructType } from '@aztec/foundation/abi'; import { JsonStringify } from '@aztec/foundation/json-rpc'; import { createConsoleLogger, createDebugLogger } from '@aztec/foundation/log'; import { SchnorrAccountContractAbi } from '@aztec/noir-contracts/artifacts'; -import { ContractData, L2BlockL2Logs, PrivateKey, TxHash } from '@aztec/types'; +import { CompleteAddress, ContractData, L2BlockL2Logs, PrivateKey, TxHash } from '@aztec/types'; import { Command } from 'commander'; import { mnemonicToAccount } from 'viem/accounts'; @@ -254,8 +254,8 @@ async function main() { }); program - .command('register-public-key') - .description("Register an account's public key to the RPC server") + .command('register-recipient') + .description('Register a recipient in the Aztec RPC.') .option('-a, --address ', "The account's Aztec address.") .option('-p, --public-key ', 'The account public key.') .option('-pa, --partial-address ', 'The Aztec address to get the public key for') + .command('get-account') + .description('Gets an account given its Aztec address.') + .argument('
', 'The Aztec address to get account for') .option('-u, --rpc-url ', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080') .action(async (_address, options) => { const client = createAztecRpcClient(options.rpcUrl); const address = AztecAddress.fromString(_address); - const [pk, partialAddress] = await client.getPublicKeyAndPartialAddress(address); + const account = await client.getAccount(address); - if (!pk) { + if (!account) { log(`Unknown account ${_address}`); } else { - log(`Public Key: \n ${pk.toString()}\nPartial Address: ${partialAddress.toString()}\n`); + log(account.toReadableString()); + } + }); + + program + .command('get-recipients') + .description('Gets all the recipients stored in the Aztec RPC.') + .option('-u, --rpc-url ', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080') + .action(async (options: any) => { + const client = createAztecRpcClient(options.rpcUrl); + const recipients = await client.getRecipients(); + if (!recipients.length) { + log('No recipients found.'); + } else { + log(`Recipients found: \n`); + for (const recipient of recipients) { + log(recipient.toReadableString()); + } + } + }); + + program + .command('get-recipient') + .description('Gets a recipient given its Aztec address.') + .argument('
', 'The Aztec address to get recipient for') + .option('-u, --rpc-url ', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080') + .action(async (_address, options) => { + const client = createAztecRpcClient(options.rpcUrl); + const address = AztecAddress.fromString(_address); + const recipient = await client.getRecipient(address); + + if (!recipient) { + log(`Unknown recipient ${_address}`); + } else { + log(recipient.toReadableString()); } }); diff --git a/yarn-project/aztec-cli/src/utils.ts b/yarn-project/aztec-cli/src/utils.ts index 3c16ec7d437..3587cdabac1 100644 --- a/yarn-project/aztec-cli/src/utils.ts +++ b/yarn-project/aztec-cli/src/utils.ts @@ -9,7 +9,7 @@ import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts'; import { encodeArgs } from './cli_encoder.js'; /** - * Helper type to dynamically import contarcts. + * Helper type to dynamically import contracts. */ interface ArtifactsType { [key: string]: ContractAbi; @@ -105,9 +105,9 @@ export async function getTxSender(client: AztecRPC, _from?: string) { } else { const accounts = await client.getAccounts(); if (!accounts.length) { - throw new Error('No accounts found in Aztec RPC insance.'); + throw new Error('No accounts found in Aztec RPC instance.'); } - from = accounts[0]; + from = accounts[0].address; } return from; } diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts b/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts index 6359587c80e..ef0fe709462 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts @@ -2,6 +2,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; import { JsonRpcServer } from '@aztec/foundation/json-rpc/server'; import { + CompleteAddress, ContractData, ContractDataAndBytecode, ContractDeploymentTx, @@ -27,6 +28,7 @@ export function getHttpRpcServer(aztecRpcServer: AztecRPCServer): JsonRpcServer const generatedRpcServer = new JsonRpcServer( aztecRpcServer, { + CompleteAddress, AztecAddress, TxExecutionRequest, ContractData, diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.test.ts b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.test.ts index 901b53f63f3..0a672a468e5 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.test.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.test.ts @@ -1,71 +1,65 @@ -import { AztecAddress, CircuitsWasm, Fr, Point, PrivateKey } from '@aztec/circuits.js'; -import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis'; +import { AztecAddress, CompleteAddress, Fr } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { ConstantKeyPair, TestKeyStore } from '@aztec/key-store'; import { AztecNode } from '@aztec/types'; -import { MockProxy, mock } from 'jest-mock-extended'; +import { mock } from 'jest-mock-extended'; import { MemoryDB } from '../database/memory_db.js'; import { RpcServerConfig } from '../index.js'; import { AztecRPCServer } from './aztec_rpc_server.js'; describe('AztecRpcServer', function () { - let wasm: CircuitsWasm; - let keyStore: TestKeyStore; - let db: MemoryDB; - let node: MockProxy; let rpcServer: AztecRPCServer; beforeEach(async () => { - keyStore = new TestKeyStore(await Grumpkin.new()); - node = mock(); - db = new MemoryDB(); + const keyStore = new TestKeyStore(await Grumpkin.new()); + const node = mock(); + const db = new MemoryDB(); const config: RpcServerConfig = { l2BlockPollingIntervalMS: 100, }; rpcServer = new AztecRPCServer(keyStore, node, db, config); - wasm = await CircuitsWasm.get(); }); - it('registers a public key in the db when adding a new account', async () => { + it('registers an account and returns it as an account only and not as a recipient', async () => { const keyPair = ConstantKeyPair.random(await Grumpkin.new()); - const pubKey = keyPair.getPublicKey(); - const partialAddress = Fr.random(); - const address = computeContractAddressFromPartial(wasm, pubKey, partialAddress); + const completeAddress = await CompleteAddress.fromPrivateKey(await keyPair.getPrivateKey()); - await rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress); - expect(await db.getPublicKeyAndPartialAddress(address)).toEqual([pubKey, partialAddress]); + await rpcServer.registerAccount(await keyPair.getPrivateKey(), completeAddress); + const accounts = await rpcServer.getAccounts(); + const recipients = await rpcServer.getRecipients(); + expect(accounts).toEqual([completeAddress]); + expect(recipients).toEqual([]); }); - it('refuses to add an account with incorrect address for given partial address and privkey', async () => { - const privateKey = PrivateKey.random(); - const partialAddress = Fr.random(); - const address = AztecAddress.random(); + it('registers a recipient and returns it as a recipient only and not as an account', async () => { + const completeAddress = await CompleteAddress.random(); - await expect(rpcServer.addAccount(privateKey, address, partialAddress)).rejects.toThrowError(/cannot be derived/); + await rpcServer.registerRecipient(completeAddress); + const accounts = await rpcServer.getAccounts(); + const recipients = await rpcServer.getRecipients(); + expect(accounts).toEqual([]); + expect(recipients).toEqual([completeAddress]); }); - it('refuses to add an account with incorrect address for given partial address and pubkey', async () => { - const publicKey = Point.random(); - const partialAddress = Fr.random(); - const address = AztecAddress.random(); + it('cannot register the same account twice', async () => { + const keyPair = ConstantKeyPair.random(await Grumpkin.new()); + const completeAddress = await CompleteAddress.fromPrivateKey(await keyPair.getPrivateKey()); - await expect(rpcServer.addPublicKeyAndPartialAddress(address, publicKey, partialAddress)).rejects.toThrowError( - /cannot be derived/, + await rpcServer.registerAccount(await keyPair.getPrivateKey(), completeAddress); + await expect(async () => rpcServer.registerAccount(await keyPair.getPrivateKey(), completeAddress)).rejects.toThrow( + `Complete address corresponding to ${completeAddress.address} already exists`, ); }); - it('cannot add the same account twice', async () => { - const keyPair = ConstantKeyPair.random(await Grumpkin.new()); - const pubKey = keyPair.getPublicKey(); - const partialAddress = Fr.random(); - const address = computeContractAddressFromPartial(wasm, pubKey, partialAddress); + it('cannot register the same recipient twice', async () => { + const completeAddress = await CompleteAddress.random(); - await rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress); - await expect(async () => - rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress), - ).rejects.toThrow(`Account ${address} already exists`); + await rpcServer.registerRecipient(completeAddress); + await expect(() => rpcServer.registerRecipient(completeAddress)).rejects.toThrow( + `Complete address corresponding to ${completeAddress.address} already exists`, + ); }); it('throws when getting public storage for non-existent contract', async () => { diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts index af1ddbc6984..bdf4488a2ff 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts @@ -4,8 +4,7 @@ import { collectEnqueuedPublicFunctionCalls, collectUnencryptedLogs, } from '@aztec/acir-simulator'; -import { AztecAddress, CircuitsWasm, FunctionData, PartialAddress, PrivateKey, PublicKey } from '@aztec/circuits.js'; -import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis'; +import { AztecAddress, CompleteAddress, FunctionData, PrivateKey } from '@aztec/circuits.js'; import { encodeArguments } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; @@ -82,35 +81,55 @@ export class AztecRPCServer implements AztecRPC { this.log.info('Stopped'); } - public async addAccount(privKey: PrivateKey, address: AztecAddress, partialAddress: PartialAddress) { + public async registerAccount(privKey: PrivateKey, account: CompleteAddress) { const pubKey = this.keyStore.addAccount(privKey); - const wasm = await CircuitsWasm.get(); - const expectedAddress = computeContractAddressFromPartial(wasm, pubKey, partialAddress); - if (!expectedAddress.equals(address)) { - throw new Error( - `Address cannot be derived from pubkey and partial address (received ${address.toString()}, derived ${expectedAddress.toString()})`, - ); - } - await this.db.addPublicKeyAndPartialAddress(address, pubKey, partialAddress); + // TODO: Re-enable this check once https://github.com/AztecProtocol/aztec-packages/issues/1556 is solved + // if (!pubKey.equals(account.publicKey)) { + // throw new Error(`Public key mismatch: ${pubKey.toString()} != ${account.publicKey.toString()}`); + // } + await this.db.addCompleteAddress(account); this.synchroniser.addAccount(pubKey, this.keyStore); - this.log.info(`Added account ${address.toString()}`); - return address; } - public async addPublicKeyAndPartialAddress( - address: AztecAddress, - publicKey: PublicKey, - partialAddress: PartialAddress, - ): Promise { - const wasm = await CircuitsWasm.get(); - const expectedAddress = computeContractAddressFromPartial(wasm, publicKey, partialAddress); - if (!expectedAddress.equals(address)) { - throw new Error( - `Address cannot be derived from pubkey and partial address (received ${address.toString()}, derived ${expectedAddress.toString()})`, - ); + public async getAccounts(): Promise { + // Get complete addresses of both the recipients and the accounts + const addresses = await this.db.getCompleteAddresses(); + // Filter out the addresses not corresponding to accounts + const accountPubKeys = await this.keyStore.getAccounts(); + const accounts = addresses.filter(address => accountPubKeys.find(pubKey => pubKey.equals(address.publicKey))); + return accounts; + } + + public async getAccount(address: AztecAddress): Promise { + const result = await this.getAccounts(); + const account = result.find(r => r.address.equals(address)); + if (!account) { + throw new Error(`Unable to get complete address for address ${address.toString()}`); } - await this.db.addPublicKeyAndPartialAddress(address, publicKey, partialAddress); - this.log.info(`Added public key for ${address.toString()}`); + return Promise.resolve(account); + } + + public async registerRecipient(recipient: CompleteAddress): Promise { + await this.db.addCompleteAddress(recipient); + this.log.info(`Added recipient: ${recipient.toString()}`); + } + + public async getRecipients(): Promise { + // Get complete addresses of both the recipients and the accounts + const addresses = await this.db.getCompleteAddresses(); + // Filter out the addresses corresponding to accounts + const accountPubKeys = await this.keyStore.getAccounts(); + const recipients = addresses.filter(address => !accountPubKeys.find(pubKey => pubKey.equals(address.publicKey))); + return recipients; + } + + public async getRecipient(address: AztecAddress): Promise { + const result = await this.getRecipients(); + const recipient = result.find(r => r.address.equals(address)); + if (!recipient) { + throw new Error(`Unable to get complete address for address ${address.toString()}`); + } + return Promise.resolve(recipient); } public async addContracts(contracts: DeployedContract[]) { @@ -123,18 +142,6 @@ export class AztecRPCServer implements AztecRPC { } } - public async getAccounts(): Promise { - return await this.db.getAccounts(); - } - - public async getPublicKeyAndPartialAddress(address: AztecAddress): Promise<[PublicKey, PartialAddress]> { - const result = await this.db.getPublicKeyAndPartialAddress(address); - if (!result) { - throw new Error(`Unable to get public key for address ${address.toString()}`); - } - return Promise.resolve(result); - } - public async getPublicStorageAt(contract: AztecAddress, storageSlot: Fr) { if ((await this.getContractData(contract)) === undefined) { throw new Error(`Contract ${contract.toString()} is not deployed`); diff --git a/yarn-project/aztec-rpc/src/database/database.ts b/yarn-project/aztec-rpc/src/database/database.ts index 4a9a110c0fb..d1cae3100a8 100644 --- a/yarn-project/aztec-rpc/src/database/database.ts +++ b/yarn-project/aztec-rpc/src/database/database.ts @@ -1,4 +1,4 @@ -import { HistoricBlockData, PartialAddress } from '@aztec/circuits.js'; +import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { ContractDatabase, MerkleTreeId, PublicKey, TxHash } from '@aztec/types'; @@ -125,34 +125,22 @@ export interface Database extends ContractDatabase { setHistoricBlockData(historicBlockData: HistoricBlockData): Promise; /** - * Adds public key and partial address to a database. - * @param address - Address of the account to add public key and partial address for. - * @param publicKey - Public key of the corresponding user. - * @param partialAddress - The partially computed address of the account contract. - * @returns A Promise that resolves once the public key has been added to the database. + * Adds complete address to the database. + * @param address - The complete address to add. + * @returns Empty promise. */ - addPublicKeyAndPartialAddress( - address: AztecAddress, - publicKey: PublicKey, - partialAddress: PartialAddress, - ): Promise; + addCompleteAddress(address: CompleteAddress): Promise; /** - * Retrieve the public key and partial address associated with an address. - * Throws an error if the account is not found in the key store. - * - * @param address - The AztecAddress instance representing the account to get public key and partial address for. - * @returns A Promise resolving to the PublicKey instance representing the public key. - * @remarks The public key and partial address form a preimage of a contract address. See - * https://github.com/AztecProtocol/aztec-packages/blob/janb/rpc-interface-cleanup/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys + * Retrieves the complete address corresponding to the provided aztec address. + * @param address - The aztec address of the complete address contract. + * @returns A promise that resolves to a CompleteAddress instance if the address is found, or undefined if not found. */ - getPublicKeyAndPartialAddress(address: AztecAddress): Promise<[PublicKey, PartialAddress] | undefined>; + getCompleteAddress(address: AztecAddress): Promise; /** - * Retrieves the list of Aztec addresses added to this database - * The addresses are returned as a promise that resolves to an array of AztecAddress objects. - * + * Retrieves the list of complete address added to this database * @returns A promise that resolves to an array of AztecAddress instances. */ - getAccounts(): Promise; + getCompleteAddresses(): Promise; } diff --git a/yarn-project/aztec-rpc/src/database/memory_db.ts b/yarn-project/aztec-rpc/src/database/memory_db.ts index 8171029cfa6..c6b213159de 100644 --- a/yarn-project/aztec-rpc/src/database/memory_db.ts +++ b/yarn-project/aztec-rpc/src/database/memory_db.ts @@ -1,4 +1,4 @@ -import { HistoricBlockData, PartialAddress } from '@aztec/circuits.js'; +import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -20,7 +20,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { private noteSpendingInfoTable: NoteSpendingInfoDao[] = []; private treeRoots: Record | undefined; private globalVariablesHash: Fr | undefined; - private publicKeysAndPartialAddresses: Map = new Map(); + private addresses: CompleteAddress[] = []; constructor(logSuffix?: string) { super(createDebugLogger(logSuffix ? 'aztec:memory_db_' + logSuffix : 'aztec:memory_db')); @@ -121,24 +121,23 @@ export class MemoryDB extends MemoryContractDatabase implements Database { }); } - addPublicKeyAndPartialAddress( - address: AztecAddress, - publicKey: PublicKey, - partialAddress: PartialAddress, - ): Promise { - if (this.publicKeysAndPartialAddresses.has(address.toBigInt())) { - throw new Error(`Account ${address} already exists`); + public addCompleteAddress(completeAddress: CompleteAddress): Promise { + const accountIndex = this.addresses.findIndex(r => r.address.equals(completeAddress.address)); + if (accountIndex !== -1) { + throw new Error( + `Complete address corresponding to ${completeAddress.address.toString()} already exists in memory database`, + ); } - this.publicKeysAndPartialAddresses.set(address.toBigInt(), [publicKey, partialAddress]); + this.addresses.push(completeAddress); return Promise.resolve(); } - getPublicKeyAndPartialAddress(address: AztecAddress): Promise<[PublicKey, Fr] | undefined> { - return Promise.resolve(this.publicKeysAndPartialAddresses.get(address.toBigInt())); + public getCompleteAddress(address: AztecAddress): Promise { + const recipient = this.addresses.find(r => r.address.equals(address)); + return Promise.resolve(recipient); } - getAccounts(): Promise { - const addresses = Array.from(this.publicKeysAndPartialAddresses.keys()); - return Promise.resolve(addresses.map(AztecAddress.fromBigInt)); + public getCompleteAddresses(): Promise { + return Promise.resolve(this.addresses); } } diff --git a/yarn-project/aztec-rpc/src/simulator_oracle/index.ts b/yarn-project/aztec-rpc/src/simulator_oracle/index.ts index 3995512a6c5..1d7fd51a26f 100644 --- a/yarn-project/aztec-rpc/src/simulator_oracle/index.ts +++ b/yarn-project/aztec-rpc/src/simulator_oracle/index.ts @@ -2,10 +2,10 @@ import { CommitmentDataOracleInputs, DBOracle, MessageLoadOracleInputs } from '@ import { AztecAddress, CircuitsWasm, + CompleteAddress, EthAddress, Fr, HistoricBlockData, - PartialAddress, PrivateKey, PublicKey, } from '@aztec/circuits.js'; @@ -32,13 +32,13 @@ export class SimulatorOracle implements DBOracle { return this.keyStore.getAccountPrivateKey(pubKey); } - async getPublicKey(address: AztecAddress): Promise<[PublicKey, PartialAddress]> { - const result = await this.db.getPublicKeyAndPartialAddress(address); - if (!result) + async getCompleteAddress(address: AztecAddress): Promise { + const completeAddress = await this.db.getCompleteAddress(address); + if (!completeAddress) throw new Error( - `Unknown public key for address ${address.toString()}. Add public key to Aztec RPC server by calling server.addPublicKeyAndPartialAddress(...)`, + `Unknown complete address for address ${address.toString()}. Add the information to Aztec RPC server by calling server.registerRecipient(...) or server.registerAccount(...)`, ); - return result; + return completeAddress; } async getNotes(contractAddress: AztecAddress, storageSlot: Fr) { diff --git a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts index 0b0e444dace..8dcc3942339 100644 --- a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts +++ b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts @@ -1,4 +1,4 @@ -import { AztecAddress, Fr, HistoricBlockData, PrivateKey } from '@aztec/circuits.js'; +import { CompleteAddress, Fr, HistoricBlockData, PrivateKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { TestKeyStore } from '@aztec/key-store'; import { AztecNode, L2Block, MerkleTreeId } from '@aztec/types'; @@ -103,17 +103,17 @@ describe('Synchroniser', () => { // Manually adding account to database so that we can call synchroniser.isAccountStateSynchronised const keyStore = new TestKeyStore(await Grumpkin.new()); - keyStore.addAccount(PrivateKey.random()); - const pubKey = (await keyStore.getAccounts())[0]; - const address = AztecAddress.random(); - await database.addPublicKeyAndPartialAddress(address, pubKey, new Fr(0)); + const privateKey = PrivateKey.random(); + keyStore.addAccount(privateKey); + const completeAddress = await CompleteAddress.fromPrivateKey(privateKey); + await database.addCompleteAddress(completeAddress); // Add the account which will add the note processor to the synchroniser - synchroniser.addAccount(pubKey, keyStore); + synchroniser.addAccount(completeAddress.publicKey, keyStore); await synchroniser.workNoteProcessorCatchUp(); - expect(await synchroniser.isAccountStateSynchronised(address)).toBe(true); + expect(await synchroniser.isAccountStateSynchronised(completeAddress.address)).toBe(true); }); }); diff --git a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts index a7e1d32006c..140d757a7f1 100644 --- a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts +++ b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts @@ -251,12 +251,11 @@ export class Synchroniser { * retrieved information from contracts might be old/stale (e.g. old token balance). */ public async isAccountStateSynchronised(account: AztecAddress) { - const result = await this.db.getPublicKeyAndPartialAddress(account); - if (!result) { + const completeAddress = await this.db.getCompleteAddress(account); + if (!completeAddress) { return false; } - const publicKey = result[0]; - const processor = this.noteProcessors.find(x => x.publicKey.equals(publicKey)); + const processor = this.noteProcessors.find(x => x.publicKey.equals(completeAddress.publicKey)); if (!processor) { return false; } diff --git a/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts b/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts index 1d831149a2b..338ecd1cbdd 100644 --- a/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts +++ b/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts @@ -48,37 +48,37 @@ async function main() { wallet = await createAccounts(aztecRpcClient, SchnorrSingleKeyAccountContractAbi, privateKey, Fr.random(), 2); const accounts = await aztecRpcClient.getAccounts(); - const [ownerAddress, address2] = accounts; + const [owner, account2] = accounts; logger(`Created ${accounts.length} accounts`); - logger(`Created Owner account ${ownerAddress.toString()}`); + logger(`Created Owner account ${owner.toString()}`); - const zkContract = await deployZKContract(ownerAddress); - const [balance1] = await zkContract.methods.getBalance(ownerAddress).view({ from: ownerAddress }); + const zkContract = await deployZKContract(owner.address); + const [balance1] = await zkContract.methods.getBalance(owner.address).view({ from: owner.address }); logger(`Initial owner balance: ${balance1}`); // Mint more tokens logger(`Minting ${SECONDARY_AMOUNT} more coins`); - const mintTx = zkContract.methods.mint(SECONDARY_AMOUNT, ownerAddress).send({ origin: ownerAddress }); + const mintTx = zkContract.methods.mint(SECONDARY_AMOUNT, owner.address).send({ origin: owner.address }); await mintTx.isMined({ interval: 0.5 }); - const balanceAfterMint = await getBalance(zkContract, ownerAddress); + const balanceAfterMint = await getBalance(zkContract, owner.address); logger(`Owner's balance is now: ${balanceAfterMint}`); // Perform a transfer logger(`Transferring ${SECONDARY_AMOUNT} tokens from owner to another account.`); const transferTx = zkContract.methods - .transfer(SECONDARY_AMOUNT, ownerAddress, address2) - .send({ origin: ownerAddress }); + .transfer(SECONDARY_AMOUNT, owner.address, account2.address) + .send({ origin: owner.address }); await transferTx.isMined({ interval: 0.5 }); - const balanceAfterTransfer = await getBalance(zkContract, ownerAddress); - const receiverBalance = await getBalance(zkContract, address2); + const balanceAfterTransfer = await getBalance(zkContract, owner.address); + const receiverBalance = await getBalance(zkContract, account2.address); logger(`Owner's balance is now ${balanceAfterTransfer}`); logger(`The transfer receiver's balance is ${receiverBalance}`); } main() .then(() => { - logger('Finished running successfuly.'); + logger('Finished running successfully.'); process.exit(0); }) .catch(err => { diff --git a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts index 66c61b233fe..bb98e700123 100644 --- a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts +++ b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts @@ -172,7 +172,7 @@ async function main() { const accounts = await wallet.getAccounts(); const [owner, receiver] = accounts; - const result = await deployAllContracts(owner); + const result = await deployAllContracts(owner.address); const { daiL2Contract, daiContract, @@ -215,14 +215,14 @@ async function main() { await delay(5000); // send a transfer tx to force through rollup with the message included const transferAmount = 1n; - await transferWethOnL2(aztecRpcClient, wethL2Contract, owner, receiver, transferAmount); + await transferWethOnL2(aztecRpcClient, wethL2Contract, owner.address, receiver.address, transferAmount); // 3. Claim WETH on L2 logger('Minting weth on L2'); // Call the mint tokens function on the noir contract const consumptionTx = wethL2Contract.methods - .mint(wethAmountToBridge, owner, messageKey, secret, ethAccount.toField()) - .send({ origin: owner }); + .mint(wethAmountToBridge, owner.address, messageKey, secret, ethAccount.toField()) + .send({ origin: owner.address }); await consumptionTx.isMined({ interval: 0.5 }); const consumptionReceipt = await consumptionTx.getReceipt(); // expect(consumptionReceipt.status).toBe(TxStatus.MINED); @@ -230,8 +230,8 @@ async function main() { // await expectBalanceOnL2(ownerAddress, wethAmountToBridge + initialBalance - transferAmount, wethL2Contract); // Store balances - const wethBalanceBeforeSwap = await getL2BalanceOf(aztecRpcClient, owner, wethL2Contract); - const daiBalanceBeforeSwap = await getL2BalanceOf(aztecRpcClient, owner, daiL2Contract); + const wethBalanceBeforeSwap = await getL2BalanceOf(aztecRpcClient, owner.address, wethL2Contract); + const daiBalanceBeforeSwap = await getL2BalanceOf(aztecRpcClient, owner.address, daiL2Contract); // 4. Send L2 to L1 message to withdraw funds and another message to swap assets. logger('Send L2 tx to withdraw WETH to uniswap portal and send message to swap assets on L1'); @@ -247,21 +247,21 @@ async function main() { new Fr(3000), daiL2Contract.address.toField(), new Fr(minimumOutputAmount), - owner, - owner, + owner.address, + owner.address, secretHash, new Fr(2 ** 32 - 1), ethAccount.toField(), ethAccount.toField(), ) - .send({ origin: owner }); + .send({ origin: owner.address }); await withdrawTx.isMined({ interval: 0.5 }); const withdrawReceipt = await withdrawTx.getReceipt(); // expect(withdrawReceipt.status).toBe(TxStatus.MINED); logger(`Withdraw receipt status: ${withdrawReceipt.status} should be ${TxStatus.MINED}`); - // check weth balance of owner on L2 (we first briedged `wethAmountToBridge` into L2 and now withdrew it!) - await logExpectedBalanceOnL2(aztecRpcClient, owner, INITIAL_BALANCE - transferAmount, wethL2Contract); + // check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!) + await logExpectedBalanceOnL2(aztecRpcClient, owner.address, INITIAL_BALANCE - transferAmount, wethL2Contract); // 5. Consume L2 to L1 message by calling uniswapPortal.swap() logger('Execute withdraw and swap on the uniswapPortal!'); @@ -273,7 +273,7 @@ async function main() { 3000, daiTokenPortalAddress.toString(), minimumOutputAmount, - owner.toString(), + owner.address.toString(), secretString, deadline, ethAccount.toString(), @@ -298,22 +298,27 @@ async function main() { // Wait for the archiver to process the message await delay(5000); // send a transfer tx to force through rollup with the message included - await transferWethOnL2(aztecRpcClient, wethL2Contract, owner, receiver, transferAmount); + await transferWethOnL2(aztecRpcClient, wethL2Contract, owner.address, receiver.address, transferAmount); // 6. claim dai on L2 logger('Consuming messages to mint dai on L2'); // Call the mint tokens function on the noir contract const daiMintTx = daiL2Contract.methods - .mint(daiAmountToBridge, owner, depositDaiMessageKey, secret, ethAccount.toField()) - .send({ origin: owner }); + .mint(daiAmountToBridge, owner.address, depositDaiMessageKey, secret, ethAccount.toField()) + .send({ origin: owner.address }); await daiMintTx.isMined({ interval: 0.5 }); const daiMintTxReceipt = await daiMintTx.getReceipt(); // expect(daiMintTxReceipt.status).toBe(TxStatus.MINED); logger(`DAI mint TX status: ${daiMintTxReceipt.status} should be ${TxStatus.MINED}`); - await logExpectedBalanceOnL2(aztecRpcClient, owner, INITIAL_BALANCE + BigInt(daiAmountToBridge), daiL2Contract); + await logExpectedBalanceOnL2( + aztecRpcClient, + owner.address, + INITIAL_BALANCE + BigInt(daiAmountToBridge), + daiL2Contract, + ); - const wethBalanceAfterSwap = await getL2BalanceOf(aztecRpcClient, owner, wethL2Contract); - const daiBalanceAfterSwap = await getL2BalanceOf(aztecRpcClient, owner, daiL2Contract); + const wethBalanceAfterSwap = await getL2BalanceOf(aztecRpcClient, owner.address, wethL2Contract); + const daiBalanceAfterSwap = await getL2BalanceOf(aztecRpcClient, owner.address, daiL2Contract); logger('WETH balance before swap: ', wethBalanceBeforeSwap.toString()); logger('DAI balance before swap : ', daiBalanceBeforeSwap.toString()); diff --git a/yarn-project/aztec-sandbox/src/index.ts b/yarn-project/aztec-sandbox/src/index.ts index fcadd02815f..7edfbc5fdce 100644 --- a/yarn-project/aztec-sandbox/src/index.ts +++ b/yarn-project/aztec-sandbox/src/index.ts @@ -98,12 +98,12 @@ async function main() { const registeredAccounts = await aztecRpcServer.getAccounts(); for (const account of accounts) { - const completedAddress = await account.account.getCompleteAddress(); - if (registeredAccounts.find(a => a.equals(completedAddress.address))) { - accountStrings.push(` Address: ${completedAddress.address.toString()}\n`); - accountStrings.push(` Partial Address: ${completedAddress.partialAddress.toString()}\n`); + const completeAddress = await account.account.getCompleteAddress(); + if (registeredAccounts.find(a => a.equals(completeAddress))) { + accountStrings.push(` Address: ${completeAddress.address.toString()}\n`); + accountStrings.push(` Partial Address: ${completeAddress.partialAddress.toString()}\n`); accountStrings.push(` Private Key: ${account.privateKey.toString()}\n`); - accountStrings.push(` Public Key: ${completedAddress.publicKey.toString()}\n\n`); + accountStrings.push(` Public Key: ${completeAddress.publicKey.toString()}\n\n`); } } logger.info(`${splash}\n${github}\n\n`.concat(...accountStrings)); diff --git a/yarn-project/aztec.js/src/account/account.ts b/yarn-project/aztec.js/src/account/account.ts index 60b1174bf41..70f27e5df24 100644 --- a/yarn-project/aztec.js/src/account/account.ts +++ b/yarn-project/aztec.js/src/account/account.ts @@ -1,8 +1,7 @@ import { Fr, PublicKey, getContractDeploymentInfo } from '@aztec/circuits.js'; -import { AztecRPC, PrivateKey } from '@aztec/types'; +import { AztecRPC, CompleteAddress, PrivateKey } from '@aztec/types'; import { AccountWallet, ContractDeployer, DeployMethod, WaitOpts, generatePublicKey } from '../index.js'; -import { CompleteAddress, isCompleteAddress } from './complete_address.js'; import { DeployAccountSentTx } from './deploy_account_sent_tx.js'; import { AccountContract, Entrypoint, Salt } from './index.js'; @@ -24,7 +23,7 @@ export class Account { private accountContract: AccountContract, saltOrAddress?: Salt | CompleteAddress, ) { - if (isCompleteAddress(saltOrAddress)) { + if (saltOrAddress instanceof CompleteAddress) { this.completeAddress = saltOrAddress; } else { this.salt = saltOrAddress ? new Fr(saltOrAddress) : Fr.random(); @@ -56,12 +55,13 @@ export class Account { public async getCompleteAddress(): Promise { if (!this.completeAddress) { const encryptionPublicKey = await generatePublicKey(this.encryptionPrivateKey); - this.completeAddress = await getContractDeploymentInfo( + const contractDeploymentInfo = await getContractDeploymentInfo( this.accountContract.getContractAbi(), await this.accountContract.getDeploymentArgs(), this.salt!, encryptionPublicKey, ); + this.completeAddress = contractDeploymentInfo.completeAddress; } return this.completeAddress; } @@ -83,8 +83,8 @@ export class Account { * @returns A Wallet instance. */ public async register(): Promise { - const { address, partialAddress } = await this.getCompleteAddress(); - await this.rpc.addAccount(this.encryptionPrivateKey, address, partialAddress); + const completeAddress = await this.getCompleteAddress(); + await this.rpc.registerAccount(this.encryptionPrivateKey, completeAddress); return this.getWallet(); } diff --git a/yarn-project/aztec.js/src/account/complete_address.ts b/yarn-project/aztec.js/src/account/complete_address.ts deleted file mode 100644 index adaba9a16a0..00000000000 --- a/yarn-project/aztec.js/src/account/complete_address.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { AztecAddress, PartialAddress, PublicKey } from '@aztec/circuits.js'; - -/** Address and preimages associated with an account. */ -export type CompleteAddress = { - /** Address of an account. Derived from the partial address and public key. */ - address: AztecAddress; - /** Partial address of the account. Required for deriving the address from the encryption public key. */ - partialAddress: PartialAddress; - /** Encryption public key associated with this address. */ - publicKey: PublicKey; -}; - -/** Returns whether the argument looks like a CompleteAddress. */ -export function isCompleteAddress(obj: any): obj is CompleteAddress { - if (!obj) return false; - const maybe = obj as CompleteAddress; - return !!maybe.address && !!maybe.partialAddress && !!maybe.publicKey; -} diff --git a/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts b/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts index 11ea1931ca7..03dc5cce64e 100644 --- a/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts @@ -1,9 +1,8 @@ import { Ecdsa } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; -import { NodeInfo, PrivateKey } from '@aztec/types'; +import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; import EcdsaAccountContractAbi from '../../abis/ecdsa_account_contract.json' assert { type: 'json' }; -import { CompleteAddress } from '../complete_address.js'; import { StoredKeyAccountEntrypoint } from '../entrypoint/stored_key_account_entrypoint.js'; import { AccountContract } from './index.js'; diff --git a/yarn-project/aztec.js/src/account/contract/index.ts b/yarn-project/aztec.js/src/account/contract/index.ts index 6f267ff33d9..fffb64f3161 100644 --- a/yarn-project/aztec.js/src/account/contract/index.ts +++ b/yarn-project/aztec.js/src/account/contract/index.ts @@ -1,8 +1,7 @@ import { ContractAbi } from '@aztec/foundation/abi'; -import { NodeInfo } from '@aztec/types'; +import { CompleteAddress, NodeInfo } from '@aztec/types'; import { Entrypoint } from '../index.js'; -import { CompleteAddress } from './../complete_address.js'; export * from './ecdsa_account_contract.js'; export * from './schnorr_account_contract.js'; diff --git a/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts b/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts index e38b98e79b1..a8e3b9f4586 100644 --- a/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts @@ -1,9 +1,8 @@ import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; -import { NodeInfo, PrivateKey } from '@aztec/types'; +import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; import SchnorrAccountContractAbi from '../../abis/schnorr_account_contract.json' assert { type: 'json' }; -import { CompleteAddress } from '../complete_address.js'; import { StoredKeyAccountEntrypoint } from '../entrypoint/stored_key_account_entrypoint.js'; import { AccountContract } from './index.js'; diff --git a/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts b/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts index f886ad52db6..c47574bb3a5 100644 --- a/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts @@ -1,9 +1,8 @@ import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; -import { NodeInfo, PrivateKey } from '@aztec/types'; +import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; import SchnorrSingleKeyAccountContractAbi from '../../abis/schnorr_single_key_account_contract.json' assert { type: 'json' }; -import { CompleteAddress } from '../complete_address.js'; import { SingleKeyAccountEntrypoint } from '../entrypoint/single_key_account_entrypoint.js'; import { AccountContract } from './index.js'; diff --git a/yarn-project/aztec.js/src/account/index.ts b/yarn-project/aztec.js/src/account/index.ts index 666dd7249ac..6794922ac68 100644 --- a/yarn-project/aztec.js/src/account/index.ts +++ b/yarn-project/aztec.js/src/account/index.ts @@ -1,8 +1,7 @@ -import { AztecRPC, PrivateKey } from '@aztec/types'; +import { AztecRPC, CompleteAddress, PrivateKey } from '@aztec/types'; import { AccountContract, AccountWallet, AztecAddress, Fr } from '../index.js'; import { Account } from './account.js'; -import { CompleteAddress } from './complete_address.js'; import { EcdsaAccountContract } from './contract/ecdsa_account_contract.js'; import { SchnorrAccountContract } from './contract/schnorr_account_contract.js'; import { SingleKeyAccountContract } from './contract/single_key_account_contract.js'; @@ -93,9 +92,11 @@ export async function getWallet( address: AztecAddress, accountContract: AccountContract, ): Promise { - const [publicKey, partialAddress] = await rpc.getPublicKeyAndPartialAddress(address); + const completeAddress = await rpc.getAccount(address); + if (!completeAddress) { + throw new Error(`Account ${address} not found`); + } const nodeInfo = await rpc.getNodeInfo(); - const completeAddress: CompleteAddress = { publicKey, partialAddress, address }; const entrypoint = await accountContract.getEntrypoint(completeAddress, nodeInfo); return new AccountWallet(rpc, entrypoint, completeAddress); } diff --git a/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts b/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts index 5429fe7009e..5dcd4d4610b 100644 --- a/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts +++ b/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts @@ -1,4 +1,4 @@ -import { AztecAddress, EthAddress, Fr, Point, PrivateKey } from '@aztec/circuits.js'; +import { AztecAddress, CompleteAddress, EthAddress, Fr, Point, PrivateKey } from '@aztec/circuits.js'; import { createJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rpc/client'; import { AztecRPC, @@ -18,6 +18,7 @@ export const createAztecRpcClient = (url: string, fetch = defaultFetch): AztecRP createJsonRpcClient( url, { + CompleteAddress, AztecAddress, TxExecutionRequest, ContractData, diff --git a/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts b/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts index 6a71a3490a4..bd01275174b 100644 --- a/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts +++ b/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts @@ -1,4 +1,4 @@ -import { AztecAddress, CircuitsWasm, Fr, PartialAddress, PrivateKey, PublicKey, TxContext } from '@aztec/circuits.js'; +import { AztecAddress, CircuitsWasm, Fr, PrivateKey, TxContext } from '@aztec/circuits.js'; import { AztecRPC, ContractData, @@ -31,19 +31,24 @@ export abstract class BaseWallet implements Wallet { abstract createTxExecutionRequest(execs: FunctionCall[], opts?: CreateTxRequestOpts): Promise; - addAccount(privKey: PrivateKey, address: AztecAddress, partialAddress: Fr): Promise { - return this.rpc.addAccount(privKey, address, partialAddress); + registerAccount(privKey: PrivateKey, completeAddress: CompleteAddress): Promise { + return this.rpc.registerAccount(privKey, completeAddress); } - addPublicKeyAndPartialAddress( - address: AztecAddress, - publicKey: PublicKey, - partialAddress: PartialAddress, - ): Promise { - return this.rpc.addPublicKeyAndPartialAddress(address, publicKey, partialAddress); + registerRecipient(account: CompleteAddress): Promise { + return this.rpc.registerRecipient(account); } - getAccounts(): Promise { + getAccounts(): Promise { return this.rpc.getAccounts(); } + getAccount(address: AztecAddress): Promise { + return this.rpc.getAccount(address); + } + getRecipients(): Promise { + return this.rpc.getRecipients(); + } + getRecipient(address: AztecAddress): Promise { + return this.rpc.getRecipient(address); + } addContracts(contracts: DeployedContract[]): Promise { return this.rpc.addContracts(contracts); } @@ -77,9 +82,6 @@ export abstract class BaseWallet implements Wallet { getNodeInfo(): Promise { return this.rpc.getNodeInfo(); } - getPublicKeyAndPartialAddress(address: AztecAddress): Promise<[PublicKey, PartialAddress]> { - return this.rpc.getPublicKeyAndPartialAddress(address); - } isGlobalStateSynchronised() { return this.rpc.isGlobalStateSynchronised(); } diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index 188bb08bf1c..b7d62d93b4e 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -1,4 +1,4 @@ -import { AztecAddress, EthAddress } from '@aztec/circuits.js'; +import { AztecAddress, CompleteAddress, EthAddress } from '@aztec/circuits.js'; import { ABIParameterVisibility, ContractAbi, FunctionType } from '@aztec/foundation/abi'; import { randomBytes } from '@aztec/foundation/crypto'; import { ContractData, DeployedContract, NodeInfo, Tx, TxExecutionRequest, TxHash, TxReceipt } from '@aztec/types'; @@ -12,7 +12,7 @@ describe('Contract Class', () => { let wallet: MockProxy; const contractAddress = AztecAddress.random(); - const account = AztecAddress.random(); + let account: CompleteAddress; const mockTx = { type: 'Tx' } as any as Tx; const mockTxRequest = { type: 'TxRequest' } as any as TxExecutionRequest; @@ -91,7 +91,8 @@ describe('Contract Class', () => { portalContract: EthAddress.random(), }); - beforeEach(() => { + beforeEach(async () => { + account = await CompleteAddress.random(); wallet = mock(); wallet.createTxExecutionRequest.mockResolvedValue(mockTxRequest); wallet.getContractData.mockResolvedValue(ContractData.random()); @@ -108,7 +109,7 @@ describe('Contract Class', () => { const param0 = 12; const param1 = 345n; const sentTx = fooContract.methods.bar(param0, param1).send({ - origin: account, + origin: account.address, }); const txHash = await sentTx.getTxHash(); const receipt = await sentTx.getReceipt(); @@ -123,16 +124,16 @@ describe('Contract Class', () => { it('should call view on an unconstrained function', async () => { const fooContract = await Contract.create(contractAddress, defaultAbi, wallet); const result = await fooContract.methods.qux(123n).view({ - from: account, + from: account.address, }); expect(wallet.viewTx).toHaveBeenCalledTimes(1); - expect(wallet.viewTx).toHaveBeenCalledWith('qux', [123n], contractAddress, account); + expect(wallet.viewTx).toHaveBeenCalledWith('qux', [123n], contractAddress, account.address); expect(result).toBe(mockViewResultValue); }); it('should not call create on an unconstrained function', async () => { const fooContract = await Contract.create(contractAddress, defaultAbi, wallet); - await expect(fooContract.methods.qux().create({ origin: account })).rejects.toThrow(); + await expect(fooContract.methods.qux().create({ origin: account.address })).rejects.toThrow(); }); it('should not call view on a secret or open function', async () => { diff --git a/yarn-project/aztec.js/src/contract_deployer/deploy_method.ts b/yarn-project/aztec.js/src/contract_deployer/deploy_method.ts index 5c4197a6293..51eea3c8ddc 100644 --- a/yarn-project/aztec.js/src/contract_deployer/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract_deployer/deploy_method.ts @@ -66,7 +66,7 @@ export class DeployMethod extends Bas const { chainId, version } = await this.rpc.getNodeInfo(); - const { address, constructorHash, functionTreeRoot, partialAddress } = await getContractDeploymentInfo( + const { completeAddress, constructorHash, functionTreeRoot } = await getContractDeploymentInfo( this.abi, this.args, contractAddressSalt, @@ -84,7 +84,7 @@ export class DeployMethod extends Bas const txContext = new TxContext(false, false, true, contractDeploymentData, new Fr(chainId), new Fr(version)); const args = encodeArguments(this.constructorAbi, this.args); const functionData = FunctionData.fromAbi(this.constructorAbi); - const execution = { args, functionData, to: address }; + const execution = { args, functionData, to: completeAddress.address }; const packedArguments = await PackedArguments.fromArgs(execution.args); const txRequest = TxExecutionRequest.from({ @@ -96,11 +96,11 @@ export class DeployMethod extends Bas }); this.txRequest = txRequest; - this.partialAddress = partialAddress; - this.completeContractAddress = address; + this.partialAddress = completeAddress.partialAddress; + this.completeContractAddress = completeAddress.address; // TODO: Should we add the contracts to the DB here, or once the tx has been sent or mined? - await this.rpc.addContracts([{ abi: this.abi, address, portalContract }]); + await this.rpc.addContracts([{ abi: this.abi, address: completeAddress.address, portalContract }]); return this.txRequest; } diff --git a/yarn-project/aztec.js/src/utils/account.ts b/yarn-project/aztec.js/src/utils/account.ts index 24d065de012..45aeff84ba2 100644 --- a/yarn-project/aztec.js/src/utils/account.ts +++ b/yarn-project/aztec.js/src/utils/account.ts @@ -27,7 +27,7 @@ export async function createAccounts( const privKey = i == 0 && privateKey ? privateKey : PrivateKey.random(); const publicKey = await generatePublicKey(privKey); const deploymentInfo = await getContractDeploymentInfo(accountContractAbi, [], salt, publicKey); - await aztecRpcClient.addAccount(privKey, deploymentInfo.address, deploymentInfo.partialAddress); + await aztecRpcClient.registerAccount(privKey, deploymentInfo.completeAddress); const contractDeployer = new ContractDeployer(accountContractAbi, aztecRpcClient, publicKey); const tx = contractDeployer.deploy().send({ contractAddressSalt: salt }); await tx.isMined({ interval: 0.5 }); @@ -36,15 +36,20 @@ export async function createAccounts( throw new Error(`Deployment tx not mined (status is ${receipt.status})`); } const address = receipt.contractAddress!; - if (!address.equals(deploymentInfo.address)) { + if (!address.equals(deploymentInfo.completeAddress.address)) { throw new Error( - `Deployment address does not match for account contract (expected ${deploymentInfo.address.toString()} got ${address.toString()})`, + `Deployment address does not match for account contract (expected ${deploymentInfo.completeAddress.address.toString()} got ${address.toString()})`, ); } logger(`Created account ${address.toString()} with public key ${publicKey.toString()}`); accountImpls.registerAccount( address, - new SingleKeyAccountEntrypoint(address, deploymentInfo.partialAddress, privKey, await Schnorr.new()), + new SingleKeyAccountEntrypoint( + address, + deploymentInfo.completeAddress.partialAddress, + privKey, + await Schnorr.new(), + ), ); } return new EntrypointWallet(aztecRpcClient, accountImpls); @@ -79,7 +84,7 @@ export async function getAccountWallets( salts[i], publicKey, ); - const address = deploymentInfo.address; + const address = deploymentInfo.completeAddress.address; accountCollection.registerAccount( address, diff --git a/yarn-project/canary/scripts/docker-compose.yml b/yarn-project/canary/scripts/docker-compose.yml index 59147ae7eb1..972022f60a9 100644 --- a/yarn-project/canary/scripts/docker-compose.yml +++ b/yarn-project/canary/scripts/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3" +version: '3' services: fork: image: ghcr.io/foundry-rs/foundry:nightly-a44aa13cfc23491ba32aaedc093e9488c1a6db43 @@ -10,12 +10,12 @@ services: exec anvil -p 8545 --host 0.0.0.0 --chain-id 31337 fi' ports: - - "8545:8545" + - '8545:8545' sandbox: image: aztecprotocol/aztec-sandbox:latest environment: - DEBUG: "aztec:*,wasm" + DEBUG: 'aztec:*,wasm' ETHEREUM_HOST: http://fork:8545 CHAIN_ID: 31337 ARCHIVER_POLLING_INTERVAL_MS: 50 @@ -26,7 +26,7 @@ services: ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 SEARCH_START_BLOCK: ${FORK_BLOCK_NUMBER:-0} ports: - - "8080:8080" + - '8080:8080' canary: image: aztecprotocol/canary:latest diff --git a/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts index 264c1e41821..53149bd5142 100644 --- a/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts @@ -137,10 +137,7 @@ async function deployAllContracts( }; } -const getL2BalanceOf = async ( - owner: AztecAddress, - l2Contract: NonNativeTokenContract -) => { +const getL2BalanceOf = async (owner: AztecAddress, l2Contract: NonNativeTokenContract) => { return await l2Contract.methods.getBalance(owner).view({ from: owner }); }; @@ -193,7 +190,8 @@ describe('uniswap_trade_on_l1_from_l2', () => { wallet = await getSandboxAccountsWallet(aztecRpcClient); const accounts = await wallet.getAccounts(); - const [owner, receiver] = accounts; + const owner = accounts[0].address; + const receiver = accounts[1].address; const result = await deployAllContracts(owner, publicClient, walletClient); const { @@ -290,7 +288,7 @@ describe('uniswap_trade_on_l1_from_l2', () => { expect(withdrawReceipt.status).toBe(TxStatus.MINED); logger(`Withdraw receipt status: ${withdrawReceipt.status}`); - // check weth balance of owner on L2 (we first briedged `wethAmountToBridge` into L2 and now withdrew it!) + // check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!) await expectBalanceOnL2(owner, INITIAL_BALANCE - transferAmount, wethL2Contract); // 5. Consume L2 to L1 message by calling uniswapPortal.swap() diff --git a/yarn-project/circuits.js/src/contract/contract_deployment_info.ts b/yarn-project/circuits.js/src/contract/contract_deployment_info.ts index be3389e2d73..8554b6fa314 100644 --- a/yarn-project/circuits.js/src/contract/contract_deployment_info.ts +++ b/yarn-project/circuits.js/src/contract/contract_deployment_info.ts @@ -7,7 +7,7 @@ import { } from '@aztec/circuits.js/abis'; import { ContractAbi, encodeArguments, generateFunctionSelector } from '@aztec/foundation/abi'; -import { CircuitsWasm, DeploymentInfo, Fr, FunctionData, PublicKey } from '../index.js'; +import { CircuitsWasm, CompleteAddress, DeploymentInfo, Fr, FunctionData, PublicKey } from '../index.js'; import { generateFunctionLeaves, hashVKStr, isConstructor } from './contract_tree/contract_tree.js'; /** @@ -55,11 +55,11 @@ export async function getContractDeploymentInfo( constructorHash, ); + const completeAddress = await CompleteAddress.create(contractAddress, publicKey, partialAddress); + return { - address: contractAddress, - partialAddress, + completeAddress, constructorHash: constructorVkHash, functionTreeRoot, - publicKey, }; } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 286053b6a31..0cb5d77479a 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -2,8 +2,8 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { mapTuple, numToUInt32BE } from '@aztec/foundation/serialize'; -import { computeCallStackItemHash, computeContractAddressFromPartial } from '../abis/abis.js'; -import { Grumpkin, SchnorrSignature } from '../barretenberg/index.js'; +import { computeCallStackItemHash } from '../abis/abis.js'; +import { SchnorrSignature } from '../barretenberg/index.js'; import { ARGS_LENGTH, AggregationObject, @@ -65,7 +65,6 @@ import { PrivateCircuitPublicInputs, PrivateKernelInputsInit, PrivateKernelInputsInner, - PrivateKey, Proof, PublicCallData, PublicCallRequest, @@ -948,18 +947,3 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { export function fr(n: number): Fr { return new Fr(BigInt(n)); } - -/** - * Computes a valid address, partial address, and public key out of a private key. - * @param privateKey - A private encryption key (optional, will use a random one if not set). - * @returns A valid address, partial address, and public key. - */ -export async function makeAddressWithPreimagesFromPrivateKey(privateKey?: PrivateKey) { - privateKey = privateKey ?? PrivateKey.random(); - const wasm = await CircuitsWasm.get(); - const grumpkin = new Grumpkin(wasm); - const publicKey = grumpkin.mul(Grumpkin.generator, privateKey); - const partialAddress = Fr.random(); - const address = computeContractAddressFromPartial(wasm, publicKey, partialAddress); - return { address, partialAddress, publicKey, privateKey }; -} diff --git a/yarn-project/circuits.js/src/types/complete_address.test.ts b/yarn-project/circuits.js/src/types/complete_address.test.ts new file mode 100644 index 00000000000..52953661b54 --- /dev/null +++ b/yarn-project/circuits.js/src/types/complete_address.test.ts @@ -0,0 +1,30 @@ +import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { Fr, Point } from '@aztec/foundation/fields'; + +import { CompleteAddress } from './complete_address.js'; + +describe('CompleteAddress', () => { + it('refuses to add an account with incorrect address for given partial address and pubkey', async () => { + await expect(CompleteAddress.create(AztecAddress.random(), Point.random(), Fr.random())).rejects.toThrowError( + /cannot be derived/, + ); + }); + + it('equals returns true when 2 instances are equal', async () => { + const address1 = await CompleteAddress.random(); + const address2 = await CompleteAddress.create(address1.address, address1.publicKey, address1.partialAddress); + expect(address1.equals(address2)).toBe(true); + }); + + it('equals returns true when 2 instances are not equal', async () => { + const address1 = await CompleteAddress.random(); + const address2 = await CompleteAddress.random(); + expect(address1.equals(address2)).toBe(false); + }); + + it('serializes / deserializes correctly', async () => { + const expectedAddress = await CompleteAddress.random(); + const address = CompleteAddress.fromBuffer(expectedAddress.toBuffer()); + expect(address.equals(expectedAddress)).toBe(true); + }); +}); diff --git a/yarn-project/circuits.js/src/types/complete_address.ts b/yarn-project/circuits.js/src/types/complete_address.ts new file mode 100644 index 00000000000..eb88b49d3da --- /dev/null +++ b/yarn-project/circuits.js/src/types/complete_address.ts @@ -0,0 +1,133 @@ +import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { BufferReader } from '@aztec/foundation/serialize'; + +import { computeContractAddressFromPartial } from '../abis/abis.js'; +import { Grumpkin } from '../barretenberg/index.js'; +import { CircuitsWasm, Fr, Point, PrivateKey } from '../index.js'; +import { PartialAddress } from './partial_address.js'; +import { PublicKey } from './public_key.js'; + +/** + * A complete address is a combination of an Aztec address, a public key and a partial address. + * + * @remarks We have introduced this type because it is common that these 3 values are used together. They are commonly + * used together because it is the information needed to send user a note. + * @remarks See the link bellow for details about how address is computed: + * https://github.com/AztecProtocol/aztec-packages/blob/master/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys + */ +export class CompleteAddress { + // TODO: This constructor should be private so that the check in create method is always enforced. However, this is + // not possible now because we need the class to be compatible with `StringIOClass` to be able to pass it + // through `JsonRpcServer`. + public constructor( + /** Contract address (typically of an account contract) */ + public address: AztecAddress, + /** Public key corresponding to the address (used during note encryption). */ + public publicKey: PublicKey, + /** Partial key corresponding to the public key to the address. */ + public partialAddress: PartialAddress, + ) {} + + static async create( + address: AztecAddress, + publicKey: PublicKey, + partialAddress: PartialAddress, + ): Promise { + const wasm = await CircuitsWasm.get(); + const expectedAddress = computeContractAddressFromPartial(wasm, publicKey, partialAddress); + if (!expectedAddress.equals(address)) { + throw new Error( + `Address cannot be derived from pubkey and partial address (received ${address.toString()}, derived ${expectedAddress.toString()})`, + ); + } + return new CompleteAddress(address, publicKey, partialAddress); + } + + static async random(): Promise { + const partialAddress = Fr.random(); + const pubKey = Point.random(); + const wasm = await CircuitsWasm.get(); + const address = computeContractAddressFromPartial(wasm, pubKey, partialAddress); + return new CompleteAddress(address, pubKey, partialAddress); + } + + static async fromPrivateKey(privateKey: PrivateKey): Promise { + const wasm = await CircuitsWasm.get(); + const grumpkin = new Grumpkin(wasm); + const pubKey = grumpkin.mul(Grumpkin.generator, privateKey); + const partialAddress = Fr.random(); + const address = computeContractAddressFromPartial(wasm, pubKey, partialAddress); + return new CompleteAddress(address, pubKey, partialAddress); + } + + /** + * Gets a readable string representation of a the complete address. + * @returns A readable string representation of the complete address. + */ + public toReadableString(): string { + return `Address: ${this.address.toString()}, Public Key: ${this.publicKey.toString()}, Partial Address: ${this.partialAddress.toString()}`; + } + + /** + * Determines if this CompleteAddress instance is equal to the given CompleteAddress instance. + * Equality is based on the content of their respective buffers. + * + * @param other - The CompleteAddress instance to compare against. + * @returns True if the buffers of both instances are equal, false otherwise. + */ + equals(other: CompleteAddress) { + return ( + this.address.equals(other.address) && + this.publicKey.equals(other.publicKey) && + this.partialAddress.equals(other.partialAddress) + ); + } + + /** + * Converts the CompleteAddress instance into a Buffer. + * This method should be used when encoding the address for storage, transmission or serialization purposes. + * + * @returns A Buffer representation of the CompleteAddress instance. + */ + toBuffer() { + return Buffer.concat([this.address.toBuffer(), this.publicKey.toBuffer(), this.partialAddress.toBuffer()]); + } + + /** + * Creates an CompleteAddress instance from a given buffer or BufferReader. + * If the input is a Buffer, it wraps it in a BufferReader before processing. + * Throws an error if the input length is not equal to the expected size. + * + * @param buffer - The input buffer or BufferReader containing the address data. + * @returns - A new CompleteAddress instance with the extracted address data. + */ + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + const address = reader.readObject(AztecAddress); + const publicKey = reader.readObject(Point); + const partialAddress = reader.readObject(Fr); + return new this(address, publicKey, partialAddress); + } + + /** + * Create a CompleteAddress instance from a hex-encoded string. + * The input 'address' should be prefixed with '0x' or not, and have exactly 128 hex characters representing the x and y coordinates. + * Throws an error if the input length is invalid or coordinate values are out of range. + * + * @param address - The hex-encoded string representing the complete address. + * @returns A Point instance. + */ + static fromString(address: string): CompleteAddress { + return this.fromBuffer(Buffer.from(address.replace(/^0x/i, ''), 'hex')); + } + + /** + * Convert the CompleteAddress to a hexadecimal string representation, with a "0x" prefix. + * The resulting string will have a length of 66 characters (including the prefix). + * + * @returns A hexadecimal string representation of the CompleteAddress. + */ + toString(): string { + return `0x${this.toBuffer().toString('hex')}`; + } +} diff --git a/yarn-project/circuits.js/src/types/deployment_info.ts b/yarn-project/circuits.js/src/types/deployment_info.ts index 8f604020d71..a8abba47126 100644 --- a/yarn-project/circuits.js/src/types/deployment_info.ts +++ b/yarn-project/circuits.js/src/types/deployment_info.ts @@ -1,17 +1,13 @@ -import { AztecAddress, Fr, PartialAddress, PublicKey } from '../index.js'; +import { CompleteAddress, Fr } from '../index.js'; /** * Represents the data generated as part of contract deployment. */ export type DeploymentInfo = { /** - * The derived aztec address of the contract. + * The complete address of the deployed contract. */ - address: AztecAddress; - /** - * The partially derived aztec address of the contract. - */ - partialAddress: PartialAddress; + completeAddress: CompleteAddress; /** * The contract's constructor hash. */ @@ -20,8 +16,4 @@ export type DeploymentInfo = { * The root of the contract's function tree. */ functionTreeRoot: Fr; - /** - * The public key associated with the contract. - */ - publicKey: PublicKey; }; diff --git a/yarn-project/circuits.js/src/types/index.ts b/yarn-project/circuits.js/src/types/index.ts index 7010ecfcde2..95609ef2323 100644 --- a/yarn-project/circuits.js/src/types/index.ts +++ b/yarn-project/circuits.js/src/types/index.ts @@ -1,4 +1,5 @@ export * from './contract_function_dao.js'; +export * from './complete_address.js'; export * from './deployment_info.js'; export * from './partial_address.js'; export * from './private_key.js'; diff --git a/yarn-project/circuits.js/src/types/partial_address.ts b/yarn-project/circuits.js/src/types/partial_address.ts index 85e4a0db8be..37c3c42da69 100644 --- a/yarn-project/circuits.js/src/types/partial_address.ts +++ b/yarn-project/circuits.js/src/types/partial_address.ts @@ -2,6 +2,6 @@ import { Fr } from '../index.js'; /** * A type which along with public key forms a preimage of a contract address. See the link bellow for more details - * https://github.com/AztecProtocol/aztec-packages/blob/janb/rpc-interface-cleanup/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys + * https://github.com/AztecProtocol/aztec-packages/blob/master/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys */ export type PartialAddress = Fr; diff --git a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts index 426b36ff7a5..518b218502e 100644 --- a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts @@ -5,7 +5,7 @@ import { DebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; import { toBigInt } from '@aztec/foundation/serialize'; import { ChildContract, PrivateTokenContract } from '@aztec/noir-contracts/types'; -import { AztecRPC, TxStatus } from '@aztec/types'; +import { AztecRPC, CompleteAddress, TxStatus } from '@aztec/types'; import { expectUnencryptedLogsFromLastBlockToBe, @@ -22,8 +22,8 @@ describe('e2e_2_rpc_servers', () => { let aztecRpcServerB: AztecRPC; let walletA: Wallet; let walletB: Wallet; - let userA: AztecAddress; - let userB: AztecAddress; + let userA: CompleteAddress; + let userB: CompleteAddress; let logger: DebugLogger; beforeEach(async () => { @@ -31,7 +31,7 @@ describe('e2e_2_rpc_servers', () => { if (SANDBOX_URL) { throw new Error(`Test can't be run against the sandbox as 2 RPC servers are required`); } - let accounts: AztecAddress[] = []; + let accounts: CompleteAddress[] = []; ({ aztecNode, aztecRpcServer: aztecRpcServerA, accounts, wallet: walletA, logger } = await setup(1)); [userA] = accounts; @@ -93,14 +93,12 @@ describe('e2e_2_rpc_servers', () => { const transferAmount1 = 654n; const transferAmount2 = 323n; - const tokenAddress = await deployPrivateTokenContract(initialBalance, userA); + const tokenAddress = await deployPrivateTokenContract(initialBalance, userA.address); - // Add account B pub key and partial address to wallet A - const [accountBPubKey, accountBPartialAddress] = await aztecRpcServerB.getPublicKeyAndPartialAddress(userB); - await aztecRpcServerA.addPublicKeyAndPartialAddress(userB, accountBPubKey, accountBPartialAddress); - // Add account A pub key and partial address to wallet B - const [accountAPubKey, accountAPartialAddress] = await aztecRpcServerA.getPublicKeyAndPartialAddress(userA); - await aztecRpcServerB.addPublicKeyAndPartialAddress(userA, accountAPubKey, accountAPartialAddress); + // Add account B to wallet A + await aztecRpcServerA.registerRecipient(userB); + // Add account A to wallet B + await aztecRpcServerB.registerRecipient(userA); // Add privateToken to RPC server B await aztecRpcServerB.addContracts([ @@ -112,14 +110,16 @@ describe('e2e_2_rpc_servers', () => { ]); // Check initial balances and logs are as expected - await expectTokenBalance(walletA, tokenAddress, userA, initialBalance); - await expectTokenBalance(walletB, tokenAddress, userB, 0n); + await expectTokenBalance(walletA, tokenAddress, userA.address, initialBalance); + await expectTokenBalance(walletB, tokenAddress, userB.address, 0n); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 1); await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Balance set in constructor']); // Transfer funds from A to B via RPC server A const contractWithWalletA = await PrivateTokenContract.create(tokenAddress, walletA); - const txAToB = contractWithWalletA.methods.transfer(transferAmount1, userA, userB).send({ origin: userA }); + const txAToB = contractWithWalletA.methods + .transfer(transferAmount1, userA.address, userB.address) + .send({ origin: userA.address }); await txAToB.isMined({ interval: 0.1 }); const receiptAToB = await txAToB.getReceipt(); @@ -127,14 +127,16 @@ describe('e2e_2_rpc_servers', () => { expect(receiptAToB.status).toBe(TxStatus.MINED); // Check balances and logs are as expected - await expectTokenBalance(walletA, tokenAddress, userA, initialBalance - transferAmount1); - await expectTokenBalance(walletB, tokenAddress, userB, transferAmount1); + await expectTokenBalance(walletA, tokenAddress, userA.address, initialBalance - transferAmount1); + await expectTokenBalance(walletB, tokenAddress, userB.address, transferAmount1); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 2); await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Coins transferred']); // Transfer funds from B to A via RPC server B const contractWithWalletB = await PrivateTokenContract.create(tokenAddress, walletB); - const txBToA = contractWithWalletB.methods.transfer(transferAmount2, userB, userA).send({ origin: userB }); + const txBToA = contractWithWalletB.methods + .transfer(transferAmount2, userB.address, userA.address) + .send({ origin: userB.address }); await txBToA.isMined({ interval: 0.1 }); const receiptBToA = await txBToA.getReceipt(); @@ -142,8 +144,8 @@ describe('e2e_2_rpc_servers', () => { expect(receiptBToA.status).toBe(TxStatus.MINED); // Check balances and logs are as expected - await expectTokenBalance(walletA, tokenAddress, userA, initialBalance - transferAmount1 + transferAmount2); - await expectTokenBalance(walletB, tokenAddress, userB, transferAmount1 - transferAmount2); + await expectTokenBalance(walletA, tokenAddress, userA.address, initialBalance - transferAmount1 + transferAmount2); + await expectTokenBalance(walletB, tokenAddress, userB.address, transferAmount1 - transferAmount2); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 2); await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Coins transferred']); }, 120_000); @@ -187,7 +189,7 @@ describe('e2e_2_rpc_servers', () => { const newValueToSet = 256n; const childContractWithWalletB = await ChildContract.create(childAddress, walletB); - const tx = childContractWithWalletB.methods.pubStoreValue(newValueToSet).send({ origin: userB }); + const tx = childContractWithWalletB.methods.pubStoreValue(newValueToSet).send({ origin: userB.address }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); diff --git a/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts b/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts index 3c91b4290b2..ae21869dfc4 100644 --- a/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts +++ b/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts @@ -27,6 +27,20 @@ const { SANDBOX_URL } = process.env; const conditionalDescribe = () => (SANDBOX_URL ? describe : describe.skip); const privKey = PrivateKey.random(); +/** + * This test is a bit of a special case as it's relying on sandbox and web browser and not only on anvil and node.js. + * To run the test, do the following: + * 1) Build the whole repository, + * 2) go to `yarn-project/aztec.js` and build the web packed package with `yarn build:web`, + * 3) start anvil: `anvil`, + * 4) open new terminal and optionally set the more verbose debug level: `DEBUG=aztec:*`, + * 5) go to the sandbox dir `yarn-project/aztec-sandbox` and run `yarn start`, + * 6) open new terminal and export the sandbox URL: `export SANDBOX_URL='http://localhost:8080'`, + * 7) go to `yarn-project/end-to-end` and run the test: `yarn test aztec_js_browser` + * + * NOTE: If you see aztec-sandbox logs spammed with unexpected logs there is probably a chrome process with a webpage + * unexpectedly running in the background. Kill it with `killall chrome` + */ conditionalDescribe()('e2e_aztec.js_browser', () => { const initialBalance = 33n; const transferAmount = 3n; @@ -110,24 +124,35 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { privKey.toString(), ); const accounts = await testClient.getAccounts(); - const stringAccounts = accounts.map(acc => acc.toString()); + const stringAccounts = accounts.map(acc => acc.address.toString()); expect(stringAccounts.includes(result)).toBeTruthy(); }); it('Deploys Private Token contract', async () => { const txHash = await page.evaluate( - async (rpcUrl, initialBalance, PrivateTokenContractAbi) => { - const { DeployMethod, createAztecRpcClient, mustSucceedFetch } = window.AztecJs; + async (rpcUrl, privateKeyString, initialBalance, PrivateTokenContractAbi) => { + const { PrivateKey, DeployMethod, createAztecRpcClient, mustSucceedFetch, getUnsafeSchnorrAccount } = + window.AztecJs; const client = createAztecRpcClient(rpcUrl!, mustSucceedFetch); - const owner = (await client.getAccounts())[0]; - const publicKey = (await client.getPublicKeyAndPartialAddress(owner))[0]; - const tx = new DeployMethod(publicKey, client, PrivateTokenContractAbi, [initialBalance, owner]).send(); + let accounts = await client.getAccounts(); + if (accounts.length === 0) { + // This test needs an account for deployment. We create one in case there is none available in the RPC server. + const privateKey = PrivateKey.fromString(privateKeyString); + await getUnsafeSchnorrAccount(client, privateKey).waitDeploy(); + accounts = await client.getAccounts(); + } + const owner = accounts[0]; + const tx = new DeployMethod(owner.publicKey, client, PrivateTokenContractAbi, [ + initialBalance, + owner.address, + ]).send(); await tx.wait(); const receipt = await tx.getReceipt(); console.log(`Contract Deployed: ${receipt.contractAddress}`); return receipt.txHash.toString(); }, SANDBOX_URL, + privKey.toString(), initialBalance, PrivateTokenContractAbi, ); @@ -142,7 +167,7 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { async (rpcUrl, contractAddress, PrivateTokenContractAbi) => { const { Contract, AztecAddress, createAztecRpcClient, mustSucceedFetch } = window.AztecJs; const client = createAztecRpcClient(rpcUrl!, mustSucceedFetch); - const [owner] = await client.getAccounts(); + const owner = (await client.getAccounts())[0].address; const wallet = await AztecJs.getSandboxAccountsWallet(client); const contract = await Contract.create( AztecAddress.fromString(contractAddress), @@ -166,7 +191,9 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { console.log(`Starting transfer tx`); const { AztecAddress, Contract, createAztecRpcClient, mustSucceedFetch } = window.AztecJs; const client = createAztecRpcClient(rpcUrl!, mustSucceedFetch); - const [owner, receiver] = await client.getAccounts(); + const accounts = await client.getAccounts(); + const owner = accounts[0].address; + const receiver = accounts[1].address; const wallet = await AztecJs.getSandboxAccountsWallet(client); const contract = await Contract.create( AztecAddress.fromString(contractAddress), @@ -174,7 +201,7 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { wallet, ); await contract.methods.transfer(transferAmount, owner, receiver).send({ origin: owner }).wait(); - console.log(`Transfered ${transferAmount} tokens to new Account`); + console.log(`Transferred ${transferAmount} tokens to new Account`); return await contract.methods.getBalance(receiver).view({ from: receiver }); }, SANDBOX_URL, diff --git a/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts b/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts index 37cd528ce07..7721b18554b 100644 --- a/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts +++ b/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts @@ -29,7 +29,7 @@ describe('e2e_cheat_codes', () => { walletClient = deployL1ContractsValues.walletClient; publicClient = deployL1ContractsValues.publicClient; rollupAddress = deployL1ContractsValues.rollupAddress; - recipient = accounts[0]; + recipient = accounts[0].address; }, 100_000); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts index 337133e0985..74ba52a52dc 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts @@ -1,7 +1,7 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, ContractDeployer, Fr, isContractDeployed } from '@aztec/aztec.js'; -import { getContractDeploymentInfo } from '@aztec/circuits.js'; +import { CompleteAddress, getContractDeploymentInfo } from '@aztec/circuits.js'; import { DebugLogger } from '@aztec/foundation/log'; import { TestContractAbi } from '@aztec/noir-contracts/artifacts'; import { AztecRPC, TxStatus } from '@aztec/types'; @@ -11,7 +11,7 @@ import { setup } from './fixtures/utils.js'; describe('e2e_deploy_contract', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; - let accounts: AztecAddress[]; + let accounts: CompleteAddress[]; let logger: DebugLogger; beforeEach(async () => { @@ -30,7 +30,7 @@ describe('e2e_deploy_contract', () => { * https://hackmd.io/ouVCnacHQRq2o1oRc5ksNA#Interfaces-and-Responsibilities */ it('should deploy a contract', async () => { - const publicKey = (await aztecRpcServer.getPublicKeyAndPartialAddress(accounts[0]))[0]; + const publicKey = accounts[0].publicKey; const salt = Fr.random(); const deploymentData = await getContractDeploymentInfo(TestContractAbi, [], salt, publicKey); const deployer = new ContractDeployer(TestContractAbi, aztecRpcServer, publicKey); @@ -41,7 +41,7 @@ describe('e2e_deploy_contract', () => { expect.objectContaining({ status: TxStatus.PENDING, error: '', - contractAddress: deploymentData.address, + contractAddress: deploymentData.completeAddress.address, }), ); logger(`Receipt received and expecting contract deployment at ${receipt.contractAddress}`); 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 b7a045d2964..df96d89fdc6 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 @@ -1,7 +1,7 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, BatchCall, Wallet, generatePublicKey } from '@aztec/aztec.js'; -import { Fr, PrivateKey, getContractDeploymentInfo } from '@aztec/circuits.js'; +import { CompleteAddress, Fr, PrivateKey, getContractDeploymentInfo } from '@aztec/circuits.js'; import { generateFunctionSelector } from '@aztec/foundation/abi'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { DebugLogger } from '@aztec/foundation/log'; @@ -15,7 +15,7 @@ describe('e2e_escrow_contract', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; let wallet: Wallet; - let accounts: AztecAddress[]; + let accounts: CompleteAddress[]; let logger: DebugLogger; let privateTokenContract: PrivateTokenContract; @@ -36,7 +36,8 @@ describe('e2e_escrow_contract', () => { beforeEach(async () => { // Setup environment ({ aztecNode, aztecRpcServer, accounts, wallet, logger } = await setup(2)); - [owner, recipient] = accounts; + owner = accounts[0].address; + recipient = accounts[1].address; // Generate private key for escrow contract, register key in rpc server, and deploy // Note that we need to register it first if we want to emit an encrypted note for it in the constructor @@ -44,7 +45,7 @@ describe('e2e_escrow_contract', () => { escrowPublicKey = await generatePublicKey(escrowPrivateKey); const salt = Fr.random(); const deployInfo = await getContractDeploymentInfo(EscrowContractAbi, [owner], salt, escrowPublicKey); - await aztecRpcServer.addAccount(escrowPrivateKey, deployInfo.address, deployInfo.partialAddress); + await aztecRpcServer.registerAccount(escrowPrivateKey, deployInfo.completeAddress); escrowContract = await EscrowContract.deployWithPublicKey(wallet, escrowPublicKey, owner) .send({ contractAddressSalt: salt }) 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 60b1a7235ef..de92bdf4461 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 @@ -1,7 +1,7 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, Fr, Wallet } from '@aztec/aztec.js'; -import { CircuitsWasm } from '@aztec/circuits.js'; +import { CircuitsWasm, CompleteAddress } from '@aztec/circuits.js'; import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg'; import { DebugLogger } from '@aztec/foundation/log'; import { LendingContract } from '@aztec/noir-contracts/types'; @@ -13,7 +13,7 @@ describe('e2e_lending_contract', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; let wallet: Wallet; - let accounts: AztecAddress[]; + let accounts: CompleteAddress[]; let logger: DebugLogger; let contract: LendingContract; @@ -85,7 +85,7 @@ describe('e2e_lending_contract', () => { it('Full lending run-through', async () => { const recipientIdx = 0; - const recipient = accounts[recipientIdx]; + const recipient = accounts[recipientIdx].address; const { contract: deployedContract } = await deployContract(); const account = new Account(recipient, new Fr(42)); diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index 342e977a6b1..beba91eadd5 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -42,9 +42,8 @@ describe('e2e_multiple_accounts_1_enc_key', () => { // Verify that all accounts use the same encryption key const encryptionPublicKey = await generatePublicKey(encryptionPrivateKey); - for (let i = 0; i < numAccounts; i++) { - const accountEncryptionPublicKey = (await aztecRpcServer.getPublicKeyAndPartialAddress(accounts[i]))[0]; - expect(accountEncryptionPublicKey).toEqual(encryptionPublicKey); + for (const account of await aztecRpcServer.getAccounts()) { + expect(account.publicKey).toEqual(encryptionPublicKey); } logger(`Deploying Private Token...`); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts index fb8cdedd015..cf66d962d60 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts @@ -6,7 +6,7 @@ import { DebugLogger } from '@aztec/foundation/log'; import { toBigInt } from '@aztec/foundation/serialize'; import { ChildContractAbi, ParentContractAbi } from '@aztec/noir-contracts/artifacts'; import { ChildContract, ImportTestContract, ParentContract, TestContract } from '@aztec/noir-contracts/types'; -import { AztecRPC, TxStatus } from '@aztec/types'; +import { AztecRPC, CompleteAddress, TxStatus } from '@aztec/types'; import { setup } from './fixtures/utils.js'; @@ -14,11 +14,13 @@ describe('e2e_nested_contract', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; let wallet: Wallet; - let accounts: AztecAddress[]; + let sender: AztecAddress; let logger: DebugLogger; beforeEach(async () => { + let accounts: CompleteAddress[]; ({ aztecNode, aztecRpcServer, accounts, wallet, logger } = await setup()); + sender = accounts[0].address; }, 100_000); afterEach(async () => { @@ -61,7 +63,7 @@ describe('e2e_nested_contract', () => { it('performs nested calls', async () => { const tx = parentContract.methods .entryPoint(childContract.address, Fr.fromBuffer(childContract.methods.value.selector)) - .send({ origin: accounts[0] }); + .send({ origin: sender }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); @@ -72,7 +74,7 @@ describe('e2e_nested_contract', () => { it('performs public nested calls', async () => { const tx = parentContract.methods .pubEntryPoint(childContract.address, Fr.fromBuffer(childContract.methods.pubValue.selector), 42n) - .send({ origin: accounts[0] }); + .send({ origin: sender }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); @@ -83,7 +85,7 @@ describe('e2e_nested_contract', () => { it('enqueues a single public call', async () => { const tx = parentContract.methods .enqueueCallToChild(childContract.address, Fr.fromBuffer(childContract.methods.pubStoreValue.selector), 42n) - .send({ origin: accounts[0] }); + .send({ origin: sender }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); @@ -101,7 +103,7 @@ describe('e2e_nested_contract', () => { Fr.fromBuffer(childContract.methods.pubStoreValue.selector).value, 42n, ) - .send({ origin: accounts[0] }); + .send({ origin: sender }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); @@ -117,7 +119,7 @@ describe('e2e_nested_contract', () => { Fr.fromBuffer(childContract.methods.pubStoreValue.selector), 42n, ) - .send({ origin: accounts[0] }); + .send({ origin: sender }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); @@ -135,7 +137,7 @@ describe('e2e_nested_contract', () => { Fr.fromBuffer(childContract.methods.pubStoreValue.selector), 42n, ) - .send({ origin: accounts[0] }); + .send({ origin: sender }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); @@ -154,7 +156,7 @@ describe('e2e_nested_contract', () => { Fr.fromBuffer(childContract.methods.pubStoreValue.selector).value, 42n, ) - .send({ origin: accounts[0] }); + .send({ origin: sender }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); diff --git a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts index 753cc5419fc..4c219a708aa 100644 --- a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts +++ b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts @@ -3,7 +3,7 @@ import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, SignerlessWallet, Wallet } from '@aztec/aztec.js'; import { DebugLogger } from '@aztec/foundation/log'; import { PokeableTokenContract } from '@aztec/noir-contracts/types'; -import { AztecRPC, TxStatus } from '@aztec/types'; +import { AztecRPC, CompleteAddress, TxStatus } from '@aztec/types'; import { expectsNumOfEncryptedLogsInTheLastBlockToBe, setup } from './fixtures/utils.js'; @@ -22,10 +22,10 @@ describe('e2e_non_contract_account', () => { const initialBalance = 987n; beforeEach(async () => { - let accounts: AztecAddress[]; + let accounts: CompleteAddress[]; ({ aztecNode, aztecRpcServer, accounts, wallet, logger } = await setup(2)); - sender = accounts[0]; - recipient = accounts[1]; + sender = accounts[0].address; + recipient = accounts[1].address; pokerWallet = new SignerlessWallet(aztecRpcServer); logger(`Deploying L2 contract...`); diff --git a/yarn-project/end-to-end/src/e2e_p2p_network.test.ts b/yarn-project/end-to-end/src/e2e_p2p_network.test.ts index 13f5035ee52..e0a2b10be85 100644 --- a/yarn-project/end-to-end/src/e2e_p2p_network.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p_network.test.ts @@ -6,8 +6,7 @@ import { getConfigEnvVars as getRpcConfig, } from '@aztec/aztec-rpc'; import { ContractDeployer, SentTx, isContractDeployed } from '@aztec/aztec.js'; -import { AztecAddress, CircuitsWasm, Fr, PublicKey, getContractDeploymentInfo } from '@aztec/circuits.js'; -import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis'; +import { AztecAddress, CompleteAddress, Fr, PublicKey, getContractDeploymentInfo } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { DebugLogger } from '@aztec/foundation/log'; import { TestContractAbi } from '@aztec/noir-contracts/artifacts'; @@ -135,7 +134,7 @@ describe('e2e_p2p_network', () => { const txs: SentTx[] = []; for (let i = 0; i < numTxs; i++) { const salt = Fr.random(); - const deploymentInfo = await getContractDeploymentInfo(TestContractAbi, [], salt, publicKey); + const origin = (await getContractDeploymentInfo(TestContractAbi, [], salt, publicKey)).completeAddress.address; const deployer = new ContractDeployer(TestContractAbi, aztecRpcServer, publicKey); const tx = deployer.deploy().send({ contractAddressSalt: salt }); logger(`Tx sent with hash ${await tx.getTxHash()}`); @@ -144,7 +143,7 @@ describe('e2e_p2p_network', () => { expect.objectContaining({ status: TxStatus.PENDING, error: '', - contractAddress: deploymentInfo.address, + contractAddress: origin, }), ); logger(`Receipt received and expecting contract deployment at ${receipt.contractAddress}`); @@ -160,16 +159,15 @@ describe('e2e_p2p_network', () => { ): Promise => { const rpcConfig = getRpcConfig(); const aztecRpcServer = await createAztecRPCServer(node, rpcConfig, {}, true); + const keyPair = ConstantKeyPair.random(await Grumpkin.new()); - const partialAddress = Fr.random(); - const publicKey = keyPair.getPublicKey(); - const address = computeContractAddressFromPartial(await CircuitsWasm.get(), publicKey, partialAddress); - const account = await aztecRpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress); + const completeAddress = await CompleteAddress.fromPrivateKey(await keyPair.getPrivateKey()); + await aztecRpcServer.registerAccount(await keyPair.getPrivateKey(), completeAddress); - const txs = await submitTxsTo(aztecRpcServer, account, numTxs, publicKey); + const txs = await submitTxsTo(aztecRpcServer, completeAddress.address, numTxs, completeAddress.publicKey); return { txs, - account, + account: completeAddress.address, rpcServer: aztecRpcServer, node, }; diff --git a/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts index ee0242eebb3..d7b686c51c5 100644 --- a/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts @@ -3,7 +3,7 @@ import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, Fr, Wallet } from '@aztec/aztec.js'; import { DebugLogger } from '@aztec/foundation/log'; import { PendingCommitmentsContract } from '@aztec/noir-contracts/types'; -import { AztecRPC, TxStatus } from '@aztec/types'; +import { AztecRPC, CompleteAddress, TxStatus } from '@aztec/types'; import { setup } from './fixtures/utils.js'; @@ -11,13 +11,15 @@ describe('e2e_pending_commitments_contract', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; let wallet: Wallet; - let accounts: AztecAddress[]; let logger: DebugLogger; + let owner: AztecAddress; let contract: PendingCommitmentsContract; beforeEach(async () => { + let accounts: CompleteAddress[]; ({ aztecNode, aztecRpcServer, accounts, wallet, logger } = await setup(2)); + owner = accounts[0].address; }, 100_000); afterEach(async () => { @@ -68,7 +70,6 @@ describe('e2e_pending_commitments_contract', () => { it('Noir function can "get" notes it just "inserted"', async () => { const mintAmount = 65n; - const [owner] = accounts; const deployedContract = await deployContract(); @@ -85,7 +86,6 @@ describe('e2e_pending_commitments_contract', () => { // Kernel will squash the noteHash and its nullifier. // Realistic way to describe this test is "Mint note A, then burn note A in the same transaction" const mintAmount = 65n; - const [owner] = accounts; const deployedContract = await deployContract(); @@ -111,7 +111,6 @@ describe('e2e_pending_commitments_contract', () => { // Kernel will squash both noteHashes and their nullifier. // Realistic way to describe this test is "Mint notes A and B, then burn both in the same transaction" const mintAmount = 65n; - const [owner] = accounts; const deployedContract = await deployContract(); @@ -138,7 +137,6 @@ describe('e2e_pending_commitments_contract', () => { // The other note will become persistent! // Realistic way to describe this test is "Mint notes A and B, then burn note A in the same transaction" const mintAmount = 65n; - const [owner] = accounts; const deployedContract = await deployContract(); @@ -166,7 +164,6 @@ describe('e2e_pending_commitments_contract', () => { // but the nullifier for the persistent note (from the first TX) will itself become persistent. // Realistic way to describe this test is "Mint note A, then burn note A in the same transaction" const mintAmount = 65n; - const [owner] = accounts; const deployedContract = await deployContract(); diff --git a/yarn-project/end-to-end/src/e2e_private_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_token_contract.test.ts index 5d9509139ed..e769433b458 100644 --- a/yarn-project/end-to-end/src/e2e_private_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_token_contract.test.ts @@ -3,7 +3,7 @@ import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, Wallet } from '@aztec/aztec.js'; import { DebugLogger } from '@aztec/foundation/log'; import { PrivateTokenContract } from '@aztec/noir-contracts/types'; -import { AztecRPC, TxStatus } from '@aztec/types'; +import { AztecRPC, CompleteAddress, TxStatus } from '@aztec/types'; import { expectUnencryptedLogsFromLastBlockToBe, @@ -15,13 +15,17 @@ describe('e2e_private_token_contract', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; let wallet: Wallet; - let accounts: AztecAddress[]; let logger: DebugLogger; + let owner: AztecAddress; + let receiver: AztecAddress; let contract: PrivateTokenContract; beforeEach(async () => { + let accounts: CompleteAddress[]; ({ aztecNode, aztecRpcServer, accounts, wallet, logger } = await setup(2)); + owner = accounts[0].address; + receiver = accounts[1].address; }, 100_000); afterEach(async () => { @@ -49,9 +53,9 @@ describe('e2e_private_token_contract', () => { */ it('1.3 should deploy private token contract with initial token minted to the account', async () => { const initialBalance = 987n; - await deployContract(initialBalance, accounts[0]); - await expectBalance(accounts[0], initialBalance); - await expectBalance(accounts[1], 0n); + await deployContract(initialBalance, owner); + await expectBalance(owner, initialBalance); + await expectBalance(receiver, 0n); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 1); await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Balance set in constructor']); @@ -63,8 +67,6 @@ describe('e2e_private_token_contract', () => { it('1.4 should call mint and increase balance', async () => { const mintAmount = 65n; - const [owner] = accounts; - await deployContract(0n, owner); await expectBalance(owner, 0n); @@ -88,7 +90,6 @@ describe('e2e_private_token_contract', () => { it('1.5 should call transfer and increase balance of another account', async () => { const initialBalance = 987n; const transferAmount = 654n; - const [owner, receiver] = accounts; await deployContract(initialBalance, owner); @@ -98,7 +99,7 @@ describe('e2e_private_token_contract', () => { await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 1); await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Balance set in constructor']); - const tx = contract.methods.transfer(transferAmount, owner, receiver).send({ origin: accounts[0] }); + const tx = contract.methods.transfer(transferAmount, owner, receiver).send({ origin: owner }); await tx.isMined({ interval: 0.1 }); const receipt = await tx.getReceipt(); diff --git a/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts index 49d7d925b3c..d3f06df47a7 100644 --- a/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts @@ -3,7 +3,7 @@ import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, Wallet } from '@aztec/aztec.js'; import { DebugLogger } from '@aztec/foundation/log'; import { PublicTokenContract } from '@aztec/noir-contracts/types'; -import { AztecRPC, L2BlockL2Logs, TxStatus } from '@aztec/types'; +import { AztecRPC, CompleteAddress, L2BlockL2Logs, TxStatus } from '@aztec/types'; import times from 'lodash.times'; @@ -13,8 +13,8 @@ describe('e2e_public_token_contract', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; let wallet: Wallet; - let accounts: AztecAddress[]; let logger: DebugLogger; + let recipient: AztecAddress; let contract: PublicTokenContract; @@ -36,7 +36,9 @@ describe('e2e_public_token_contract', () => { }; beforeEach(async () => { + let accounts: CompleteAddress[]; ({ aztecNode, aztecRpcServer, accounts, wallet, logger } = await setup()); + recipient = accounts[0].address; }, 100_000); afterEach(async () => { @@ -54,9 +56,6 @@ describe('e2e_public_token_contract', () => { it('should deploy a public token contract and mint tokens to a recipient', async () => { const mintAmount = 359n; - const recipientIdx = 0; - - const recipient = accounts[recipientIdx]; await deployContract(); const tx = contract.methods.mint(mintAmount, recipient).send({ origin: recipient }); @@ -75,8 +74,6 @@ describe('e2e_public_token_contract', () => { // Regression for https://github.com/AztecProtocol/aztec-packages/issues/640 it('should mint tokens thrice to a recipient within the same block', async () => { const mintAmount = 42n; - const recipientIdx = 0; - const recipient = accounts[recipientIdx]; await deployContract(); diff --git a/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts index dcede5d2deb..0a16ea1d297 100644 --- a/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts @@ -1,7 +1,7 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; import { Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; -import { AztecAddress, EthAddress, Fr, PublicKey } from '@aztec/circuits.js'; +import { AztecAddress, CompleteAddress, EthAddress, Fr, PublicKey } from '@aztec/circuits.js'; import { DeployL1Contracts } from '@aztec/ethereum'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { sha256ToField } from '@aztec/foundation/crypto'; @@ -25,7 +25,7 @@ export class CrossChainTestHarness { aztecNode: AztecNodeService | undefined, aztecRpcServer: AztecRPC, deployL1ContractsValues: DeployL1Contracts, - accounts: AztecAddress[], + accounts: CompleteAddress[], wallet: Wallet, logger: DebugLogger, cheatCodes: CheatCodes, @@ -33,8 +33,7 @@ export class CrossChainTestHarness { const walletClient = deployL1ContractsValues.walletClient; const publicClient = deployL1ContractsValues.publicClient; const ethAccount = EthAddress.fromString((await walletClient.getAddresses())[0]); - const [ownerAddress, receiver] = accounts; - const ownerPub = (await aztecRpcServer.getPublicKeyAndPartialAddress(ownerAddress))[0]; + const [owner, receiver] = accounts; const outbox = getContract({ address: deployL1ContractsValues.outboxAddress.toString(), @@ -50,7 +49,7 @@ export class CrossChainTestHarness { publicClient, deployL1ContractsValues!.registryAddress, initialBalance, - ownerAddress, + owner.address, ); const l2Contract = contracts.l2Contract; const underlyingERC20 = contracts.underlyingERC20; @@ -73,9 +72,9 @@ export class CrossChainTestHarness { outbox, publicClient, walletClient, - ownerAddress, - receiver, - ownerPub, + owner.address, + receiver.address, + owner.publicKey, ); } constructor( @@ -86,7 +85,7 @@ export class CrossChainTestHarness { /** CheatCodes. */ public cc: CheatCodes, /** Accounts. */ - public accounts: AztecAddress[], + public accounts: CompleteAddress[], /** Logger. */ public logger: DebugLogger, @@ -105,7 +104,7 @@ export class CrossChainTestHarness { public outbox: any, /** Viem Public client instance. */ public publicClient: PublicClient, - /** Viem Walllet Client instance. */ + /** Viem Wallet Client instance. */ public walletClient: any, /** Aztec address to use in tests. */ @@ -160,7 +159,7 @@ export class CrossChainTestHarness { // send a transfer tx to force through rollup with the message included const transferTx = this.l2Contract.methods .transfer(transferAmount, this.ownerAddress, this.receiver) - .send({ origin: this.accounts[0] }); + .send({ origin: this.accounts[0].address }); await transferTx.isMined({ interval: 0.1 }); const transferReceipt = await transferTx.getReceipt(); diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 7da10dda70c..0377f851bc2 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -14,7 +14,7 @@ import { getSandboxAccountsWallet, getUnsafeSchnorrAccount, } from '@aztec/aztec.js'; -import { PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { CompleteAddress, PrivateKey, PublicKey } from '@aztec/circuits.js'; import { DeployL1Contracts, deployL1Contract, deployL1Contracts } from '@aztec/ethereum'; import { ContractAbi } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; @@ -140,7 +140,7 @@ export async function setupAztecRPCServer( /** * The accounts created by the RPC server. */ - accounts: AztecAddress[]; + accounts: CompleteAddress[]; /** * The wallet to be used. */ @@ -210,7 +210,7 @@ export async function setup( /** * The accounts created by the RPC server. */ - accounts: AztecAddress[]; + accounts: CompleteAddress[]; /** * The Aztec Node configuration. */ @@ -343,7 +343,7 @@ export function getLogger() { * @param rollupRegistryAddress - address of rollup registry to pass to initialize the token portal * @param initialBalance - initial balance of the owner of the L2 contract * @param owner - owner of the L2 contract - * @param underlyingERC20Address - address of the underlying ERC20 contract to use (if noone supplied, it deploys one) + * @param underlyingERC20Address - address of the underlying ERC20 contract to use (if none supplied, it deploys one) * @returns l2 contract instance, token portal instance, token portal address and the underlying ERC20 instance */ export async function deployAndInitializeNonNativeL2TokenContracts( diff --git a/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts b/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts index 6a6c255a78c..60b903fd0da 100644 --- a/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts +++ b/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts @@ -1,7 +1,7 @@ import { Archiver } from '@aztec/archiver'; import { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; -import { AztecAddress, AztecRPC, Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; +import { AztecAddress, AztecRPC, CompleteAddress, Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; import { DeployL1Contracts } from '@aztec/ethereum'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; @@ -17,7 +17,6 @@ describe('archiver integration with l1 to l2 messages', () => { let aztecRpcServer: AztecRPC; let wallet: Wallet; let archiver: Archiver; - let accounts: AztecAddress[]; let logger: DebugLogger; let config: AztecNodeConfig; @@ -30,11 +29,12 @@ describe('archiver integration with l1 to l2 messages', () => { let publicClient: PublicClient; const initialBalance = 10n; - let ownerAddress: AztecAddress; + let owner: AztecAddress; let receiver: AztecAddress; beforeEach(async () => { let deployL1ContractsValues: DeployL1Contracts | undefined; + let accounts: CompleteAddress[]; ({ aztecNode, aztecRpcServer, wallet, deployL1ContractsValues, accounts, config, logger } = await setup(2)); archiver = await Archiver.createAndSync(config); @@ -42,7 +42,8 @@ describe('archiver integration with l1 to l2 messages', () => { publicClient = deployL1ContractsValues.publicClient; ethAccount = EthAddress.fromString((await walletClient.getAddresses())[0]); - [ownerAddress, receiver] = accounts; + owner = accounts[0].address; + receiver = accounts[1].address; // Deploy and initialize all required contracts logger('Deploying Portal, initializing and deploying l2 contract...'); @@ -52,13 +53,13 @@ describe('archiver integration with l1 to l2 messages', () => { publicClient, deployL1ContractsValues!.registryAddress, initialBalance, - ownerAddress, + owner, ); l2Contract = contracts.l2Contract; underlyingERC20 = contracts.underlyingERC20; tokenPortal = contracts.tokenPortal; tokenPortalAddress = contracts.tokenPortalAddress; - await expectBalance(accounts[0], initialBalance); + await expectBalance(owner, initialBalance); logger('Successfully deployed contracts and initialized portal'); }, 100_000); @@ -97,7 +98,7 @@ describe('archiver integration with l1 to l2 messages', () => { const mintAmount = 100n; logger('Sending messages to L1 portal'); - const args = [ownerAddress.toString(), mintAmount, deadline, secretString, ethAccount.toString()] as const; + const args = [owner.toString(), mintAmount, deadline, secretString, ethAccount.toString()] as const; await tokenPortal.write.depositToAztec(args, {} as any); expect(await underlyingERC20.read.balanceOf([ethAccount.toString()])).toBe(1000000n - mintAmount); @@ -109,7 +110,7 @@ describe('archiver integration with l1 to l2 messages', () => { // cancel the message logger('cancelling the l1 to l2 message'); - const argsCancel = [ownerAddress.toString(), 100n, deadline, secretString, 0n] as const; + const argsCancel = [owner.toString(), 100n, deadline, secretString, 0n] as const; await tokenPortal.write.cancelL1ToAztecMessage(argsCancel, { gas: 1_000_000n } as any); expect(await underlyingERC20.read.balanceOf([ethAccount.toString()])).toBe(1000000n); // let archiver sync up @@ -122,7 +123,7 @@ describe('archiver integration with l1 to l2 messages', () => { it('archiver handles l1 to l2 message correctly even when l2block has no such messages', async () => { // send a transfer tx to force through rollup with the message included const transferAmount = 1n; - l2Contract.methods.transfer(transferAmount, ownerAddress, receiver).send({ origin: accounts[0] }); + l2Contract.methods.transfer(transferAmount, owner, receiver).send({ origin: owner }); expect((await archiver.getPendingL1ToL2Messages(10)).length).toEqual(0); expect(() => archiver.getConfirmedL1ToL2Message(Fr.ZERO)).toThrow(); diff --git a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts index 064c3a546e5..e7a17258485 100644 --- a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts @@ -6,7 +6,7 @@ import { EthAddress } from '@aztec/foundation/eth-address'; import { DebugLogger } from '@aztec/foundation/log'; import { UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-artifacts'; import { UniswapContract } from '@aztec/noir-contracts/types'; -import { AztecRPC, TxStatus } from '@aztec/types'; +import { AztecRPC, CompleteAddress, TxStatus } from '@aztec/types'; import { getContract, parseEther } from 'viem'; @@ -35,12 +35,12 @@ describe('uniswap_trade_on_l1_from_l2', () => { let aztecNode: AztecNodeService | undefined; let aztecRpcServer: AztecRPC; let wallet: Wallet; - let accounts: AztecAddress[]; + let accounts: CompleteAddress[]; let logger: DebugLogger; let cheatCodes: CheatCodes; let ethAccount: EthAddress; - let ownerAddress: AztecAddress; + let owner: AztecAddress; let receiver: AztecAddress; const initialBalance = 10n; const wethAmountToBridge = parseEther('1'); @@ -67,8 +67,9 @@ describe('uniswap_trade_on_l1_from_l2', () => { } ethAccount = EthAddress.fromString((await walletClient.getAddresses())[0]); - [ownerAddress, receiver] = accounts; - const ownerPublicKey = (await aztecRpcServer.getPublicKeyAndPartialAddress(ownerAddress))[0]; + owner = accounts[0].address; + const ownerPublicKey = accounts[0].publicKey; + receiver = accounts[1].address; logger('Deploying DAI Portal, initializing and deploying l2 contract...'); const daiContracts = await deployAndInitializeNonNativeL2TokenContracts( @@ -77,7 +78,7 @@ describe('uniswap_trade_on_l1_from_l2', () => { publicClient, deployL1ContractsValues!.registryAddress, initialBalance, - ownerAddress, + owner, DAI_ADDRESS, ); daiCrossChainHarness = new CrossChainTestHarness( @@ -94,7 +95,7 @@ describe('uniswap_trade_on_l1_from_l2', () => { null, publicClient, walletClient, - ownerAddress, + owner, receiver, ownerPublicKey, ); @@ -106,7 +107,7 @@ describe('uniswap_trade_on_l1_from_l2', () => { publicClient, deployL1ContractsValues!.registryAddress, initialBalance, - ownerAddress, + owner, WETH9_ADDRESS, ); wethCrossChainHarness = new CrossChainTestHarness( @@ -123,7 +124,7 @@ describe('uniswap_trade_on_l1_from_l2', () => { null, publicClient, walletClient, - ownerAddress, + owner, receiver, ownerPublicKey, ); @@ -181,11 +182,11 @@ describe('uniswap_trade_on_l1_from_l2', () => { // 3. Claim WETH on L2 logger('Minting weth on L2'); await wethCrossChainHarness.consumeMessageOnAztecAndMintSecretly(wethAmountToBridge, messageKey, secret); - await wethCrossChainHarness.expectBalanceOnL2(ownerAddress, wethAmountToBridge + initialBalance - transferAmount); + await wethCrossChainHarness.expectBalanceOnL2(owner, wethAmountToBridge + initialBalance - transferAmount); // Store balances - const wethBalanceBeforeSwap = await wethCrossChainHarness.getL2BalanceOf(ownerAddress); - const daiBalanceBeforeSwap = await daiCrossChainHarness.getL2BalanceOf(ownerAddress); + const wethBalanceBeforeSwap = await wethCrossChainHarness.getL2BalanceOf(owner); + const daiBalanceBeforeSwap = await daiCrossChainHarness.getL2BalanceOf(owner); // 4. Send L2 to L1 message to withdraw funds and another message to swap assets. logger('Send L2 tx to withdraw WETH to uniswap portal and send message to swap assets on L1'); @@ -200,20 +201,20 @@ describe('uniswap_trade_on_l1_from_l2', () => { new Fr(3000), daiCrossChainHarness.l2Contract.address.toField(), new Fr(minimumOutputAmount), - ownerAddress, - ownerAddress, + owner, + owner, secretHash, new Fr(2 ** 32 - 1), ethAccount.toField(), ethAccount.toField(), ) - .send({ origin: ownerAddress }); + .send({ origin: owner }); await withdrawTx.isMined({ interval: 0.1 }); const withdrawReceipt = await withdrawTx.getReceipt(); expect(withdrawReceipt.status).toBe(TxStatus.MINED); // check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!) - await wethCrossChainHarness.expectBalanceOnL2(ownerAddress, initialBalance - transferAmount); + await wethCrossChainHarness.expectBalanceOnL2(owner, initialBalance - transferAmount); // 5. Consume L2 to L1 message by calling uniswapPortal.swap() logger('Execute withdraw and swap on the uniswapPortal!'); @@ -225,7 +226,7 @@ describe('uniswap_trade_on_l1_from_l2', () => { 3000, daiCrossChainHarness.tokenPortalAddress.toString(), minimumOutputAmount, - ownerAddress.toString(), + owner.toString(), secretHash.toString(true), deadline, ethAccount.toString(), @@ -250,10 +251,10 @@ describe('uniswap_trade_on_l1_from_l2', () => { // 6. claim dai on L2 logger('Consuming messages to mint dai on L2'); await daiCrossChainHarness.consumeMessageOnAztecAndMintSecretly(daiAmountToBridge, depositDaiMessageKey, secret); - await daiCrossChainHarness.expectBalanceOnL2(ownerAddress, initialBalance + daiAmountToBridge); + await daiCrossChainHarness.expectBalanceOnL2(owner, initialBalance + daiAmountToBridge); - const wethBalanceAfterSwap = await wethCrossChainHarness.getL2BalanceOf(ownerAddress); - const daiBalanceAfterSwap = await daiCrossChainHarness.getL2BalanceOf(ownerAddress); + const wethBalanceAfterSwap = await wethCrossChainHarness.getL2BalanceOf(owner); + const daiBalanceAfterSwap = await daiCrossChainHarness.getL2BalanceOf(owner); logger('WETH balance before swap: ', wethBalanceBeforeSwap.toString()); logger('DAI balance before swap : ', daiBalanceBeforeSwap.toString()); diff --git a/yarn-project/foundation/src/aztec-address/index.ts b/yarn-project/foundation/src/aztec-address/index.ts index c66330c78cb..0b25e4277a9 100644 --- a/yarn-project/foundation/src/aztec-address/index.ts +++ b/yarn-project/foundation/src/aztec-address/index.ts @@ -126,11 +126,11 @@ export class AztecAddress { * Determines if this AztecAddress instance is equal to the given AztecAddress instance. * Equality is based on the content of their respective buffers. * - * @param rhs - The AztecAddress instance to compare against. + * @param other - The AztecAddress instance to compare against. * @returns True if the buffers of both instances are equal, false otherwise. */ - equals(rhs: AztecAddress) { - return this.buffer.equals(rhs.buffer); + equals(other: AztecAddress) { + return this.buffer.equals(other.buffer); } /** diff --git a/yarn-project/types/src/interfaces/aztec_rpc.ts b/yarn-project/types/src/interfaces/aztec_rpc.ts index a12de8b246b..6348b4d88b3 100644 --- a/yarn-project/types/src/interfaces/aztec_rpc.ts +++ b/yarn-project/types/src/interfaces/aztec_rpc.ts @@ -1,6 +1,7 @@ -import { AztecAddress, EthAddress, Fr, PartialAddress, PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { AztecAddress, EthAddress, Fr, PrivateKey } from '@aztec/circuits.js'; import { ContractAbi } from '@aztec/foundation/abi'; import { + CompleteAddress, ContractData, ContractDataAndBytecode, L2BlockL2Logs, @@ -63,22 +64,54 @@ export type SyncStatus = { */ export interface AztecRPC { /** - * Registers an account backed by an account contract. + * Registers an account in the Aztec RPC server. * * @param privKey - Private key of the corresponding user master public key. - * @param address - Address of the account contract. - * @param partialAddress - The partially computed address of the account contract. - * @returns The address of the account contract. + * @param account - A complete address of the account. + * @returns Empty promise. */ - addAccount(privKey: PrivateKey, address: AztecAddress, partialAddress: PartialAddress): Promise; + registerAccount(privKey: PrivateKey, account: CompleteAddress): Promise; /** - * Retrieves the list of Aztec addresses added to this rpc server - * The addresses are returned as a promise that resolves to an array of AztecAddress objects. + * Registers recipient in the Aztec RPC server. + * @param recipient - A complete address of the recipient + * @returns Empty promise. + * @remarks Called recipient because we can only send notes to this account and not receive them via this RPC server. + * This is because we don't have the associated private key and for this reason we can't decrypt + * the recipient's notes. We can send notes to this account because we can encrypt them with the recipient's + * public key. + */ + registerRecipient(recipient: CompleteAddress): Promise; + + /** + * Retrieves the list of accounts added to this rpc server. + * The addresses are returned as a promise that resolves to an array of CompleteAddress objects. + * + * @returns A promise that resolves to an array of the accounts registered on this RPC server. + */ + getAccounts(): Promise; + + /** + * Retrieves the complete address of the account corresponding to the provided aztec address. + * @param address - The aztec address of the account contract. + * @returns A promise that resolves to the complete address of the requested account. + */ + getAccount(address: AztecAddress): Promise; + + /** + * Retrieves the list of recipients added to this rpc server. + * The addresses are returned as a promise that resolves to an array of CompleteAddress objects. * - * @returns A promise that resolves to an array of AztecAddress instances. + * @returns A promise that resolves to an array registered recipients on this RPC server. */ - getAccounts(): Promise; + getRecipients(): Promise; + + /** + * Retrieves the complete address of the recipient corresponding to the provided aztec address. + * @param address - The aztec address of the recipient. + * @returns A promise that resolves to the complete address of the requested recipient. + */ + getRecipient(address: AztecAddress): Promise; /** * Add an array of deployed contracts to the database. @@ -173,30 +206,6 @@ export interface AztecRPC { */ getNodeInfo(): Promise; - /** - * Adds public key and partial address to a database. - * @param address - Address of the account to add public key and partial address for. - * @param publicKey - Public key of the corresponding user. - * @param partialAddress - The partially computed address of the account contract. - * @returns A Promise that resolves once the public key has been added to the database. - */ - addPublicKeyAndPartialAddress( - address: AztecAddress, - publicKey: PublicKey, - partialAddress: PartialAddress, - ): Promise; - - /** - * Retrieve the public key and partial address associated with an address. - * Throws an error if the account is not found in the key store. - * - * @param address - The AztecAddress instance representing the account to get public key and partial address for. - * @returns A Promise resolving to the PublicKey instance representing the public key. - * @remarks The public key and partial address form a preimage of a contract address. See - * https://github.com/AztecProtocol/aztec-packages/blob/janb/rpc-interface-cleanup/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys - */ - getPublicKeyAndPartialAddress(address: AztecAddress): Promise<[PublicKey, PartialAddress]>; - /** * Checks whether all the blocks were processed (tree roots updated, txs updated with block info, etc.). * @returns True if there are no outstanding blocks to be synched.