Migration notes
Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them.
TBD
[Aztec Tools]
Contract compilation now requires two steps
The aztec-nargo
command is now a direct pass-through to vanilla nargo, without any special compilation flags or postprocessing. Contract compilation for Aztec now requires two explicit steps:
- Compile your contracts with
aztec-nargo compile
- Run postprocessing with the new
aztec-postprocess-contract
command
The postprocessing step includes:
- Transpiling functions for the Aztec VM
- Generating verification keys for private functions
- Caching verification keys for faster subsequent compilations
Update your build scripts accordingly:
- aztec-nargo compile
+ aztec-nargo compile
+ aztec-postprocess-contract
If you're using the aztec-up
installer, the aztec-postprocess-contract
command will be automatically installed alongside aztec-nargo
.
[Aztec.js] Mandatory from
As we prepare for a bigger Wallet
interface refactor and the upcoming WalletSDK
, a new parameter has been added to contract interactions, which now should indicate explicitly the address of the entrypoint (usually the account contract) that will be used to authenticate the request. This will be checked in runtime against the current this.wallet.getAddress()
value, to ensure consistent behavior while the rest of the API is reworked.
- await contract.methods.my_func(arg).send().wait();
+ await contract.methods.my_func(arg).send({ from: account1Address }).wait();
[Aztec.nr]
Unified oracles into single get_utility_context oracle
The following oracles:
- get_contract_address,
- get_block_number,
- get_timestamp,
- get_chain_id,
- get_version
were replaced with a single get_utility_context
oracle whose return value contains all the values returned from the removed oracles.
If you have used one of these removed oracles before, update the import, e.g.:
- aztec::oracle::execution::get_chain_id;
+ aztec::oracle::execution::get_utility_context
and get the value out of the returned utility context:
- let chain_id = get_chain_id();
+ let chain_id = get_utility_context().chain_id();
Note emission API changes
The note emission API has been significantly reworked to provide clearer semantics around message delivery guarantees. The key changes are:
encode_and_encrypt_note
has been removed in favor of callingemit
directly withMessageDelivery.CONSTRAINED_ONCHAIN
encode_and_encrypt_note_unconstrained
has been removed in favor of callingemit
directly withMessageDelivery.UNCONSTRAINED_ONCHAIN
encode_and_encrypt_note_and_emit_as_offchain_message
has been removed in favor of usingemit
withMessageDelivery.UNCONSTRAINED_OFFCHAIN
- Note emission now takes a
delivery_mode
parameter with the following values:CONSTRAINED_ONCHAIN
: For onchain delivery with cryptographic guarantees that recipients can discover and decrypt messages. Uses constrained encryption but is slower to prove. Best for critical messages that contracts need to verify.UNCONSTRAINED_ONCHAIN
: For onchain delivery without encryption constraints. Faster proving but trusts the sender. Good when the sender is incentivized to perform encryption correctly (e.g. they are buying something and will only get it if the recipient sees the note). No guarantees that recipients will be able to find or decrypt messages.UNCONSTRAINED_OFFCHAIN
: For offchain delivery (e.g. cloud storage) without constraints. Lowest cost since no onchain storage needed. Requires custom infrastructure for delivery. No guarantees that messages will be delivered or that recipients will ever find them.
Example migration:
First you need to update imports in your contract:
- aztec::messages::logs::note::encode_and_encrypt_note;
- aztec::messages::logs::note::encode_and_encrypt_note_unconstrained;
- aztec::messages::logs::note::encode_and_encrypt_note_and_emit_as_offchain_message;
+ aztec::messages::message_delivery::MessageDelivery;
Then update the emissions:
- storage.balances.at(from).sub(from, amount).emit(encode_and_encrypt_note(&mut context, from));
+ storage.balances.at(from).sub(from, amount).emit(&mut context, from, MessageDelivery.CONSTRAINED_ONCHAIN);
- storage.balances.at(from).add(from, change).emit(encode_and_encrypt_note_unconstrained(&mut context, from));
+ storage.balances.at(from).add(from, change).emit(&mut context, from, MessageDelivery.UNCONSTRAINED_ONCHAIN);
- storage.balances.at(owner).insert(note).emit(encode_and_encrypt_note_and_emit_as_offchain_message(&mut context, context.msg_sender());
+ storage.balances.at(owner).insert(note).emit(&mut context, context.msg_sender(), MessageDelivery.UNCONSTRAINED_OFFCHAIN);
emit_event_in_public_log
function renamed as emit_event_in_public
This change was done to make the naming consistent with the private counterpart (emit_event_in_private
).
Private event emission API changes
The private event emission API has been significantly reworked to provide clearer semantics around message delivery guarantees. The key changes are:
emit_event_in_private_log
has been renamed toemit_event_in_private
and now takes adelivery_mode
parameter instead ofconstraints
emit_event_as_offchain_message
has been removed in favor of usingemit_event_in_private
withMessageDelivery.UNCONSTRAINED_OFFCHAIN
PrivateLogContent
enum has been replaced withMessageDelivery
enum with the following values:CONSTRAINED_ONCHAIN
: For onchain delivery with cryptographic guarantees that recipients can discover and decrypt messages. Uses constrained encryption but is slower to prove. Best for critical messages that contracts need to verify.UNCONSTRAINED_ONCHAIN
: For onchain delivery without encryption constraints. Faster proving but trusts the sender. Good when the sender is incentivized to perform encryption correctly (e.g. they are buying something and will only get it if the recipient sees the note). No guarantees that recipients will be able to find or decrypt messages.UNCONSTRAINED_OFFCHAIN
: For offchain delivery (e.g. cloud storage) without constraints. Lowest cost since no onchain storage needed. Requires custom infrastructure for delivery. No guarantees that messages will be delivered or that recipients will ever find them.
Contract functions can no longer be pub
or pub(crate)
With the latest changes to TestEnvironment
, making contract functions have public visibility is no longer required given the new call_public
and simulate_utility
functions. To avoid accidental direct invocation, and to reduce confusion with the autogenerated interfaces, we're forbidding them being public.
- pub(crate) fn balance_of_private(account: AztecAddress) -> 128 {
+ fn balance_of_private(account: AztecAddress) -> 128 {
Notes require you to manually implement or derive Packable
We have decided to drop auto-derivation of Packable
from the #[note]
macro because we want to make the macros less magical.
With this change you will be forced to either apply #[derive(Packable)
on your notes:
+use aztec::protocol_types::traits::Packable;
+#[derive(Packable)]
#[note]
pub struct UintNote {
owner: AztecAddress,
randomness: Field,
value: u128,
}
or to implement it manually yourself:
impl Packable for UintNote {
let N: u32 = 3;
fn pack(self) -> [Field; Self::N] {
[self.owner.to_field(), randomness, value as Field]
}
fn unpack(fields: [Field; Self::N]) -> Self {
let owner = AztecAddress::from_field(fields[0]);
let randomness = fields[1];
let value = fields[2] as u128;
UintNote { owner, randomness, value }
}
}
Tagging sender now managed via oracle functions
Now, instead of manually needing to pass a tagging sender as an argument to log emission functions (e.g. encode_and_encrypt_note
, encode_and_encrypt_note_unconstrained
, emit_event_in_private_log
, ...) we automatically load the sender via the get_sender_for_tags()
oracle.
This value is expected to be populated by account contracts that should call set_sender_for_tags()
in their entry point functions.
The changes you need to do in your contracts are quite straightforward.
You simply need to drop the sender
arg from the callsites of the log emission functions.
E.g. note emission:
storage.balances.at(from).sub(from, amount).emit(encode_and_encrypt_note(
&mut context,
from,
- tagging_sender,
));
E.g. private event emission:
emit_event_in_private_log(
Transfer { from, to, amount },
&mut context,
- tagging_sender,
to,
PrivateLogContent.NO_CONSTRAINTS,
);
This change affected arguments prepare_private_balance_increase
and mint_to_private
functions on the Token
contract.
Drop the from
argument when calling these.
Example n TypeScript test:
- await token.methods.mint_to_private(fundedWallet.getAddress(), alice, mintAmount).send().wait();
+ await token.methods.mint_to_private(alice, mintAmount).send().wait();
Example when
let token_out_partial_note = Token::at(token_out).prepare_private_balance_increase(
sender,
- tagging_sender
).call(&mut context);
SharedMutable -> DelayedPublicMutable
The SharedMutable
state variable has been renamed to DelayedPublicMutable
. It is a public mutable with a delay before state changes take effect. It can be read in private during the delay period. The name "shared" confuses developers who actually wish to work with so-called "shared private state". Also, we're working on a DelayedPrivateMutable
which will have similar properties, except writes will be scheduled from private instead. With this new state variable in mind, the new name works nicely.
[TXE] - Testing Aztec Contracts using Noir
Full TestEnvironment
API overhaul
As part of a broader effort to make Noir tests that leverage TXE easier to use and reason about, large parts of it were changed or adapted, resulting in the API now being quite different. No functionality was lost, so it should be possible to migrate any older Noir test to use the new API.
Network State Manipulation
committed_timestamp
removed: this function did not work correctlyprivate_at_timestamp
: this function was not really meaningful: private contexts are built from block numbers, not timestampspending_block_number
was renamed tonext_block_number
.pending_timestamp
was removed since it was confusing and not usefulcommitted_block_number
was renamed tolast_block_number
advance_timestamp_to
andadvance_timestamp_by
were renamed toset_next_block_timestamp
andadvance_next_block_timestamp_by
respectivelyadvance_block_to
was renamed tomine_block_at
, which takes a timestamp instead of a target block numberadvance_block_by
was renamed tomine_block
, which now mines a single block
Account Management
create_account
was renamed tocreate_light_account
create_account_contract
was renamed tocreate_contract_account
Contract Deployment
deploy_self
removed: merged intodeploy
deploy
now accepts both local and external contracts
Contract Interactions
The old way of calling contract functions is gone. Contract functions are now invoked via the call_private
, view_private
, call_public
, view_public
and simulate_utility
TestEnvironment
methods. These take a CallInterface
, like their old counterparts, but now also take an explicit from
parameter (for the call
variants - this is left out of the view
and simulate
methods for simplicity).
Raw Context Access
The private
and public
methods are gone. Private, public and utility contexts can now be crated with the private_context
, public_context
and utility_context
functions, all of which takes a callback function that is called with the corresponding context. This functions are expected to be defined in-line as lambdas, and contain the user-defined test logic. This helps delineate where contexts begin and end. Contexts automatically mine blocks on closing, when appropriate.
Error-expecting Functions
assert_public_call_revert
and variants have been removed. Use #[test(should_fail_with = "message")]
instead.
Example Migration
The following are two tests using the older version of TestEnvironment
:
#[test]
unconstrained fn initial_empty_value() {
let mut env = TestEnvironment::new();
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let admin = env.create_account(1);
let initializer_call_interface = Auth::interface().constructor(admin);
let auth_contract =
env.deploy_self("Auth").with_public_void_initializer(admin, initializer_call_interface);
let auth_contract_address = auth_contract.to_address();
env.impersonate(admin);
let authorized = Auth::at(auth_contract_address).get_authorized().view(&mut env.public());
assert_eq(authorized, AztecAddress::from_field(0));
}
#[test]
unconstrained fn non_admin_cannot_set_authorized() {
let mut env = TestEnvironment::new();
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let admin = env.create_account(1);
let other = env.create_account(2);
let initializer_call_interface = Auth::interface().constructor(admin);
let auth_contract =
env.deploy_self("Auth").with_public_void_initializer(admin, initializer_call_interface);
let auth_contract_address = auth_contract.to_address();
env.impersonate(other);
env.assert_public_call_fails(Auth::at(auth_contract_address).set_authorized(to_authorize));
}
These now look like this:
#[test]
unconstrained fn authorized_initially_unset() {
let mut env = TestEnvironment::new();
let admin = env.create_light_account(); // Manual secret management gone
let auth_contract_address =
env.deploy("Auth").with_public_initializer(admin, Auth::interface().constructor(admin)); // deploy_self replaced
let auth = Auth::at(auth_contract_address);
assert_eq(env.view_public(auth.get_authorized()), AztecAddress::zero()); // .view_public() instead of .public()
}
#[test(should_fail_with = "caller is not admin")]
unconstrained fn non_admin_cannot_set_unauthorized() {
let mut env = TestEnvironment::new();
let admin = env.create_light_account();
let other = env.create_light_account();
let auth_contract_address =
env.deploy("Auth").with_public_initializer(admin, Auth::interface().constructor(admin)); // deploy_self replaced
let auth = Auth::at(auth_contract_address);
env.call_public(other, auth.set_authorized(other)); // .call_public(), should_fail_with
}
[Aztec.js]
Cheatcodes
Cheatcodes where moved out of the @aztec/aztec.js
package to @aztec/ethereum
and @aztec/aztec
packages.
While all of the cheatcodes can be imported from the @aztec/aztec
package EthCheatCodes
and RollupCheatCodes
reside in @aztec/ethereum
package and if you need only those importing only that package should result in a lighter build.
Note exports dropped from artifact
Notes are no longer exported in the contract artifact. Exporting notes was technical debt from when we needed to interpret notes in TypeScript.
The following code will no longer work since notes
is no longer available on the artifact:
const valueNoteTypeId = StatefulTestContractArtifact.notes['ValueNote'].id;
[core protocol, Aztec.nr, Aztec.js] Max block number property changed to be seconds based
max_block_number
-> include_by_timestamp
The transaction expiration mechanism has been updated to use seconds rather than number of blocks.
As part of this change, the transaction property max_block_number
has been renamed to include_by_timestamp
.
This change significantly impacts the SharedMutable
state variable in Aztec.nr
, which now operates on a seconds instead of number of blocks.
If your contract uses SharedMutable
, you'll need to:
- Update the
INITIAL_DELAY
numeric generic to use seconds instead of blocks - Modify any related logic to account for timestamp-based timing
- Note that timestamps use
u64
values while block numbers useu32
Removed prelude
, so your dep::aztec::prelude::...
imports will need to be amended.
Instead of importing common types from dep::aztec::prelude...
, you'll now need to import them from their lower-level locations.
The Noir Language Server vscode extension is now capable of autocompleting imports: just type some of the import and press 'tab' when it pops up with the correct item, and the import will be inserted at the top of the file.
As a quick reference, here are the paths to the types that were previously in the prelude
.
So, for example, if you were previously using dep::aztec::prelude::AztecAddress
, you'll need to replace it with dep::aztec::protocol_types::address::AztecAddress
.
Apologies for any pain this brings. The reasoning is that these types were somewhat arbitrary, and it was unclear which types were worthy enough to be included here.
use dep::aztec::{
context::{PrivateCallInterface, PrivateContext, PublicContext, UtilityContext, ReturnsHash},
note::{
note_getter_options::NoteGetterOptions,
note_interface::{NoteHash, NoteType},
note_viewer_options::NoteViewerOptions,
retrieved_note::RetrievedNote,
},
state_vars::{
map::Map, private_immutable::PrivateImmutable, private_mutable::PrivateMutable,
private_set::PrivateSet, public_immutable::PublicImmutable, public_mutable::PublicMutable,
shared_mutable::SharedMutable,
},
};
use dep::aztec::protocol_types::{
abis::function_selector::FunctionSelector,
address::{AztecAddress, EthAddress},
point::Point,
traits::{Deserialize, Serialize},
};
include_by_timestamp
is now mandatory
Each transaction must now include a valid include_by_timestamp
that satisfies the following conditions:
- It must be greater than the historical block’s timestamp.
- The duration between the
include_by_timestamp
and the historical block’s timestamp must not exceed the maximum allowed (currently 24 hours). - It must be greater than or equal to the timestamp of the block in which the transaction is included.
The protocol circuits compute the include_by_timestamp
for contract updates during each private function iteration. If a contract does not explicitly specify a value, the default will be the maximum allowed duration. This ensures that include_by_timestamp
is never left unset.
No client-side changes are required. However, please note that transactions now have a maximum lifespan of 24 hours and will be removed from the transaction pool once expired.
0.88.0
[Aztec.nr] Deprecation of the authwit
library
It is now included in aztec-nr
, so imports must be updated:
-dep::authwit::...
+dep::aztec::authwit...
and stale dependencies removed from Nargo.toml
-authwit = { path = "../../../../aztec-nr/authwit" }
0.87.0
[Aztec.js/TS libraries]
We've bumped our minimum supported node version to v20, as v18 is now EOL. As a consequence, the deprecated type assertion syntax has been replaced with modern import attributes whenever contract artifact JSONs are loaded:
-import ArtifactJson from '../artifacts/contract-Contract.json' assert { type: 'json' };
+import ArtifactJson from '../artifacts/contract-Contract.json' with { type: 'json' };
[Aztec.js/PXE] simulateUtility
return type
pxe.simulateUtility()
now returns a complex object (much like .simulateTx()
) so extra information can be provided such as simulation timings.
This information can be accessed setting the includeMetadata
flag in SimulateMethodOptions
to true
, but not providing it (which is the default) will NOT change the behavior of the current code.
-const result = await pxe.simulateUtility(...);
+const { meta, result } = await pxe.simulateUtility(...);
const result = await Contract.methods.myFunction(...).simulate();
const { result, meta} = await Contract.methods.myFunction(...).simulate({ includeMetadata: true });
[Aztec.js] Removed mandatory simulation before proving in contract interfaces
Previously, our autogenerated contract classes would perform a simulation when calling .prove
or .send
on them. This could potentially catch errors earlier, but took away control from the app/wallets on how to handle network interactions. Now this process has to be triggered manually, which means just proving an interaction (or proving and sending it to the network in one go via .send
) is much faster.
WARNING: This means users can incurr in network fees if a transaction that would otherwise be invalid is sent without sanity checks. To ensure this, it is recommended to do:
+await Contract.method.simulate();
await Contract.method.send().wait();
0.86.0
[PXE] Removed PXE_L2_STARTING_BLOCK environment variable
PXE now fast-syncs by skipping finalized blocks and never downloads all blocks, so there is no longer a need to specify a starting block.
[Aztec.nr] Logs and messages renaming
The following renamings have taken place:
encrypted_logs
tomessages
: this module now handles much more than just encrypted logs (including unconstrained message delivery, message encoding, etc.)log_assembly_strategies
tologs
discovery
moved tomessages
: given that what is discovered are messagesdefault_aes128
removed
Most contracts barely used these modules, the only frequent imports are the encode_and_encrypt
functions:
- use dep::aztec::messages::logs::note::encode_and_encrypt_note;
+ use dep::aztec::messages::logs::note::encode_and_encrypt_note;
[noir-contracts] Reference Noir contracts directory structure change
noir-projects/noir-contracts/contracts
directory became too cluttered so we grouped contracts into account
, app
, docs
, fees
, libs
, protocol
and test
dirs.
If you import contract from the directory make sure to update the paths accordingly.
E.g. for a token contract:
#[dependencies]
-token = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "v0.83.0", directory = "noir-projects/noir-contracts/contracts/src/token_contract" }
+token = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "v0.83.0", directory = "noir-projects/noir-contracts/contracts/app/src/token_contract" }
[Aztec.nr] #[utility] contract functions
Aztec contracts have three kinds of functions: #[private]
, #[public]
and what was sometimes called 'top-level unconstrained': an unmarked unconstrained function in the contract module. These are now called [#utility]
functions, and must be explicitly marked as such:
+ #[utility]
unconstrained fn balance_of_private(owner: AztecAddress) -> u128 {
storage.balances.at(owner).balance_of()
}
Utility functions are standalone unconstrained functions that cannot be called from private or public functions: they are meant to be called by applications to perform auxiliary tasks: query contract state (e.g. a token balance), process messages received offchain, etc.
All functions in a contract
block must now be marked as one of either #[private]
, #[public]
, #[utility]
, #[contract_library_method]
, or #[test]
.
Additionally, the UnconstrainedContext
type has been renamed to UtilityContext
. This led us to rename the unkonstrained
method on TestEnvironment
to utility
, so any tests using it also need updating:
- SharedMutable::new(env.unkonstrained(), storage_slot)
+ SharedMutable::new(env.utility(), storage_slot)
[AuthRegistry] function name change
As part of the broader transition from "top-level unconstrained" to "utility" name (detailed in the note above), the unconstrained_is_consumable
function in AuthRegistry has been renamed to utility_is_consumable
. The function's signature and behavior remain unchanged - only the name has been updated to align with the new convention. If you're currently using this function, a simple rename in your code will suffice.
0.83.0
[aztec.js] AztecNode.getPrivateEvents API change
The getPrivateEvents
method signature has changed to require an address of a contract that emitted the event and use recipient addresses instead of viewing public keys:
- const events = await wallet.getPrivateEvents<Transfer>(TokenContract.events.Transfer, 1, 1, [recipient.getCompleteAddress().publicKeys.masterIncomingViewingPublicKey()]);
+ const events = await wallet.getPrivateEvents<Transfer>(token.address, TokenContract.events.Transfer, 1, 1, [recipient.getAddress()]);
[portal contracts] Versions and Non-following message boxes
The version number is no longer hard-coded to be 1
across all deployments (it not depends on where it is deployed to and with what genesis and logic).
This means that if your portal were hard-coding 1
it will now fail when inserting into the inbox
or consuming from the outbox
because of a version mismatch.
Instead you can get the real version (which don't change for a deployment) by reading the VERSION
on inbox and outbox, or using getVersion()
on the rollup.
New Deployments of the protocol do not preserve former state/across each other. This means that after a new deployment, any "portal" following the registry would try to send messages into this empty rollup to non-existant contracts. To solve, the portal should be linked to a specific deployment, e.g., a specific inbox. This can be done by storing the inbox/outbox/version at the time of deployment or initialize and not update them.
Both of these issues were in the token portal and the uniswap portal, so if you used them as a template it is very likely that you will also have it.
0.82.0
[aztec.js] AztecNode.findLeavesIndexes returns indexes with block metadata
It's common that we need block metadata of a block in which leaves where inserted when querying indexes of these tree leaves. For this reason we now return that information along with the indexes. This allows us to reduce the number of individual AztecNode queries.
Along this change findNullifiersIndexesWithBlock
and findBlockNumbersForIndexes
functions wer removed as all its uses can now be replaced with the newly modified findLeavesIndexes
function.
[aztec.js] AztecNode.getPublicDataTreeWitness renamed as AztecNode.getPublicDataWitness
This change was done to have consistent naming across codebase.
[aztec.js] Wallet interface and Authwit management
The Wallet
interface in aztec.js
is undergoing transformations, trying to be friendlier to wallet builders and reducing the surface of its API. This means Wallet
no longer extends PXE
, and instead just implements a subset of the methods of the former. This is NOT going to be its final form, but paves the way towards better interfaces and starts to clarify what the responsibilities of the wallet are:
/**
* The wallet interface.
*/
export type Wallet = AccountInterface &
Pick<
PXE,
// Simulation
| "simulateTx"
| "simulateUnconstrained"
| "profileTx"
// Sending
| "sendTx"
// Contract management (will probably be collapsed in the future to avoid instance and class versions)
| "getContractClassMetadata"
| "getContractMetadata"
| "registerContract"
| "registerContractClass"
// Likely to be removed
| "proveTx"
// Will probably be collapsed
| "getNodeInfo"
| "getPXEInfo"
// Fee info
| "getCurrentBaseFees"
// Still undecided, kept for the time being
| "updateContract"
// Sender management
| "registerSender"
| "getSenders"
| "removeSender"
// Tx status
| "getTxReceipt"
// Events. Kept since events are going to be reworked and changes will come when that's done
| "getPrivateEvents"
| "getPublicEvents"
> & {
createAuthWit(intent: IntentInnerHash | IntentAction): Promise<AuthWitness>;
};
As a side effect, a few debug only features have been removed
// Obtain tx effects
const { txHash, debugInfo } = await contract.methods
.set_constant(value)
.send()
-- .wait({ interval: 0.1, debug: true });
++ .wait({ interval: 0.1 })
-- // check that 1 note hash was created
-- expect(debugInfo!.noteHashes.length).toBe(1);
++ const txEffect = await aztecNode.getTxEffect(txHash);
++ const noteHashes = txEffect?.data.noteHashes;
++ // check that 1 note hash was created
++ expect(noteHashes?.length).toBe(1);
// Wait for a tx to be proven
-- tx.wait({ timeout: 300, interval: 10, proven: true, provenTimeout: 3000 })));
++ const receipt = await tx.wait({ timeout: 300, interval: 10 });
++ await waitForProven(aztecNode, receipt, { provenTimeout: 3000 });
Authwit management has changed, and PXE no longer stores them. This is unnecessary because now they can be externally provided to simulations and transactions, making sure no stale authorizations are kept inside PXE's db.
const witness = await wallet.createAuthWit({ caller, action });
--await callerWallet.addAuthWitness(witness);
--await action.send().wait();
++await action.send({ authWitnesses: [witness] }).wait();
Another side effect of this is that the interface of the lookupValidity
method has changed, and now the authwitness has to be provided:
const witness = await wallet.createAuthWit({ caller, action });
--await callerWallet.addAuthWitness(witness);
--await wallet.lookupValidity(wallet.getAddress(), { caller, action });
++await wallet.lookupValidity(wallet.getAddress(), { caller, action }, witness);
0.80.0
[PXE] Concurrent contract function simulation disabled
PXE is no longer be able to execute contract functions concurrently (e.g. by collecting calls to simulateTx
and then using await Promise.all
). They will instead be put in a job queue and executed sequentially in order of arrival.
0.79.0
[aztec.js] Changes to BatchCall
and BaseContractInteraction
The constructor arguments of BatchCall
have been updated to improve usability. Previously, it accepted an array of FunctionCall
, requiring users to manually set additional data such as authwit
and capsules
. Now, BatchCall
takes an array of BaseContractInteraction
, which encapsulates all necessary information.
class BatchCall extends BaseContractInteraction {
- constructor(wallet: Wallet, protected calls: FunctionCall[]) {
+ constructor(wallet: Wallet, protected calls: BaseContractInteraction[]) {
...
}
The request
method of BaseContractInteraction
now returns ExecutionPayload
. This object includes all the necessary data to execute one or more functions. BatchCall
invokes this method on all interactions to aggregate the required information. It is also used internally in simulations for fee estimation.
Declaring a BatchCall
:
new BatchCall(wallet, [
- await token.methods.transfer(alice, amount).request(),
- await token.methods.transfer_to_private(bob, amount).request(),
+ token.methods.transfer(alice, amount),
+ token.methods.transfer_to_private(bob, amount),
])
0.77.0
[aztec-nr] TestEnvironment::block_number()
refactored
The block_number
function from TestEnvironment
has been expanded upon with two extra functions, the first being pending_block_number
, and the second being committed_block_number
. pending_block_number
now returns what block_number
does. In other words, it returns the block number of the block we are currently building. committed_block_number
returns the block number of the last committed block, i.e. the block number that gets used to execute the private part of transactions when your PXE is successfully synced to the tip of the chain.
+ `TestEnvironment::pending_block_number()`
+ `TestEnvironment::committed_block_number()`