diff --git a/.circleci/config.yml b/.circleci/config.yml index 82b41376504..c8d57a6a382 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -703,7 +703,7 @@ jobs: command: ./scripts/cond_run_script end-to-end $JOB_NAME ./scripts/run_tests_local e2e_lending_contract.test.ts working_directory: yarn-project/end-to-end - e2e-zk-token-contract: + e2e-private-token-contract: machine: image: ubuntu-2004:202010-01 resource_class: large @@ -715,6 +715,17 @@ jobs: command: ./scripts/cond_run_script end-to-end $JOB_NAME ./scripts/run_tests_local e2e_private_token_contract.test.ts working_directory: yarn-project/end-to-end + e2e-sandbox-example: + docker: + - image: aztecprotocol/alpine-build-image + resource_class: small + steps: + - *checkout + - *setup_env + - run: + name: "Test" + command: cond_spot_run_tests end-to-end e2e_sandbox_example.test.ts docker-compose-e2e-sandbox.yml + e2e-multi-transfer-contract: docker: - image: aztecprotocol/alpine-build-image @@ -1310,7 +1321,8 @@ workflows: - e2e-2-rpc-servers: *e2e_test - e2e-deploy-contract: *e2e_test - e2e-lending-contract: *e2e_test - - e2e-zk-token-contract: *e2e_test + - e2e-private-token-contract: *e2e_test + - e2e-sandbox-example: *e2e_test - e2e-multi-transfer-contract: *e2e_test - e2e-block-building: *e2e_test - e2e-nested-contract: *e2e_test @@ -1338,7 +1350,8 @@ workflows: - e2e-2-rpc-servers - e2e-deploy-contract - e2e-lending-contract - - e2e-zk-token-contract + - e2e-private-token-contract + - e2e-sandbox-example - e2e-multi-transfer-contract - e2e-block-building - e2e-nested-contract diff --git a/docs/docs/dev_docs/getting_started/sandbox.md b/docs/docs/dev_docs/getting_started/sandbox.md index 951ebad7b3c..9fde1de0c4b 100644 --- a/docs/docs/dev_docs/getting_started/sandbox.md +++ b/docs/docs/dev_docs/getting_started/sandbox.md @@ -171,9 +171,13 @@ Add a `tsconfig.json` file into the project root, here is an example: yarn add @aztec/aztec.js @aztec/noir-contracts ``` -7. Create an `index.ts` file in the `src` directory and add the following snippet +7. Create an `index.ts` file in the `src` directory and add the following imports: -#include_code index /docs/src/code_examples/sandbox_example.ts typescript +#include_code imports /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript + +and the following setup code: + +#include_code setup /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript 8. Finally, run the package: @@ -198,7 +202,7 @@ The next step is to create some accounts. An in-depth explaining about accounts Continue with adding the following to the `index.ts` file in our example: -#include_code Accounts /docs/src/code_examples/sandbox_example.ts typescript +#include_code Accounts /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript Running `yarn start` should now output: @@ -224,7 +228,7 @@ If you were looking at your terminal that is running the Sandbox you should hope Now that we have our accounts setup, let's move on to deploy our private token contract. Add this to `index.ts`: -#include_code Deployment /docs/src/code_examples/sandbox_example.ts typescript +#include_code Deployment /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript `yarn start` will now give the following output: @@ -252,7 +256,7 @@ The Private Token Contract emits an unencrypted log message during construction: We can retrieve this emitted log using the `getUnencryptedLogs()` api: -#include_code Logs /docs/src/code_examples/sandbox_example.ts typescript +#include_code Logs /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript Our output will now be: @@ -278,7 +282,7 @@ A token contract wouldn't be very useful if you aren't able to query the balance Call this function using the following code: -#include_code Balance /docs/src/code_examples/sandbox_example.ts typescript +#include_code Balance /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript Running now should yield output: @@ -312,7 +316,7 @@ Now lets transfer some funds from Alice to Bob by calling the `transfer` functio We will again view the unencrypted logs emitted by the function and check the balances after the transfer: -#include_code Transfer /docs/src/code_examples/sandbox_example.ts typescript +#include_code Transfer /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript Our output should now look like this: @@ -346,7 +350,7 @@ Finally, the contract has a `mint` function that can be used to generate new tok Let's mint some tokens to Bob's account: -#include_code Mint /docs/src/code_examples/sandbox_example.ts typescript +#include_code Mint /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript Our complete output should now be: diff --git a/docs/src/code_examples/sandbox_example.ts b/docs/src/code_examples/sandbox_example.ts deleted file mode 100644 index 5e5e391eb14..00000000000 --- a/docs/src/code_examples/sandbox_example.ts +++ /dev/null @@ -1,151 +0,0 @@ -// docs:start:index -import { - AztecRPC, - L2BlockL2Logs, - PrivateKey, - createAztecRpcClient, - createDebugLogger, - getSchnorrAccount, - mustSucceedFetch, -} 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 aztecRpc = createAztecRpcClient(sandboxUrl, mustSucceedFetch); - -const nodeInfo = await aztecRpc.getNodeInfo(); - -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 accountManagers = Array(numAccounts) - .fill(0) - .map(x => - getSchnorrAccount( - aztecRpc, - PrivateKey.random(), // encryption private key - PrivateKey.random(), // signing private key - ), - ); - return await Promise.all( - accountManagers.map(async x => { - await x.waitDeploy({}); - return x; - }), - ); -}; - -// Create 2 accounts and wallets to go with each -logger(`Creating accounts using schnorr signers...`); -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); - -// Verify that the accounts were deployed -const registeredAccounts = (await aztecRpc.getAccounts()).map(x => x.address); -for (const [account, name] of [ - [alice, 'Alice'], - [bob, 'Bob'], -] as const) { - if (registeredAccounts.find(acc => acc.equals(account))) { - logger(`Created ${name}'s account at ${account.toShortString()}`); - continue; - } - logger(`Failed to create account for ${name}!`); -} -// docs:end:Accounts - -// docs:start:Deployment -////////////// DEPLOY OUR PRIVATE TOKEN CONTRACT ////////////// - -// 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...`); -const tokenContractTx = PrivateTokenContract.deploy( - aztecRpc, - initialSupply, // 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 contractData = await aztecRpc.getContractData(receipt.contractAddress!); -if (contractData) { - logger(`Contract successfully deployed at address ${receipt.contractAddress!.toShortString()}`); -} -// docs:end:Deployment -// docs:start:Logs - -////////////// RETRIEVE THE UNENCRYPTED LOGS EMITTED DURING DEPLOYMENT ////////////// - -// We can view the unencrypted logs emitted by the contract... -const viewUnencryptedLogs = async () => { - const lastBlock = await aztecRpc.getBlockNum(); - 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')); - logger(`Emitted logs: `, asciiLogs); -}; -await viewUnencryptedLogs(); - -// docs:end:Logs -// docs:start:Balance - -////////////// QUERYING THE TOKEN BALANCE FOR EACH ACCOUNT ////////////// - -// Create the contract abstraction and link to Alice's wallet for future signing -const tokenContractAlice = await PrivateTokenContract.at(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.at(receipt.contractAddress!, await accounts[1].getWallet()); - -const checkBalances = async () => { - // Check Alice's balance - logger(`Alice's balance ${await tokenContractAlice.methods.getBalance(alice).view()}`); - // Check Bob's balance - logger(`Bob's balance ${await tokenContractBob.methods.getBalance(bob).view()}`); -}; -// Check the initial balances -await checkBalances(); -// docs:end:Balance -// docs:start:Transfer -////////////// TRANSFER FUNDS FROM ALICE TO BOB ////////////// - -// 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(); - -// See if any logs were emitted -await viewUnencryptedLogs(); - -// Check the new balances -await checkBalances(); -// docs:end:Transfer -// docs:start:Mint -////////////// MINT SOME MORE TOKENS TO BOB'S ACCOUNT ////////////// - -// Now mint some further funds for Bob -const mintQuantity = 10_000; -logger(`Minting ${mintQuantity} tokens to Bob...`); -await tokenContractBob.methods.mint(mintQuantity, bob).send().wait(); - -// See if any logs were emitted -await viewUnencryptedLogs(); - -// Check the new balances -await checkBalances(); -// docs:end:Mint diff --git a/yarn-project/end-to-end/.prettierignore b/yarn-project/end-to-end/.prettierignore new file mode 100644 index 00000000000..c9af29d5038 --- /dev/null +++ b/yarn-project/end-to-end/.prettierignore @@ -0,0 +1 @@ +src/e2e_sandbox_example.test.ts 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 64017816f1d..444376f1d2b 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 @@ -113,7 +113,7 @@ describe('e2e_2_rpc_servers', () => { 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']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServerA, ['Balance set in constructor']); // Transfer funds from A to B via RPC server A const contractWithWalletA = await PrivateTokenContract.at(tokenAddress, walletA); @@ -130,7 +130,7 @@ describe('e2e_2_rpc_servers', () => { await expectTokenBalance(walletA, tokenAddress, userA.address, initialBalance - transferAmount1); await expectTokenBalance(walletB, tokenAddress, userB.address, transferAmount1); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 2); - await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Coins transferred']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServerA, ['Coins transferred']); // Transfer funds from B to A via RPC server B const contractWithWalletB = await PrivateTokenContract.at(tokenAddress, walletB); @@ -147,7 +147,7 @@ describe('e2e_2_rpc_servers', () => { 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']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServerA, ['Coins transferred']); }, 120_000); const deployChildContractViaServerA = async () => { 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 6533534d0f5..7ace13af30d 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 @@ -96,7 +96,7 @@ describe('e2e_multiple_accounts_1_enc_key', () => { } await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 2); - await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Coins transferred']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServer, ['Coins transferred']); logger(`Transfer ${transferAmount} from ${sender} to ${receiver} successful`); }; 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 e769433b458..03a5df9272e 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 @@ -58,7 +58,7 @@ describe('e2e_private_token_contract', () => { await expectBalance(receiver, 0n); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 1); - await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Balance set in constructor']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServer, ['Balance set in constructor']); }, 30_000); /** @@ -81,7 +81,7 @@ describe('e2e_private_token_contract', () => { await expectBalance(owner, mintAmount); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 1); - await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Coins minted']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServer, ['Coins minted']); }, 60_000); /** @@ -97,7 +97,7 @@ describe('e2e_private_token_contract', () => { await expectBalance(receiver, 0n); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 1); - await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Balance set in constructor']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServer, ['Balance set in constructor']); const tx = contract.methods.transfer(transferAmount, owner, receiver).send({ origin: owner }); @@ -110,6 +110,6 @@ describe('e2e_private_token_contract', () => { await expectBalance(receiver, transferAmount); await expectsNumOfEncryptedLogsInTheLastBlockToBe(aztecNode, 2); - await expectUnencryptedLogsFromLastBlockToBe(aztecNode, ['Coins transferred']); + await expectUnencryptedLogsFromLastBlockToBe(aztecRpcServer, ['Coins transferred']); }, 60_000); }); diff --git a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts new file mode 100644 index 00000000000..7464b988161 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts @@ -0,0 +1,212 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ + +/* eslint-disable import/no-duplicates */ +// docs:start:imports +import { + AztecRPC, + L2BlockL2Logs, + PrivateKey, + createAztecRpcClient, + createDebugLogger, + getSchnorrAccount, + makeFetch, + waitForSandbox, +} from '@aztec/aztec.js'; +// docs:end:imports + +/* eslint-enable @typescript-eslint/no-unused-vars */ +// Note: this is a hack to make the docs use http://localhost:8080 and CI to use the SANDBOX_URL +import { createAztecRpcClient as createAztecRpcClient2 } from '@aztec/aztec.js'; +import { defaultFetch } from '@aztec/foundation/json-rpc/client'; +import { PrivateTokenContract } from '@aztec/noir-contracts/types'; + +import { expectUnencryptedLogsFromLastBlockToBe } from './fixtures/utils.js'; + +const { SANDBOX_URL } = process.env; + +describe('e2e_sandbox_example', () => { + // Note: this is a hack to make the docs use http://localhost:8080 and CI to use the SANDBOX_URL + const createAztecRpcClient = (url: string, fetch = defaultFetch) => { + return createAztecRpcClient2(SANDBOX_URL!, fetch); + }; + + it('sandbox example works', async () => { + // docs:start:setup + ////////////// CREATE THE CLIENT INTERFACE AND CONTACT THE SANDBOX ////////////// + const logger = createDebugLogger('private-token'); + const sandboxUrl = 'http://localhost:8080'; + + // We create AztecRPC client connected to the sandbox URL and we use fetch with + // 3 automatic retries and a 1s, 2s and 3s intervals between failures. + const aztecRpc = createAztecRpcClient(sandboxUrl, makeFetch([1, 2, 3], false)); + // Wait for sandbox to be ready + await waitForSandbox(aztecRpc); + + const nodeInfo = await aztecRpc.getNodeInfo(); + + logger('Aztec Sandbox Info ', nodeInfo); + // docs:end:setup + + expect(typeof nodeInfo.version).toBe('number'); + expect(typeof nodeInfo.chainId).toBe('number'); + expect(typeof nodeInfo.rollupAddress).toBe('object'); + + // 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 accountManagers = Array(numAccounts) + .fill(0) + .map(() => + getSchnorrAccount( + aztecRpc, + PrivateKey.random(), // encryption private key + PrivateKey.random(), // signing private key + ), + ); + return await Promise.all( + accountManagers.map(async x => { + await x.waitDeploy({}); + return x; + }), + ); + }; + + // Create 2 accounts and wallets to go with each + logger(`Creating accounts using schnorr signers...`); + 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); + + // Verify that the accounts were deployed + const registeredAccounts = (await aztecRpc.getAccounts()).map(x => x.address); + for (const [account, name] of [ + [alice, 'Alice'], + [bob, 'Bob'], + ] as const) { + if (registeredAccounts.find(acc => acc.equals(account))) { + logger(`Created ${name}'s account at ${account.toShortString()}`); + continue; + } + logger(`Failed to create account for ${name}!`); + } + // docs:end:Accounts + + // check that alice and bob are in registeredAccounts + expect(registeredAccounts.find(acc => acc.equals(alice))).toBeTruthy(); + expect(registeredAccounts.find(acc => acc.equals(bob))).toBeTruthy(); + + // docs:start:Deployment + ////////////// DEPLOY OUR PRIVATE TOKEN CONTRACT ////////////// + + // 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_000n; + + logger(`Deploying private token contract minting an initial ${initialSupply} tokens to Alice...`); + const contract = await PrivateTokenContract.deploy( + aztecRpc, + initialSupply, // the initial supply + alice, // the owner of the initial supply + ) + .send() + .deployed(); + + logger(`Contract successfully deployed at address ${contract.address!.toShortString()}`); + // docs:end:Deployment + + // ensure that private token contract is registered in the rpc + expect(await aztecRpc.getContracts()).toEqual(expect.arrayContaining([contract.address])); + + // docs:start:Logs + + ////////////// RETRIEVE THE UNENCRYPTED LOGS EMITTED DURING DEPLOYMENT ////////////// + + // We can view the unencrypted logs emitted by the contract... + const viewUnencryptedLogs = async () => { + const lastBlock = await aztecRpc.getBlockNumber(); + 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')); + logger(`Emitted logs: `, asciiLogs); + }; + await viewUnencryptedLogs(); + + // docs:end:Logs + + await expectUnencryptedLogsFromLastBlockToBe(aztecRpc, ['Balance set in constructor']); + + // docs:start:Balance + + ////////////// QUERYING THE TOKEN BALANCE FOR EACH ACCOUNT ////////////// + + // Create the contract abstraction and link to Alice's wallet for future signing + const tokenContractAlice = await PrivateTokenContract.at(contract.address!, 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.at(contract.address!, await accounts[1].getWallet()); + + let aliceBalance = await tokenContractAlice.methods.getBalance(alice).view(); + logger(`Alice's balance ${aliceBalance}`); + + let bobBalance = await tokenContractBob.methods.getBalance(bob).view(); + logger(`Bob's balance ${bobBalance}`); + + // docs:end:Balance + + expect(aliceBalance).toBe(initialSupply); + expect(bobBalance).toBe(0n); + + // docs:start:Transfer + ////////////// TRANSFER FUNDS FROM ALICE TO BOB ////////////// + + // We will now transfer tokens from ALice to Bob + const transferQuantity = 543n; + logger(`Transferring ${transferQuantity} tokens from Alice to Bob...`); + await tokenContractAlice.methods.transfer(transferQuantity, alice, bob).send().wait(); + + // See if any logs were emitted + await viewUnencryptedLogs(); + + // Check the new balances + aliceBalance = await tokenContractAlice.methods.getBalance(alice).view(); + logger(`Alice's balance ${aliceBalance}`); + + bobBalance = await tokenContractBob.methods.getBalance(bob).view(); + logger(`Bob's balance ${bobBalance}`); + // docs:end:Transfer + + expect(aliceBalance).toBe(initialSupply - transferQuantity); + expect(bobBalance).toBe(transferQuantity); + + await expectUnencryptedLogsFromLastBlockToBe(aztecRpc, ['Coins transferred']); + + // docs:start:Mint + ////////////// MINT SOME MORE TOKENS TO BOB'S ACCOUNT ////////////// + + // Now mint some further funds for Bob + const mintQuantity = 10_000n; + logger(`Minting ${mintQuantity} tokens to Bob...`); + await tokenContractBob.methods.mint(mintQuantity, bob).send().wait(); + + // See if any logs were emitted + await viewUnencryptedLogs(); + + // Check the new balances + aliceBalance = await tokenContractAlice.methods.getBalance(alice).view(); + logger(`Alice's balance ${aliceBalance}`); + + bobBalance = await tokenContractBob.methods.getBalance(bob).view(); + logger(`Bob's balance ${bobBalance}`); + // docs:end:Mint + + expect(aliceBalance).toBe(initialSupply - transferQuantity); + expect(bobBalance).toBe(transferQuantity + mintQuantity); + + await expectUnencryptedLogsFromLastBlockToBe(aztecRpc, ['Coins minted']); + }, 60_000); +}); diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index deb92ad7042..91c7b619282 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -426,21 +426,12 @@ export const expectsNumOfEncryptedLogsInTheLastBlockToBe = async ( /** * Checks that the last block contains the given expected unencrypted log messages. - * @param aztecNode - The instance of aztec node for retrieving the logs. + * @param rpc - The instance of AztecRPC for retrieving the logs. * @param logMessages - The set of expected log messages. - * @returns */ -export const expectUnencryptedLogsFromLastBlockToBe = async ( - aztecNode: AztecNodeService | undefined, - logMessages: string[], -) => { - if (!aztecNode) { - // An api for retrieving encrypted logs does not exist on the rpc server so we have to use the node - // This means we can't perform this check if there is no node - return; - } - const l2BlockNum = await aztecNode.getBlockNumber(); - const unencryptedLogs = await aztecNode.getLogs(l2BlockNum, 1, LogType.UNENCRYPTED); +export const expectUnencryptedLogsFromLastBlockToBe = async (rpc: AztecRPC, logMessages: string[]) => { + const l2BlockNum = await rpc.getBlockNumber(); + const unencryptedLogs = await rpc.getUnencryptedLogs(l2BlockNum, 1); const unrolledLogs = L2BlockL2Logs.unrollLogs(unencryptedLogs); const asciiLogs = unrolledLogs.map(log => log.toString('ascii'));