Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Install the required tools:

```bash
# Install Aztec CLI
bash -i <(curl -s https://install.aztec.network)
bash -i <(curl -s -L https://install.aztec.network)
aztec-up 3.0.0-devnet.6-patch.1

# Install Nargo via noirup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Before working with devnet, ensure you have:
2. Aztec CLI installed:

```sh
bash -i <(curl -s https://install.aztec.network)
bash -i <(curl -s -L https://install.aztec.network)
```

3. The devnet version installed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Docker needs to be running in order to install the local network. Find instructi
Run:

```bash
bash -i <(curl -s https://install.aztec.network)
bash -i <(curl -s -L https://install.aztec.network)
```

Once the installation is complete, install the specific version:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,58 +23,35 @@ yarn add @aztec/aztec.js@#include_version_without_prefix @aztec/test-wallet@#inc

Create a node client and TestWallet to interact with the local network:

```typescript
import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node";
import {
TestWallet,
registerInitialLocalNetworkAccountsInWallet,
} from "@aztec/test-wallet/server";
#include_code connect_to_network /docs/examples/ts/aztecjs_connection/index.ts typescript

const nodeUrl = "http://localhost:8080";
const node = createAztecNodeClient(nodeUrl);
:::note About TestWallet
`TestWallet` is a simplified wallet for local development that implements the same `Wallet` interface used in production. It handles key management, transaction signing, and proof generation in-process without external dependencies.

// Wait for the network to be ready
await waitForNode(node);
**Why use it for testing?** It starts instantly, requires no setup, and provides deterministic behavior—ideal for automated tests and rapid iteration.

// Create a TestWallet connected to the node
const wallet = await TestWallet.create(node);
```

`TestWallet` is a development wallet that handles account management and transaction signing locally, suitable for testing and development.
**Production wallets** (like browser extensions or mobile apps) implement the same interface but store keys securely, may require user confirmation for transactions, and typically run in a separate process. Code written against `TestWallet` works with any `Wallet` implementation, so your application logic transfers directly to production.
:::

### Verify the connection

Get node information to confirm your connection:

```typescript
const nodeInfo = await node.getNodeInfo();
console.log("Connected to local network version:", nodeInfo.nodeVersion);
console.log("Chain ID:", nodeInfo.l1ChainId);
```
#include_code verify_connection /docs/examples/ts/aztecjs_connection/index.ts typescript

### Load pre-funded accounts

The local network has accounts pre-funded with fee juice to pay for gas. Register them in your wallet:

```typescript
const [alice, bob] = await registerInitialLocalNetworkAccountsInWallet(wallet);

console.log(`Alice's address: ${alice.toString()}`);
console.log(`Bob's address: ${bob.toString()}`);
```
#include_code load_accounts /docs/examples/ts/aztecjs_connection/index.ts typescript

These accounts are pre-funded with fee juice (the native gas token) at genesis, so you can immediately send transactions without needing to bridge funds from L1.

### Check fee juice balance

Verify that an account has fee juice for transactions:

```typescript
import { getFeeJuiceBalance } from "@aztec/aztec.js/utils";

const aliceBalance = await getFeeJuiceBalance(alice, node);
console.log(`Alice's fee juice balance: ${aliceBalance}`);
```
#include_code check_fee_juice /docs/examples/ts/aztecjs_connection/index.ts typescript

## Next steps

Expand Down
31 changes: 11 additions & 20 deletions docs/docs-developers/docs/aztec-js/how_to_create_account.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,9 @@ yarn add @aztec/aztec.js@#include_version_without_prefix @aztec/test-wallet@#inc

## Create a new account

Use the wallet's `createSchnorrAccount` method to create a new account with a random secret and salt:
Using the [`wallet` from the connection guide](./how_to_connect_to_local_network.md), call `createSchnorrAccount` to create a new account with a random secret and salt:

```typescript
import { Fr } from "@aztec/aztec.js/fields";

const secret = Fr.random();
const salt = Fr.random();
const newAccount = await wallet.createSchnorrAccount(secret, salt);
console.log("New account address:", newAccount.address.toString());
```
#include_code create_account /docs/examples/ts/aztecjs_connection/index.ts typescript

The secret is used to derive the account's encryption keys, and the salt ensures address uniqueness. The signing key is automatically derived from the secret.

Expand All @@ -48,13 +41,12 @@ If your account doesn't have Fee Juice, use the [Sponsored Fee Payment Contract]
```typescript
import { AztecAddress } from "@aztec/aztec.js/addresses";

// newAccount is the account created in the previous section
const deployMethod = await newAccount.getDeployMethod();
await deployMethod
.send({
from: AztecAddress.ZERO,
fee: { paymentMethod: sponsoredPaymentMethod },
})
.wait();
await deployMethod.send({
from: AztecAddress.ZERO,
fee: { paymentMethod: sponsoredPaymentMethod },
});
```

:::info
Expand All @@ -68,12 +60,11 @@ If your account already has Fee Juice (for example, [bridged from L1](./how_to_p
```typescript
import { AztecAddress } from "@aztec/aztec.js/addresses";

// newAccount is the account created in the previous section
const deployMethod = await newAccount.getDeployMethod();
await deployMethod
.send({
from: AztecAddress.ZERO,
})
.wait();
await deployMethod.send({
from: AztecAddress.ZERO,
});
```

The `from: AztecAddress.ZERO` is required because there's no existing account to send from—the transaction itself creates the account.
Expand Down
108 changes: 28 additions & 80 deletions docs/docs-developers/docs/aztec-js/how_to_deploy_contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ This guide shows you how to deploy compiled contracts to Aztec using the generat

## Overview

Deploying a contract to Aztec involves publishing the contract class (the bytecode) and creating a contract instance at a specific address. The generated TypeScript classes handle this process through an API: you call `deploy()` with constructor arguments, `send()` with transaction options, and `deployed()` to wait for completion. The contract address is deterministically computed from the contract class, constructor arguments, salt, and deployer address.
Deploying a contract to Aztec involves publishing the contract class (the bytecode) and creating a contract instance at a specific address. The generated TypeScript classes handle this process through an API: you call `deploy()` with constructor arguments and `send()` with transaction options to deploy and get the contract instance. The contract address is deterministically computed from the contract class, constructor arguments, salt, and deployer address.

## Prerequisites

- Compiled contract artifacts (see [How to Compile](../aztec-nr/how_to_compile_contract.md))
- Running Aztec local network
- Funded wallet for deployment fees
- [Connected to a network](./how_to_connect_to_local_network.md) with a `TestWallet` instance and funded accounts
- TypeScript project set up

## Generate TypeScript bindings
Expand Down Expand Up @@ -51,26 +50,24 @@ In the examples below, `wallet` refers to a `Wallet` instance that manages keys
How you deploy depends on how you pay for it. When paying using an account's fee juice (like a test account on the local network):

```typescript
// wallet and alice are from the connection guide
// Deploy with constructor arguments
const contract = await MyContract.deploy(
deployer_wallet,
wallet,
constructorArg1,
constructorArg2
)
.send({ from: testAccount.address }) // testAccount has fee juice and is registered in the deployer_wallet
.deployed();
constructorArg2,
).send({ from: aliceAddress }); // alice has fee juice and is registered in the wallet
```

On testnet, you likely won't have funds in `testAccount` to pay for fee juice. Instead, pay fees using the [Sponsored Fee Payment Contract method](./how_to_pay_fees.md):
On testnet, your account likely won't have Fee Juice. Instead, pay fees using the [Sponsored Fee Payment Contract method](./how_to_pay_fees.md):

```typescript
// wallet is from the connection guide; sponsoredPaymentMethod is from the fees guide
const contract = await MyContract.deploy(
wallet,
constructorArg1,
constructorArg2
)
.send({ from: alice.address, fee: { paymentMethod: sponsoredPaymentMethod } }) // using the Sponsored FPC
.deployed();
constructorArg2,
).send({ from: aliceAddress, fee: { paymentMethod: sponsoredPaymentMethod } }); // using the Sponsored FPC
```

Here's a complete example from the test suite:
Expand All @@ -86,14 +83,13 @@ By default, the deployment's salt is random, but you can specify it (for example
```typescript
import { Fr } from "@aztec/aztec.js/fields";

// wallet and alice are from the connection guide
const salt = Fr.random();

const contract = await MyContract.deploy(wallet, arg1, arg2)
.send({
from: testAccount.address,
contractAddressSalt: salt,
})
.deployed();
const contract = await MyContract.deploy(wallet, arg1, arg2).send({
from: aliceAddress,
contractAddressSalt: salt,
});
```

### Deploy universally
Expand All @@ -110,20 +106,7 @@ Universal deployment excludes the sender from address computation, allowing the

Deploy without running the constructor:

```typescript
const contract = await MyContract.deploy(wallet)
.send({
from: testAccount.address,
skipInitialization: true,
})
.deployed();

// Initialize later
await contract.methods
.initialize(arg1, arg2)
.send({ from: testAccount.address })
.wait();
```
#include_code skip_initialization /docs/examples/ts/aztecjs_advanced/index.ts typescript

### Deploy with a specific initializer

Expand All @@ -132,6 +115,7 @@ Some contracts have multiple initializer functions (e.g., both a private `constr
#include_code deploy_with_opts yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts typescript

The `deployWithOpts` method accepts an options object as its first argument:

- `wallet`: The wallet to use for deployment (required)
- `method`: The name of the initializer function to call (optional, defaults to `constructor`)
- `publicKeys`: Custom public keys for the contract instance (optional)
Expand All @@ -152,6 +136,7 @@ import { Fr } from "@aztec/aztec.js/fields";
const salt = Fr.random();

// Calculate address without deploying
// wallet is from the connection guide (see prerequisites)
const deployMethod = MyContract.deploy(wallet, arg1, arg2);
const instance = await deployMethod.getInstance({ contractAddressSalt: salt });
const address = instance.address;
Expand All @@ -167,23 +152,13 @@ This is an advanced pattern. For most use cases, deploy the contract directly an

### Track deployment transaction

```typescript
const deployTx = MyContract.deploy(wallet, arg1, arg2).send({
from: testAccount.address,
});
Use `NO_WAIT` to get the transaction hash immediately and track deployment:

// Get transaction hash immediately
const txHash = await deployTx.getTxHash();
console.log(`Deployment tx: ${txHash}`);
#include_code no_wait_deploy /docs/examples/ts/aztecjs_advanced/index.ts typescript

// Wait for the transaction to be mined
const receipt = await deployTx.wait();
console.log(`Deployed in block ${receipt.blockNumber}`);
For most use cases, simply await the deployment to get the contract directly:

// Get the deployed contract instance
const contract = await deployTx.deployed();
console.log(`Contract address: ${contract.address}`);
```
#include_code deploy_contract /docs/examples/ts/aztecjs_connection/index.ts typescript

## Deploy multiple contracts

Expand All @@ -197,40 +172,11 @@ Here's an example deploying a `TokenContract` with constructor arguments for adm

When one contract depends on another, deploy them sequentially and pass the first contract's address:

```typescript
// Deploy first contract
const token = await TokenContract.deploy(
wallet,
admin.address,
"MyToken",
"MTK",
18
)
.send({ from: admin.address })
.deployed();

// Deploy second contract with reference to first
const vault = await VaultContract.deploy(wallet, token.address)
.send({ from: admin.address })
.deployed();
```
#include_code deploy_with_dependencies /docs/examples/ts/aztecjs_advanced/index.ts typescript

### Deploy contracts in parallel

```typescript
// Start all deployments simultaneously
const deployments = [
Contract1.deploy(wallet, arg1).send({ from: deployer.address }),
Contract2.deploy(wallet, arg2).send({ from: deployer.address }),
Contract3.deploy(wallet, arg3).send({ from: deployer.address }),
];

// Wait for all to complete
const receipts = await Promise.all(deployments.map((d) => d.wait()));

// Get deployed contract instances
const contracts = await Promise.all(deployments.map((d) => d.deployed()));
```
#include_code parallel_deploy /docs/examples/ts/aztecjs_advanced/index.ts typescript

:::tip[Parallel deployment considerations]
Parallel deployment is faster, but transactions from the same account share a nonce sequence. The wallet handles nonce assignment automatically, but if one deployment fails, subsequent deployments may also fail due to nonce gaps. For reliable parallel deployments:
Expand Down Expand Up @@ -263,11 +209,12 @@ The `getContractMetadata` method returns:
### Verify contract is callable

```typescript
// contract is from the deployment step above; alice is from the connection guide
try {
// Try calling a view function
const result = await contract.methods
.get_version()
.simulate({ from: testAccount.address });
.simulate({ from: aliceAddress });
console.log("Contract is callable, version:", result);
} catch (error) {
console.error("Contract not accessible:", error.message);
Expand All @@ -281,6 +228,7 @@ try {
If a contract was deployed by another account:

```typescript
// wallet is from the connection guide; contractAddress is the address of the deployed contract
const contract = await MyContract.at(contractAddress, wallet);

// Register the contract with the wallet
Expand All @@ -306,7 +254,7 @@ const instance = await getContractInstanceFromInstantiationParams(
constructorArgs: [arg1, arg2],
deployer: deployerAddress,
salt: deploymentSalt,
}
},
);

await wallet.registerContract(instance, MyContract.artifact);
Expand Down
Loading
Loading