Skip to content

Commit f95bcff

Browse files
critesjoshjzaki
andauthored
fix(docs): Dapp tutorial edits (#8695)
closes: AztecProtocol/dev-rel#383 --------- Co-authored-by: James Zaki <james.zaki@proton.me>
1 parent 367c38c commit f95bcff

File tree

11 files changed

+82
-56
lines changed

11 files changed

+82
-56
lines changed

docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ You can see all of our example contracts in the monorepo [here (GitHub link)](ht
166166
If you wish to run components of the Aztec network stack separately, you can use the `aztec start` command with various options for enabling components.
167167

168168
```bash
169-
aztec start --node [nodeOptions] --pxe [pxeOptions] --archiver [archiverOptions] --sequencer [sequencerOptions] --prover [proverOptions] ----p2p-bootstrap [p2pOptions]
169+
aztec start --node [nodeOptions] --pxe [pxeOptions] --archiver [archiverOptions] --sequencer [sequencerOptions] --prover [proverOptions] --p2p-bootstrap [p2pOptions]
170170
```
171171

172172
Starting the aztec node alongside a PXE, sequencer or archiver, will attach the components to the node. Eg if you want to run a PXE separately to a node, you can [read this guide](../../../guides/developer_guides/local_env/run_more_than_one_pxe_sandbox.md).

docs/docs/tutorials/codealong/simple_dapp/0_project_setup.md

+2-6
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@ cd sample-dapp
2020
yarn init -yp
2121
```
2222

23-
3. Add the `aztec.js` and `accounts` libraries as a dependency:
23+
3. Add the `aztec.js` and `accounts` libraries as dependencies. Also add `noir-contracts.js` for quick use of example contracts:
2424

2525
```sh
26-
yarn add @aztec/aztec.js @aztec/accounts
26+
yarn add @aztec/aztec.js @aztec/accounts @aztec/noir-contracts.js
2727
```
28-
29-
## Next steps
30-
31-
With your project already set up, let's [connect to the Private eXecution Environment (PXE) running inside Sandbox and grab an account to interact with it](./1_pxe_service.md).

docs/docs/tutorials/codealong/simple_dapp/1_pxe_service.md

+9-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ PXE is a component of the Aztec Protocol that provides a private execution envir
44

55
As an app developer, the PXE interface provides you with access to the user's accounts and their private state, as well as a connection to the network for accessing public global state.
66

7-
During the Sandbox phase, this role is fulfilled by the [Aztec Sandbox](../../../reference/developer_references/sandbox_reference/index.md), which runs a local PXE and an Aztec Node, both connected to a local Ethereum development node like Anvil.
7+
The [Aztec Sandbox](../../../reference/developer_references/sandbox_reference/index.md) runs a local PXE and an Aztec Node, both connected to a local Ethereum development node like Anvil.
88
The Sandbox also includes a set of pre-initialized accounts that you can use from your app.
99

1010
In this section, we'll connect to the Sandbox from our project.
@@ -20,7 +20,13 @@ Let's create our first file `src/index.mjs` with the following contents:
2020

2121
#include_code all yarn-project/end-to-end/src/sample-dapp/connect.mjs javascript
2222

23-
Run this example as `node src/index.mjs` and you should see the following output:
23+
Make sure the [Sandbox is running](../../../guides/developer_guides/getting_started.md) and run the example
24+
25+
```bash
26+
node src/index.mjs
27+
```
28+
29+
and you should see the following output:
2430

2531
```
2632
Connected to chain 31337
@@ -37,7 +43,7 @@ Let's try loading the accounts:
3743

3844
#include_code showAccounts yarn-project/end-to-end/src/sample-dapp/index.mjs javascript
3945

40-
Run again the above, and we should see:
46+
Call the `showAccounts` function from `main`, run again the above, and you should see something like:
4147

4248
```
4349
User accounts:

docs/docs/tutorials/codealong/simple_dapp/2_contract_deployment.md

+11-7
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ Last, copy-paste the code from the `Token` contract into `contracts/token/main.n
3030

3131
### Helper files
3232

33+
:::info
34+
Remove the `mod test;` line from `contracts/token/src/main.nr` as we will not be using TXE tests in this tutorial.
35+
:::
36+
3337
The `Token` contract also requires some helper files. You can view the files [here (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/noir-contracts/contracts/token_contract/src). Copy the `types.nr` and the `types` folder into `contracts/token/src`.
3438

3539
## Compile your contract
@@ -46,15 +50,15 @@ aztec-nargo compile
4650

4751
Let's now write a script for deploying your contracts to the Sandbox. We'll create a Private eXecution Environment (PXE) client, and then use the `ContractDeployer` class to deploy our contracts, and store the deployment address to a local JSON file.
4852

49-
Create a new file `src/deploy.mjs`:
53+
Create a new file `src/deploy.mjs`. We import the contract artifacts we have generated plus the dependencies we'll need, and then we can deploy the contracts by adding the following code to the `src/deploy.mjs` file.
5054

5155
```js
5256
// src/deploy.mjs
57+
#include_code deploy-imports yarn-project/end-to-end/src/sample-dapp/deploy.mjs raw
58+
import TokenContractJson from "../contracts/token/target/token-Token.json" assert { type: "json" };
5359
import { writeFileSync } from 'fs';
54-
import { Contract, loadContractArtifact, createPXEClient } from '@aztec/aztec.js';
55-
import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
56-
import TokenContractJson from "../contracts/token/target/token_contract-Token.json" assert { type: "json" };
5760

61+
const TokenContractArtifact = loadContractArtifact(TokenContractJson);
5862

5963
#include_code dapp-deploy yarn-project/end-to-end/src/sample-dapp/deploy.mjs raw
6064

@@ -64,12 +68,12 @@ main().catch((err) => {
6468
});
6569
```
6670

67-
We import the contract artifacts we have generated plus the dependencies we'll need, and then we can deploy the contracts by adding the following code to the `src/deploy.mjs` file. Here, we are using the `ContractDeployer` class with the compiled artifact to send a new deployment transaction. The `wait` method will block execution until the transaction is successfully mined, and return a receipt with the deployed contract address.
71+
Here, we are using the `Contract` class with the compiled artifact to send a new deployment transaction. The `deployed` method will block execution until the transaction is successfully mined, and return a receipt with the deployed contract address.
6872

69-
Note that the token's `_initialize()` method expects an `owner` address to mint an initial set of tokens to. We are using the first account from the Sandbox for this.
73+
Note that the token's `constructor()` method expects an `owner` address to set as the contract `admin`. We are using the first account from the Sandbox for this.
7074

7175
:::info
72-
If you are using the generated typescript classes, you can drop the generic `ContractDeployer` in favor of using the `deploy` method of the generated class, which will automatically load the artifact for you and type-check the constructor arguments. SEe the [How to deploy a contract](../../../guides/developer_guides/smart_contracts/how_to_deploy_contract.md) page for more info.
76+
If you are using the generated typescript classes, you can drop the generic `ContractDeployer` in favor of using the `deploy` method of the generated class, which will automatically load the artifact for you and type-check the constructor arguments. See the [How to deploy a contract](../../../guides/developer_guides/smart_contracts/how_to_deploy_contract.md) page for more info.
7377
:::
7478

7579
Run the snippet above as `node src/deploy.mjs`, and you should see the following output, along with a new `addresses.json` file in your project root:

docs/docs/tutorials/codealong/simple_dapp/3_contract_interaction.md

+28-24
Original file line numberDiff line numberDiff line change
@@ -18,53 +18,57 @@ To do this, let's first initialize a new `Contract` instance using `aztec.js` th
1818

1919
```js
2020
// src/contracts.mjs
21-
import { Contract } from "@aztec/aztec.js";
22-
import { readFileSync } from "fs";
23-
import TokenContractJson from "../contracts/token/target/token_contract-Token.json" assert { type: "json" };
21+
#include_code imports yarn-project/end-to-end/src/sample-dapp/contracts.mjs raw
2422
```
2523

26-
And then add the following code for initializing the `Contract` instances:
24+
You may have noticed that we are importing the `TokenContract` class from `@aztec/noir-contracts.js`. This is an alternative way to get the contract interface for interacting with the contract. With this, we can add the following code for initializing the `TokenContract` instance:
2725

2826
#include_code get-tokens yarn-project/end-to-end/src/sample-dapp/contracts.mjs javascript
2927

30-
:::info
31-
You can use the typescript autogenerated interface instead of the generic `Contract` class to get type-safe methods.
32-
:::
28+
We can now get the token instance in our main code in `src/index.mjs`, by importing the function from `src/contracts.mjs`. Update the imports in `src/index.mjs` to look like this:
29+
30+
```js
31+
// src/index.mjs
32+
#include_code imports yarn-project/end-to-end/src/sample-dapp/index.mjs raw
33+
```
3334

34-
We can now get the token instance in our main code in `src/index.mjs`, and query the private balance for each of the user accounts. To query a function, without sending a transaction, use the `view` function of the method:
35+
and query the private balance for each of the user accounts. To query a function, without sending a transaction, use the `simulate` function of the method:
3536

3637
#include_code showPrivateBalances yarn-project/end-to-end/src/sample-dapp/index.mjs javascript
3738

38-
Run this as `node src/index.mjs` and you should now see the following output:
39+
Call the function in `main` and run this with `node src/index.mjs` and you should now see the following output:
3940

4041
```
41-
Balance of 0x0c8a6673d7676cc80aaebe7fa7504cf51daa90ba906861bfad70a58a98bf5a7d: 100
42+
Balance of 0x0c8a6673d7676cc80aaebe7fa7504cf51daa90ba906861bfad70a58a98bf5a7d: 0
4243
Balance of 0x226f8087792beff8d5009eb94e65d2a4a505b70baf4a9f28d33c8d620b0ba972: 0
4344
Balance of 0x0e1f60e8566e2c6d32378bdcadb7c63696e853281be798c107266b8c3a88ea9b: 0
4445
```
4546

46-
## Transferring private tokens
47+
## Mint tokens
4748

48-
Now that we can see the balance for each user, let's transfer tokens from one account to another. To do this, we will first need access to a `Wallet` object. This wraps access to an PXE and also provides an interface to craft and sign transactions on behalf of one of the user accounts.
49+
Before we can transfer tokens, we need to mint some tokens to our user accounts. Add the following function to `src/index.mjs`:
4950

50-
We can initialize a wallet using one of the `getAccount` methods from the `accounts` package, along with the corresponding signing and encryption keys:
51+
#include_code mintPrivateFunds yarn-project/end-to-end/src/sample-dapp/index.mjs javascript
5152

52-
```js
53-
import { getSchnorrAccount } from "@aztec/accounts/schnorr";
54-
const wallet = await getSchnorrAccount(
55-
client,
56-
ENCRYPTION_PRIVATE_KEY,
57-
SIGNING_PRIVATE_KEY
58-
).getWallet();
53+
Call the function in `main`, run the script and after printing the balances of each account it will then privately mint tokens. After that completes, you should then see 20 tokens in the balance of the first account.
54+
55+
```text
56+
Balance of 0x0c8a6673d7676cc80aaebe7fa7504cf51daa90ba906861bfad70a58a98bf5a7d: 20
57+
Balance of 0x226f8087792beff8d5009eb94e65d2a4a505b70baf4a9f28d33c8d620b0ba972: 0
58+
Balance of 0x0e1f60e8566e2c6d32378bdcadb7c63696e853281be798c107266b8c3a88ea9b: 0
5959
```
6060

61-
For ease of use, `accounts` also ships with a helper `getInitialTestAccountsWallets` method that returns a wallet for each of the pre-initialized accounts in the Sandbox, so you can send transactions as any of them.
61+
## Transferring private tokens
62+
63+
Now that we can see the balance for each user, let's transfer tokens from one account to another. To do this, we will first need access to a `Wallet` object. This wraps access to an PXE and also provides an interface to craft and sign transactions on behalf of one of the user accounts.
64+
65+
For ease of use, `@aztec/accounts` also ships with a helper `getInitialTestAccountsWallets` method that returns a wallet for each of the pre-initialized accounts in the Sandbox, so you can send transactions as any of them.
6266

6367
```js
6468
import { getInitialTestAccountsWallets } from "@aztec/accounts/testing";
6569
```
6670

67-
We'll use one of these wallets to initialize the `Contract` instance that represents our private token contract, so every transaction sent through it will be sent through that wallet.
71+
We'll use one of these wallets to initialize the `TokenContract` instance that represents our private token contract, so every transaction sent through it will be sent through that wallet.
6872

6973
#include_code transferPrivateFunds yarn-project/end-to-end/src/sample-dapp/index.mjs javascript
7074

@@ -77,14 +81,14 @@ Run this new snippet and you should see the following:
7781
```text
7882
Sent transfer transaction 16025a7c4f6c44611d7ac884a5c27037d85d9756a4924df6d97fb25f6e83a0c8
7983
80-
Balance of 0x0c8a6673d7676cc80aaebe7fa7504cf51daa90ba906861bfad70a58a98bf5a7d: 100
84+
Balance of 0x0c8a6673d7676cc80aaebe7fa7504cf51daa90ba906861bfad70a58a98bf5a7d: 20
8185
Balance of 0x226f8087792beff8d5009eb94e65d2a4a505b70baf4a9f28d33c8d620b0ba972: 0
8286
Balance of 0x0e1f60e8566e2c6d32378bdcadb7c63696e853281be798c107266b8c3a88ea9b: 0
8387
8488
Awaiting transaction to be mined
8589
Transaction has been mined on block 4
8690
87-
Balance of 0x0c8a6673d7676cc80aaebe7fa7504cf51daa90ba906861bfad70a58a98bf5a7d: 99
91+
Balance of 0x0c8a6673d7676cc80aaebe7fa7504cf51daa90ba906861bfad70a58a98bf5a7d: 19
8892
Balance of 0x226f8087792beff8d5009eb94e65d2a4a505b70baf4a9f28d33c8d620b0ba972: 1
8993
Balance of 0x0e1f60e8566e2c6d32378bdcadb7c63696e853281be798c107266b8c3a88ea9b: 0
9094
```

docs/docs/tutorials/codealong/simple_dapp/4_testing.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ import {
3131
waitForPXE,
3232
} from "@aztec/aztec.js";
3333
import { createAccount } from "@aztec/accounts/testing";
34-
import { TokenContractArtifact } from "@aztec/noir-contracts.js/Token";
34+
import { TokenContract } from "@aztec/noir-contracts.js/Token";
3535

3636
const {
3737
PXE_URL = "http://localhost:8080",
3838
ETHEREUM_HOST = "http://localhost:8545",
3939
} = process.env;
4040

41-
describe("token contract", () => {});
41+
describe("token contract", () => {
42+
// <tests go here>
43+
});
4244
```
4345

4446
Let's set up our test suite. We'll make sure the Sandbox is running, create two fresh accounts to test with, and deploy an instance of our contract. `aztec.js` provides the helper functions we need to do this:

yarn-project/end-to-end/src/sample-dapp/connect.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createPXEClient } from '@aztec/aztec.js';
44
const { PXE_URL = 'http://localhost:8080' } = process.env;
55

66
async function main() {
7-
const pxe = createPXEClient(PXE_URL);
7+
const pxe = await createPXEClient(PXE_URL);
88
const { l1ChainId } = await pxe.getNodeInfo();
99
console.log(`Connected to chain ${l1ChainId}`);
1010
}

yarn-project/end-to-end/src/sample-dapp/contracts.mjs

+3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
// docs:start:imports
12
import { AztecAddress } from '@aztec/aztec.js';
23
import { TokenContract } from '@aztec/noir-contracts.js/Token';
34

45
import { readFileSync } from 'fs';
56

7+
// docs:end:imports
8+
69
// docs:start:get-tokens
710
export async function getToken(client) {
811
const addresses = JSON.parse(readFileSync('addresses.json'));

yarn-project/end-to-end/src/sample-dapp/deploy.mjs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
// docs:start:deploy-imports
12
import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
23
import { Contract, createPXEClient, loadContractArtifact, waitForPXE } from '@aztec/aztec.js';
4+
// docs:end:deploy-imports
35
import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js';
46

57
import { writeFileSync } from 'fs';
@@ -15,7 +17,9 @@ async function main() {
1517
const [ownerWallet] = await getInitialTestAccountsWallets(pxe);
1618
const ownerAddress = ownerWallet.getAddress();
1719

18-
const token = await TokenContract.deploy(ownerWallet, ownerAddress, 'TokenName', 'TKN', 18).send().deployed();
20+
const token = await Contract.deploy(ownerWallet, TokenContractArtifact, [ownerAddress, 'TokenName', 'TKN', 18])
21+
.send()
22+
.deployed();
1923

2024
console.log(`Token deployed at ${token.address.toString()}`);
2125

yarn-project/end-to-end/src/sample-dapp/index.mjs

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,38 @@
1+
// docs:start:imports
12
import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
23
import { ExtendedNote, Fr, Note, computeSecretHash, createPXEClient, waitForPXE } from '@aztec/aztec.js';
34
import { fileURLToPath } from '@aztec/foundation/url';
45
import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
56

67
import { getToken } from './contracts.mjs';
78

9+
// docs:end:imports
10+
811
const { PXE_URL = 'http://localhost:8080' } = process.env;
912

13+
// docs:start:showAccounts
1014
async function showAccounts(pxe) {
11-
// docs:start:showAccounts
1215
const accounts = await pxe.getRegisteredAccounts();
1316
console.log(`User accounts:\n${accounts.map(a => a.address).join('\n')}`);
14-
// docs:end:showAccounts
1517
}
18+
// docs:end:showAccounts
1619

20+
// docs:start:showPrivateBalances
1721
async function showPrivateBalances(pxe) {
1822
const [owner] = await getInitialTestAccountsWallets(pxe);
1923
const token = await getToken(owner);
2024

21-
// docs:start:showPrivateBalances
2225
const accounts = await pxe.getRegisteredAccounts();
2326

2427
for (const account of accounts) {
2528
// highlight-next-line:showPrivateBalances
2629
const balance = await token.methods.balance_of_private(account.address).simulate();
2730
console.log(`Balance of ${account.address}: ${balance}`);
2831
}
29-
// docs:end:showPrivateBalances
3032
}
33+
// docs:end:showPrivateBalances
3134

35+
// docs:start:mintPrivateFunds
3236
async function mintPrivateFunds(pxe) {
3337
const [owner] = await getInitialTestAccountsWallets(pxe);
3438
const token = await getToken(owner);
@@ -49,15 +53,17 @@ async function mintPrivateFunds(pxe) {
4953
TokenContract.notes.TransparentNote.id,
5054
receipt.txHash,
5155
);
56+
5257
await pxe.addNote(extendedNote, owner.getAddress());
5358

54-
await token.methods.redeem_shield(owner.getAddress(), mintAmount, secret).send().wait();
59+
await token.withWallet(owner).methods.redeem_shield(owner.getAddress(), mintAmount, secret).send().wait();
5560

5661
await showPrivateBalances(pxe);
5762
}
63+
// docs:end:mintPrivateFunds
5864

65+
// docs:start:transferPrivateFunds
5966
async function transferPrivateFunds(pxe) {
60-
// docs:start:transferPrivateFunds
6167
const [owner, recipient] = await getInitialTestAccountsWallets(pxe);
6268
const token = await getToken(owner);
6369

@@ -67,26 +73,26 @@ async function transferPrivateFunds(pxe) {
6773

6874
console.log(`Transaction ${receipt.txHash} has been mined on block ${receipt.blockNumber}`);
6975
await showPrivateBalances(pxe);
70-
// docs:end:transferPrivateFunds
7176
}
77+
// docs:end:transferPrivateFunds
7278

79+
// docs:start:showPublicBalances
7380
async function showPublicBalances(pxe) {
7481
const [owner] = await getInitialTestAccountsWallets(pxe);
7582
const token = await getToken(owner);
7683

77-
// docs:start:showPublicBalances
7884
const accounts = await pxe.getRegisteredAccounts();
7985

8086
for (const account of accounts) {
8187
// highlight-next-line:showPublicBalances
8288
const balance = await token.methods.balance_of_public(account.address).simulate();
8389
console.log(`Balance of ${account.address}: ${balance}`);
8490
}
85-
// docs:end:showPublicBalances
8691
}
92+
// docs:end:showPublicBalances
8793

94+
// docs:start:mintPublicFunds
8895
async function mintPublicFunds(pxe) {
89-
// docs:start:mintPublicFunds
9096
const [owner] = await getInitialTestAccountsWallets(pxe);
9197
const token = await getToken(owner);
9298

@@ -97,7 +103,6 @@ async function mintPublicFunds(pxe) {
97103
console.log(`Transaction ${receipt.txHash} has been mined on block ${receipt.blockNumber}`);
98104

99105
await showPublicBalances(pxe);
100-
// docs:end:mintPublicFunds
101106

102107
// docs:start:showLogs
103108
const blockNumber = await pxe.getBlockNumber();
@@ -106,6 +111,7 @@ async function mintPublicFunds(pxe) {
106111
for (const log of textLogs) console.log(`Log emitted: ${log}`);
107112
// docs:end:showLogs
108113
}
114+
// docs:end:mintPublicFunds
109115

110116
async function main() {
111117
const pxe = createPXEClient(PXE_URL);

yarn-project/end-to-end/src/sample-dapp/index.test.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe('token', () => {
3030
TokenContract.notes.TransparentNote.id,
3131
receipt.txHash,
3232
);
33+
3334
await pxe.addNote(extendedNote, owner.getAddress());
3435

3536
await token.methods.redeem_shield(owner.getAddress(), initialBalance, secret).send().wait();

0 commit comments

Comments
 (0)