diff --git a/.circleci/config.yml b/.circleci/config.yml index 611cfc34b85..bd7238dad61 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -969,6 +969,17 @@ jobs: command: ./scripts/cond_run_script end-to-end $JOB_NAME ./scripts/run_tests_local aztec_rpc_sandbox.test.ts ./scripts/docker-compose-e2e-sandbox.yml working_directory: yarn-project/end-to-end + cli-docs-sandbox: + machine: + image: ubuntu-2004:202010-01 + steps: + - *checkout + - *setup_env + - run: + name: "Test" + command: ./scripts/cond_run_script end-to-end $JOB_NAME ./scripts/run_tests_local cli_docs_sandbox.test.ts ./scripts/docker-compose-e2e-sandbox.yml + working_directory: yarn-project/end-to-end + guides-writing-an-account-contract: machine: image: ubuntu-2004:202010-01 @@ -1429,6 +1440,7 @@ workflows: - e2e-browser-sandbox: *e2e_test - e2e-card-game: *e2e_test - aztec-rpc-sandbox: *e2e_test + - cli-docs-sandbox: *e2e_test - guides-writing-an-account-contract: *e2e_test - guides-dapp-testing: *e2e_test @@ -1461,6 +1473,7 @@ workflows: - e2e-canary-test - e2e-card-game - aztec-rpc-sandbox + - cli-docs-sandbox - guides-writing-an-account-contract - guides-dapp-testing <<: *defaults diff --git a/docs/docs/concepts/foundation/accounts/main.md b/docs/docs/concepts/foundation/accounts/main.md index 7343fd73f3a..8666a33eff9 100644 --- a/docs/docs/concepts/foundation/accounts/main.md +++ b/docs/docs/concepts/foundation/accounts/main.md @@ -1,6 +1,6 @@ # Accounts -**Every account in Aztec is a smart contract** which defines the rules for whether a transaction is or not valid. This allows implementing different schemes for transaction signing, nonce management, and fee payments. However, encryption and nullifying keys, which are specific to private blockchains, are still enshrined at the protocol level. +**Every account in Aztec is a smart contract** which defines the rules for whether a transaction is or is not valid. This allows implementing different schemes for transaction signing, nonce management, and fee payments. However, encryption and nullifying keys, which are specific to private blockchains, are still enshrined at the protocol level. ## Background diff --git a/docs/docs/dev_docs/getting_started/cli.md b/docs/docs/dev_docs/getting_started/cli.md index b3154f4a4a3..d5681106936 100644 --- a/docs/docs/dev_docs/getting_started/cli.md +++ b/docs/docs/dev_docs/getting_started/cli.md @@ -36,10 +36,7 @@ Lets first establish that we are able to communicate with the Sandbox. Most comm To test communication with the Sandbox, let's run the command: -```bash -% aztec-cli block-number -1 -``` +#include_code block-number yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash You should see the current block number (1) printed to the screen! @@ -47,25 +44,7 @@ You should see the current block number (1) printed to the screen! We have shipped a number of example contracts in the `@aztec/noir-contracts` npm package. This is included with the cli by default so you are able to use these contracts to test with. To get a list of the names of the contracts run: -```bash -% aztec-cli example-contracts -ChildContractAbi -EasyPrivateTokenContractAbi -EcdsaAccountContractAbi -EscrowContractAbi -LendingContractAbi -NonNativeTokenContractAbi -ParentContractAbi -PendingCommitmentsContractAbi -PokeableTokenContractAbi -PrivateTokenAirdropContractAbi -PrivateTokenContractAbi -PublicTokenContractAbi -SchnorrAccountContractAbi -SchnorrSingleKeyAccountContractAbi -TestContractAbi -UniswapContractAbi -``` +#include_code example-contracts yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash In the following sections there will be commands that require contracts as options. You can either specify the full directory path to the contract abi, or you can use the name of one of these examples as the option value. This will become clearer later on. @@ -73,19 +52,11 @@ In the following sections there will be commands that require contracts as optio The first thing we want to do is create a couple of accounts. We will use the `create-account` command which will generate a new private key for us, register the account on the sandbox, and deploy a simple account contract which [uses a single key for privacy and authentication](../../concepts/foundation/accounts/keys.md): -```bash -% aztec-cli create-account -Created new account: - -Address: 0x20d3321707d53cebb168568e25c5c62a853ae1f0766d965e00d6f6c4eb05d599 -Public key: 0x02d18745eadddd496be95274367ee2cbf0bf667b81373fb6bed715c18814a09022907c273ec1c469fcc678738bd8efc3e9053fe1acbb11fa32da0d6881a1370e -Private key: 0x2aba9e7de7075deee3e3f4ad1e47749f985f0f72543ed91063cc97a40d851f1e -Partial address: 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed -``` +#include_code create-account yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash Once the account is set up, the CLI returns the resulting address, its privacy key, and partial address. You can read more about these [here](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys). -Save the Address and Private key as environement variables. We will be using them later. +Save the Address and Private key as environment variables. We will be using them later. ```bash export ADDRESS=
@@ -94,38 +65,13 @@ export PRIVATE_KEY= Alternatively, we can also manually generate a private key and use it for creating the account, either via a `-k` option or by setting the `PRIVATE_KEY` environment variable. -```bash -% aztec-cli generate-private-key - -Private Key: 0x6622c828e9cd5adc86f10878765fe921d2b8cb2c79bdbc391157e43811ce88e3 -Public Key: 0x08aad54f32f1b6621ee5f25267166e160147cd355a2dfc129fa646a651dd29471d814ac749c2cda831fcca361c830ba56db4b4bd5951d4953c81865d0ae0cbe7 - - -% aztec-cli create-account --private-key 0x6622c828e9cd5adc86f10878765fe921d2b8cb2c79bdbc391157e43811ce88e3 - -Created new account: - -Address: 0x175310d40cd3412477db1c2a2188efd586b63d6830115fbb46c592a6303dbf6c -Public key: 0x08aad54f32f1b6621ee5f25267166e160147cd355a2dfc129fa646a651dd29471d814ac749c2cda831fcca361c830ba56db4b4bd5951d4953c81865d0ae0cbe7 -Partial address: 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed -``` +#include_code create-account-from-private-key yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash For all commands that require a user's private key, the CLI will look for the `PRIVATE_KEY` environment variable in absence of an optional argument. Let's double check that the accounts have been registered with the sandbox using the `get-accounts` command: -```bash -% aztec-cli get-accounts -Accounts found: - -Address: 0x20d3321707d53cebb168568e25c5c62a853ae1f0766d965e00d6f6c4eb05d599 -Public key: 0x02d18745eadddd496be95274367ee2cbf0bf667b81373fb6bed715c18814a09022907c273ec1c469fcc678738bd8efc3e9053fe1acbb11fa32da0d6881a1370e -Partial address: 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed - -Address: 0x175310d40cd3412477db1c2a2188efd586b63d6830115fbb46c592a6303dbf6c -Public key: 0x08aad54f32f1b6621ee5f25267166e160147cd355a2dfc129fa646a651dd29471d814ac749c2cda831fcca361c830ba56db4b4bd5951d4953c81865d0ae0cbe7 -Partial address: 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed -``` +#include_code get-accounts yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash Save one of the printed accounts (not the one that you generated above) in an environment variable. We will use it later. @@ -137,11 +83,7 @@ export ADDRESS2= We will now deploy the private token contract using the `deploy` command, minting 1000000 initial tokens to address `0x175310d40cd3412477db1c2a2188efd586b63d6830115fbb46c592a6303dbf6c`. Make sure to replace this address with one of the two you created earlier. -```bash -% aztec-cli deploy PrivateTokenContractAbi --args 1000000 $ADDRESS - -Contract deployed at 0x1ae8eea0dc265fb7f160dae62cc8912686d8a9ed78e821fbdd8bcedc54c06d0f -``` +#include_code deploy yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash Save the contract address as an environment variable. We will use it later. @@ -158,30 +100,17 @@ Alternatively you can pass the name of an example contract as exported by `@azte The command takes a few optional arguments while the most important one is: -- `--args` - Arguments to the constructor of the contract. In this case we have minted 1000000 initial tokens to the aztec address 0x175310d40cd3412477db1c2a2188efd586b63d6830115fbb46c592a6303dbf6c. +- `--args` - Arguments to the constructor of the contract. In this case we have minted 1000000 initial tokens to the aztec address 0x20d3321707d53cebb168568e25c5c62a853ae1f0766d965e00d6f6c4eb05d599. The CLI tells us that the contract was successfully deployed. We can use the `check-deploy` command to verify that a contract has been successfully deployed to that address: -```bash -% aztec-cli check-deploy --contract-address $CONTRACT_ADDRESS - -Contract found at 0x1ae8eea0dc265fb7f160dae62cc8912686d8a9ed78e821fbdd8bcedc54c06d0f -``` +#include_code check-deploy yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash ## Calling a View Method When we deployed the token contract, an initial supply of tokens was minted to the address provided in the constructor. We can now query the `getBalance()` method on the contract to retrieve the balance of that address. Make sure to replace the `contract-address` with the deployment address you got from the previous command, and the `args` with the account you used in the constructor. -```bash -% aztec-cli call getBalance \ - --args $ADDRESS \ - --contract-abi PrivateTokenContractAbi \ - --contract-address $CONTRACT_ADDRESS - -View result: [ - "{\"type\":\"bigint\",\"data\":\"1000000\"}" -] -``` +#include_code call yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash The `call` command calls a read-only method on a contract, one that will not generate a transaction to be sent to the network. The arguments here are: @@ -195,19 +124,7 @@ As you can see from the result, this address has a balance of 1000000, as expect We can now send a transaction to the network. We will transfer funds from the owner of the initial minted tokens to our other account. For this we will use the `send` command, which expects as arguments the quantity of tokens to be transferred, the sender's address, and the recipient's address. Make sure to replace all addresses in this command with the ones for your run. -```bash -% aztec-cli send transfer \ - --args 543 $ADDRESS2 \ - --contract-abi PrivateTokenContractAbi \ - --contract-address $CONTRACT_ADDRESS \ - --private-key $PRIVATE_KEY - -Transaction has been mined -Transaction hash: 15c5a8e58d5f895c7e3017a706efbad693635e01f67345fa60a64a340d83c78c -Status: mined -Block number: 5 -Block hash: 163697608599543b2bee9652f543938683e4cdd0f94ac506e5764d8b908d43d4 -``` +#include_code send yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash We called the `transfer` function of the contract and provided these arguments: @@ -218,32 +135,8 @@ We called the `transfer` function of the contract and provided these arguments: The command output tells us the details of the transaction such as its hash and status. We can use this hash to query the receipt of the transaction at a later time: -```bash -% aztec-cli get-tx-receipt 15c5a8e58d5f895c7e3017a706efbad693635e01f67345fa60a64a340d83c78c - -Transaction receipt: -{ - "txHash": "15c5a8e58d5f895c7e3017a706efbad693635e01f67345fa60a64a340d83c78c", - "status": "mined", - "error": "", - "blockHash": "163697608599543b2bee9652f543938683e4cdd0f94ac506e5764d8b908d43d4", - "blockNumber": 5, - "origin": "0x2337f1d5cfa6c03796db5539b0b2d5a57e9aed42665df2e0907f66820cb6eebe" -} -``` +#include_code get-tx-receipt yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash Let's now call `getBalance()` on each of our accounts and we should see updated values: -```bash -% aztec-cli call getBalance -a $ADDRESS -c PrivateTokenContractAbi -ca $CONTRACT_ADDRESS - -View result: [ - "{\"type\":\"bigint\",\"data\":\"999457\"}" -] - -% aztec-cli call getBalance -a $ADDRESS2 -c PrivateTokenContractAbi -ca $CONTRACT_ADDRESS - -View result: [ - "{\"type\":\"bigint\",\"data\":\"543\"}" -] -``` +#include_code calls yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash diff --git a/yarn-project/cli/src/encoding.ts b/yarn-project/cli/src/encoding.ts index da1381c321c..93cbc4296a5 100644 --- a/yarn-project/cli/src/encoding.ts +++ b/yarn-project/cli/src/encoding.ts @@ -90,7 +90,9 @@ function encodeArg(arg: string, abiType: ABIType, name: string): any { */ export function encodeArgs(args: any[], params: ABIParameter[]) { if (args.length !== params.length) { - throw new Error(`Invalid number of args provided. Expected: ${params.length}, received: ${args.length}`); + throw new Error( + `Invalid number of args provided. Expected: ${params.length}, received: ${args.length}\nReceived args: ${args}`, + ); } return args .map((arg: any, index) => { diff --git a/yarn-project/end-to-end/src/cli_docs_sandbox.test.ts b/yarn-project/end-to-end/src/cli_docs_sandbox.test.ts new file mode 100644 index 00000000000..9975f3addc4 --- /dev/null +++ b/yarn-project/end-to-end/src/cli_docs_sandbox.test.ts @@ -0,0 +1,397 @@ +import { AztecAddress, createDebugLogger, sleep } from '@aztec/aztec.js'; +import { getProgram } from '@aztec/cli'; +import { TxHash } from '@aztec/types'; + +import stringArgv from 'string-argv'; +import { format } from 'util'; + +const debug = createDebugLogger('aztec:e2e_cli'); + +const { SANDBOX_URL = 'http://localhost:8080' } = process.env; + +describe('CLI docs sandbox', () => { + let cli: ReturnType; + let log: (...args: any[]) => void; + + // All logs emitted by the cli will be collected here, and reset between tests + const logs: string[] = []; + + beforeAll(async () => { + log = (...args: any[]) => { + logs.push(format(...args)); + debug(...args); + }; + + await waitForSandboxWithCli(); + }, 60_000); + + const waitForSandboxWithCli = async () => { + while (true) { + resetCli(); + try { + await run('get-node-info'); + break; + } catch (err) { + await sleep(1000); + } + } + }; + + // in order to run the same command twice, we need to create a new CLI instance + const resetCli = () => { + cli = getProgram(log, debug); + }; + + beforeEach(() => { + logs.splice(0); + resetCli(); + }); + + // Run a command on the CLI + const run = (cmd: string, addRpcUrl = true) => { + const args = stringArgv(cmd, 'node', 'dest/bin/index.js'); + if (addRpcUrl) { + args.push('--rpc-url', SANDBOX_URL); + } + return cli.parseAsync(args); + }; + + // Returns first match across all logs collected so far + const findInLogs = (regex: RegExp) => { + for (const log of logs) { + const match = regex.exec(log); + if (match) return match; + } + }; + + const findMultipleInLogs = (regex: RegExp) => { + const matches = []; + for (const log of logs) { + const match = regex.exec(log); + if (match) matches.push(match); + } + return matches; + }; + + const clearLogs = () => { + logs.splice(0); + }; + + it('prints example contracts', async () => { + const docs = ` +// docs:start:example-contracts +% aztec-cli example-contracts +CardGameContractAbi +ChildContractAbi +DocsExampleContractAbi +EasyPrivateTokenContractAbi +EcdsaAccountContractAbi +EscrowContractAbi +ImportTestContractAbi +LendingContractAbi +MultiTransferContractAbi +NativeTokenContractAbi +NonNativeTokenContractAbi +ParentContractAbi +PendingCommitmentsContractAbi +PokeableTokenContractAbi +PriceFeedContractAbi +PrivateTokenAirdropContractAbi +PrivateTokenContractAbi +PublicTokenContractAbi +SchnorrAccountContractAbi +SchnorrAuthWitnessAccountContractAbi +SchnorrHardcodedAccountContractAbi +SchnorrSingleKeyAccountContractAbi +TestContractAbi +UniswapContractAbi +// docs:end:example-contracts +`; + + const command = docs.split('\n')[2].split('aztec-cli ')[1]; + const expectedConsoleOutput = docs.split('\n').slice(3, -2); + + await run(command, false); + expect(logs).toEqual(expectedConsoleOutput); + }); + + it('gets a block number', async () => { + const docs = ` +// docs:start:block-number +% aztec-cli block-number +1 +// docs:end:block-number +`; + + const command = docs.split('\n')[2].split('aztec-cli ')[1]; + + await run(command); + // expect logs to contain a number and nothing else + expect(logs.length).toEqual(1); + expect(logs[0]).toMatch(/\d+/); + }); + + it('creates an account from private key', async () => { + const docs = ` +// docs:start:create-account-from-private-key +% aztec-cli generate-private-key + +Private Key: 0x12684562c8676e66be100878434b01286a757dea468233f818b906f66fb34984 +Public Key: 0x1003732857c052c1d6af4dd74b5631863a056c90a586c4e3ea6d94782ee712d317cdb713ed1ba02d3df0ac2b581d269490f9e24916c1b677c7259444aa0ad66b + + +% aztec-cli create-account --private-key 0x12684562c8676e66be100878434b01286a757dea468233f818b906f66fb34984 + +Created new account: + +Address: 0x26e831b1b146d1faf0c1d27fc72f2243887e9963cc87a6b3af64fe6481920a80 +Public key: 0x1003732857c052c1d6af4dd74b5631863a056c90a586c4e3ea6d94782ee712d317cdb713ed1ba02d3df0ac2b581d269490f9e24916c1b677c7259444aa0ad66b +Partial address: 0x01e5e7b2abbfb98a93b7549ae80faa6886f8ea8e8f412416fb330b565fd2b4ed +// docs:end:create-account-from-private-key +`; + + const generateCommand = docs.split('\n')[2].split('aztec-cli ')[1]; + await run(generateCommand, false); + + const foundPrivateKey = findInLogs(/Private\sKey:\s+(?0x[a-fA-F0-9]+)/)?.groups?.privateKey; + expect(foundPrivateKey).toBeDefined(); + const foundPublicKeyGenerate = findInLogs(/Public\sKey:\s+(?0x[a-fA-F0-9]+)/)?.groups?.publicKey; + expect(foundPublicKeyGenerate).toBeDefined(); + + clearLogs(); + + const createCommand = docs.split('\n')[8].split('aztec-cli ')[1]; + + await run(createCommand); + const foundAddress = findInLogs(/Address:\s+(?
0x[a-fA-F0-9]+)/)?.groups?.address; + expect(foundAddress).toBeDefined(); + const foundPublicKey = findInLogs(/Public\skey:\s+(?0x[a-fA-F0-9]+)/)?.groups?.publicKey; + expect(foundPublicKey).toBeDefined(); + const foundPartialAddress = findInLogs(/Partial\saddress:\s+(?0x[a-fA-F0-9]+)/)?.groups + ?.partialAddress; + expect(foundPartialAddress).toBeDefined(); + }); + + it('creates an account, gets account, deploys, checks deployed, view method, sending a tx... [SEQUENTIAL]', async () => { + // Test create-account + let docs = ` +// docs:start:create-account +% aztec-cli create-account +Created new account: + +Address: 0x20d3321707d53cebb168568e25c5c62a853ae1f0766d965e00d6f6c4eb05d599 +Public key: 0x02d18745eadddd496be95274367ee2cbf0bf667b81373fb6bed715c18814a09022907c273ec1c469fcc678738bd8efc3e9053fe1acbb11fa32da0d6881a1370e +Private key: 0x2aba9e7de7075deee3e3f4ad1e47749f985f0f72543ed91063cc97a40d851f1e +Partial address: 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed +// docs:end:create-account +`; + + let command = docs.split('\n')[2].split('aztec-cli ')[1]; + + await run(command); + const foundAddress = findInLogs(/Address:\s+(?
0x[a-fA-F0-9]+)/)?.groups?.address; + expect(foundAddress).toBeDefined(); + const foundPublicKey = findInLogs(/Public\skey:\s+(?0x[a-fA-F0-9]+)/)?.groups?.publicKey; + expect(foundPublicKey).toBeDefined(); + const foundPrivateKey = findInLogs(/Private\skey:\s+(?0x[a-fA-F0-9]+)/)?.groups?.privateKey; + expect(foundPrivateKey).toBeDefined(); + const foundPartialAddress = findInLogs(/Partial\saddress:\s+(?0x[a-fA-F0-9]+)/)?.groups + ?.partialAddress; + expect(foundPartialAddress).toBeDefined(); + const newAddress = AztecAddress.fromString(foundAddress!); + + clearLogs(); + + // Test get-account + docs = ` +// docs:start:get-accounts +% aztec-cli get-accounts +Accounts found: + +Address: 0x20d3321707d53cebb168568e25c5c62a853ae1f0766d965e00d6f6c4eb05d599 +Public key: 0x02d18745eadddd496be95274367ee2cbf0bf667b81373fb6bed715c18814a09022907c273ec1c469fcc678738bd8efc3e9053fe1acbb11fa32da0d6881a1370e +Partial address: 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed + +Address: 0x175310d40cd3412477db1c2a2188efd586b63d6830115fbb46c592a6303dbf6c +Public key: 0x08aad54f32f1b6621ee5f25267166e160147cd355a2dfc129fa646a651dd29471d814ac749c2cda831fcca361c830ba56db4b4bd5951d4953c81865d0ae0cbe7 +Partial address: 0x72bf7c9537875b0af267b4a8c497927e251f5988af6e30527feb16299042ed +// docs:end:get-accounts +`; + + command = docs.split('\n')[2].split('aztec-cli ')[1]; + await run(command); + + const fetchedAddresses = findMultipleInLogs(/Address:\s+(?
0x[a-fA-F0-9]+)/); + const foundFetchedAddress = fetchedAddresses.find(match => match.groups?.address === newAddress.toString()); + expect(foundFetchedAddress).toBeDefined(); + + clearLogs(); + + // Set some of the found addresses as address2 for later use + const address2 = AztecAddress.fromString(fetchedAddresses[1].groups?.address as string); + + // Test deploy + docs = ` +// docs:start:deploy +% aztec-cli deploy PrivateTokenContractAbi --args 1000000 $ADDRESS + +Contract deployed at 0x1ae8eea0dc265fb7f160dae62cc8912686d8a9ed78e821fbdd8bcedc54c06d0f +// docs:end:deploy + `; + + command = docs.split('\n')[2].split('aztec-cli ')[1].replace('$ADDRESS', newAddress.toString()); + await run(command); + + let foundContractAddress = findInLogs(/Contract\sdeployed\sat\s(?
0x[a-fA-F0-9]+)/)?.groups?.address; + expect(foundContractAddress).toBeDefined(); + const contractAddress = AztecAddress.fromString(foundContractAddress!); + + clearLogs(); + + // Test check-deploy + docs = ` +// docs:start:check-deploy +% aztec-cli check-deploy --contract-address $CONTRACT_ADDRESS + +Contract found at 0x1ae8eea0dc265fb7f160dae62cc8912686d8a9ed78e821fbdd8bcedc54c06d0f +// docs:end:check-deploy +`; + command = docs.split('\n')[2].split('aztec-cli ')[1].replace('$CONTRACT_ADDRESS', contractAddress.toString()); + await run(command); + + foundContractAddress = findInLogs(/Contract\sfound\sat\s(?
0x[a-fA-F0-9]+)/)?.groups?.address; + expect(foundContractAddress).toEqual(contractAddress.toString()); + + clearLogs(); + + // Test call + docs = ` +// docs:start:call +% aztec-cli call getBalance \ + --args $ADDRESS \ + --contract-abi PrivateTokenContractAbi \ + --contract-address $CONTRACT_ADDRESS + +View result: 1000000n +// docs:end:call +`; + command = docs + .split('\n')[2] + .split('aztec-cli ')[1] + .replace('$ADDRESS', newAddress.toString()) + .replace('$CONTRACT_ADDRESS', contractAddress.toString()); + await run(command); + + let foundBalance = findInLogs(/View\sresult:\s+(?\S+)/)?.groups?.data; + expect(foundBalance!).toEqual(`${BigInt(1000000).toString()}n`); + + clearLogs(); + + // We reset CLI so that we can call the same command again later on + resetCli(); + + // Test send + docs = ` +// docs:start:send +% aztec-cli send transfer \ + --args 543 $ADDRESS2 \ + --contract-abi PrivateTokenContractAbi \ + --contract-address $CONTRACT_ADDRESS \ + --private-key $PRIVATE_KEY + +Transaction has been mined +Transaction hash: 15c5a8e58d5f895c7e3017a706efbad693635e01f67345fa60a64a340d83c78c +Status: mined +Block number: 5 +Block hash: 163697608599543b2bee9652f543938683e4cdd0f94ac506e5764d8b908d43d4 +// docs:end:send +`; + + command = docs + .split('\n')[2] + .split('aztec-cli ')[1] + .replace('$ADDRESS2', address2.toString()) + .replace('$CONTRACT_ADDRESS', contractAddress.toString()) + .replace('$PRIVATE_KEY', foundPrivateKey!); + await run(command); + + let foundTxHash = findInLogs(/Transaction\shash:\s+(?\S+)/)?.groups?.txHash; + expect(foundTxHash).toBeDefined(); + + clearLogs(); + + // Save the tx hash for later use + const transferTxHash = TxHash.fromString(foundTxHash!); + + // Test get-tx-receipt + docs = ` +// docs:start:get-tx-receipt +% aztec-cli get-tx-receipt 15c5a8e58d5f895c7e3017a706efbad693635e01f67345fa60a64a340d83c78c + +Transaction receipt: +{ + "txHash": "15c5a8e58d5f895c7e3017a706efbad693635e01f67345fa60a64a340d83c78c", + "status": "mined", + "error": "", + "blockHash": "163697608599543b2bee9652f543938683e4cdd0f94ac506e5764d8b908d43d4", + "blockNumber": 5, + "origin": "0x2337f1d5cfa6c03796db5539b0b2d5a57e9aed42665df2e0907f66820cb6eebe" +} +// docs:end:get-tx-receipt +`; + + command = docs + .split('\n')[2] + .split('aztec-cli ')[1] + .replace('15c5a8e58d5f895c7e3017a706efbad693635e01f67345fa60a64a340d83c78c', transferTxHash.toString()); + await run(command); + + foundTxHash = findInLogs(/"txHash":\s+"(?\S+)"/)?.groups?.txHash; + expect(foundTxHash).toEqual(transferTxHash.toString()); + const status = findInLogs(/"status":\s+"(?\S+)"/)?.groups?.status; + expect(status).toEqual('mined'); + const error = findInLogs(/"error":\s+"(?\S*)"/)?.groups?.error; + expect(error).toEqual(''); + + clearLogs(); + + // get balance + docs = ` +// docs:start:calls +% aztec-cli call getBalance -a $ADDRESS -c PrivateTokenContractAbi -ca $CONTRACT_ADDRESS + +View result: 999457n + +% aztec-cli call getBalance -a $ADDRESS2 -c PrivateTokenContractAbi -ca $CONTRACT_ADDRESS + +View result: 543n +// docs:end:calls +`; + command = docs + .split('\n')[2] + .split('aztec-cli ')[1] + .replace('$ADDRESS', newAddress.toString()) + .replace('$CONTRACT_ADDRESS', contractAddress.toString()); + + await run(command); + + foundBalance = findInLogs(/View\sresult:\s+(?\S+)/)?.groups?.data; + expect(foundBalance!).toEqual(`${BigInt(999457).toString()}n`); + + clearLogs(); + resetCli(); + + command = docs + .split('\n')[6] + .split('aztec-cli ')[1] + .replace('$ADDRESS2', address2.toString()) + .replace('$CONTRACT_ADDRESS', contractAddress.toString()); + + await run(command); + + foundBalance = findInLogs(/View\sresult:\s+(?\S+)/)?.groups?.data; + expect(foundBalance!).toEqual(`${BigInt(543).toString()}n`); + + clearLogs(); + }, 60_000); +});