diff --git a/docs/pages/aztec-nr/advanced-features/custom-notes.md b/docs/pages/aztec-nr/advanced-features/custom-notes.md
index 32cf96a..1443568 100644
--- a/docs/pages/aztec-nr/advanced-features/custom-notes.md
+++ b/docs/pages/aztec-nr/advanced-features/custom-notes.md
@@ -4,8 +4,8 @@ This guide shows you how to create custom note types for storing specialized pri
## Prerequisites
-- Basic understanding of [Aztec private state](../../concepts/storage/state_model.md)
-- Familiarity with [notes and UTXOs](../../concepts/storage/index.md)
+- Basic understanding of Aztec private state
+- Familiarity with notes and UTXOs
- Aztec development environment set up
## Why create custom notes?
@@ -329,11 +329,10 @@ fn get_order(owner: AztecAddress, target_id: Field) -> OrderNote {
## Further reading
-- [What the `#[note]` macro does](../../concepts/smart_contracts/functions/attributes.md#implementing-notes)
-- [Note lifecycle and nullifiers](../../concepts/advanced/storage/indexed_merkle_tree.mdx)
-- [Advanced note patterns](./advanced/how_to_retrieve_filter_notes.md)
-- [Note portals for L1 communication](./how_to_communicate_cross_chain.md)
-- [Macros reference](../../reference/smart_contract_reference/macros.md)
-- [Keys, including npk_m_hash](../../concepts/accounts/keys.md)
+- What the `#[note]` macro does - See concepts section
+- Note lifecycle and nullifiers - See concepts section
+- Advanced note patterns - See advanced features
+- Note portals for L1 communication - See cross-chain interactions
+- Macros reference - See reference section
+- Keys, including npk_m_hash - See concepts section
-
\ No newline at end of file
diff --git a/docs/pages/aztec-nr/compile.md b/docs/pages/aztec-nr/compile.md
index dd1c8ca..e3cee10 100644
--- a/docs/pages/aztec-nr/compile.md
+++ b/docs/pages/aztec-nr/compile.md
@@ -87,4 +87,3 @@ After compilation, use the generated artifacts to:
- Interact with deployed contracts using type-safe interfaces
- Import contracts in other Aztec.nr projects
-
\ No newline at end of file
diff --git a/docs/pages/aztec-nr/debugging.md b/docs/pages/aztec-nr/debugging.md
index 43dd869..e59889f 100644
--- a/docs/pages/aztec-nr/debugging.md
+++ b/docs/pages/aztec-nr/debugging.md
@@ -185,6 +185,6 @@ Check hex errors against [Errors.sol](https://github.com/AztecProtocol/aztec-pac
## Related Resources
-- [Circuit Architecture](../../concepts/advanced/circuits/index.md)
-- [Private-Public Execution](../../concepts/smart_contracts/functions/public_private_calls.md)
-- [Aztec.nr Dependencies](../../reference/smart_contract_reference/dependencies.md)
+- Circuit Architecture - See concepts section
+- Private-Public Execution - See concepts section
+- Aztec.nr Dependencies - See reference section
diff --git a/docs/pages/aztec-nr/getting-started.md b/docs/pages/aztec-nr/getting-started.md
index 419aee7..e61e0c4 100644
--- a/docs/pages/aztec-nr/getting-started.md
+++ b/docs/pages/aztec-nr/getting-started.md
@@ -2,7 +2,6 @@
## Noir VSCode Extension
-
Install the [Noir Language Support extension](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir) to get syntax highlighting, syntax error detection and go-to definitions for your Aztec contracts.
@@ -16,7 +15,6 @@ which aztec-nargo
To specify a custom nargo executable, go to the VSCode settings and search for "noir", or click extension settings on the `noir-lang` LSP plugin. Update the `Noir: Nargo Path` field to point to your desired `aztec-nargo` executable.
-
## Creating an Aztec.nr Project
diff --git a/docs/pages/aztec-nr/installation.md b/docs/pages/aztec-nr/installation.md
index 76185e6..265bfc7 100644
--- a/docs/pages/aztec-nr/installation.md
+++ b/docs/pages/aztec-nr/installation.md
@@ -15,7 +15,7 @@ Before learning how to create Aztec smart contracts, we must first install some
- [Docker](https://docs.docker.com/get-docker/)
-## Install Aztec Tools
+## Install Aztec Tools
1. Docker needs to be running in order to install the sandbox.
@@ -33,7 +33,6 @@ aztec --version
## Noir VSCode Extension
-
Install the [Noir Language Support extension](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir) to get syntax highlighting, syntax error detection and go-to definitions for your Aztec contracts.
@@ -47,7 +46,6 @@ which aztec-nargo
To specify a custom nargo executable, go to the VSCode settings and search for "noir", or click extension settings on the `noir-lang` LSP plugin. Update the `Noir: Nargo Path` field to point to your desired `aztec-nargo` executable.
-
## Creating an Aztec.nr Project
diff --git a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md
index fae291e..2f26fc9 100644
--- a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md
+++ b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md
@@ -8,8 +8,8 @@ Private smart contracts on Aztec allow you to build applications where transacti
## Getting Started
-- [A Simple Aztec Smart Contract](./simple-contract) - Start with a basic example
-- [Example Aztec Smart Contracts](./examples) - Explore more complex patterns
+- A Simple Aztec Smart Contract - Start with a basic example
+- Example Aztec Smart Contracts - Explore more complex patterns
## Key Concepts
diff --git a/docs/pages/aztec-nr/language-description/authentication-witness.md b/docs/pages/aztec-nr/language-description/authentication-witness.md
index c13dc38..1fa3692 100644
--- a/docs/pages/aztec-nr/language-description/authentication-witness.md
+++ b/docs/pages/aztec-nr/language-description/authentication-witness.md
@@ -1,6 +1,5 @@
# Authentication Witness
-
Authentication witnesses (authwit) allow other contracts to execute actions on behalf of your account. This guide shows you how to implement and use authwits in your Aztec smart contracts.
@@ -10,7 +9,7 @@ Authentication witnesses (authwit) allow other contracts to execute actions on b
- Understanding of private and public functions in Aztec
- Access to the `authwit` library in your contract
-For conceptual background, see [Authentication Witnesses](../../concepts/advanced/authwit.md).
+For conceptual background, see Authentication Witnesses in the concepts section.
## Set up the authwit library
@@ -91,4 +90,3 @@ fn _approve_and_execute_action(
}
```
-
diff --git a/docs/pages/aztec-nr/language-description/calling-other-contracts.md b/docs/pages/aztec-nr/language-description/calling-other-contracts.md
index aba631e..5c62e8d 100644
--- a/docs/pages/aztec-nr/language-description/calling-other-contracts.md
+++ b/docs/pages/aztec-nr/language-description/calling-other-contracts.md
@@ -20,7 +20,6 @@
- Stealthifying Addresses
- Custom Stealth Addresses
-
This guide shows you how to call functions in other contracts from your Aztec smart contracts, enabling contract composability and interaction.
@@ -83,11 +82,10 @@ OtherContract::at(contract_address)
```
:::info
-Public functions always execute after private execution completes. Learn more in the [concepts overview](../../concepts/index.md).
+Public functions always execute after private execution completes. Learn more in the concepts overview.
:::
### Use other call types
-Explore additional call types for specialized use cases in the [call types reference](../../concepts/call_types.md).
+Explore additional call types for specialized use cases in the call types reference.
-
\ No newline at end of file
diff --git a/docs/pages/aztec-nr/language-description/contract-structure.md b/docs/pages/aztec-nr/language-description/contract-structure.md
index e417c8d..f0af307 100644
--- a/docs/pages/aztec-nr/language-description/contract-structure.md
+++ b/docs/pages/aztec-nr/language-description/contract-structure.md
@@ -8,7 +8,7 @@
- Events
- See the dedicated section below
-A contract is a collection of persistent state variables and [functions](./functions/index.md) which may manipulate these variables. Functions and state variables within a contract's scope are said to belong to that contract. A contract can only access and modify its own state. If a contract wishes to access or modify another contract's state, it must make a call to an external function of the other contract. For anything to happen on the Aztec network, an external function of a contract needs to be called.
+A contract is a collection of persistent state variables and functions which may manipulate these variables. Functions and state variables within a contract's scope are said to belong to that contract. A contract can only access and modify its own state. If a contract wishes to access or modify another contract's state, it must make a call to an external function of the other contract. For anything to happen on the Aztec network, an external function of a contract needs to be called.
## Contract
diff --git a/docs/pages/aztec-nr/language-description/cross-chain-interactions.md b/docs/pages/aztec-nr/language-description/cross-chain-interactions.md
index 51c517e..4dec7db 100644
--- a/docs/pages/aztec-nr/language-description/cross-chain-interactions.md
+++ b/docs/pages/aztec-nr/language-description/cross-chain-interactions.md
@@ -13,7 +13,7 @@
- An Aztec contract project set up with `aztec-nr` dependency
- Understanding of Aztec L1/L2 architecture
- Access to Ethereum development environment for L1 contracts
-- Deployed portal contract on L1 (see [token bridge tutorial](../../tutorials/js_tutorials/token_bridge.md))
+- Deployed portal contract on L1 (see token bridge tutorial)
## Send messages from L1 to L2
@@ -195,6 +195,5 @@ bytes memory message = abi.encodeWithSignature(
## Next steps
-Follow the [cross-chain messaging tutorial](../../tutorials/js_tutorials/token_bridge.md) for a complete implementation example.
+Follow the cross-chain messaging tutorial for a complete implementation example.
-
\ No newline at end of file
diff --git a/docs/pages/aztec-nr/language-description/events-and-logs.md b/docs/pages/aztec-nr/language-description/events-and-logs.md
index f9aac5e..facd8df 100644
--- a/docs/pages/aztec-nr/language-description/events-and-logs.md
+++ b/docs/pages/aztec-nr/language-description/events-and-logs.md
@@ -104,4 +104,3 @@ Event data is published to Ethereum as blobs, which incurs costs. Consider:
- Future alternatives for data availability may become available
- Balance event utility with cost implications
-
\ No newline at end of file
diff --git a/docs/pages/aztec-nr/language-description/index.md b/docs/pages/aztec-nr/language-description/index.md
index 3be1da0..facd721 100644
--- a/docs/pages/aztec-nr/language-description/index.md
+++ b/docs/pages/aztec-nr/language-description/index.md
@@ -27,7 +27,7 @@ This section covers all aspects of the Aztec.nr language:
### Communication
- **Private Messaging** - Encrypted messaging between accounts
-- **L1<>L2 Messaging** - Cross-layer communication
+- **L1↔L2 Messaging** - Cross-layer communication
- **Cross-chain Interactions** - Interacting with other chains
### Advanced Topics
diff --git a/docs/pages/aztec-nr/language-description/macros.md b/docs/pages/aztec-nr/language-description/macros.md
index efe5c1d..9e157eb 100644
--- a/docs/pages/aztec-nr/language-description/macros.md
+++ b/docs/pages/aztec-nr/language-description/macros.md
@@ -25,4 +25,4 @@ It is also worth mentioning Noir's `unconstrained` function type [here (Noir doc
- `#[storage]` - Defines contract storage
## Further reading
-[How do Aztec macros work?](../../concepts/smart_contracts/functions/function_transforms.md)
+How do Aztec macros work? - See concepts section
diff --git a/docs/pages/aztec-nr/testing.md b/docs/pages/aztec-nr/testing.md
index 0643ebe..f5bdde6 100644
--- a/docs/pages/aztec-nr/testing.md
+++ b/docs/pages/aztec-nr/testing.md
@@ -5,7 +5,6 @@
2. Testing end-to-end apps.
- See Aztec.js?
-
This guide shows you how to test your Aztec smart contracts using Noir's `TestEnvironment` for fast, lightweight testing.
@@ -16,7 +15,7 @@ This guide shows you how to test your Aztec smart contracts using Noir's `TestEn
- Basic understanding of Noir syntax
:::tip
-For complex cross-chain or integration testing, see the [TypeScript testing guide](../aztec-js/how_to_test.md).
+For complex cross-chain or integration testing, see the TypeScript testing guide in the Aztec.js section.
:::
## Write Aztec contract tests
@@ -27,7 +26,7 @@ Use `TestEnvironment` from `aztec-nr` for contract unit testing:
- **Convenient**: Similar to Foundry for simple contract tests
- **Limited**: No rollup circuits or cross-chain messaging
-For complex end-to-end tests, use [TypeScript testing](../aztec-js/how_to_test.md) with `aztec.js`.
+For complex end-to-end tests, use TypeScript testing with `aztec.js`.
## Run your tests
@@ -334,4 +333,3 @@ unconstrained fn test_missing_authwit() {
```
-
diff --git a/docs/pages/protocol-architecture/addresses-and-keys.md b/docs/pages/foundational-topics/addresses-and-keys.md
similarity index 94%
rename from docs/pages/protocol-architecture/addresses-and-keys.md
rename to docs/pages/foundational-topics/addresses-and-keys.md
index fe46952..1894257 100644
--- a/docs/pages/protocol-architecture/addresses-and-keys.md
+++ b/docs/pages/foundational-topics/addresses-and-keys.md
@@ -122,13 +122,13 @@ Account contracts are also expected, though not required by the protocol, to imp
When executing a private function, this authorization is checked by requesting an authentication witness from the execution oracle, which is usually a signed message. Authentication Witness is a scheme for authenticating actions on Aztec, so users can allow third-parties (e.g. contracts) to execute an action on their behalf.
-The user's [Private eXecution Environment (PXE)](../pxe/index.md) is responsible for storing these auth witnesses and returning them to the requesting account contract. Auth witnesses can belong to the current user executing the local transaction, or to another user who shared it offchain.
+The user's Private eXecution Environment (PXE) is responsible for storing these auth witnesses and returning them to the requesting account contract. Auth witnesses can belong to the current user executing the local transaction, or to another user who shared it offchain.
-However, during a public function execution, it is not possible to retrieve a value from the local [oracle](../smart_contracts/oracles/index.md). To support authorizations in public functions, account contracts should save in a public authwit registry what actions have been pre-authorized by their owner.
+However, during a public function execution, it is not possible to retrieve a value from the local oracle. To support authorizations in public functions, account contracts should save in a public authwit registry what actions have been pre-authorized by their owner.
These two patterns combined allow an account contract to answer whether an action `is_valid_impl` for a given user both in private and public contexts.
-You can read more about authorizing actions with authorization witnesses on [this page](../advanced/authwit.md).
+You can read more about authorizing actions with authorization witnesses in the concepts section.
:::info
@@ -152,7 +152,7 @@ Nonce abstraction is mostly relevant to those building wallets. For example, a d
### Fee abstraction
-It doesn't have to be the transaction sender who pays the transaction fees. Wallets or dapp developers can choose any payment logic they want using a paymaster. To learn more about fees on Aztec – check [this page](../fees.md).
+It doesn't have to be the transaction sender who pays the transaction fees. Wallets or dapp developers can choose any payment logic they want using a paymaster. To learn more about fees on Aztec – check the fees section.
Paymaster is a contract that can pay for transactions on behalf of users. It is invoked during the private execution stage and set as the fee payer.
@@ -184,9 +184,9 @@ To spend a note, the user computes a nullifier corresponding to this note. A nul
### Address keys
-Address keys are used for account [address derivation](../accounts/index.md).
+Address keys are used for account address derivation.
-
+
Address keys are a pair of keys `AddressPublicKey` and `address_sk` where `address_sk` is a scalar defined as `address_sk = pre_address + ivsk` and `AddressPublicKey` is an elliptic curve point defined as `AddressPublicKey = address_sk * G`. This is useful for encrypting notes for the recipient with only their address.
@@ -232,7 +232,7 @@ When it comes to notes encryption and decryption:
### Signing keys
-Thanks to the native [account abstraction](../accounts/index.md), authorization logic can be implemented in an alternative way that is up to the developer (e.g. using Google authorization credentials, vanilla password logic or Face ID mechanism). In these cases, signing keys may not be relevant.
+Thanks to the native account abstraction, authorization logic can be implemented in an alternative way that is up to the developer (e.g. using Google authorization credentials, vanilla password logic or Face ID mechanism). In these cases, signing keys may not be relevant.
However if one wants to implement authorization logic containing signatures (e.g. ECDSA or Shnorr) they will need signing keys. Usually, an account contract will validate a signature of the incoming payload against a known signing public key.
@@ -263,7 +263,7 @@ When it comes to storing the signing key in a private note, there are several de
#### Using Delayed Public Mutable state
-By [Delayed Public Mutable](../../guides/smart_contracts/how_to_define_storage.md#delayed-public-mutable) we mean privately readable publicly mutable state.
+By Delayed Public Mutable we mean privately readable publicly mutable state.
To make public state accessible privately, there is a delay window in public state updates. One needs this window to be able to generate proofs client-side. This approach would not generate additional nullifiers and commitments for each transaction while allowing the user to rotate their key. However, this causes every transaction to now have a time-to-live determined by the frequency of the delayed mutable state, as well as imposing restrictions on how fast keys can be rotated due to minimum delays.
@@ -277,7 +277,7 @@ Since there are no restrictions on the actions that an account contract may exec
### Keys generation
-All key pairs (except for the signing keys) are generated in the [Private Execution Environment](../pxe/index.md) (PXE) when a user creates an account. PXE is also responsible for the further key management (oracle access to keys, app siloed keys derivation, etc.)
+All key pairs (except for the signing keys) are generated in the Private Execution Environment (PXE) when a user creates an account. PXE is also responsible for the further key management (oracle access to keys, app siloed keys derivation, etc.)
### Keys derivation
@@ -301,7 +301,7 @@ App-siloed keys allow to minimize damage of potential key leaks as a leak of the
App-siloed keys are derived from the corresponding master keys and the contract address. For example, for the app-siloed nullifier secret key: `nsk_app = hash(nsk_m, app_contract_address)`.
-App-siloed keys [are derived](../advanced/storage/storage_slots.md#implementation) in PXE every time the user interacts with the application.
+App-siloed keys are derived in PXE every time the user interacts with the application.
App-siloed incoming viewing key also allows per-application auditability. A user may choose to disclose this key for a given application to an auditor or regulator (or for 3rd party interfaces, e.g. giving access to a block explorer to display my activity), as a means to reveal all their activity within that context, while retaining privacy across all other applications in the network.
diff --git a/docs/pages/protocol-architecture/call-types.md b/docs/pages/foundational-topics/call-types.md
similarity index 99%
rename from docs/pages/protocol-architecture/call-types.md
rename to docs/pages/foundational-topics/call-types.md
index f686a25..86b5c95 100644
--- a/docs/pages/protocol-architecture/call-types.md
+++ b/docs/pages/foundational-topics/call-types.md
@@ -144,7 +144,7 @@ aztec = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "#incl
Even with the router contract achieving good privacy is hard.
For example, if the value being checked against is unique and stored in the contract's public storage, it's then simple to find private transactions that are using that value in the enqueued public reads, and therefore link them to this contract.
-For this reason it is encouraged to try to avoid public function calls and instead privately read [Shared State](../guides/smart_contracts/how_to_define_storage.md#delayed-public-mutable) when possible.
+For this reason it is encouraged to try to avoid public function calls and instead privately read Shared State when possible.
### Public Execution
diff --git a/docs/pages/protocol-architecture/circuits.md b/docs/pages/foundational-topics/circuits.md
similarity index 96%
rename from docs/pages/protocol-architecture/circuits.md
rename to docs/pages/foundational-topics/circuits.md
index 3dbfc68..22d290c 100644
--- a/docs/pages/protocol-architecture/circuits.md
+++ b/docs/pages/foundational-topics/circuits.md
@@ -49,7 +49,7 @@ In other words, since neither the EVM nor other rollups have rules for how to pr
What kind of extra rules / checks does a rollup need, to enforce notions of private states and private functions? Stuff like:
-- "Perform state reads and writes using new tree structures which prevent tx linkability" (see [indexed merkle tree](../storage/indexed_merkle_tree.mdx).
+- "Perform state reads and writes using new tree structures which prevent tx linkability" (see indexed merkle tree section).
- "Hide which function was just executed, by wrapping it in a zk-snark"
- "Hide all functions which were executed as part of this tx's stack trace, by wrapping the whole tx in a zk-snark"
@@ -77,7 +77,7 @@ Most so-called "zk-Rollups" do not make use of this "zero-knowledge" property. T
### Public Kernel Circuit
-This circuit is executed by a Sequencer, since only a Sequencer knows the current state of the [public data tree](../../../storage/state_model.md#public-state) at any time. A Sequencer might choose to delegate proof generation to the Prover pool.
+This circuit is executed by a Sequencer, since only a Sequencer knows the current state of the public data tree at any time. A Sequencer might choose to delegate proof generation to the Prover pool.
## Rollup Circuits
diff --git a/docs/pages/protocol-architecture/fees.md b/docs/pages/foundational-topics/fees.md
similarity index 85%
rename from docs/pages/protocol-architecture/fees.md
rename to docs/pages/foundational-topics/fees.md
index a995475..fe59782 100644
--- a/docs/pages/protocol-architecture/fees.md
+++ b/docs/pages/foundational-topics/fees.md
@@ -38,21 +38,15 @@ More information about the design/choices can be found in the fees section of th
As part of a transaction the follow gas settings are available to be defined by the user.
-import { Gas_Settings_Components, Gas_Settings, Tx_Teardown_Phase } from '@site/src/components/Snippets/general_snippets';
-
-
-
These are:
#include_code gas_settings_vars yarn-project/stdlib/src/gas/gas_settings.ts javascript
-
-
## Fee payment
A fee payer will have bridged fee-juice from L1. On Aztec this fee asset is non-transferrable, and only deducted by the protocol to pay for fees. A user can claim bridged fee juice and use it to pay for transaction fees in the same transaction.
-The mechanisms for bridging is the same as any other token. For more on this concept see the start of the [Token Bridge Tutorial](../tutorials/js_tutorials/token_bridge.md) where it describes the components and how bridging works (under the hood this makes use of [portals](https://docs.aztec.network/developers/docs/concepts/communication/cross_chain_calls)).
+The mechanisms for bridging is the same as any other token. For more on this concept see the Token Bridge Tutorial where it describes the components and how bridging works (under the hood this makes use of portals).
### Payment methods
@@ -62,8 +56,6 @@ An account making a transaction can also refer to "fee-paying contracts" (FPCs)
### Teardown phase
-
-
### Operator rewards
The calculated fee-juice of a transaction is deducted from the fee payer (nominated account or fee-paying contract), then pooled together each transaction, block, and epoch.
@@ -75,4 +67,4 @@ The fees section of the protocol specification explains this distribution of fee
More comprehensive technical details for implementers will be available from the updated protocol specifications soon.
-For a guide showing ways to pay fees programmatically, see [here](../guides/aztec-js/how_to_pay_fees).
+For a guide showing ways to pay fees programmatically, see the Aztec.js guides section.
diff --git a/docs/pages/protocol-architecture/index.md b/docs/pages/foundational-topics/index.md
similarity index 100%
rename from docs/pages/protocol-architecture/index.md
rename to docs/pages/foundational-topics/index.md
diff --git a/docs/pages/protocol-architecture/note-discovery.md b/docs/pages/foundational-topics/note-discovery.md
similarity index 95%
rename from docs/pages/protocol-architecture/note-discovery.md
rename to docs/pages/foundational-topics/note-discovery.md
index ae02058..15f973f 100644
--- a/docs/pages/protocol-architecture/note-discovery.md
+++ b/docs/pages/foundational-topics/note-discovery.md
@@ -1,7 +1,7 @@
# Note Discovery
-Note discovery refers to the process of a user identifying and decrypting the [encrypted notes](../../storage/notes.md) that belong to them.
+Note discovery refers to the process of a user identifying and decrypting the encrypted notes that belong to them.
## Existing solutions
@@ -39,4 +39,4 @@ This note discovery scheme will be implemented by Aztec contracts rather than by
## Further reading
-- [How partial notes are discovered](./partial_notes.md#note-discovery)
+- How partial notes are discovered
diff --git a/docs/pages/protocol-architecture/overview.md b/docs/pages/foundational-topics/nullifier-merkle-tree.md
similarity index 100%
rename from docs/pages/protocol-architecture/overview.md
rename to docs/pages/foundational-topics/nullifier-merkle-tree.md
diff --git a/docs/pages/protocol-architecture/pxe-and-acir-simulator.md b/docs/pages/foundational-topics/pxe-and-acir-simulator.md
similarity index 100%
rename from docs/pages/protocol-architecture/pxe-and-acir-simulator.md
rename to docs/pages/foundational-topics/pxe-and-acir-simulator.md
diff --git a/docs/pages/protocol-architecture/storage-slots.md b/docs/pages/foundational-topics/storage-slots.md
similarity index 76%
rename from docs/pages/protocol-architecture/storage-slots.md
rename to docs/pages/foundational-topics/storage-slots.md
index 6deb9df..665f026 100644
--- a/docs/pages/protocol-architecture/storage-slots.md
+++ b/docs/pages/foundational-topics/storage-slots.md
@@ -2,7 +2,7 @@
## Public State Slots
-As mentioned in [State Model](../../storage/state_model.md), Aztec public state behaves similarly to public state on Ethereum from the point of view of the developer. Behind the scenes however, the storage is managed differently. As mentioned, public state has just one large sparse tree in Aztec - so we silo slots of public data by hashing it together with its contract address.
+As mentioned in the State Model section, Aztec public state behaves similarly to public state on Ethereum from the point of view of the developer. Behind the scenes however, the storage is managed differently. As mentioned, public state has just one large sparse tree in Aztec - so we silo slots of public data by hashing it together with its contract address.
The mental model is that we have a key-value store, where the siloed slot is the key, and the value is the data stored in that slot. You can think of the `real_storage_slot` identifying its position in the tree, and the `logical_storage_slot` identifying the position in the contract storage.
@@ -10,13 +10,13 @@ The mental model is that we have a key-value store, where the siloed slot is the
real_storage_slot = H(contract_address, logical_storage_slot)
```
-The siloing is performed by the [Kernel circuits](../circuits/kernels/private_kernel.md).
+The siloing is performed by the Kernel circuits.
For structs and arrays, we are logically using a similar storage slot computation to ethereum, e.g., as a struct with 3 fields would be stored in 3 consecutive slots. However, because the "actual" storage slot is computed as a hash of the contract address and the logical storage slot, the actual storage slot is not consecutive.
## Private State Slots
-Private storage is a different beast. As you might remember from [Hybrid State Model](../../storage/state_model.md), private state is stored in encrypted logs and the corresponding private state commitments in append-only tree, called the note hash tree where each leaf is a commitment. Append-only means that leaves are never updated or deleted; instead a nullifier is emitted to signify that some note is no longer valid. A major reason we used this tree, is that updates at a specific storage slot would leak information in the context of private state, even if the value is encrypted. That is not good privacy.
+Private storage is a different beast. As you might remember from the Hybrid State Model, private state is stored in encrypted logs and the corresponding private state commitments in append-only tree, called the note hash tree where each leaf is a commitment. Append-only means that leaves are never updated or deleted; instead a nullifier is emitted to signify that some note is no longer valid. A major reason we used this tree, is that updates at a specific storage slot would leak information in the context of private state, even if the value is encrypted. That is not good privacy.
Following this, the storage slot as we know it doesn't really exist. The leaves of the note hashes tree are just commitments to content (think of it as a hash of its content).
@@ -68,26 +68,6 @@ In the end a siloed note hash is computed in the kernel.
Some of the syntax below is a little butchered to make it easier to follow variables without the full code.
:::
-```mermaid
-sequenceDiagram
- alt Call
- Token->>BalanceMap: Map::new(map_slot);
- Token->>Token: to_bal = storage.balances.at(to)
- Token->>BalanceMap: BalanceMap.at(to)
- BalanceMap->>BalanceMap: derived_slot = H(map_slot, to)
- BalanceMap->>BalanceSet: BalanceSet::new(to, derived_slot)
- Token->>BalanceSet: to_bal.add(amount)
- BalanceSet->>BalanceSet: note = UintNote::new(amount, to)
- BalanceSet->>Set: insert(note)
- Set->>LifeCycle: create_note(derived_slot, note)
- LifeCycle->>LifeCycle: note.header = NoteHeader { contract_address,
storage_slot: derived_slot, nonce: 0, note_hash_counter }
- UintPartialNotePrivateContent->>UintNote: note_hash = compute_partial_commitment(storage_slot).x
- LifeCycle->>Context: push_note_hash(note_hash)
- end
- Context->>Kernel: unique_note_hash = H(nonce, note_hash)
- Context->>Kernel: siloed_note_hash = H(contract_address, unique_note_hash)
-```
-
Notice the `siloed_note_hash` at the very end. It's a hash that will be inserted into the note hashes tree. To clarify what this really is, we "unroll" the values to their simplest components. This gives us a better idea around what is actually inserted into the tree.
```rust
diff --git a/docs/pages/foundational-topics/transactions.md b/docs/pages/foundational-topics/transactions.md
new file mode 100644
index 0000000..53d4ec7
--- /dev/null
+++ b/docs/pages/foundational-topics/transactions.md
@@ -0,0 +1,110 @@
+On this page you'll learn:
+
+- The step-by-step process of sending a transaction on Aztec
+- The role of components like PXE, Aztec Node, ACIR simulator, and the sequencer
+- The Aztec Kernel and its two circuits: private and public, and how they execute function calls
+- The call stacks for private & public functions and how they determine a transaction's completion
+
+## Simple Example of the (Private) Transaction Lifecycle
+
+The transaction lifecycle for an Aztec transaction is fundamentally different from the lifecycle of an Ethereum transaction.
+
+The introduction of the Private eXecution Environment (PXE) provides a safe environment for the execution of sensitive operations, ensuring that decrypted data are not accessible to unauthorized applications. However, the PXE exists client-side on user devices, which creates a different model for imagining what the lifecycle of a typical transaction might look like. The existence of a sequencing network also introduces some key differences between the Aztec transaction model and the transaction model used for other networks.
+
+The accompanying diagram illustrates the flow of interactions between a user, their wallet, the PXE, the node operators (sequencers / provers), and the L1 chain.
+
+
+
+1. **The user initiates a transaction** – In this example, the user decides to privately send 10 DAI to gudcause.eth. After inputting the amount and the receiving address, the user clicks the confirmation button on their wallet.
+
+_The transaction has not been broadcasted to the sequencer network yet. For now, the transaction exists solely within the context of the PXE._
+
+2. **The PXE executes transfer locally** – The PXE, running locally on the user's device, executes the transfer method on the DAI token contract on Aztec and computes the state difference based on the user’s intention.
+
+_The transaction has still not been broadcasted to the sequencer network yet and continues to live solely within the context of the PXE._
+
+3. **The PXE proves correct execution** – At this point, the PXE proves correct execution (via zero-knowledge proofs) of the authorization and of the private transfer method. Once the proofs have been generated, the PXE sends the proofs and required inputs (inputs are new note commitments, stored in the note hash tree and nullifiers stored in the nullifiers tree) to the sequencer. Nullifiers are data that invalidate used note commitments, ensuring that they can only be used once.
+
+_The sequencer has received the transaction proof and can begin to process the transaction - verifying proofs and applying updates to the relevant data trees - alongside other public and private transactions._
+
+4. **The sequencer has the necessary information to act** – the randomly-selected sequencer (based on the Fernet sequencer selection protocol) validates the transaction proofs along with required inputs (e.g. the note commitments and nullifiers) for this private transfer. The sequencer also executes public functions and requests proofs of public execution from a prover network. The sequencer updates the corresponding data trees and does the same for other private transactions. When the sequencer receives proofs from the prover network, the proofs will be bundled into a final rollup proof.
+
+_The sequencer has passed the transaction information – proofs of correct execution and authorization, or public function execution information – to the prover, who will submit the new state root to Ethereum._
+
+5. **The transaction settles to L1** – the verifier contract on Ethereum can now validate the rollup proof and record a new state root. The state root is submitted to the rollup smart contract. Once the state root is verified in an Ethereum transaction, the private transfer has settled and the transaction is considered final.
+
+### Detailed Diagram
+
+Transactions on Aztec start with a call from Aztec.js, which creates a request containing transaction details. This request moves to the Private Execution Environment (PXE) which simulates and processes it. Then the PXE interacts with the Aztec Node which uses the sequencer to ensure that all the transaction details are enqueued properly. The sequencer then submits the block to the rollup contract, and the transaction is successfully mined.
+
+
+
+See [this diagram](https://raw.githubusercontent.com/AztecProtocol/aztec-packages/2fa143e4d88b3089ebbe2a9e53645edf66157dc8/docs/static/img/sandbox_sending_a_tx.svg) for a more detailed overview of the transaction execution process. It highlights 3 different types of transaction execution: contract deployments, private transactions and public transactions.
+
+See the page on contract communication for more context on transaction execution.
+
+### Transaction Requests
+
+Transaction requests are how transactions are constructed and sent to the network.
+
+In Aztec.js:
+
+#include_code constructor yarn-project/stdlib/src/tx/tx_request.ts javascript
+
+Where:
+
+- `origin` is the account contract where the transaction is initiated from.
+- `functionData` contains the function selector and indicates whether the function is private or public.
+- `argsHash` is the hash of the arguments of all of the calls to be executed. The complete set of arguments is passed to the PXE as part of the [TxExecutionRequest](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/stdlib/src/tx/tx_execution_request.ts) and checked against this hash.
+- `txContext` contains the chain id, version, and gas settings.
+
+The `functionData` includes an `AppPayload`, which includes information about the application functions and arguments, and a `FeePayload`, which includes info about how to pay for the transaction.
+
+An account contract validates that the transaction request has been authorized via its specified authorization mechanism, via the `is_valid_impl` function (e.g. [an ECDSA signature](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/account/ecdsa_k_account_contract/src/main.nr#L56-L57), generated [in JS](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/accounts/src/ecdsa/ecdsa_k/account_contract.ts#L30)).
+
+Transaction requests are simulated in the PXE in order to generate the necessary inputs for generating proofs. Once transactions are proven, a [transaction object](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/stdlib/src/tx/tx.ts#L26) is created and can be sent to the network to be included in a block.
+
+#### Contract Interaction Methods
+
+Most transaction requests are created as interactions with specific contracts. The exception is transactions that deploy contracts. Here are the main methods for interacting with contracts related to transactions.
+
+1. [`simulate`](#simulate)
+2. [`prove`](#prove)
+3. [`send`](#send)
+
+##### `simulate`
+
+#include_code simulate yarn-project/aztec.js/src/contract/contract_function_interaction.ts javascript
+
+##### `prove`
+
+#include_code prove yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript
+
+##### `send`
+
+#include_code send yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript
+
+### Batch Transactions
+
+Batched transactions are a way to send multiple transactions in a single call. They are created by the [`BatchCall` class in Aztec.js](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec.js/src/contract/batch_call.ts). This allows a batch of function calls from a single wallet to be sent as a single transaction through a wallet.
+
+### Enabling Transaction Semantics
+
+There are two kernel circuits in Aztec, the private kernel and the public kernel. Each circuit validates the correct execution of a particular function call.
+
+A transaction is built up by generating proofs for multiple recursive iterations of kernel circuits. Each call in the call stack is modeled as new iteration of the kernel circuit and are managed by a [FIFO](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)) queue containing pending function calls. There are two call stacks, one for private calls and one for public calls.
+
+One iteration of a kernel circuit will pop a call off of the stack and execute the call. If the call triggers subsequent contract calls, these are pushed onto the stack.
+
+Private kernel proofs are generated first. The transaction is ready to move to the next phase when the private call stack is empty.
+
+The public kernel circuit takes in proof of a public/private kernel circuit with an empty private call stack, and operates recursively until the public call stack is also empty.
+
+A transaction is considered complete when both call stacks are empty.
+
+The only information leaked about the transaction is:
+
+1. The number of private state updates triggered
+2. The set of public calls generated
+
+The addresses of all private calls are hidden from observers.
diff --git a/docs/pages/foundational-topics/wallets.md b/docs/pages/foundational-topics/wallets.md
new file mode 100644
index 0000000..9943d4a
--- /dev/null
+++ b/docs/pages/foundational-topics/wallets.md
@@ -0,0 +1,89 @@
+# Wallets
+
+On this page we will cover the main responsibilities of a wallet in the Aztec network.
+
+See the wallet architecture section for an overview of its architecture and a reference on the interface a wallet must implement.
+
+Wallets are the applications through which users manage their accounts. Users rely on wallets to browse through their accounts, monitor their balances, and create new accounts. Wallets also store seed phrases and private keys, or interact with external keystores such as hardware wallets.
+
+Wallets also provide an interface for dapps. Dapps may request access to see the user accounts, in order to show the state of those accounts in the context of the application, and request to send transactions from those accounts as the user interacts with the dapp.
+
+In addition to these usual responsibilities, wallets in Aztec also need to track private state. This implies keeping a local database of all private notes encrypted for any of the user's accounts, so dapps and contracts can query the user's private state. Aztec wallets are also responsible for producing local proofs of execution for private functions.
+
+## Account setup
+
+The first step for any wallet is to let the user set up their accounts. An account in Aztec is represented onchain by its corresponding account contract that the user must deploy to begin interacting with the network. This account contract dictates how transactions are authenticated and executed.
+
+A wallet must support at least one specific account contract implementation, which means being able to deploy such a contract, as well as interacting with it when sending transactions. Code-wise, this requires [implementing the `AccountContract` interface](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec.js/src/account/interface.ts).
+
+Note that users must be able to receive funds in Aztec before deploying their account. A wallet should let a user generate a deterministic complete address without having to interact with the network, so they can share it with others to receive funds. This requires that the wallet pins a specific contract implementation, its initialization arguments, a deployment salt, and a privacy key. These values yield a deterministic address, so when the account contract is actually deployed, it is available at the precalculated address. Once the account contract is deployed, the user can start sending transactions using it as the transaction origin.
+
+## Transaction lifecycle
+
+Every transaction in Aztec is broadcast to the network as a zero-knowledge proof of correct execution, in order to preserve privacy. This means that transaction proofs are generated on the wallet and not on a remote node. This is one of the biggest differences with regard to EVM chain wallets.
+
+A wallet is responsible for **creating** an _execution request_ out of one or more _function calls_ requested by a dapp. For example, a dapp may request a wallet to "invoke the `transfer` function on the contract at `0x1234` with the following arguments", in response to a user action. The wallet turns that into an execution request with the signed instructions to execute that function call from the user's account contract. In an [ECDSA-based account](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/noir-contracts/contracts/account/ecdsa_k_account_contract/src/main.nr), for instance, this is an execution request that encodes the function call in the _entrypoint payload_, and includes its ECDSA signature with the account's signing private key.
+
+Once the _execution request_ is created, the wallet is responsible for **simulating** and **proving** the execution of its private functions. The simulation yields an execution trace, which can be used to provide the user with a list of side effects of the private execution of the transaction. During this simulation, the wallet is responsible of providing data to the virtual machine, such as private notes, encryption keys, or nullifier secrets. This execution trace is fed into the prover, which returns a zero-knowledge proof that guarantees correct execution and hides all private information. The output of this process is a _transaction object_.
+
+:::info
+Since private functions rely on a UTXO model, the private execution trace of a transaction is determined exclusively by the notes used as inputs. Since these notes are immutable, the trace of a transaction is always the same, so any effects observed during simulation will be exactly the same when the transaction is mined. However, the transaction may be dropped if it attempts to consume a private note that another transaction nullified before it gets mined. Note that this applies only to private function execution. Public functions rely on an account model, similar to Ethereum, so their execution trace depends on the chain's public state at the point they are included in a block, which may have changed since the transaction was simulated locally.
+:::
+
+Finally, the wallet **sends** the resulting _transaction_ object, which includes the proof of execution, to an Aztec Node. The transaction is then broadcasted through the peer-to-peer network, to be eventually picked up by a sequencer and included in a block.
+
+:::warning
+There are no proofs generated as of the Sandbox release. This will be included in a future release before testnet.
+:::
+
+## Authorizing actions
+
+Account contracts in Aztec expose an interface for other contracts to validate whether an action is authorized by the account or not. For example, an application contract may want to transfer tokens on behalf of a user, in which case the token contract will check with the account contract whether the application is authorized to do so. These actions may be carried out in private or in public functions, and in transactions originated by the user or by someone else.
+
+Wallets should manage these authorizations, prompting the user when they are requested by an application. Authorizations in private executions come in the form of _auth witnesses_, which are usually signatures over an identifier for an action. Applications can request the wallet to produce an auth witness via the `createAuthWit` call. In public functions, authorizations are pre-stored in the account contract storage, which is handled by a call to an internal function in the account contract implementation.
+
+## Key management
+
+As in EVM-based chains, wallets are expected to manage user keys, or provide an interface to hardware wallets or alternative key stores. Keep in mind that in Aztec each account requires two sets of keys: privacy keys and authentication keys. Privacy keys are mandated by the protocol and used for encryption and nullification, whereas authentication keys are dependent on the account contract implementation rolled out by the wallet. Should the account contract support it, wallets must provide the user with the means to rotate or recover their authentication keys.
+
+:::info
+Due to limitations in the current architecture, privacy keys need to be available in the wallet software itself and cannot be punted to an external keystore. This restriction may be lifted in a future release.
+:::
+
+## Recipient encryption keys
+
+Wallets are also expected to manage the public encryption keys of any recipients of local transactions. When creating an encrypted note for a recipient given their address, the wallet needs to provide their complete address. Recipients broadcast their complete addresses when deploying their account contracts, and wallets collect this information and save it in a local registry for easy access when needed.
+
+Note that, in order to interact with a recipient who has not yet deployed their account contract (and thus not broadcasted their complete address), it must also be possible to manually add an entry to a wallet's local registry of complete addresses.
+
+## Private state
+
+Last but not least, wallets also store the user's private state. Wallets currently rely on brute force decryption, where every new block is downloaded and its encrypted data blobs are attempted to be decrypted with the user decryption keys. Whenever a blob is decrypted properly, it is added to the corresponding account's private state. Note that wallets must also scan for private state in blocks prior to the deployment of a user's account contract, since users may have received private state before deployment.
+
+:::info
+At the time of this writing, all private state is encrypted and broadcasted through the network, and eventually committed to L1. This means that a wallet can reconstruct its entire private state out of its encryption keys in the event of local data loss.
+:::
+
+Encrypted data blobs do not carry any public information as to whom their recipient is. Therefore, it is not possible for a remote node to identify the notes that belong to a user, and it is not possible for a wallet to query a remote node for its private state. As such, wallets need to keep a local database of their accounts private state, in order to be able to answer any queries on their private state.
+
+Dapps may require access to the user's private state, in order to show information relevant to the current application. For instance, a dapp for a token may require access to the user's private notes in the token contract in order to display the user's balance. It is responsibility of the wallet to require authorization from the user before disclosing private state to a dapp.
+
+## Wallet Architecture
+
+This page talks about the architecture of a wallet in Aztec. Wallets expose to dapps an interface that allows them to act on behalf of the user, such as querying private state or sending transactions. Bear in mind that, as in Ethereum, wallets should require user confirmation whenever carrying out a potentially sensitive action requested by a dapp.
+
+## Overview
+
+Architecture-wise, a wallet is an instance of an **Private Execution Environment (PXE)** which manages user keys and private state.
+The PXE also communicates with an **Aztec Node** for retrieving public information or broadcasting transactions.
+Note that the PXE requires a local database for keeping private state, and is also expected to be continuously syncing new blocks for trial-decryption of user notes.
+
+Additionally, a wallet must be able to handle one or more account contract implementation. When a user creates a new account, the account is represented onchain by an account contract. The wallet is responsible for deploying and interacting with this contract. A wallet may support multiple flavours of accounts, such as an account that uses ECDSA signatures, or one that relies on WebAuthn, or one that requires multi-factor authentication. For a user, the choice of what account implementation to use is then determined by the wallet they interact with.
+
+In code, this translates to a wallet implementing an **AccountInterface** interface that defines how to create an _execution request_ out of an array of _function calls_ for the specific implementation of an account contract and how to generate an _auth witness_ for authorizing actions on behalf of the user. Think of this interface as the Javascript counterpart of an account contract, or the piece of code that knows how to format a transaction and authenticate an action based on the rules defined by the user's account contract implementation.
+
+## Account interface
+
+The account interface is used for creating an _execution request_ out of one or more _function calls_ requested by a dapp, as well as creating an _auth witness_ for a given message hash. Account contracts are expected to handle multiple function calls per transaction, since dapps may choose to batch multiple actions into a single request to the wallet.
+
+#include_code account-interface yarn-project/aztec.js/src/account/interface.ts typescript
diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx
index b72aa36..d36b4f5 100644
--- a/docs/pages/index.mdx
+++ b/docs/pages/index.mdx
@@ -42,7 +42,7 @@ Private state works with UTXOs, which are chunks of data that we call notes. To
Public state works similarly to other chains like Ethereum, behaving like a public ledger. Public data is stored in a public data tree.
-
+
Aztec smart contract developers should keep in mind that different data types are used when manipulating private or public state. Working with private state is creating commitments and nullifiers to state, whereas working with public state is directly updating state.
diff --git a/docs/pages/protocol-architecture/nullifier-merkle-tree.md b/docs/pages/protocol-architecture/nullifier-merkle-tree.md
deleted file mode 100644
index b1568aa..0000000
--- a/docs/pages/protocol-architecture/nullifier-merkle-tree.md
+++ /dev/null
@@ -1,391 +0,0 @@
-# Indexed Merkle Trees
-
-## Overview
-
-This article will introduce the concept of an indexed merkle tree, and how it can be used to improve the performance of nullifier trees in circuits.
-
-This page will answer:
-
-- Why we need nullifier trees at all
-- How indexed merkle trees work
-- How they can be used for membership exclusion proofs
-- How they can leverage batch insertions
-- Tradeoffs of using indexed merkle trees
-
-The content was also covered in a presentation for the [Privacy + Scaling Explorations team at the Ethereum Foundation](https://pse.dev/).
-
-
-
-## Primer on Nullifier Trees
-
-Currently the only feasible way to get privacy in public blockchains is via a UTXO model. In this model, state is stored in encrypted UTXO's in merkle trees. However, to maintain privacy, state cannot be updated. The very act of performing an update leaks information. In order to simulate "updating" the state, we "destroy" old UTXO's and create new ones for each state update. Resulting in a merkle tree that is append-only.
-
-A classic merkle tree:
-
-
-
-To destroy state, the concept of a "nullifier" tree is introduced. Typically represented as a sparse Merkle Tree, the structure is utilized to store notes deterministically linked to values in the append-only tree of encrypted notes.
-
-A sparse merkle tree (not every leaf stores a value):
-
-
-
-In order to spend / modify a note in the private state tree, one must create a nullifier for it, and prove that the nullifier does not already exist in the nullifier tree. As nullifier trees are modeled as sparse merkle trees, non membership checks are (conceptually) trivial.
-
-Data is stored at the leaf index corresponding to its value. E.g. if I have a sparse tree that can contain $2^{256}$ values and want to prove non membership of the value $2^{128}$.
-
-I can prove via a merkle membership proof that $tree\_values[2^{128}] = 0$, conversely if I can prove that $tree\_values[2^{128}] == 1$ I can prove that the item exists.
-
-## Problems introduced by using Sparse Merkle Trees for Nullifier Trees
-
-While sparse Merkle Trees offer a simple and elegant solution, their implementation comes with some drawbacks. A sparse nullifier tree must have an index for $e \in \mathbb{F}_p$, which for the bn254 curve means that the sparse tree will need to have a depth of 254.
-If you're familiar with hashing in circuits the alarm bells have probably started ringing. A tree of depth 254 means 254 hashes per membership proof.
-In routine nullifier insertions, a non membership check for a value is performed, then an insertion of said value. This amounts to two trips from leaf to root, hashing all the way up. This means that there are $254 \times 2$ hashes per tree insertion. As the tree is sparse, insertions are random and must be performed in sequence. This means the number of hashes performed in the circuit scales linearly with the number of nullifiers being inserted. As a consequence number of constraints in a rollup circuit (where these checks are performed) will sky rocket, leading to long rollup proving times.
-
-## Indexed Merkle Tree Constructions
-
-As it turns out, we can do better. [This paper](https://eprint.iacr.org/2021/1263.pdf) (page 6) introduces the idea of an indexed merkle tree. A Merkle Tree that allows us to perform efficient non-membership proofs. It achieves this by extending each node to include a specialized data structure. Each node not only stores some value $v \in \mathbb{F}_p$ but also some pointers to the leaf with the next higher value. The data structure is as follows:
-
-$$
-\textsf{leaf} = \{v, i_{\textsf{next}}, v_{\textsf{next}}\}.
-$$
-
-Based on the tree's insertion rules, we can assume that there are no leaves in the tree that exist between the range $(v, v_{\textsf{next}})$.
-
-More simply put, the merkle tree pretty much becomes a linked list of increasing size, where once inserted the pointers at a leaf can change, but the nullifier value cannot.
-
-Despite being a minor modification, the performance implications are massive. We no longer position leaves in place $(index == value)$ therefore we no longer need a deep tree, rather we can use an arbitrarily small tree (32 levels should suffice).
-
-Some quick back of the napkin maths can show that insertions can be improved by a factor of 8 $(256 / 32)$.
-
-_For the remainder of this article we will refer to the node that provides the non membership check as a "low nullifier"._
-
-The insertion protocol is described below:
-
-1. Look for a nullifier's corresponding low_nullifier where:
-
- $$
- low\_nullifier_{\textsf{next\_value}} > new\_nullifier
- $$
-
- > if $new\_nullifier$ is the largest use the leaf:
-
- $$
- low\_nullifier_{\textsf{next\_value}} == 0
- $$
-
-2. Perform membership check of the low nullifier.
-3. Perform a range check on the low nullifier's value and next_value fields:
-
-$$
-\begin{aligned}
-new\_nullifier &> low\_nullifier_{\textsf{value}} \: \&\& \\
-&( new\_nullifier < low\_nullifier_{\textsf{next\_value}} \: || \: low\_nullifier_{\textsf{next\_value}} == 0 )
-\end{aligned}
-$$
-
-4. Update the low nullifier pointers
-
- $$
- low\_nullifier_{\textsf{next\_index}} = new\_insertion\_index
- $$
-
- $$
- low\_nullifier_{\textsf{next\_value}} = new\_nullifier
- $$
-
-5. Perform insertion of new updated low nullifier (yields new root)
-6. Update pointers on new leaf. Note: low_nullifier is from before update in step 4
-
-$$
-new\_nullifier\_leaf_{\textsf{value}} = new\_nullifier
-$$
-
-$$
-new\_nullifier\_leaf_{\textsf{next\_value}} = low\_nullifier_{\textsf{next\_value}}
-$$
-
-$$
-new\_nullifier\_leaf_{\textsf{next\_index}} = low\_nullifier_{\textsf{next\_index}}
-$$
-
-7. Perform insertion of new leaf (yields new root)
-
-#### Number of insertion constraints, in total:
-
-- `3n` hashes of 2 field elements (where `n` is the height of the tree).
-- `3` hashes of 3 field elements.
-- `2` range checks.
-- A handful of equality constraints.
-
-**Special cases**
-You'll notice at step 3 the $low\_nullifier_{\textsf{next\_value}}$ can be 0. This is a special case as if a value is the max, it will not point to anything larger (as it does not exist). Instead it points to zero. By doing so we close the loop, so we are always inserting into a ring, if we could insert outside the ring we could cause a split.
-
-A visual aid for insertion is presented below:
-
-1. Initial state
-
-
-
-2. Add a new value $v=30$
-
-
-
-3. Add a new value $v=10$
-
-
-
-4. Add a new value $v=20$
-
-
-
-5. Add a new value $v=50$
-
- img={require("@site/static/img/indexed-merkle-tree/index-merkle-tree-5.png")}
-/>
-
-By studying the transitions between each diagram you can see how the pointers are updated between each insertion.
-
-A further implementation detail is that we assume the first 0 node is pre-populated. As a consequence, the first insertion into the tree will be made into the second index.
-
-### Non-membership proof
-
-Suppose we want to show that the value `20` doesn't exist in the tree. We just reveal the leaf which 'steps over' `20`. I.e. the leaf whose value is less than `20`, but whose next value is greater than `20`. Call this leaf the `low_nullifier`.
-
-- hash the low nullifier: $low\_nullifier = h(10, 1, 30)$.
-- Prove the low leaf exists in the tree: `n` hashes.
-- Check the new value 'would have' belonged in the range given by the low leaf: `2` range checks.
- - If ($low\_nullifier_{\textsf{next\_index}} == 0$):
- - Special case, the low leaf is at the very end, so the new_value must be higher than all values in the tree:
- - $assert(low\_nullifier_{\textsf{value}} < new\_value_{\textsf{value}})$
- - Else:
- - $assert(low\_nullifier_{\textsf{value}} < new\_value_{\textsf{value}})$
- - $assert(low\_nullifier_{\textsf{next\_value}} > new\_value_{\textsf{value}})$
-
-This is already a massive performance improvement, however we can go further, as this tree is not sparse. We can perform batch insertions.
-
-## Batch insertions
-
-As our nullifiers will all be inserted deterministically (append only), we can insert entire subtrees into our tree rather than appending nodes one by one, this optimization is globally applied to append only merkle trees. I wish this was it, but for every node we insert, we must also update low nullifier pointers, this introduces a bit of complexity while performing subtree insertions, as the low nullifier itself may exist within the subtree we are inserting - we must be careful how we prove these sort of insertions are correct (addressed later).
-We must update all of the impacted low nullifiers before.
-
-First we will go over batch insertions in an append only merkle tree.
-
-1. First we prove that the subtree we are inserting into consists of all empty values.
-1. We work out the root of an empty subtree, and perform an inclusion proof for an empty root, which proves that there is nothing within our subtree.
-1. We re-create our subtree within our circuit.
-1. We then use the same sibling path the get the new root of the tree after we insert the subtree.
-
-In the following example we insert a subtree of size 4 into our tree at step 4. above. Our subtree is greyed out as it is "pending".
-
-**Legend**:
-
-- Green: New Inserted Value
-- Orange: Low Nullifier
-
-**Example**
-
-1. Prepare to insert subtree $[35,50,60,15]$
-
-
-
-2. Update low nullifier for new nullifier $35$.
-
-
-
-3. Update low nullifier for new nullifier $50$. (Notice how the low nullifier exists within our pending insertion subtree, this becomes important later).
-
-
-
-4. Update low nullifier for new nullifier $60$.
-
-
-
-5. Update low nullifier for new nullifier $15$.
-
-
-
-6. Update pointers for new nullifier $15$.
-
-
-
-7. Insert subtree.
-
-
-
-### Performance gains from subtree insertion
-
-Let's go back over the numbers:
-Insertions into a sparse nullifier tree involve 1 non membership check (254 hashes) and 1 insertion (254 hashes). If we were performing insertion for 4 values that would entail 2032 hashes.
-In the depth 32 indexed tree construction, each subtree insertion costs 1 non membership check (32 hashes), 1 pointer update (32 hashes) for each value as well as the cost of constructing and inserting a subtree (~67 hashes. Which is 327 hashes, an incredible efficiency increase.)
-
-_I am ignoring range check constraint costs as they a negligible compared to the costs of a hash_.
-
-## Performing subtree insertions in a circuit context
-
-Some fun engineering problems occur when we inserting a subtree in circuits when the low nullifier for a value exists within the subtree we are inserting. In this case we cannot perform a non membership check against the root of the tree, as our leaf that we would use for non membership has NOT yet been inserted into the tree. We need another protocol to handle such cases, we like to call these "pending" insertions.
-
-**Circuit Inputs**
-
-- `new_nullifiers`: `fr[]`
-- `low_nullifier_leaf_preimages`: `tuple of {value: fr, next_index: fr, next_value: fr}`
-- `low_nullifier_membership_witnesses`: A sibling path and a leaf index of low nullifier
-- `current_nullifier_tree_root`: Current root of the nullifier tree
-- `next_insertion_index`: fr, the tip our nullifier tree
-- `subtree_insertion_sibling_path`: A sibling path to check our subtree against the root
-
-Protocol without batched insertion:
-Before adding a nullifier to the pending insertion tree, we check for its non membership using the previously defined protocol by consuming the circuit inputs:
-Pseudocode:
-
-```cpp
-
-auto empty_subtree_hash = SOME_CONSTANT_EMPTY_SUBTREE;
-auto pending_insertion_subtree = [];
-auto insertion_index = inputs.next_insertion_index;
-auto root = inputs.current_nullifier_tree_root;
-
-// Check nothing exists where we would insert our subtree
-assert(membership_check(root, empty_subtree_hash, insertion_index >> subtree_depth, inputs.subtree_insertion_sibling_path));
-
-for (i in len(new_nullifiers)) {
- auto new_nullifier = inputs.new_nullifiers[i];
- auto low_nullifier_leaf_preimage = inputs.low_nullifier_leaf_preimages[i];
- auto low_nullifier_membership_witness = inputs.low_nullifier_membership_witnesses[i];
-
- // Membership check for low nullifier
- assert(perform_membership_check(root, hash(low_nullifier_leaf_preimage), low_nullifier_membership_witness));
-
- // Range check low nullifier against new nullifier
- assert(new_nullifier < low_nullifier_leaf_preimage.next_value || low_nullifier_leaf.next_value == 0);
- assert(new_nullifier > low_nullifier_leaf_preimage.value);
-
- // Update new nullifier pointers
- auto new_nullifier_leaf = {
- .value = new_nullifier,
- .next_index = low_nullifier_preimage.next_index,
- .next_value = low_nullifier_preimage.next_value
- };
-
- // Update low nullifier pointers
- low_nullifier_preimage.next_index = next_insertion_index;
- low_nullifier_preimage.next_value = new_nullifier;
-
- // Update state vals for next iteration
- root = update_low_nullifier(low_nullifier, low_nullifier_membership_witness);
- pending_insertion_subtree.push(new_nullifier_leaf);
- next_insertion_index += 1;
-}
-
-// insert subtree
-root = insert_subtree(root, inputs.next_insertion_index >> subtree_depth, pending_insertion_subtree);
-
-```
-
-From looking at the code above we can probably deduce why we need pending insertion. If the low nullifier does not yet exist in the tree, all of our membership checks will fail, we cannot produce a non membership proof.
-
-To perform batched insertions, our circuit must keep track of all values that are pending insertion.
-
-- If the `low_nullifier_membership_witness` is identified to be nonsense ( all zeros, or has a leaf index of -1 ) we will know that this is a pending low nullifier read request and we will have to look within our pending subtree for the nearest low nullifier.
- - Loop back through all "pending_insertions"
- - If the pending insertion value is lower than the nullifier we are trying to insert
- - If the pending insertion value is NOT found, then out circuit is invalid and should self abort.
-
-The updated pseudocode is as follows:
-
-```cpp
-
-auto empty_subtree_hash = SOME_CONSTANT_EMPTY_SUBTREE;
-auto pending_insertion_subtree = [];
-auto insertion_index = inputs.next_insertion_index;
-auto root = inputs.current_nullifier_tree_root;
-
-// Check nothing exists where we would insert our subtree
-assert(membership_check(root, empty_subtree_hash, insertion_index >> subtree_depth, inputs.subtree_insertion_sibling_path));
-
-for (i in len(new_nullifiers)) {
- auto new_nullifier = inputs.new_nullifiers[i];
- auto low_nullifier_leaf_preimage = inputs.low_nullifier_leaf_preimages[i];
- auto low_nullifier_membership_witness = inputs.low_nullifier_membership_witnesses[i];
-
- if (low_nullifier_membership_witness is garbage) {
- bool matched = false;
-
- // Search for the low nullifier within our pending insertion subtree
- for (j in range(0, i)) {
- auto pending_nullifier = pending_insertion_subtree[j];
-
- if (pending_nullifier.is_garbage()) continue;
- if (pending_nullifier[j].value < new_nullifier && (pending_nullifier[j].next_value > new_nullifier || pending_nullifier[j].next_value == 0)) {
-
- // bingo
- matched = true;
-
- // Update pointers
- auto new_nullifier_leaf = {
- .value = new_nullifier,
- .next_index = pending_nullifier.next_index,
- .next_value = pending_nullifier.next_value
- }
-
- // Update pending subtree
- pending_nullifier.next_index = insertion_index;
- pending_nullifier.next_value = new_nullifier;
-
- pending_insertion_subtree.push(new_nullifier_leaf);
- break;
- }
- }
-
- // could not find a matching low nullifier in the pending insertion subtree
- assert(matched);
-
- } else {
- // Membership check for low nullifier
- assert(perform_membership_check(root, hash(low_nullifier_leaf_preimage), low_nullifier_membership_witness));
-
- // Range check low nullifier against new nullifier
- assert(new_nullifier < low_nullifier_leaf_preimage.next_value || low_nullifier_leaf.next_value == 0);
- assert(new_nullifier > low_nullifier_leaf_preimage.value);
-
- // Update new nullifier pointers
- auto new_nullifier_leaf = {
- .value = new_nullifier,
- .next_index = low_nullifier_preimage.next_index,
- .next_value = low_nullifier_preimage.next_value
- };
-
- // Update low nullifier pointers
- low_nullifier_preimage.next_index = next_insertion_index;
- low_nullifier_preimage.next_value = new_nullifier;
-
- // Update state vals for next iteration
- root = update_low_nullifier(low_nullifier, low_nullifier_membership_witness);
-
- pending_insertion_subtree.push(new_nullifier_leaf);
-
- }
-
- next_insertion_index += 1;
-}
-
-// insert subtree
-root = insert_subtree(root, inputs.next_insertion_index >> subtree_depth, pending_insertion_subtree);
-
-```
-
-#### Drawbacks
-
-Despite offering large performance improvements within the circuits, these come at the expense of increased computation / storage performed by the node. To provide a non membership proof we must find the "low nullifier" for it. In a naive implementation this entails a brute force search against the existing nodes in the tree. This performance can be increased by the node maintaining a sorted data structure of existing nullifiers, increasing its storage footprint.
-
-#### Closing Notes
-
-We have been working with these new trees in order to reduce the proving time for our rollups in Aztec, however we think EVERY protocol leveraging nullifier trees should know about these trees as their performance benefit is considerable.
diff --git a/docs/pages/protocol-architecture/transactions.md b/docs/pages/protocol-architecture/transactions.md
deleted file mode 100644
index e69de29..0000000
diff --git a/docs/pages/protocol-architecture/wallets.md b/docs/pages/protocol-architecture/wallets.md
deleted file mode 100644
index e69de29..0000000
diff --git a/docs/pages/run-a-node/guides/index.md b/docs/pages/run-a-node/guides/index.md
index 557eae2..e385181 100644
--- a/docs/pages/run-a-node/guides/index.md
+++ b/docs/pages/run-a-node/guides/index.md
@@ -8,10 +8,10 @@ Learn how to set up and run different components of the Aztec network.
## Available Guides
-### [Run a Sequencer](./run-a-sequencer)
+### Run a Sequencer
Learn how to set up and operate a sequencer node on the Aztec network. Sequencers are responsible for ordering transactions and producing blocks.
-### [Run a Prover](./run-a-prover)
+### Run a Prover
Learn how to set up and operate a prover node. Provers generate zero-knowledge proofs for transactions and blocks.
## Prerequisites
diff --git a/docs/pages/run-a-node/reference/index.md b/docs/pages/run-a-node/reference/index.md
index a413817..6e2adf8 100644
--- a/docs/pages/run-a-node/reference/index.md
+++ b/docs/pages/run-a-node/reference/index.md
@@ -8,18 +8,18 @@ This section contains reference materials for node operators, including governan
## Contents
-### [Governance and Proposals](./governance-and-proposals)
+### Governance and Proposals
Information about network governance and the proposal process.
-### [FAQs](./faqs)
+### FAQs
Frequently asked questions about running Aztec nodes.
-### [Commands](./commands)
+### Commands
Reference for common node operation commands.
-### [CLI Reference](./cli-reference)
+### CLI Reference
Complete command-line interface reference for node operators.
## Additional Resources
-For getting started with running a node, see the [Getting Started](../getting-started) guide.
+For getting started with running a node, see the Getting Started guide.
diff --git a/vocs.config.ts b/vocs.config.ts
index c38349b..09ad047 100644
--- a/vocs.config.ts
+++ b/vocs.config.ts
@@ -1,21 +1,21 @@
import { defineConfig } from 'vocs'
-import remarkMath from 'remark-math'
-import rehypeKatex from 'rehype-katex'
import * as path from 'path'
import { remarkIncludeCode } from './src/plugins/remark-include-code'
+import remarkMath from 'remark-math'
+import rehypeKatex from 'rehype-katex'
export default defineConfig({
title: 'Aztec Docs',
markdown: {
- rehypePlugins: [
- [rehypeKatex, { strict: false }]
- ],
remarkPlugins: [
remarkMath,
[remarkIncludeCode, {
rootDir: path.join(__dirname, 'submodules/aztec-packages'),
commitTag: process.env.COMMIT_TAG
}]
+ ],
+ rehypePlugins: [
+ rehypeKatex
]
},
topNav: [
@@ -37,259 +37,256 @@ export default defineConfig({
link: '/aztec-nr/aztec-vs-ethereum',
},
{
- text: '4. Protocol Architecture',
- link: '/protocol-architecture',
- collapsed: true,
+ text: '4. Foundational Topics',
+ link: '/foundational-topics',
+ collapsed: false,
items: [
{
text: '4.1 Overview',
- link: '/protocol-architecture/overview',
- },
- {
- text: '4.2 Addresses & Keys',
- link: '/protocol-architecture/addresses-and-keys',
- },
- {
- text: '4.3 Wallets',
- link: '/protocol-architecture/wallets',
+ link: '/foundational-topics/overview',
},
{
- text: '4.4 Call Types',
- link: '/protocol-architecture/call-types',
+ text: '4.2 Transactions',
+ link: '/foundational-topics/transactions',
},
{
- text: '4.5 PXE & ACIR Simulator',
- link: '/protocol-architecture/pxe-and-acir-simulator',
+ text: '4.4 State Management',
+ link: '/foundational-topics/state-management',
},
{
- text: '4.6 Transactions',
- link: '/protocol-architecture/transactions',
+ text: '4.3 Addresses, Accounts & Keys',
+ link: '/foundational-topics/addresses-accounts-and-keys',
},
{
- text: '4.7 Fees',
- link: '/protocol-architecture/fees',
+ text: '4.7 Wallets',
+ link: '/foundational-topics/wallets',
},
{
- text: '4.8 Nullifier Merkle Tree',
- link: '/protocol-architecture/nullifier-merkle-tree',
- },
+ text: '4.6 Fees',
+ link: '/foundational-topics/fees',
+ }
+ ],
+ },
+ {
+ text: '5. Tutorials',
+ collapsed: false,
+ items: [
{
- text: '4.9 Note Discovery',
- link: '/protocol-architecture/note-discovery',
+ text: '5.1 Counter Smart Contract',
+ link: '/tutorials/counter-smart-contract',
},
{
- text: '4.10 Circuits',
- link: '/protocol-architecture/circuits',
+ text: '5.2 Private Token Smart Contract',
+ link: '/tutorials/private-token-smart-contract',
},
{
- text: '4.11 Storage Slots',
- link: '/protocol-architecture/storage-slots',
+ text: '5.3 Token Bridge',
+ link: '/tutorials/token-bridge',
}
- ],
+ ]
},
{
- text: '5. Aztec.nr',
+ text: '6. Aztec.nr',
collapsed: false,
items: [
{
- text: '5.1 Overview',
+ text: '6.1 Overview',
link: '/aztec-nr/overview',
},
{
- text: '5.2 Introduction to Private Smart Contracts',
+ text: '6.2 Introduction to Private Smart Contracts',
link: '/aztec-nr/introduction-to-private-smart-contracts',
collapsed: true,
items: [
{
- text: '5.2.1 A Simple Aztec Smart Contract',
- link: '/aztec-nr/introduction-to-private-smart-contracts/simple-contract'
+ text: '6.2.1 Private Token Contract',
+ link: '/aztec-nr/introduction-to-private-smart-contracts/private-token-contract'
},
{
- text: '5.2.2 Example Aztec Smart Contracts',
- link: '/aztec-nr/introduction-to-private-smart-contracts/examples'
+ text: '6.2.2 Account Contract',
+ link: '/aztec-nr/introduction-to-private-smart-contracts/account-contract'
}
]
},
{
- text: '5.3 Installation',
+ text: '6.3 Installation',
link: '/aztec-nr/installation',
},
{
- text: '5.4 Language Description',
- link: '/aztec-nr/language-description',
+ text: '6.4 Framework Description',
+ link: '/aztec-nr/framework-description',
collapsed: true,
items: [
{
- text: '5.4.1 Project Structure',
- link: '/aztec-nr/language-description/project-structure'
+ text: '6.4.1 Project Structure',
+ link: '/aztec-nr/framework-description/project-structure'
},
{
- text: '5.4.2 Contract Structure',
- link: '/aztec-nr/language-description/contract-structure'
+ text: '6.4.2 Contract Structure',
+ link: '/aztec-nr/framework-description/contract-structure'
},
{
- text: '5.4.3 Declaring a Contract',
- link: '/aztec-nr/language-description/declaring-a-contract'
+ text: '6.4.3 Declaring a Contract',
+ link: '/aztec-nr/framework-description/declaring-a-contract'
},
{
- text: '5.4.4 Functions',
- link: '/aztec-nr/language-description/functions'
+ text: '6.4.4 Functions',
+ link: '/aztec-nr/framework-description/functions'
},
{
- text: '5.4.5 Calling Other Contracts',
- link: '/aztec-nr/language-description/calling-other-contracts'
+ text: '6.4.5 Calling Other Contracts',
+ link: '/aztec-nr/framework-description/calling-other-contracts'
},
{
- text: '5.4.6 Aztec Attributes',
- link: '/aztec-nr/language-description/aztec-attributes'
+ text: '6.4.6 Aztec Attributes',
+ link: '/aztec-nr/framework-description/aztec-attributes'
},
{
- text: '5.4.7 Global Variables',
- link: '/aztec-nr/language-description/global-variables'
+ text: '6.4.7 Global Variables',
+ link: '/aztec-nr/framework-description/global-variables'
},
{
- text: '5.4.8 State Variables',
- link: '/aztec-nr/language-description/state-variables'
+ text: '6.4.8 State Variables',
+ link: '/aztec-nr/framework-description/state-variables'
},
{
- text: '5.4.9 Events and Logs',
- link: '/aztec-nr/language-description/events-and-logs'
+ text: '6.4.9 Events and Logs',
+ link: '/aztec-nr/framework-description/events-and-logs'
},
{
- text: '5.4.10 Private Messaging',
- link: '/aztec-nr/language-description/private-messaging'
+ text: '6.4.10 Private Messaging',
+ link: '/aztec-nr/framework-description/private-messaging'
},
{
- text: '5.4.11 L1<>L2 Messaging',
- link: '/aztec-nr/language-description/l1-l2-messaging'
+ text: '6.4.15 Libraries',
+ link: '/aztec-nr/framework-description/libraries'
},
{
- text: '5.4.12 Cross-chain Interactions',
- link: '/aztec-nr/language-description/cross-chain-interactions'
+ text: '6.4.11 Ethereum<>Aztec Messaging',
+ link: '/aztec-nr/framework-description/ethereum-aztec-messaging'
},
{
- text: '5.4.13 Macros',
- link: '/aztec-nr/language-description/macros'
+ text: '6.4.12 Cross-chain Interactions',
+ link: '/aztec-nr/framework-description/cross-chain-interactions'
},
{
- text: '5.4.14 Protocol Oracles',
- link: '/aztec-nr/language-description/protocol-oracles'
+ text: '6.4.13 Authentication Witness',
+ link: '/aztec-nr/framework-description/authentication-witness'
},
{
- text: '5.4.15 Libraries',
- link: '/aztec-nr/language-description/libraries'
+ text: '6.4.16 Upgradeable Contracts',
+ link: '/aztec-nr/framework-description/upgradeable-contracts'
},
{
- text: '5.4.16 Upgradeable Contracts',
- link: '/aztec-nr/language-description/upgradeable-contracts'
+ text: '6.4.14 Protocol Oracles',
+ link: '/aztec-nr/framework-description/protocol-oracles'
},
{
- text: '5.4.17 Error Handling',
- link: '/aztec-nr/language-description/error-handling'
+ text: '6.4.18 CoSnarks: Shared Private State',
+ link: '/aztec-nr/framework-description/cosnarks'
},
{
- text: '5.4.18 CoSnarks',
- link: '/aztec-nr/language-description/cosnarks'
+ text: '6.4.17 Error Handling',
+ link: '/aztec-nr/framework-description/error-handling'
}
]
},
{
- text: '5.5 Compiling',
+ text: '6.5 Compiling',
link: '/aztec-nr/compile',
},
{
- text: '5.6 Testing',
+ text: '6.6 Testing',
link: '/aztec-nr/testing',
},
{
- text: '5.7 Debugging',
+ text: '6.7 Debugging',
link: '/aztec-nr/debugging',
},
{
- text: '5.8 Deploying',
+ text: '6.8 Deploying',
link: '/aztec-nr/deploying',
},
{
- text: '5.9 Advanced Features',
- link: '/aztec-nr/advanced-features',
- collapsed: true,
- items: [
- {
- text: '5.9.1 Custom Notes',
- link: '/aztec-nr/advanced-features/custom-notes'
- }
- ]
- },
- {
- text: '5.10 Common Patterns',
+ text: '6.9 Common Patterns',
link: '/aztec-nr/common-patterns',
},
{
- text: '5.11 Optimizations, Gas and Profiling',
+ text: '6.10 Optimizations, Gas and Profiling',
link: '/aztec-nr/optimizations-and-gas',
collapsed: true,
items: [
{
- text: '5.11.1 Gas',
+ text: '6.10.1 Gas',
link: '/aztec-nr/optimizations-and-gas/gas'
},
{
- text: '5.11.1 Profiling',
+ text: '6.10.2 Profiling',
link: '/aztec-nr/optimizations-and-gas/profiling'
},
{
- text: '5.11.2 Optimizing Functions',
+ text: '6.10.3 Optimizing Functions',
link: '/aztec-nr/optimizations-and-gas/optimizing-functions'
},
{
- text: '5.11.4 Chosing Numeric Types',
+ text: '6.10.4 Chosing Numeric Types',
link: '/aztec-nr/optimizations-and-gas/numeric-types'
}
]
},
{
- text: '5.12 Protocol Upgrades',
+ text: '6.11 Protocol Upgrades',
link: '/aztec-nr/protocol-upgrades',
},
{
- text: '5.13 Reference',
+ text: '6.12 Reference',
link: '/aztec-nr/reference',
},
],
},
{
- text: '6. Aztec.js',
+ text: '7. Aztec.js',
collapsed: false,
items: [
{
- text: '6.1 Overview',
+ text: '7.1 Overview',
link: '/aztec-js/overview',
},
{
- text: '6.2 Getting Started',
- link: '/aztec-js/getting-started',
+ text: '7.2 Installation',
+ link: '/aztec-js/getting-started/installation',
},
{
- text: '6.3 Reference',
- link: '/aztec-js/reference',
+ text: '7.3 Creating Accounts',
+ link: '/aztec-js/getting-started/creating-accounts',
},
- ],
- },
- {
- text: '7. Aztec Nargo',
- collapsed: false,
- items: [
{
- text: '7.1 Overview',
- link: '/aztec-nargo/overview',
+ text: '7.4 Deploying Contracts',
+ link: '/aztec-js/getting-started/deploying-contracts',
+ },
+ {
+ text: '7.5 Sending Transactions',
+ link: '/aztec-js/getting-started/sending-transactions',
+ },
+ {
+ text: '7.6 Simulating Transactions',
+ link: '/aztec-js/getting-started/simulating-transactions',
},
{
- text: '7.2 Getting Started',
- link: '/aztec-nargo/getting-started',
+ text: '7.7 Using Authorizing Other Accounts',
+ link: '/aztec-js/getting-started/using-authorizing-other-accounts',
},
{
- text: '7.3 Reference',
- link: '/aztec-nargo/reference',
+ text: '7.8 Paying Fees',
+ link: '/aztec-js/getting-started/paying-fees',
+ },
+ {
+ text: '7.9 Testing Contracts',
+ link: '/aztec-js/getting-started/testing-contracts',
+ },
+ {
+ text: '7.10 Reference',
+ link: '/aztec-js/reference',
},
],
},
@@ -382,6 +379,10 @@ export default defineConfig({
text: '4.4 CLI Reference',
link: '/run-a-node/reference/cli-reference',
},
+ {
+ text: '4.9 Nullifier Merkle Tree',
+ link: '/foundational-topics/nullifier-merkle-tree',
+ }
],
},
],
diff --git a/yarn.lock b/yarn.lock
index bf23dc4..4bac85d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1808,6 +1808,11 @@
dependencies:
"@types/unist" "*"
+"@types/katex@^0.16.0":
+ version "0.16.7"
+ resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.16.7.tgz#03ab680ab4fa4fbc6cb46ecf987ecad5d8019868"
+ integrity sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==
+
"@types/mdast@^4.0.0", "@types/mdast@^4.0.3":
version "4.0.4"
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6"
@@ -3391,7 +3396,7 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
-katex@^0.16.22:
+katex@^0.16.0, katex@^0.16.22:
version "0.16.25"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.25.tgz#61699984277e3bdb3e89e0e446b83cd0a57d87db"
integrity sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q==
@@ -3689,6 +3694,19 @@ mdast-util-gfm@^3.0.0, mdast-util-gfm@^3.1.0:
mdast-util-gfm-task-list-item "^2.0.0"
mdast-util-to-markdown "^2.0.0"
+mdast-util-math@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-math/-/mdast-util-math-3.0.0.tgz#8d79dd3baf8ab8ac781f62b8853768190b9a00b0"
+ integrity sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==
+ dependencies:
+ "@types/hast" "^3.0.0"
+ "@types/mdast" "^4.0.0"
+ devlop "^1.0.0"
+ longest-streak "^3.0.0"
+ mdast-util-from-markdown "^2.0.0"
+ mdast-util-to-markdown "^2.1.0"
+ unist-util-remove-position "^5.0.0"
+
mdast-util-mdx-expression@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz#43f0abac9adc756e2086f63822a38c8d3c3a5096"
@@ -3765,7 +3783,7 @@ mdast-util-to-hast@^13.0.0, mdast-util-to-hast@^13.2.0:
unist-util-visit "^5.0.0"
vfile "^6.0.0"
-mdast-util-to-markdown@^2.0.0, mdast-util-to-markdown@^2.1.2:
+mdast-util-to-markdown@^2.0.0, mdast-util-to-markdown@^2.1.0, mdast-util-to-markdown@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz#f910ffe60897f04bb4b7e7ee434486f76288361b"
integrity sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==
@@ -3962,6 +3980,19 @@ micromark-extension-gfm@^3.0.0:
micromark-util-combine-extensions "^2.0.0"
micromark-util-types "^2.0.0"
+micromark-extension-math@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz#c42ee3b1dd5a9a03584e83dd8f08e3de510212c1"
+ integrity sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==
+ dependencies:
+ "@types/katex" "^0.16.0"
+ devlop "^1.0.0"
+ katex "^0.16.0"
+ micromark-factory-space "^2.0.0"
+ micromark-util-character "^2.0.0"
+ micromark-util-symbol "^2.0.0"
+ micromark-util-types "^2.0.0"
+
micromark-extension-mdx-expression@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz#43d058d999532fb3041195a3c3c05c46fa84543b"
@@ -4754,6 +4785,19 @@ rehype-class-names@^2.0.0:
hast-util-select "^6.0.0"
unified "^11.0.4"
+rehype-katex@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/rehype-katex/-/rehype-katex-7.0.1.tgz#832e6d7af2744a228981d1b0fe89483a9e7c93a1"
+ integrity sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==
+ dependencies:
+ "@types/hast" "^3.0.0"
+ "@types/katex" "^0.16.0"
+ hast-util-from-html-isomorphic "^2.0.0"
+ hast-util-to-text "^4.0.0"
+ katex "^0.16.0"
+ unist-util-visit-parents "^6.0.0"
+ vfile "^6.0.0"
+
rehype-mermaid@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/rehype-mermaid/-/rehype-mermaid-3.0.0.tgz#e7e39dcfc2700dcd0c4f0bcf30840ff2180115aa"
@@ -4821,6 +4865,16 @@ remark-gfm@^4.0.1:
remark-stringify "^11.0.0"
unified "^11.0.0"
+remark-math@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-6.0.0.tgz#0acdf74675f1c195fea6efffa78582f7ed7fc0d7"
+ integrity sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==
+ dependencies:
+ "@types/mdast" "^4.0.0"
+ mdast-util-math "^3.0.0"
+ micromark-extension-math "^3.0.0"
+ unified "^11.0.0"
+
remark-mdx-frontmatter@^5.0.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/remark-mdx-frontmatter/-/remark-mdx-frontmatter-5.2.0.tgz#fd3738b289248ef9afe84d45767acab8b9e00fcb"