Skip to content
Merged
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 @@ -215,7 +215,7 @@ const fpcClient = new FpcClient({
// Estimate gas, fetch a signed quote, and build the payment method
const payment = await fpcClient.createPaymentMethod({
wallet,
user: wallet.getAddress(),
user: aliceAddress, // the account paying the fee
tokenAddress, // the token you want to pay in
estimatedGas, // from a prior estimateGas call
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import { General } from '@site/src/components/Snippets/general_snippets';

The authwit system supports different intent types depending on your use case:

- **`CallIntent`**: Use when authorizing a specific contract function call. Contains `{ caller, action }` where `action` is a `ContractFunctionInteraction`.
- **`CallIntent`**: Use when authorizing a specific contract function call. Contains `{ caller, call }` where `call` is a `FunctionCall`, typically obtained with `await interaction.getFunctionCall()`.
- **`ContractFunctionInteractionCallIntent`**: Convenience form that takes the interaction directly. Contains `{ caller, action }` where `action` is a `ContractFunctionInteraction`; internally resolved to a `FunctionCall` before signing.
- **`IntentInnerHash`**: Use when authorizing arbitrary data. Contains `{ consumer, innerHash }` where `consumer` is the contract that will verify the authwit.

## Create private authwits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Log values from your contract using `debug_log`:

```rust
// Import debug logging
use dep::aztec::oracle::logging::{ debug_log, debug_log_format };
use aztec::oracle::logging::{ debug_log, debug_log_format };

// Log simple messages
debug_log("checkpoint reached");
Expand Down Expand Up @@ -63,28 +63,25 @@ LOG_LEVEL="info;debug:simulator:client_execution_context;debug:simulator:client_
```

:::info Log filter format
`LOG_LEVEL` accepts a semicolon-delimited list of filters. Each filter can be:

- `level` - Sets default level for all modules
- `level:module` - Sets level for a specific module
- `level:module:submodule` - Sets level for a specific submodule
`LOG_LEVEL` is a semicolon-delimited list. The **first segment must be a bare log level** — it sets the default level for all modules. Subsequent segments are `level:module` (or `level:module:submodule`) overrides.

**The default-level filter must be the first segment.** A bare `level:module` with no preceding default (e.g. `LOG_LEVEL="warn:simulator"`) is invalid and throws `Invalid log level`, because the parser reads everything before the first `;` as the default level. To filter only specific modules, lead with a default level — use `silent` to suppress everything else.

```bash
# Default level only
LOG_LEVEL="debug"

# Default level + specific module overrides
# Default level + module overrides
LOG_LEVEL="info;debug:simulator;debug:execution"

# Default level + specific submodule overrides
# Default level + submodule overrides
LOG_LEVEL="info;debug:simulator:client_execution_context;debug:simulator:client_view_context"

# Silence everything except one module
LOG_LEVEL="silent;debug:simulator"
```

A bare `level:module` (e.g. `LOG_LEVEL="warn:simulator"`) is **not valid** — the parser reads the first segment as the default level and rejects it with `Invalid log level: warn:simulator`.
:::

## Debugging common errors
Expand Down Expand Up @@ -116,9 +113,12 @@ LOG_LEVEL="silent;debug:simulator"
### Quick Fixes for Common Issues

```bash
# Archiver sync issues - force progress with dummy transactions
aztec-wallet send transfer --from test0 --to test0 --amount 0
aztec-wallet send transfer --from test0 --to test0 --amount 0
# Archiver sync issues - force progress with dummy transactions.
# Assumes you have imported the local network test accounts
# (aztec-wallet import-test-accounts) and have a deployed token
# aliased as `testtoken`.
aztec-wallet send transfer --from test0 --contract-address testtoken --args accounts:test0 0
aztec-wallet send transfer --from test0 --contract-address testtoken --args accounts:test0 0

# L1 to L2 message pending - wait for inclusion
# Messages need 2 blocks to be processed
Expand Down Expand Up @@ -210,7 +210,7 @@ LOG_LEVEL=verbose aztec start --local-network
### Common debug imports

```rust
use dep::aztec::oracle::logging::{ debug_log, debug_log_format };
use aztec::oracle::logging::{ debug_log, debug_log_format };
```

### Check contract registration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ let confirmed_note = assert_note_existed_by(header, hinted_note);
To prove a note was valid (existed AND wasn't nullified) at a historical block:

```rust
use dep::aztec::history::note::assert_note_was_valid_by;
use aztec::history::note::assert_note_was_valid_by;

let header = self.context.get_anchor_block_header();
assert_note_was_valid_by(header, hinted_note, &mut self.context);
Expand All @@ -66,7 +66,7 @@ This verifies both:
To prove against state at a specific past block (not just the anchor block):

```rust
use dep::aztec::history::note::assert_note_existed_by;
use aztec::history::note::assert_note_existed_by;

let historical_header = self.context.get_block_header_at(block_number);
assert_note_existed_by(historical_header, hinted_note);
Expand All @@ -81,7 +81,7 @@ Using `get_block_header_at` adds ~3k constraints to prove Archive tree membershi
To prove a note has been spent/nullified:

```rust
use dep::aztec::history::note::assert_note_was_nullified_by;
use aztec::history::note::assert_note_was_nullified_by;

let header = self.context.get_anchor_block_header();
assert_note_was_nullified_by(header, confirmed_note, &mut self.context);
Expand All @@ -92,7 +92,7 @@ assert_note_was_nullified_by(header, confirmed_note, &mut self.context);
To prove a contract's bytecode was published at a historical block:

```rust
use dep::aztec::history::deployment::assert_contract_bytecode_was_published_by;
use aztec::history::deployment::assert_contract_bytecode_was_published_by;

let header = self.context.get_anchor_block_header();
assert_contract_bytecode_was_published_by(header, contract_address);
Expand All @@ -101,8 +101,8 @@ assert_contract_bytecode_was_published_by(header, contract_address);
You can also prove a contract was initialized (constructor was called):

```rust
use dep::aztec::history::deployment::assert_contract_was_initialized_by;
use dep::aztec::oracle::get_contract_instance::get_contract_instance;
use aztec::history::deployment::assert_contract_was_initialized_by;
use aztec::oracle::get_contract_instance::get_contract_instance;

let header = self.context.get_anchor_block_header();
let instance = get_contract_instance(contract_address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ This guide shows you how to retrieve and filter notes from private storage using
## Required imports

```rust
use dep::aztec::note::note_getter_options::{NoteGetterOptions, NoteStatus, SortOrder};
use dep::aztec::utils::comparison::Comparator;
use aztec::note::note_getter_options::{NoteGetterOptions, NoteStatus, SortOrder};
use aztec::utils::comparison::Comparator;
```

## Set up basic note retrieval
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,11 @@ See [this example](https://github.com/noir-lang/noir-examples/blob/master/noir_b
Consider the following example of an implementation of the `sqrt` function:

```rust
use dep::aztec::macros::aztec;
use aztec::macros::aztec;

#[aztec]
pub contract OptimisationExample {
use dep::aztec::macros::{functions::{external, initializer}, storage::storage};
use aztec::macros::{functions::{external, initializer}, storage::storage};

#[storage]
struct Storage<Context> {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,18 @@ High-level structure of how Aztec smart contracts including the different compon

## Directory structure

When you create a new project with `aztec new my_project`, it generates a workspace with two crates named after your project: a `my_project_contract` crate for your smart contract and a `my_project_test` crate for Noir tests.
When you create a new project with `aztec new my_project`, it generates a single-crate Noir contract project:

```text title="layout of an aztec contract project"
─── my_project
├── Nargo.toml <-- workspace root
├── my_project_contract
│ ├── src
│ │ └── main.nr <-- your contract
│ └── Nargo.toml <-- contract package and dependencies
└── my_project_test
├── src
│ └── lib.nr <-- your tests
└── Nargo.toml <-- test package and dependencies
├── Nargo.toml <-- contract package and dependencies
└── src
└── main.nr <-- your contract
```

The workspace root `Nargo.toml` declares both crates as workspace members. The contract code lives in `my_project_contract/src/main.nr`, and tests live in a separate `my_project_test` crate that depends on the contract crate.
`Nargo.toml` declares the contract package (with `type = "contract"`) and its dependencies. Your contract code lives in `src/main.nr`. Noir tests using `#[test]` live alongside the contract in the same crate — see [Testing Contracts](../testing_contracts.md).

You can add more contracts to an existing workspace by running `aztec new <name>` from inside the workspace directory. This creates a new `<name>_contract` and `<name>_test` crate pair and adds them to the workspace.

:::warning Keep tests out of the contract crate
Do not add `#[test]` functions to the `<name>_contract` crate. Because the contract artifact depends on everything in its crate, any change — including a test-only change — forces a full recompilation of the contract. The separate `<name>_test` crate lets you iterate on tests without rebuilding the contract. See [Testing Contracts](../testing_contracts.md#keep-tests-in-the-test-crate) for details.
:::
To add another contract as a sibling of an existing one, run `aztec new <name>` from the parent directory (each contract is its own crate). To initialize a contract project inside an existing empty directory instead, `cd` into it and run `aztec init` (it takes no positional argument; pass `--name <name>` if you want the package name to differ from the directory name).

See the vanilla Noir docs for [more info on packages](https://noir-lang.org/docs/noir/modules_packages_crates/crates_and_packages).

Expand All @@ -58,7 +48,7 @@ The `#[aztec]` macro performs a lot of the low-level operations required to take

## Imports

Aside from the [`#[aztec]`](pathname:///aztec-nr-api/mainnet/noir_aztec/macros/aztec/fn.aztec) macro import, all other imports need to go _inside_ the `contract` block - this is because `contract` acts like `mod`, creating a new [module](https://noir-lang.org/docs/noir/modules_packages_crates/modules).
Aside from the [`#[aztec]`](pathname:///aztec-nr-api/mainnet/noir_aztec/macros/fn.aztec) macro import, all other imports need to go _inside_ the `contract` block - this is because `contract` acts like `mod`, creating a new [module](https://noir-lang.org/docs/noir/modules_packages_crates/modules).

```rust
use aztec::macros::aztec;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ Create constructor-like functions using the `#[initializer]` annotation:
#[initializer]
#[external("private")]
// We can name our initializer anything we want as long as it's marked as aztec(initializer)
fn initialize(headstart: u64, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart as u128).deliver(
fn initialize(headstart: u128, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ storage.votes.insert(new_vote).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); //

### Flow

1. Write your contract and specify your contract dependencies. Create a new project with `aztec new my_project`, which sets up a workspace with a `my_project_contract` crate and a `my_project_test` crate, with the `aztec` dependency already configured. If you need additional dependencies, add them to `my_project_contract/Nargo.toml`:
1. Write your contract and specify your contract dependencies. Create a new project with `aztec new my_project`, which creates a single-crate Noir contract project (`Nargo.toml` + `src/main.nr`) with the `aztec` dependency already configured. If you need additional dependencies, add them to `my_project/Nargo.toml`:

```toml
# my_project_contract/Nargo.toml
# my_project/Nargo.toml
[dependencies]
aztec = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v4.2.0", directory="aztec" }
```

Update your `my_project_contract/src/main.nr` contract file to use the Aztec.nr macros for writing contracts.
Update your `my_project/src/main.nr` contract file to use the Aztec.nr macros for writing contracts.

```rust title="setup" showLineNumbers
use aztec::macros::aztec;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,38 +44,30 @@ aztec test
Always use `aztec test` instead of `nargo test`. The `TestEnvironment` requires the TXE (Test eXecution Environment) oracle resolver.
:::

## Keep tests in the test crate

When you create a project with `aztec new` or `aztec init`, the generated workspace has two crates: `<name>_contract` and `<name>_test`. It is important that all tests live in the `<name>_test` crate, **not** in the `<name>_contract` crate.

If you place `#[test]` functions inside the contract crate, `aztec compile` will emit a warning:

```
WARNING: Found tests in contract crate(s):
my_contract::test_something
Tests should be in a dedicated test crate, not in the contract crate.
```

The reason is **unnecessary recompilation**: the contract artifact depends on everything inside the contract crate. If tests live there too, editing a test changes the crate and forces the contract to be recompiled and reprocessed, even though the contract logic itself has not changed. By keeping tests in a separate crate, you can iterate on tests without triggering a full contract rebuild.

## Basic test structure

Tests live in `<name>_test/src/lib.nr` and import the contract crate by name (not `crate::`):
Tests live in the same crate as your contract. `aztec new` creates a single-crate project, and the convention is to place `#[test]` functions in a `mod tests` block alongside the contract (or in submodules of the crate):

```rust
use my_contract::MyContract;
use aztec::{
protocol::address::AztecAddress,
test::helpers::test_environment::TestEnvironment,
};
use aztec::macros::aztec;

#[test]
unconstrained fn test_basic_flow() {
// 1. Create test environment
let mut env = TestEnvironment::new();
#[aztec]
pub contract MyContract {
// ...contract functions...
}

// 2. Create accounts
let owner = env.create_light_account();
mod tests {
use super::MyContract;
use aztec::test::helpers::test_environment::TestEnvironment;

#[test]
unconstrained fn test_basic_flow() {
// 1. Create test environment
let mut env = TestEnvironment::new();

// 2. Create accounts
let _owner = env.create_light_account();
}
}
```

Expand All @@ -88,12 +80,14 @@ unconstrained fn test_basic_flow() {
:::

:::tip Organizing test files
Tests live in the separate `<name>_test` crate that `aztec new` creates. You can organize them into modules:
For larger test suites, split tests into submodules of your crate rather than keeping them all inside `main.nr`:

- Split tests into modules like `<name>_test/src/transfer_tests.nr`, `<name>_test/src/auth_tests.nr`
- Import them in `<name>_test/src/lib.nr` with `mod transfer_tests;`, `mod auth_tests;`
- Share setup functions in `<name>_test/src/utils.nr`
:::
- Create modules like `src/transfer_tests.nr`, `src/auth_tests.nr`
- Declare them from `src/main.nr` with `mod transfer_tests;`, `mod auth_tests;`
- Share setup functions in `src/test_utils.nr`

See the [aztec-standards token contract](https://github.com/defi-wonderland/aztec-standards/tree/dev/src/token_contract) for a worked example of this layout.
:::

## Deploying contracts

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ Let’s create a constructor method to run on deployment that assigns an initial
#[initializer]
#[external("private")]
// We can name our initializer anything we want as long as it's marked as aztec(initializer)
fn initialize(headstart: u64, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart as u128).deliver(
fn initialize(headstart: u128, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,9 @@ nargo test
Expected output:

```text
[hello_circuit] Running 1 test functions
[hello_circuit] Testing test_main... ok
[hello_circuit] All tests passed
[hello_circuit] Running 1 test function
[hello_circuit] Testing test_main ... ok
[hello_circuit] 1 test passed
```

**Tip**: Circuit tests run without generating proofs, making them fast for development. Use them to verify your circuit logic before the more expensive proof generation step.
Expand All @@ -225,12 +225,14 @@ The contract demonstrates several important patterns:

### Create the Contract Project

Use `aztec init` to generate the contract project structure:
Use `aztec new` to generate the contract project structure:

```bash
aztec init --contract contract
aztec new --name ValueNotEqual contract
```

The `aztec new` wrapper stops parsing arguments at the first positional, so `--name` must come **before** the `contract` path — otherwise the flag is silently dropped and the Nargo package ends up named `contract`. The Nargo package name (`--name`) is independent of the Noir contract name declared inside `main.nr`; the artifact filename downstream is driven by the contract name.

This creates:

```tree
Expand Down Expand Up @@ -699,7 +701,7 @@ Expected output:
Proof verification: SUCCESS
Using deflattenFields to convert proof...
VK size: 115
Proof size: 508
Proof size: 500
Public inputs: 1
Done
```
Expand Down
Loading
Loading