diff --git a/boxes/boxes/react/src/hooks/useContract.tsx b/boxes/boxes/react/src/hooks/useContract.tsx index 5b3c7aca373f..ff180dfa5b59 100644 --- a/boxes/boxes/react/src/hooks/useContract.tsx +++ b/boxes/boxes/react/src/hooks/useContract.tsx @@ -24,10 +24,10 @@ export function useContract() { contractAddressSalt: salt, }); - const contract = await toast.promise(deploymentPromise, { + const { contract } = await toast.promise(deploymentPromise, { pending: 'Deploying contract...', success: { - render: ({ data }) => `Address: ${data.address}`, + render: ({ data }) => `Address: ${data.contract.address}`, }, error: 'Error deploying contract', }); diff --git a/boxes/boxes/react/src/hooks/useNumber.tsx b/boxes/boxes/react/src/hooks/useNumber.tsx index 8809b6555b42..7435cf5ebfa7 100644 --- a/boxes/boxes/react/src/hooks/useNumber.tsx +++ b/boxes/boxes/react/src/hooks/useNumber.tsx @@ -11,10 +11,10 @@ export function useNumber({ contract }: { contract: Contract }) { setWait(true); const defaultAccountAddress = deployerEnv.getDefaultAccountAddress(); - const viewTxReceipt = await contract!.methods + const { result } = await contract!.methods .getNumber(defaultAccountAddress) .simulate({ from: defaultAccountAddress }); - toast(`Number is: ${viewTxReceipt.value}`); + toast(`Number is: ${result}`); setWait(false); }; diff --git a/boxes/boxes/vanilla/app/embedded-wallet.ts b/boxes/boxes/vanilla/app/embedded-wallet.ts index 04951e383ee9..bbf32271f6b5 100644 --- a/boxes/boxes/vanilla/app/embedded-wallet.ts +++ b/boxes/boxes/vanilla/app/embedded-wallet.ts @@ -162,7 +162,7 @@ export class EmbeddedWallet extends EmbeddedWalletBase { wait: { timeout: 120 }, }; - const receipt = await deployMethod.send(deployOpts); + const { receipt } = await deployMethod.send(deployOpts); logger.info('Account deployed', receipt); diff --git a/boxes/boxes/vanilla/app/main.ts b/boxes/boxes/vanilla/app/main.ts index fa55a4cae208..ddce11af435c 100644 --- a/boxes/boxes/vanilla/app/main.ts +++ b/boxes/boxes/vanilla/app/main.ts @@ -200,7 +200,7 @@ async function updateVoteTally(wallet: Wallet, from: AztecAddress) { const batchResult = await new BatchCall(wallet, payloads).simulate({ from }); - batchResult.forEach((value, i) => { + batchResult.forEach(({ result: value }, i) => { results[i + 1] = value; }); diff --git a/boxes/boxes/vanilla/scripts/deploy.ts b/boxes/boxes/vanilla/scripts/deploy.ts index b02edaa7e6b1..e0e0f971a739 100644 --- a/boxes/boxes/vanilla/scripts/deploy.ts +++ b/boxes/boxes/vanilla/scripts/deploy.ts @@ -71,7 +71,7 @@ async function deployContract(wallet: Wallet, deployer: AztecAddress) { const sponsoredPFCContract = await getSponsoredPFCContract(); - const contract = await PrivateVotingContract.deploy(wallet, deployer).send({ + const { contract } = await PrivateVotingContract.deploy(wallet, deployer).send({ from: deployer, contractAddressSalt: salt, fee: { diff --git a/boxes/boxes/vite/src/hooks/useContract.tsx b/boxes/boxes/vite/src/hooks/useContract.tsx index 5b3c7aca373f..ff180dfa5b59 100644 --- a/boxes/boxes/vite/src/hooks/useContract.tsx +++ b/boxes/boxes/vite/src/hooks/useContract.tsx @@ -24,10 +24,10 @@ export function useContract() { contractAddressSalt: salt, }); - const contract = await toast.promise(deploymentPromise, { + const { contract } = await toast.promise(deploymentPromise, { pending: 'Deploying contract...', success: { - render: ({ data }) => `Address: ${data.address}`, + render: ({ data }) => `Address: ${data.contract.address}`, }, error: 'Error deploying contract', }); diff --git a/boxes/boxes/vite/src/hooks/useNumber.tsx b/boxes/boxes/vite/src/hooks/useNumber.tsx index 8809b6555b42..7435cf5ebfa7 100644 --- a/boxes/boxes/vite/src/hooks/useNumber.tsx +++ b/boxes/boxes/vite/src/hooks/useNumber.tsx @@ -11,10 +11,10 @@ export function useNumber({ contract }: { contract: Contract }) { setWait(true); const defaultAccountAddress = deployerEnv.getDefaultAccountAddress(); - const viewTxReceipt = await contract!.methods + const { result } = await contract!.methods .getNumber(defaultAccountAddress) .simulate({ from: defaultAccountAddress }); - toast(`Number is: ${viewTxReceipt.value}`); + toast(`Number is: ${result}`); setWait(false); }; diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 01862c1ddfaa..e38996d04e99 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -9,6 +9,224 @@ Aztec is in active development. Each version may introduce breaking changes that ## TBD +### [Aztec.js] `simulate()`, `send()`, and deploy return types changed to always return objects + +All SDK interaction methods now return structured objects that include offchain output alongside the primary result. This affects `.simulate()`, `.send()`, deploy `.send()`, and `Wallet.sendTx()`. + +**Impact**: Every call site that uses `.simulate()`, `.send()`, or deploy must destructure the result. This is a mechanical transformation. Custom wallet implementations must update `sendTx()` to return the new object shapes, using `extractOffchainOutput` to decode offchain messages from raw effects. + +The offchain output includes two fields: + +- `offchainEffects` — raw offchain effects emitted during execution, other than `offchainMessages` +- `offchainMessages` — decoded messages intended for specific recipients + +We are making this change now so in the future we can add more fields to the responses of this APIs without breaking backwards compatibility, +so this won't ever happen again. + +**`simulate()` — always returns `{ result, offchainEffects, offchainMessages }` object:** + +```diff +- const value = await contract.methods.foo(args).simulate({ from: sender }); ++ const { result: value } = await contract.methods.foo(args).simulate({ from: sender }); +``` + +When using `includeMetadata` or `fee.estimateGas`, `stats` and `estimatedGas` are also available as optional fields on the same object: + +```diff +- const { stats, estimatedGas } = await contract.methods.foo(args).simulate({ ++ const sim = await contract.methods.foo(args).simulate({ + from: sender, + includeMetadata: true, + }); ++ const stats = sim.stats!; ++ const estimatedGas = sim.estimatedGas!; +``` + +`SimulationReturn` is no longer a generic conditional type — it's a single flat type with optional `stats` and `estimatedGas` fields. + +**`send()` — returns `{ receipt, offchainEffects, offchainMessages }` object:** + +```diff +- const receipt = await contract.methods.foo(args).send({ from: sender }); ++ const { receipt } = await contract.methods.foo(args).send({ from: sender }); +``` + +When using `NO_WAIT`, returns `{ txHash, offchainEffects, offchainMessages }` instead of a bare `TxHash`: + +```diff +- const txHash = await contract.methods.foo(args).send({ from: sender, wait: NO_WAIT }); ++ const { txHash } = await contract.methods.foo(args).send({ from: sender, wait: NO_WAIT }); +``` + +Offchain messages emitted by the transaction are available on the result: + +```typescript +const { receipt, offchainMessages } = await contract.methods.foo(args).send({ from: sender }); +for (const msg of offchainMessages) { + console.log(`Message for ${msg.recipient} from contract ${msg.contractAddress}:`, msg.payload); +} +``` + +**Deploy — returns `{ contract, receipt, offchainEffects, offchainMessages }` object:** + +```diff +- const myContract = await MyContract.deploy(wallet, ...args).send({ from: sender }); ++ const { contract: myContract } = await MyContract.deploy(wallet, ...args).send({ from: sender }); +``` + +The deploy receipt is also available via `receipt` if needed (e.g. for `receipt.txHash` or `receipt.transactionFee`). + +**Custom wallet implementations — `sendTx()` must return objects:** + +If you implement the `Wallet` interface (or extend `BaseWallet`), the `sendTx()` method must now return objects that include offchain output. Use `extractOffchainOutput` to split raw effects into decoded messages and remaining effects: + +```diff ++ import { extractOffchainOutput } from '@aztec/aztec.js/contracts'; + + async sendTx(executionPayload, opts) { + const provenTx = await this.pxe.proveTx(...); ++ const offchainOutput = extractOffchainOutput(provenTx.getOffchainEffects()); + const tx = await provenTx.toTx(); + const txHash = tx.getTxHash(); + await this.aztecNode.sendTx(tx); + + if (opts.wait === NO_WAIT) { +- return txHash; ++ return { txHash, ...offchainOutput }; + } + const receipt = await waitForTx(this.aztecNode, txHash, opts.wait); +- return receipt; ++ return { receipt, ...offchainOutput }; + } +``` + +### `aztec new` crate directories are now named after the contract + +`aztec new` and `aztec init` now name the generated crate directories after the contract instead of using generic `contract/` and `test/` names. For example, `aztec new counter` now creates: + +``` +counter/ +├── Nargo.toml # [workspace] members = ["counter_contract", "counter_test"] +├── counter_contract/ +│ ├── src/main.nr +│ └── Nargo.toml # type = "contract" +└── counter_test/ + ├── src/lib.nr + └── Nargo.toml # type = "lib" +``` + +This enables adding multiple contracts to a single workspace. Running `aztec new ` inside an existing workspace (a directory with a `Nargo.toml` containing `[workspace]`) now adds a new `_contract` and `_test` crate pair to the workspace instead of creating a new directory. + +**What changed:** +- Crate directories are now `_contract/` and `_test/` instead of `contract/` and `test/`. +- Contract code is now at `_contract/src/main.nr` instead of `contract/src/main.nr`. +- Contract dependencies go in `_contract/Nargo.toml` instead of `contract/Nargo.toml`. +- Tests import the contract by its new crate name (e.g., `use counter_contract::Main;` instead of `use counter::Main;`). + +### [CLI] `--name` flag removed from `aztec new` and `aztec init` + +The `--name` flag has been removed from both `aztec new` and `aztec init`. For `aztec new`, the positional argument now serves as both the contract name and the directory name. For `aztec init`, the directory name is always used as the contract name. + +**Migration:** + +```diff +- aztec new my_project --name counter ++ aztec new counter +``` + +```diff +- aztec init --name counter ++ aztec init +``` + +**Impact**: If you were using `--name` to set a contract name different from the directory name, rename your directory or use `aztec new` with the desired contract name directly. + +### [Aztec.js] Removed `SingleKeyAccountContract` + +The `SchnorrSingleKeyAccount` contract and its TypeScript wrapper `SingleKeyAccountContract` have been removed. This contract was insecure: it used `ivpk_m` (incoming viewing public key) as its Schnorr signing key, meaning anyone who received a user's viewing key could sign transactions on their behalf. + +**Migration:** + +```diff +- import { SingleKeyAccountContract } from '@aztec/accounts/single_key'; +- const contract = new SingleKeyAccountContract(signingKey); ++ import { SchnorrAccountContract } from '@aztec/accounts/schnorr'; ++ const contract = new SchnorrAccountContract(signingKey); +``` + +**Impact**: If you were using `@aztec/accounts/single_key`, switch to `@aztec/accounts/schnorr` which uses separate keys for encryption and authentication. + +### `aztec new` and `aztec init` now create a 2-crate workspace + +`aztec new` and `aztec init` now create a workspace with two crates instead of a single contract crate: + +- A `contract` crate (type = "contract") for your smart contract code +- A `test` crate (type = "lib") for Noir tests, which depends on the contract crate + +The new project structure looks like: + +``` +my_project/ +├── Nargo.toml # [workspace] members = ["contract", "test"] +├── contract/ +│ ├── src/main.nr +│ └── Nargo.toml # type = "contract" +└── test/ + ├── src/lib.nr + └── Nargo.toml # type = "lib" +``` + +**What changed:** +- The `--contract` and `--lib` flags have been removed from `aztec new` and `aztec init`. These commands now always create a contract workspace. +- Contract code is now at `contract/src/main.nr` instead of `src/main.nr`. +- The `Nargo.toml` in the project root is now a workspace file. Contract dependencies go in `contract/Nargo.toml`. +- Tests should be written in the separate `test` crate (`test/src/lib.nr`) and import the contract by package name (e.g., `use my_contract::MyContract;`) instead of using `crate::`. + +### Scope enforcement for private state access (TXE and PXE) + +Scope enforcement is now active across both TXE (test environment) and PXE (client). Previously, private execution could implicitly access any account's keys and notes. Now, only the caller (`from`) address is in scope by default, and accessing another address's private state requires explicitly granting scope. + +#### Noir developers (TXE) + +TXE now enforces scope isolation, matching PXE behavior. During private execution, only the caller's keys and notes are accessible. If a Noir test accesses private state of an address other than `from`, it will fail. When `from` is the zero address, scopes are empty (deny-all). + +If your TXE tests fail with key or note access errors, ensure the test is calling from the correct address, or restructure the test to match the expected access pattern. + +#### Aztec.js developers (PXE/Wallet) + +The wallet now passes scopes to PXE, and only the `from` address is in scope by default. Auto-expansion of scopes for nested calls to registered accounts has been removed. A new `additionalScopes` option is available on `send()`, `simulate()`, and `deploy()` for cases where private execution needs access to another address's keys or notes. + +**When do you need `additionalScopes`?** + +1. **Deploying contracts whose constructor initializes private storage** (e.g., account contracts, or any contract using `SinglePrivateImmutable`/`SinglePrivateMutable` in the constructor). The contract's own address must be in scope so its nullifier key is accessible during initialization. + +2. **Operations that access another contract's private state** (e.g., withdrawing from an escrow contract that nullifies the contract's own token notes). + +``` + +**Example: deploying a contract with private storage (e.g., `PrivateToken`)** + +```diff + const tokenDeployment = PrivateTokenContract.deployWithPublicKeys( + tokenPublicKeys, wallet, initialBalance, sender, + ); + const tokenInstance = await tokenDeployment.getInstance(); + await wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey); + const token = await tokenDeployment.send({ + from: sender, ++ additionalScopes: [tokenInstance.address], + }); +``` + +**Example: withdrawing from an escrow contract** + +```diff + await escrowContract.methods + .withdraw(token.address, amount, recipient) +- .send({ from: owner }); ++ .send({ from: owner, additionalScopes: [escrowContract.address] }); +``` + ### `simulateUtility` renamed to `executeUtility` The `simulateUtility` method and related types have been renamed to `executeUtility` across the entire stack to better reflect that utility functions are executed, not simulated. diff --git a/docs/examples/ts/aztecjs_advanced/index.ts b/docs/examples/ts/aztecjs_advanced/index.ts index 85f3a2aef2ca..bd138a88ff79 100644 --- a/docs/examples/ts/aztecjs_advanced/index.ts +++ b/docs/examples/ts/aztecjs_advanced/index.ts @@ -30,7 +30,7 @@ const [aliceAddress, bobAddress] = await Promise.all( // docs:start:deploy_basic_local // wallet and aliceAddress are from the connection guide // Deploy with constructor arguments -const token = await TokenContract.deploy( +const { contract: token } = await TokenContract.deploy( wallet, aliceAddress, "TestToken", @@ -49,7 +49,7 @@ await wallet.registerContract(sponsoredFPCInstance, SponsoredFPCContract.artifac const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(sponsoredFPCInstance.address); // wallet is from the connection guide; sponsoredPaymentMethod is from the fees guide -const sponsoredContract = await TokenContract.deploy( +const { contract: sponsoredContract } = await TokenContract.deploy( wallet, aliceAddress, "SponsoredToken", @@ -62,7 +62,7 @@ const sponsoredContract = await TokenContract.deploy( // wallet and aliceAddress are from the connection guide const customSalt = Fr.random(); -const saltedContract = await TokenContract.deploy( +const { contract: saltedContract } = await TokenContract.deploy( wallet, aliceAddress, "SaltedToken", @@ -95,7 +95,7 @@ console.log(`Contract will deploy at: ${predictedAddress}`); // token is from the deployment step above; aliceAddress is from the connection guide try { // Try calling a view function - const balance = await token.methods + const { result: balance } = await token.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); console.log("Contract is callable, balance:", balance); @@ -128,7 +128,7 @@ await token.methods // docs:start:no_wait_deploy // Use NO_WAIT to get the transaction hash immediately and track deployment -const txHash = await TokenContract.deploy( +const { txHash } = await TokenContract.deploy( wallet, aliceAddress, "AnotherToken", @@ -148,7 +148,7 @@ console.log(`Deployed in block ${receipt.blockNumber}`); // docs:start:no_wait_transaction // Use NO_WAIT for regular transactions too -const transferTxHash = await token.methods +const { txHash: transferTxHash } = await token.methods .transfer(bobAddress, 100n) .send({ from: aliceAddress, wait: NO_WAIT }); @@ -166,7 +166,7 @@ const batch = new BatchCall(wallet, [ token.methods.transfer(bobAddress, 200n), ]); -const batchReceipt = await batch.send({ from: aliceAddress }); +const { receipt: batchReceipt } = await batch.send({ from: aliceAddress }); console.log(`Batch executed in block ${batchReceipt.blockNumber}`); // docs:end:batch_call @@ -193,7 +193,7 @@ console.log( // docs:start:query_tx_status // Query transaction status after sending without waiting -const statusTxHash = await token.methods +const { txHash: statusTxHash } = await token.methods .transfer(bobAddress, 10n) .send({ from: aliceAddress, wait: NO_WAIT }); @@ -207,7 +207,7 @@ console.log(`Transaction fee: ${txReceipt.transactionFee}`); // docs:start:deploy_with_dependencies // Deploy contracts with dependencies - deploy sequentially and pass addresses -const baseToken = await TokenContract.deploy( +const { contract: baseToken } = await TokenContract.deploy( wallet, aliceAddress, "BaseToken", @@ -216,7 +216,7 @@ const baseToken = await TokenContract.deploy( ).send({ from: aliceAddress }); // A second contract could reference the first (example pattern) -const derivedToken = await TokenContract.deploy( +const { contract: derivedToken } = await TokenContract.deploy( wallet, baseToken.address, // Use first contract's address as admin "DerivedToken", @@ -233,13 +233,13 @@ console.log(`Derived token at: ${derivedToken.address.toString()}`); const contracts = await Promise.all([ TokenContract.deploy(wallet, aliceAddress, "Token1", "T1", 18).send({ from: aliceAddress, - }), + }).then(({ contract }) => contract), TokenContract.deploy(wallet, aliceAddress, "Token2", "T2", 18).send({ from: aliceAddress, - }), + }).then(({ contract }) => contract), TokenContract.deploy(wallet, aliceAddress, "Token3", "T3", 18).send({ from: aliceAddress, - }), + }).then(({ contract }) => contract), ]); console.log(`Contract 1 at: ${contracts[0].address}`); @@ -249,7 +249,7 @@ console.log(`Contract 3 at: ${contracts[2].address}`); // docs:start:skip_initialization // Deploy without running the constructor using skipInitialization -const delayedToken = await TokenContract.deploy( +const { contract: delayedToken } = await TokenContract.deploy( wallet, aliceAddress, "DelayedToken", diff --git a/docs/examples/ts/aztecjs_authwit/index.ts b/docs/examples/ts/aztecjs_authwit/index.ts index da0f03a80be0..04833cd90951 100644 --- a/docs/examples/ts/aztecjs_authwit/index.ts +++ b/docs/examples/ts/aztecjs_authwit/index.ts @@ -23,7 +23,7 @@ const [aliceAddress, bobAddress] = await Promise.all( }), ); -const tokenContract = await TokenContract.deploy( +const { contract: tokenContract } = await TokenContract.deploy( wallet, aliceAddress, "TestToken", diff --git a/docs/examples/ts/aztecjs_connection/index.ts b/docs/examples/ts/aztecjs_connection/index.ts index 4267a6597b9b..5b4074c9b5ec 100644 --- a/docs/examples/ts/aztecjs_connection/index.ts +++ b/docs/examples/ts/aztecjs_connection/index.ts @@ -91,7 +91,7 @@ console.log("Account deployed:", metadata.isContractInitialized); // docs:start:deploy_contract import { TokenContract } from "@aztec/noir-contracts.js/Token"; -const token = await TokenContract.deploy( +const { contract: token } = await TokenContract.deploy( wallet, aliceAddress, "TestToken", @@ -103,7 +103,7 @@ console.log(`Token deployed at: ${token.address.toString()}`); // docs:end:deploy_contract // docs:start:send_transaction -const receipt = await token.methods +const { receipt } = await token.methods .mint_to_public(aliceAddress, 1000n) .send({ from: aliceAddress }); @@ -112,7 +112,7 @@ console.log(`Transaction fee: ${receipt.transactionFee}`); // docs:end:send_transaction // docs:start:simulate_function -const balance = await token.methods +const { result: balance } = await token.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); diff --git a/docs/examples/ts/aztecjs_getting_started/index.ts b/docs/examples/ts/aztecjs_getting_started/index.ts index 9b3e7ec27ff5..de5a4ac22eae 100644 --- a/docs/examples/ts/aztecjs_getting_started/index.ts +++ b/docs/examples/ts/aztecjs_getting_started/index.ts @@ -13,7 +13,7 @@ await wallet.createSchnorrAccount(bob.secret, bob.salt); // docs:start:deploy import { TokenContract } from "@aztec/noir-contracts.js/Token"; -const token = await TokenContract.deploy( +const { contract: token } = await TokenContract.deploy( wallet, alice.address, "TokenName", @@ -29,11 +29,11 @@ await token.methods // docs:end:mint // docs:start:check_balances -let aliceBalance = await token.methods +let { result: aliceBalance } = await token.methods .balance_of_private(alice.address) .simulate({ from: alice.address }); console.log(`Alice's balance: ${aliceBalance}`); -let bobBalance = await token.methods +let { result: bobBalance } = await token.methods .balance_of_private(bob.address) .simulate({ from: bob.address }); console.log(`Bob's balance: ${bobBalance}`); @@ -41,9 +41,9 @@ console.log(`Bob's balance: ${bobBalance}`); // docs:start:transfer await token.methods.transfer(bob.address, 10).send({ from: alice.address }); -bobBalance = await token.methods +({ result: bobBalance } = await token.methods .balance_of_private(bob.address) - .simulate({ from: bob.address }); + .simulate({ from: bob.address })); console.log(`Bob's balance: ${bobBalance}`); // docs:end:transfer @@ -55,8 +55,8 @@ await token.methods.set_minter(bob.address, true).send({ from: alice.address }); await token.methods .mint_to_private(bob.address, 100) .send({ from: bob.address }); -bobBalance = await token.methods +({ result: bobBalance } = await token.methods .balance_of_private(bob.address) - .simulate({ from: bob.address }); + .simulate({ from: bob.address })); console.log(`Bob's balance: ${bobBalance}`); // docs:end:bob_mints diff --git a/docs/examples/ts/aztecjs_testing/index.ts b/docs/examples/ts/aztecjs_testing/index.ts index 68af11270b77..0c50ac8e5a33 100644 --- a/docs/examples/ts/aztecjs_testing/index.ts +++ b/docs/examples/ts/aztecjs_testing/index.ts @@ -26,7 +26,7 @@ async function setup() { }), ); - token = await TokenContract.deploy( + ({ contract: token } = await TokenContract.deploy( wallet, aliceAddress, "Test", @@ -34,7 +34,7 @@ async function setup() { 18, ).send({ from: aliceAddress, - }); + })); } // Test: mints tokens to an account @@ -43,7 +43,7 @@ async function testMintTokens() { .mint_to_public(aliceAddress, 1000n) .send({ from: aliceAddress }); - const balance = await token.methods + const { result: balance } = await token.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); @@ -63,10 +63,10 @@ async function testTransferTokens() { // Transfer to bob using the simple transfer method await token.methods.transfer(bobAddress, 100n).send({ from: aliceAddress }); - const aliceBalance = await token.methods + const { result: aliceBalance } = await token.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); - const bobBalance = await token.methods + const { result: bobBalance } = await token.methods .balance_of_public(bobAddress) .simulate({ from: bobAddress }); @@ -77,7 +77,7 @@ async function testTransferTokens() { // Test: reverts when transferring more than balance async function testRevertOnOverTransfer() { - const balance = await token.methods + const { result: balance } = await token.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); diff --git a/docs/examples/ts/bob_token_contract/index.ts b/docs/examples/ts/bob_token_contract/index.ts index ec71b47da703..9b154e1279a3 100644 --- a/docs/examples/ts/bob_token_contract/index.ts +++ b/docs/examples/ts/bob_token_contract/index.ts @@ -15,16 +15,20 @@ async function getBalances( await Promise.all([ contract.methods .public_balance_of(aliceAddress) - .simulate({ from: aliceAddress }), + .simulate({ from: aliceAddress }) + .then(({ result }) => result), contract.methods .private_balance_of(aliceAddress) - .simulate({ from: aliceAddress }), + .simulate({ from: aliceAddress }) + .then(({ result }) => result), contract.methods .public_balance_of(bobAddress) - .simulate({ from: bobAddress }), + .simulate({ from: bobAddress }) + .then(({ result }) => result), contract.methods .private_balance_of(bobAddress) - .simulate({ from: bobAddress }), + .simulate({ from: bobAddress }) + .then(({ result }) => result), ]).then( ([ alicePublicBalance, @@ -69,7 +73,7 @@ async function main() { const aliceAddress = aliceAccountManager.address; const bobClinicAddress = bobClinicAccountManager.address; - const bobToken = await BobTokenContract.deploy(wallet).send({ + const { contract: bobToken } = await BobTokenContract.deploy(wallet).send({ from: giggleAddress, }); diff --git a/docs/examples/ts/recursive_verification/index.ts b/docs/examples/ts/recursive_verification/index.ts index 43712fcd38eb..423d1c0d287d 100644 --- a/docs/examples/ts/recursive_verification/index.ts +++ b/docs/examples/ts/recursive_verification/index.ts @@ -65,7 +65,7 @@ async function main() { // Step 2: Deploy ValueNotEqual contract // Constructor args: initial counter (10), owner, VK hash - const valueNotEqual = await ValueNotEqualContract.deploy( + const { contract: valueNotEqual } = await ValueNotEqualContract.deploy( wallet, 10, // Initial counter value accounts[0].item, // Owner address @@ -84,9 +84,9 @@ async function main() { // Step 3: Read initial counter value // simulate() executes without submitting a transaction - let counterValue = await valueNotEqual.methods + let counterValue = (await valueNotEqual.methods .get_counter(accounts[0].item) - .simulate({ from: accounts[0].item }); + .simulate({ from: accounts[0].item })).result; console.log(`Counter value: ${counterValue}`); // Should be 10 // Step 4: Call increment() with proof data @@ -107,9 +107,9 @@ async function main() { await interaction.send(opts); // Step 6: Read updated counter - counterValue = await valueNotEqual.methods + counterValue = (await valueNotEqual.methods .get_counter(accounts[0].item) - .simulate({ from: accounts[0].item }); + .simulate({ from: accounts[0].item })).result; console.log(`Counter value: ${counterValue}`); // Should be 11 assert(counterValue === 11n, "Counter should be 11 after verification"); diff --git a/docs/examples/ts/token_bridge/index.ts b/docs/examples/ts/token_bridge/index.ts index 74ad78653034..81c410bae820 100644 --- a/docs/examples/ts/token_bridge/index.ts +++ b/docs/examples/ts/token_bridge/index.ts @@ -69,11 +69,11 @@ console.log(`NFTPortal: ${portalAddress}\n`); // docs:start:deploy_l2_contracts console.log("Deploying L2 contracts...\n"); -const l2Nft = await NFTPunkContract.deploy(aztecWallet, account.address).send({ +const { contract: l2Nft } = await NFTPunkContract.deploy(aztecWallet, account.address).send({ from: account.address, }); -const l2Bridge = await NFTBridgeContract.deploy( +const { contract: l2Bridge } = await NFTBridgeContract.deploy( aztecWallet, l2Nft.address, ).send({ from: account.address }); @@ -222,7 +222,7 @@ await mine2Blocks(aztecWallet, account.address); // Check notes before claiming (should be 0) console.log("Checking notes before claim..."); -const notesBefore = await l2Nft.methods +const { result: notesBefore } = await l2Nft.methods .notes_of(account.address) .simulate({ from: account.address }); console.log(` Notes count: ${notesBefore}`); @@ -235,7 +235,7 @@ console.log("NFT claimed on L2\n"); // Check notes after claiming (should be 1) console.log("Checking notes after claim..."); -const notesAfterClaim = await l2Nft.methods +const { result: notesAfterClaim } = await l2Nft.methods .notes_of(account.address) .simulate({ from: account.address }); console.log(` Notes count: ${notesAfterClaim}\n`); @@ -249,7 +249,7 @@ await mine2Blocks(aztecWallet, account.address); const recipientEthAddress = EthAddress.fromString(ownerEthAddress); -const exitReceipt = await l2Bridge.methods +const { receipt: exitReceipt } = await l2Bridge.methods .exit(new Fr(Number(tokenId)), recipientEthAddress) .send({ from: account.address }); @@ -257,7 +257,7 @@ console.log(`Exit message sent (block: ${exitReceipt.blockNumber})\n`); // Check notes after burning (should be 0 again) console.log("Checking notes after burn..."); -const notesAfterBurn = await l2Nft.methods +const { result: notesAfterBurn } = await l2Nft.methods .notes_of(account.address) .simulate({ from: account.address }); console.log(` Notes count: ${notesAfterBurn}\n`); diff --git a/playground/src/components/contract/components/FunctionCard.tsx b/playground/src/components/contract/components/FunctionCard.tsx index 6f4c9e5415a2..21f3b2696b2e 100644 --- a/playground/src/components/contract/components/FunctionCard.tsx +++ b/playground/src/components/contract/components/FunctionCard.tsx @@ -90,7 +90,7 @@ export function FunctionCard({ fn, contract, contractArtifact, onSendTxRequested let result; try { const call = contract.methods[fnName](...parameters); - result = await call.simulate({ from, skipFeeEnforcement: true }); + ({ result } = await call.simulate({ from, skipFeeEnforcement: true })); const stringResult = JSON.stringify(result, (key, value) => { if (typeof value === 'bigint') { return value.toString(); diff --git a/playground/src/hooks/useTransaction.tsx b/playground/src/hooks/useTransaction.tsx index 202c6017481f..9f1e6832e6c2 100644 --- a/playground/src/hooks/useTransaction.tsx +++ b/playground/src/hooks/useTransaction.tsx @@ -47,10 +47,10 @@ export function useTransaction() { if (interaction instanceof DeployMethod) { const { from, fee, ...deployOpts } = opts as DeployOptions; - txHash = await interaction.send({ from, fee, ...deployOpts, wait: NO_WAIT }); + ({ txHash } = await interaction.send({ from, fee, ...deployOpts, wait: NO_WAIT })); } else { const { from, fee, authWitnesses, capsules } = opts as SendInteractionOptions; - txHash = await interaction.send({ from, fee, authWitnesses, capsules, wait: NO_WAIT }); + ({ txHash } = await interaction.send({ from, fee, authWitnesses, capsules, wait: NO_WAIT })); } setCurrentTx({ diff --git a/yarn-project/aztec.js/src/api/contract.ts b/yarn-project/aztec.js/src/api/contract.ts index d3e9a692c67f..37481a99f94f 100644 --- a/yarn-project/aztec.js/src/api/contract.ts +++ b/yarn-project/aztec.js/src/api/contract.ts @@ -48,6 +48,8 @@ export { ContractFunctionInteraction } from '../contract/contract_function_inter export { NO_WAIT, type NoWait, + type OffchainMessage, + type OffchainOutput, type RequestInteractionOptions, type SendInteractionOptions, type ProfileInteractionOptions, @@ -56,7 +58,11 @@ export { type InteractionWaitOptions, type GasSettingsOption, type SendReturn, - type SimulationReturn, + type SimulationResult, + type TxSendResultImmediate, + type TxSendResultMined, + emptyOffchainOutput, + extractOffchainOutput, toProfileOptions, toSendOptions, toSimulateOptions, @@ -67,6 +73,7 @@ export { ContractBase, type ContractMethod, type ContractStorageLayout } from '. export { BatchCall } from '../contract/batch_call.js'; export { type DeployOptions, + type DeployResultMined, type DeployReturn, type DeployTxReceipt, type DeployWaitOptions, diff --git a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts index 8e47f1eb7cfe..12983df3a0ea 100644 --- a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts +++ b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts @@ -9,6 +9,7 @@ import { type SendInteractionOptions, type SendInteractionOptionsWithoutWait, type SendReturn, + type TxSendResultMined, toSendOptions, } from './interaction_options.js'; @@ -41,8 +42,8 @@ export abstract class BaseContractInteraction { * the AztecAddress of the sender, optional fee configuration, and optional wait settings * @returns TReturn (if wait is undefined/WaitOpts) or TxHash (if wait is NO_WAIT) */ - // Overload for when wait is not specified at all - returns TReturn - public send(options: SendInteractionOptionsWithoutWait): Promise; + // Overload for when wait is not specified at all - returns { receipt: TReturn, offchainEffects } + public send(options: SendInteractionOptionsWithoutWait): Promise>; // Generic overload for explicit wait values // eslint-disable-next-line jsdoc/require-jsdoc public send( diff --git a/yarn-project/aztec.js/src/contract/batch_call.test.ts b/yarn-project/aztec.js/src/contract/batch_call.test.ts index 976884e68745..bcb976b1729c 100644 --- a/yarn-project/aztec.js/src/contract/batch_call.test.ts +++ b/yarn-project/aztec.js/src/contract/batch_call.test.ts @@ -119,6 +119,7 @@ describe('BatchCall', () => { nested: [{ values: privateReturnValues }], } as any); txSimResult.getPublicReturnValues.mockReturnValue([{ values: publicReturnValues }] as any); + Object.defineProperty(txSimResult, 'offchainEffects', { value: [] }); // Mock wallet.batch to return both utility results and simulateTx result wallet.batch.mockResolvedValue([ @@ -166,13 +167,13 @@ describe('BatchCall', () => { expect(results).toHaveLength(4); // First utility - decoded from Fr[] to bigint (single field returns the value directly, not as array) - expect(results[0]).toEqual(utilityResult1.result[0].toBigInt()); + expect(results[0].result).toEqual(utilityResult1.result[0].toBigInt()); // Results[1] will be the decoded private values (decoded from privateReturnValues) - expect(results[1]).toEqual(privateReturnValues.map(v => v.toBigInt())); // Private call (decoded) + expect(results[1].result).toEqual(privateReturnValues.map(v => v.toBigInt())); // Private call (decoded) // Second utility - decoded from Fr[] to bigint - expect(results[2]).toEqual(utilityResult2.result[0].toBigInt()); + expect(results[2].result).toEqual(utilityResult2.result[0].toBigInt()); // Results[3] will be the decoded public value (single value is returned directly, not as array) - expect(results[3]).toEqual(publicReturnValues[0].toBigInt()); // Public call (decoded) + expect(results[3].result).toEqual(publicReturnValues[0].toBigInt()); // Public call (decoded) }); it('should handle only utility calls without calling simulateTx', async () => { @@ -215,8 +216,8 @@ describe('BatchCall', () => { // Verify results - decoded from Fr[] to bigint expect(results).toHaveLength(2); - expect(results[0]).toEqual(utilityResult1.result[0].toBigInt()); - expect(results[1]).toEqual(utilityResult2.result[0].toBigInt()); + expect(results[0].result).toEqual(utilityResult1.result[0].toBigInt()); + expect(results[1].result).toEqual(utilityResult2.result[0].toBigInt()); }); it('should handle only private/public calls using wallet.batch with simulateTx', async () => { @@ -236,6 +237,7 @@ describe('BatchCall', () => { nested: [{ values: privateReturnValues }], } as any); txSimResult.getPublicReturnValues.mockReturnValue([{ values: publicReturnValues }] as any); + Object.defineProperty(txSimResult, 'offchainEffects', { value: [] }); wallet.batch.mockResolvedValue([{ name: 'simulateTx', result: txSimResult }] as any); @@ -259,8 +261,8 @@ describe('BatchCall', () => { // Verify results (decoded) expect(results).toHaveLength(2); - expect(results[0]).toEqual(privateReturnValues[0].toBigInt()); // Single value returned directly - expect(results[1]).toEqual(publicReturnValues[0].toBigInt()); // Single value returned directly + expect(results[0].result).toEqual(privateReturnValues[0].toBigInt()); // Single value returned directly + expect(results[1].result).toEqual(publicReturnValues[0].toBigInt()); // Single value returned directly }); it('should handle empty batch', async () => { diff --git a/yarn-project/aztec.js/src/contract/batch_call.ts b/yarn-project/aztec.js/src/contract/batch_call.ts index cd112be6f59b..66c668340687 100644 --- a/yarn-project/aztec.js/src/contract/batch_call.ts +++ b/yarn-project/aztec.js/src/contract/batch_call.ts @@ -6,6 +6,8 @@ import { BaseContractInteraction } from './base_contract_interaction.js'; import { type RequestInteractionOptions, type SimulateInteractionOptions, + emptyOffchainOutput, + extractOffchainOutput, toSimulateOptions, } from './interaction_options.js'; @@ -108,7 +110,10 @@ export class BatchCall extends BaseContractInteraction { const wrappedResult = batchResults[i]; if (wrappedResult.name === 'executeUtility') { const rawReturnValues = (wrappedResult.result as UtilityExecutionResult).result; - results[resultIndex] = rawReturnValues ? decodeFromAbi(call.returnTypes, rawReturnValues) : []; + results[resultIndex] = { + result: rawReturnValues ? decodeFromAbi(call.returnTypes, rawReturnValues) : [], + ...emptyOffchainOutput(), + }; } } @@ -127,7 +132,10 @@ export class BatchCall extends BaseContractInteraction { ? simulatedTx.getPrivateReturnValues()?.nested?.[resultIndex].values : simulatedTx.getPublicReturnValues()?.[resultIndex].values; - results[callIndex] = rawReturnValues ? decodeFromAbi(call.returnTypes, rawReturnValues) : []; + results[callIndex] = { + result: rawReturnValues ? decodeFromAbi(call.returnTypes, rawReturnValues) : [], + ...extractOffchainOutput(simulatedTx.offchainEffects), + }; }); } } diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index 28005f6ecbfc..36519b918f7c 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -136,7 +136,7 @@ describe('Contract Class', () => { wallet.simulateTx.mockResolvedValue(mockTxSimulationResult); account.createTxExecutionRequest.mockResolvedValue(mockTxRequest); wallet.registerContract.mockResolvedValue(contractInstance); - wallet.sendTx.mockResolvedValue(mockTxReceipt); + wallet.sendTx.mockResolvedValue({ receipt: mockTxReceipt, offchainEffects: [], offchainMessages: [] }); wallet.executeUtility.mockResolvedValue(mockUtilityResultValue); }); @@ -144,7 +144,7 @@ describe('Contract Class', () => { const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); const param0 = 12; const param1 = 345n; - const receipt = await fooContract.methods.bar(param0, param1).send({ from: account.getAddress() }); + const { receipt } = await fooContract.methods.bar(param0, param1).send({ from: account.getAddress() }); expect(receipt).toBe(mockTxReceipt); expect(wallet.sendTx).toHaveBeenCalledTimes(1); @@ -152,7 +152,7 @@ describe('Contract Class', () => { it('should call view on a utility function', async () => { const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); - const result = await fooContract.methods.qux(123n).simulate({ from: account.getAddress() }); + const { result } = await fooContract.methods.qux(123n).simulate({ from: account.getAddress() }); expect(wallet.executeUtility).toHaveBeenCalledTimes(1); expect(wallet.executeUtility).toHaveBeenCalledWith( expect.objectContaining({ name: 'qux', to: contractAddress }), diff --git a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts index a087d85f0525..30d553d55151 100644 --- a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts +++ b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts @@ -8,7 +8,7 @@ import { } from '@aztec/stdlib/abi'; import type { AuthWitness } from '@aztec/stdlib/auth-witness'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; -import { type Capsule, type HashedValues, type TxProfileResult, collectOffchainEffects } from '@aztec/stdlib/tx'; +import type { Capsule, HashedValues, TxProfileResult } from '@aztec/stdlib/tx'; import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx'; import type { Wallet } from '../wallet/wallet.js'; @@ -18,7 +18,9 @@ import { type ProfileInteractionOptions, type RequestInteractionOptions, type SimulateInteractionOptions, - type SimulationReturn, + type SimulationResult, + emptyOffchainOutput, + extractOffchainOutput, toProfileOptions, toSimulateOptions, } from './interaction_options.js'; @@ -97,17 +99,9 @@ export class ContractFunctionInteraction extends BaseContractInteraction { * function or a rich object containing extra metadata, such as estimated gas costs (if requested via options), * execution statistics and emitted offchain effects */ - public async simulate( - options: T, - ): Promise['estimateGas']>>; - // eslint-disable-next-line jsdoc/require-jsdoc - public async simulate( - options: T, - ): Promise>; - // eslint-disable-next-line jsdoc/require-jsdoc public async simulate( - options: SimulateInteractionOptions, - ): Promise> { + options: SimulateInteractionOptions = {} as SimulateInteractionOptions, + ): Promise { // docs:end:simulate if (this.functionDao.functionType == FunctionType.UTILITY) { const call = await this.getFunctionCall(); @@ -122,11 +116,11 @@ export class ContractFunctionInteraction extends BaseContractInteraction { if (options.includeMetadata) { return { stats: utilityResult.stats, + ...emptyOffchainOutput(), result: returnValue, }; - } else { - return returnValue; } + return { result: returnValue, ...emptyOffchainOutput() }; } const executionPayload = await this.request(options); @@ -148,6 +142,7 @@ export class ContractFunctionInteraction extends BaseContractInteraction { } const returnValue = rawReturnValues ? decodeFromAbi(this.functionDao.returnTypes, rawReturnValues) : []; + const offchainOutput = extractOffchainOutput(simulatedTx.offchainEffects); if (options.includeMetadata || options.fee?.estimateGas) { const { gasLimits, teardownGasLimits } = getGasLimits(simulatedTx, options.fee?.estimatedGasPadding); @@ -156,13 +151,12 @@ export class ContractFunctionInteraction extends BaseContractInteraction { ); return { stats: simulatedTx.stats, - offchainEffects: collectOffchainEffects(simulatedTx.privateExecutionResult), + ...offchainOutput, result: returnValue, estimatedGas: { gasLimits, teardownGasLimits }, }; - } else { - return returnValue; } + return { result: returnValue, ...offchainOutput }; } /** diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 4fc50d66265a..f91881a5245a 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -9,14 +9,7 @@ import { getContractInstanceFromInstantiationParams, } from '@aztec/stdlib/contract'; import type { PublicKeys } from '@aztec/stdlib/keys'; -import { - type Capsule, - HashedValues, - TxHash, - type TxProfileResult, - type TxReceipt, - collectOffchainEffects, -} from '@aztec/stdlib/tx'; +import { type Capsule, HashedValues, type TxProfileResult, type TxReceipt } from '@aztec/stdlib/tx'; import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx'; import { publishContractClass } from '../deployment/publish_class.js'; @@ -29,11 +22,15 @@ import { getGasLimits } from './get_gas_limits.js'; import { NO_WAIT, type NoWait, + type OffchainOutput, type ProfileInteractionOptions, type RequestInteractionOptions, type SendInteractionOptionsWithoutWait, type SimulationInteractionFeeOptions, - type SimulationReturn, + type SimulationResult, + type TxSendResultImmediate, + type TxSendResultMined, + extractOffchainOutput, toProfileOptions, toSendOptions, toSimulateOptions, @@ -89,7 +86,7 @@ export type DeployOptionsWithoutWait = Omit & * is mutually exclusive with "deployer" */ universalDeploy?: boolean; -} & Pick; +} & Pick; /** * Extends the deployment options with the required parameters to send the transaction. @@ -130,20 +127,32 @@ export type DeployTxReceipt = TxR instance: ContractInstanceWithAddress; }; +/** Wait options that request a full receipt instead of just the contract instance. */ +type WaitWithReturnReceipt = { + /** Request the full receipt instead of just the contract instance. */ + returnReceipt: true; +}; + /** * Represents the result type of deploying a contract. * - If wait is NO_WAIT, returns TxHash immediately. * - If wait has returnReceipt: true, returns DeployTxReceipt after waiting. * - Otherwise (undefined or DeployWaitOptions without returnReceipt), returns TContract after waiting. */ +/** Result of deploying a contract when waiting for mining (default case). */ +export type DeployResultMined = { + /** The deployed contract instance. */ + contract: TContract; + /** The deploy transaction receipt. */ + receipt: DeployTxReceipt; +} & OffchainOutput; + +/** Conditional return type for deploy based on wait options. */ export type DeployReturn = W extends NoWait - ? TxHash - : W extends { - // eslint-disable-next-line jsdoc/require-jsdoc - returnReceipt: true; - } - ? DeployTxReceipt - : TContract; + ? TxSendResultImmediate + : W extends WaitWithReturnReceipt + ? TxSendResultMined> + : DeployResultMined; /** * Contract interaction for deployment. @@ -325,8 +334,7 @@ export class DeployMethod extends * @returns TxHash (if wait is NO_WAIT), TContract (if wait is undefined or doesn't have returnReceipt), or DeployTxReceipt (if wait.returnReceipt is true) */ // Overload for when wait is not specified at all - returns the contract - public override send(options: DeployOptionsWithoutWait): Promise; - // Generic overload for explicit wait values + public override send(options: DeployOptionsWithoutWait): Promise>; // eslint-disable-next-line jsdoc/require-jsdoc public override send( options: DeployOptions, @@ -337,12 +345,15 @@ export class DeployMethod extends const sendOptions = this.convertDeployOptionsToSendOptions(options); if (options.wait === NO_WAIT) { - const txHash = await this.wallet.sendTx(executionPayload, sendOptions as SendOptions); - this.log.debug(`Sent deployment tx ${txHash.hash} of ${this.artifact.name} contract`); - return txHash; + const result = await this.wallet.sendTx(executionPayload, sendOptions as SendOptions); + this.log.debug(`Sent deployment tx ${result.txHash.hash} of ${this.artifact.name} contract`); + return result; } - const receipt = await this.wallet.sendTx(executionPayload, sendOptions as SendOptions); + const { receipt, ...offchainOutput } = await this.wallet.sendTx( + executionPayload, + sendOptions as SendOptions, + ); this.log.debug(`Deployed ${this.artifact.name} contract in tx ${receipt.txHash}`); // Attach contract instance @@ -351,10 +362,10 @@ export class DeployMethod extends // Return full receipt if requested, otherwise just the contract if (options.wait && typeof options.wait === 'object' && options.wait.returnReceipt) { - return { ...receipt, contract, instance }; + return { receipt: { ...receipt, contract, instance }, ...offchainOutput }; } - return contract; + return { contract, receipt, ...offchainOutput }; } /** @@ -383,7 +394,7 @@ export class DeployMethod extends * @returns A simulation result object containing metadata of the execution, including gas * estimations (if requested via options), execution statistics and emitted offchain effects */ - public async simulate(options: SimulateDeployOptions): Promise> { + public async simulate(options: SimulateDeployOptions): Promise { const executionPayload = await this.request(this.convertDeployOptionsToRequestOptions(options)); const simulatedTx = await this.wallet.simulateTx(executionPayload, toSimulateOptions(options)); @@ -393,7 +404,7 @@ export class DeployMethod extends ); return { stats: simulatedTx.stats!, - offchainEffects: collectOffchainEffects(simulatedTx.privateExecutionResult), + ...extractOffchainOutput(simulatedTx.offchainEffects), result: undefined, estimatedGas: { gasLimits, teardownGasLimits }, }; diff --git a/yarn-project/aztec.js/src/contract/interaction_options.test.ts b/yarn-project/aztec.js/src/contract/interaction_options.test.ts new file mode 100644 index 000000000000..7818299a3854 --- /dev/null +++ b/yarn-project/aztec.js/src/contract/interaction_options.test.ts @@ -0,0 +1,81 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; +import { AztecAddress } from '@aztec/stdlib/aztec-address'; +import { OFFCHAIN_MESSAGE_IDENTIFIER, type OffchainEffect } from '@aztec/stdlib/tx'; + +import { extractOffchainOutput } from './interaction_options.js'; + +describe('extractOffchainOutput', () => { + const makeEffect = (data: Fr[], contractAddress?: AztecAddress): OffchainEffect => ({ + data, + contractAddress: contractAddress ?? AztecAddress.fromField(Fr.random()), + }); + + const makeMessageEffect = async (recipient?: AztecAddress, payload?: Fr[], contractAddress?: AztecAddress) => + makeEffect( + [ + OFFCHAIN_MESSAGE_IDENTIFIER, + (recipient ?? (await AztecAddress.random())).toField(), + ...(payload ?? [Fr.random()]), + ], + contractAddress, + ); + + it('returns empty output for empty input', () => { + const result = extractOffchainOutput([]); + expect(result.offchainEffects).toEqual([]); + expect(result.offchainMessages).toEqual([]); + }); + + it('keeps non-message effects as-is', () => { + const effects = [makeEffect([Fr.random(), Fr.random()]), makeEffect([Fr.random()])]; + const result = extractOffchainOutput(effects); + expect(result.offchainEffects).toEqual(effects); + expect(result.offchainMessages).toEqual([]); + }); + + it('extracts a message effect into offchainMessages', async () => { + const recipient = await AztecAddress.random(); + const payload = [Fr.random(), Fr.random(), Fr.random()]; + const contractAddress = await AztecAddress.random(); + const effect = await makeMessageEffect(recipient, payload, contractAddress); + + const result = extractOffchainOutput([effect]); + + expect(result.offchainEffects).toEqual([]); + expect(result.offchainMessages).toHaveLength(1); + expect(result.offchainMessages[0]).toEqual({ + recipient, + payload, + contractAddress, + }); + }); + + it('splits a mixed array of effects and messages', async () => { + const plainEffect1 = makeEffect([Fr.random()]); + const plainEffect2 = makeEffect([Fr.random(), Fr.random()]); + const messageEffect = await makeMessageEffect(); + + const result = extractOffchainOutput([plainEffect1, messageEffect, plainEffect2]); + + expect(result.offchainEffects).toEqual([plainEffect1, plainEffect2]); + expect(result.offchainMessages).toHaveLength(1); + }); + + it('handles multiple message effects', async () => { + const msg1 = await makeMessageEffect(); + const msg2 = await makeMessageEffect(); + + const result = extractOffchainOutput([msg1, msg2]); + + expect(result.offchainEffects).toEqual([]); + expect(result.offchainMessages).toHaveLength(2); + }); + + it('does not treat an effect as a message if data has only the identifier (no recipient)', () => { + const effect = makeEffect([OFFCHAIN_MESSAGE_IDENTIFIER]); + const result = extractOffchainOutput([effect]); + + expect(result.offchainEffects).toEqual([effect]); + expect(result.offchainMessages).toEqual([]); + }); +}); diff --git a/yarn-project/aztec.js/src/contract/interaction_options.ts b/yarn-project/aztec.js/src/contract/interaction_options.ts index 2651c9f5f49d..005908dd35b8 100644 --- a/yarn-project/aztec.js/src/contract/interaction_options.ts +++ b/yarn-project/aztec.js/src/contract/interaction_options.ts @@ -1,8 +1,16 @@ +import type { Fr } from '@aztec/foundation/curves/bn254'; import type { FieldsOf } from '@aztec/foundation/types'; import type { AuthWitness } from '@aztec/stdlib/auth-witness'; -import type { AztecAddress } from '@aztec/stdlib/aztec-address'; +import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { GasSettings } from '@aztec/stdlib/gas'; -import type { Capsule, OffchainEffect, SimulationStats, TxHash, TxReceipt } from '@aztec/stdlib/tx'; +import { + type Capsule, + OFFCHAIN_MESSAGE_IDENTIFIER, + type OffchainEffect, + type SimulationStats, + type TxHash, + type TxReceipt, +} from '@aztec/stdlib/tx'; import type { FeePaymentMethod } from '../fee/fee_payment_method.js'; import type { ProfileOptions, SendOptions, SimulateOptions } from '../wallet/index.js'; @@ -82,6 +90,13 @@ export type SendInteractionOptionsWithoutWait = RequestInteractionOptions & { from: AztecAddress; /** The fee options for the transaction. */ fee?: InteractionFeeOptions; + /** + * Extra addresses whose private state (keys, notes) should be accessible during execution. + * Use when a transaction reads or nullifies private state that is owned by a different address, + * e.g. deploying contracts with private storage or withdrawing from an escrow that holds + * its own private notes. + */ + additionalScopes?: AztecAddress[]; }; /** @@ -109,8 +124,8 @@ export type SimulateInteractionOptions = Omit & { skipTxValidation?: boolean; /** Whether to ensure the fee payer is not empty and has enough balance to pay for the fee. */ skipFeeEnforcement?: boolean; - /** Whether to include metadata such as offchain effects and performance statistics (e.g. timing information of the different circuits and oracles) in - * the simulation result, instead of just the return value of the function */ + /** Whether to include metadata such as performance statistics (e.g. timing information of the different circuits and oracles) and gas estimation + * in the simulation result, in addition to the return value and offchain effects */ includeMetadata?: boolean; }; @@ -124,31 +139,89 @@ export type ProfileInteractionOptions = SimulateInteractionOptions & { skipProofGeneration?: boolean; }; +/** A message emitted during execution or proving, to be delivered offchain. */ +export type OffchainMessage = { + /** The intended recipient of the message. */ + recipient: AztecAddress; + /** The message payload (typically encrypted). */ + payload: Fr[]; + /** The contract that emitted the message. */ + contractAddress: AztecAddress; +}; + +/** Groups all unproven outputs from private execution that are returned to the client. */ +export type OffchainOutput = { + /** Raw offchain effects emitted during execution. */ + offchainEffects: OffchainEffect[]; + /** Messages emitted during execution, to be delivered offchain. */ + offchainMessages: OffchainMessage[]; +}; + /** - * Represents the result type of a simulation. - * By default, it will just be the return value of the simulated function - * If `includeMetadata` is set to true in `SimulateInteractionOptions` on the input of `simulate(...)`, - * it will provide extra information. - */ -export type SimulationReturn = T extends true - ? { - /** Additional stats about the simulation */ - stats: SimulationStats; - /** Offchain effects generated during the simulation */ - offchainEffects: OffchainEffect[]; - /** Return value of the function */ - result: any; - /** Gas estimation results */ - estimatedGas: Pick; + * Splits an array of offchain effects into decoded offchain messages and remaining effects. + * Effects whose data starts with `OFFCHAIN_MESSAGE_IDENTIFIER` are parsed as messages and removed + * from the effects array. + */ +export function extractOffchainOutput(effects: OffchainEffect[]): OffchainOutput { + const offchainEffects: OffchainEffect[] = []; + const offchainMessages: OffchainMessage[] = []; + + for (const effect of effects) { + if (effect.data.length >= 2 && effect.data[0].equals(OFFCHAIN_MESSAGE_IDENTIFIER)) { + offchainMessages.push({ + recipient: AztecAddress.fromField(effect.data[1]), + payload: effect.data.slice(2), + contractAddress: effect.contractAddress, + }); + } else { + offchainEffects.push(effect); } - : any; + } + + return { offchainEffects, offchainMessages }; +} + +/** + * Returns an empty `OffchainOutput` (no effects, no messages). + */ +export function emptyOffchainOutput(): OffchainOutput { + return { offchainEffects: [], offchainMessages: [] }; +} + +/** + * Represents the result of a simulation. + * Always includes the return value and offchain output. + * When `includeMetadata` or `fee.estimateGas` is set, also includes stats and gas estimation. + */ +export type SimulationResult = { + /** Return value of the function */ + result: any; + /** Additional stats about the simulation. Present when `includeMetadata` is set. */ + stats?: SimulationStats; + /** Gas estimation results. Present when `includeMetadata` or `fee.estimateGas` is set. */ + estimatedGas?: Pick; +} & OffchainOutput; + +/** Result of sendTx when not waiting for mining. */ +export type TxSendResultImmediate = { + /** The hash of the sent transaction. */ + txHash: TxHash; +} & OffchainOutput; + +/** Result of sendTx when waiting for mining. */ +export type TxSendResultMined = { + /** The transaction receipt. */ + receipt: TReturn; +} & OffchainOutput; /** * Represents the result type of sending a transaction. - * If `wait` is NO_WAIT, returns TxHash immediately without waiting. - * If `wait` is undefined or WaitOpts, returns TReturn (defaults to TxReceipt) after waiting. + * If `wait` is NO_WAIT, returns TxSendResultImmediate. + * Otherwise returns TxSendResultMined. */ -export type SendReturn = T extends NoWait ? TxHash : TReturn; +export type SendReturn = T extends NoWait + ? TxSendResultImmediate + : TxSendResultMined; /** * Transforms and cleans up the higher level SendInteractionOptions defined by the interaction into diff --git a/yarn-project/aztec.js/src/utils/authwit.ts b/yarn-project/aztec.js/src/utils/authwit.ts index d0d8b9f1c088..67ac5edf627c 100644 --- a/yarn-project/aztec.js/src/utils/authwit.ts +++ b/yarn-project/aztec.js/src/utils/authwit.ts @@ -5,7 +5,7 @@ import { type ABIParameterVisibility, type FunctionAbi, type FunctionCall, Funct import { AuthWitness, computeInnerAuthWitHash, computeOuterAuthWitHash } from '@aztec/stdlib/auth-witness'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { computeVarArgsHash } from '@aztec/stdlib/hash'; -import type { TxHash, TxProfileResult, TxReceipt } from '@aztec/stdlib/tx'; +import type { TxProfileResult } from '@aztec/stdlib/tx'; import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js'; import type { @@ -15,7 +15,8 @@ import type { SendInteractionOptionsWithoutWait, SendReturn, SimulateInteractionOptions, - SimulationReturn, + SimulationResult, + TxSendResultMined, } from '../contract/interaction_options.js'; import type { Wallet } from '../wallet/index.js'; @@ -189,10 +190,12 @@ export async function lookupValidity( errorTypes: {}, } as FunctionAbi; try { - results.isValidInPrivate = (await new ContractFunctionInteraction(wallet, onBehalfOf, lookupValidityAbi, [ - consumer, - innerHash, - ]).simulate({ from: onBehalfOf, authWitnesses: [witness] })) as boolean; + results.isValidInPrivate = ( + await new ContractFunctionInteraction(wallet, onBehalfOf, lookupValidityAbi, [consumer, innerHash]).simulate({ + from: onBehalfOf, + authWitnesses: [witness], + }) + ).result as boolean; // TODO: Narrow down the error to make sure simulation failed due to an invalid authwit // eslint-disable-next-line no-empty } catch {} @@ -219,12 +222,12 @@ export async function lookupValidity( returnTypes: [{ kind: 'boolean' }], errorTypes: {}, } as FunctionAbi; - results.isValidInPublic = (await new ContractFunctionInteraction( - wallet, - ProtocolContractAddress.AuthRegistry, - isConsumableAbi, - [onBehalfOf, messageHash], - ).simulate({ from: onBehalfOf })) as boolean; + results.isValidInPublic = ( + await new ContractFunctionInteraction(wallet, ProtocolContractAddress.AuthRegistry, isConsumableAbi, [ + onBehalfOf, + messageHash, + ]).simulate({ from: onBehalfOf }) + ).result as boolean; return results; } @@ -262,14 +265,10 @@ export class SetPublicAuthwitContractInteraction extends ContractFunctionInterac * @param options - An optional object containing additional configuration for the transaction. * @returns The result of the transaction as returned by the contract function. */ - public override simulate( - options: Omit, - ): Promise>; - // eslint-disable-next-line jsdoc/require-jsdoc public override simulate( - options: Omit = {}, - ): Promise> { - return super.simulate({ ...options, from: this.from }); + options: Omit = {} as Omit, + ): Promise { + return super.simulate({ ...options, from: this.from } as SimulateInteractionOptions); } /** @@ -290,8 +289,7 @@ export class SetPublicAuthwitContractInteraction extends ContractFunctionInterac * @param options - An optional object containing 'fee' options information * @returns A TxReceipt (if wait is true/undefined) or TxHash (if wait is false) */ - // Overload for when wait is not specified at all - returns TxReceipt - public override send(options?: Omit): Promise; + public override send(options?: Omit): Promise; // Generic overload for explicit wait values // eslint-disable-next-line jsdoc/require-jsdoc public override send( @@ -300,7 +298,7 @@ export class SetPublicAuthwitContractInteraction extends ContractFunctionInterac // eslint-disable-next-line jsdoc/require-jsdoc public override send( options?: Omit, 'from'>, - ): Promise { + ): Promise> { return super.send({ ...options, from: this.from }); } diff --git a/yarn-project/aztec.js/src/wallet/wallet.test.ts b/yarn-project/aztec.js/src/wallet/wallet.test.ts index bcee66440e18..73b3bdb95123 100644 --- a/yarn-project/aztec.js/src/wallet/wallet.test.ts +++ b/yarn-project/aztec.js/src/wallet/wallet.test.ts @@ -11,6 +11,7 @@ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract'; import { PublicKeys } from '@aztec/stdlib/keys'; import { ExecutionPayload, + type OffchainEffect, TxHash, TxProfileResult, TxReceipt, @@ -18,7 +19,12 @@ import { UtilityExecutionResult, } from '@aztec/stdlib/tx'; -import { type InteractionWaitOptions, NO_WAIT, type SendReturn } from '../contract/interaction_options.js'; +import { + type InteractionWaitOptions, + NO_WAIT, + type OffchainMessage, + type SendReturn, +} from '../contract/interaction_options.js'; import type { AppCapabilities, WalletCapabilities } from './capabilities.js'; import type { Aliased, @@ -209,12 +215,14 @@ describe('WalletSchema', () => { const resultWithWait = await context.client.sendTx(exec, { from: await AztecAddress.random(), }); - expect(resultWithWait).toBeInstanceOf(TxReceipt); + expect(resultWithWait.receipt).toBeInstanceOf(TxReceipt); + expect(resultWithWait.offchainEffects).toEqual([]); const resultWithoutWait = await context.client.sendTx(exec, { from: await AztecAddress.random(), wait: NO_WAIT, }); - expect(resultWithoutWait).toBeInstanceOf(TxHash); + expect(resultWithoutWait.txHash).toBeInstanceOf(TxHash); + expect(resultWithoutWait.offchainEffects).toEqual([]); }); it('createAuthWit', async () => { @@ -353,7 +361,10 @@ describe('WalletSchema', () => { expect(results[8]).toEqual({ name: 'simulateTx', result: expect.any(TxSimulationResult) }); expect(results[9]).toEqual({ name: 'executeUtility', result: expect.any(UtilityExecutionResult) }); expect(results[10]).toEqual({ name: 'profileTx', result: expect.any(TxProfileResult) }); - expect(results[11]).toEqual({ name: 'sendTx', result: expect.any(TxReceipt) }); + expect(results[11]).toEqual({ + name: 'sendTx', + result: { receipt: expect.any(TxReceipt), offchainEffects: [], offchainMessages: [] }, + }); expect(results[12]).toEqual({ name: 'createAuthWit', result: expect.any(AuthWitness) }); }); }); @@ -446,9 +457,17 @@ class MockWallet implements Wallet { opts: SendOptions, ): Promise> { if (opts.wait === NO_WAIT) { - return Promise.resolve(TxHash.random()) as Promise>; + return Promise.resolve({ + txHash: TxHash.random(), + offchainEffects: [] as OffchainEffect[], + offchainMessages: [] as OffchainMessage[], + }) as Promise>; } - return Promise.resolve(TxReceipt.empty()) as Promise>; + return Promise.resolve({ + receipt: TxReceipt.empty(), + offchainEffects: [] as OffchainEffect[], + offchainMessages: [] as OffchainMessage[], + }) as Promise>; } createAuthWit(_from: AztecAddress, _messageHashOrIntent: any): Promise { diff --git a/yarn-project/aztec.js/src/wallet/wallet.ts b/yarn-project/aztec.js/src/wallet/wallet.ts index 9918542d297e..0e48f2f42726 100644 --- a/yarn-project/aztec.js/src/wallet/wallet.ts +++ b/yarn-project/aztec.js/src/wallet/wallet.ts @@ -303,6 +303,7 @@ export const SendOptionsSchema = z.object({ capsules: optional(z.array(Capsule.schema)), fee: optional(GasSettingsOptionSchema), wait: optional(z.union([z.literal(NO_WAIT), WaitOptsSchema])), + additionalScopes: optional(z.array(schemas.AztecAddress)), }); export const SimulateOptionsSchema = z.object({ @@ -313,6 +314,7 @@ export const SimulateOptionsSchema = z.object({ skipTxValidation: optional(z.boolean()), skipFeeEnforcement: optional(z.boolean()), includeMetadata: optional(z.boolean()), + additionalScopes: optional(z.array(schemas.AztecAddress)), }); export const ProfileOptionsSchema = SimulateOptionsSchema.extend({ @@ -379,6 +381,7 @@ export const ContractClassMetadataSchema = z.object({ export const ContractFunctionPatternSchema = z.object({ contract: z.union([schemas.AztecAddress, z.literal('*')]), function: z.union([z.string(), z.literal('*')]), + additionalScopes: optional(z.union([z.array(schemas.AztecAddress), z.literal('*')])), }); export const AccountsCapabilitySchema = z.object({ @@ -489,6 +492,22 @@ export const WalletCapabilitiesSchema = z.object({ expiresAt: optional(z.number()), }); +const OffchainEffectSchema = z.object({ + data: z.array(schemas.Fr), + contractAddress: schemas.AztecAddress, +}); + +const OffchainMessageSchema = z.object({ + recipient: schemas.AztecAddress, + payload: z.array(schemas.Fr), + contractAddress: schemas.AztecAddress, +}); + +const OffchainOutputSchema = z.object({ + offchainEffects: z.array(OffchainEffectSchema), + offchainMessages: z.array(OffchainMessageSchema), +}); + /** * Record of all wallet method schemas (excluding batch). * This is the single source of truth for method schemas - batch schemas are derived from this. @@ -532,7 +551,12 @@ const WalletMethodSchemas = { sendTx: z .function() .args(ExecutionPayloadSchema, SendOptionsSchema) - .returns(z.union([TxHash.schema, TxReceipt.schema])), + .returns( + z.union([ + z.object({ txHash: TxHash.schema }).merge(OffchainOutputSchema), + z.object({ receipt: TxReceipt.schema }).merge(OffchainOutputSchema), + ]), + ), createAuthWit: z.function().args(schemas.AztecAddress, MessageHashOrIntentSchema).returns(AuthWitness.schema), requestCapabilities: z.function().args(AppCapabilitiesSchema).returns(WalletCapabilitiesSchema), }; diff --git a/yarn-project/aztec/src/examples/token.ts b/yarn-project/aztec/src/examples/token.ts index 2a99d350c314..1e7e2077910d 100644 --- a/yarn-project/aztec/src/examples/token.ts +++ b/yarn-project/aztec/src/examples/token.ts @@ -32,7 +32,9 @@ async function main() { logger.info(`Fetched Alice and Bob accounts: ${alice.toString()}, ${bob.toString()}`); logger.info('Deploying Token...'); - const token = await TokenContract.deploy(wallet, alice, 'TokenName', 'TokenSymbol', 18).send({ from: alice }); + const { contract: token } = await TokenContract.deploy(wallet, alice, 'TokenName', 'TokenSymbol', 18).send({ + from: alice, + }); logger.info('Token deployed'); // Mint tokens to Alice @@ -41,7 +43,7 @@ async function main() { logger.info(`${ALICE_MINT_BALANCE} tokens were successfully minted by Alice and transferred to private`); - const balanceAfterMint = await token.methods.balance_of_private(alice).simulate({ from: alice }); + const { result: balanceAfterMint } = await token.methods.balance_of_private(alice).simulate({ from: alice }); logger.info(`Tokens successfully minted. New Alice's balance: ${balanceAfterMint}`); // We will now transfer tokens from Alice to Bob @@ -49,10 +51,10 @@ async function main() { await token.methods.transfer(bob, TRANSFER_AMOUNT).send({ from: alice }); // Check the new balances - const aliceBalance = await token.methods.balance_of_private(alice).simulate({ from: alice }); + const { result: aliceBalance } = await token.methods.balance_of_private(alice).simulate({ from: alice }); logger.info(`Alice's balance ${aliceBalance}`); - const bobBalance = await token.methods.balance_of_private(bob).simulate({ from: bob }); + const { result: bobBalance } = await token.methods.balance_of_private(bob).simulate({ from: bob }); logger.info(`Bob's balance ${bobBalance}`); } diff --git a/yarn-project/aztec/src/local-network/banana_fpc.ts b/yarn-project/aztec/src/local-network/banana_fpc.ts index 5ccb73d8746f..e5363e0eda73 100644 --- a/yarn-project/aztec/src/local-network/banana_fpc.ts +++ b/yarn-project/aztec/src/local-network/banana_fpc.ts @@ -48,7 +48,7 @@ export async function getBananaFPCAddress(initialAccounts: InitialAccountData[]) export async function setupBananaFPC(initialAccounts: InitialAccountData[], wallet: Wallet, log: LogFn) { const bananaCoinAddress = await getBananaCoinAddress(initialAccounts); const admin = getBananaAdmin(initialAccounts); - const [bananaCoin, fpc] = await Promise.all([ + const [{ contract: bananaCoin }, { contract: fpc }] = await Promise.all([ TokenContract.deploy(wallet, admin, bananaCoinArgs.name, bananaCoinArgs.symbol, bananaCoinArgs.decimal).send({ from: admin, contractAddressSalt: BANANA_COIN_SALT, diff --git a/yarn-project/bot/src/amm_bot.ts b/yarn-project/bot/src/amm_bot.ts index 362470479518..21461c775d90 100644 --- a/yarn-project/bot/src/amm_bot.ts +++ b/yarn-project/bot/src/amm_bot.ts @@ -71,12 +71,14 @@ export class AmmBot extends BaseBot { .getFunctionCall(), }); - const amountOutMin = await amm.methods - .get_amount_out_for_exact_in( - await tokenIn.methods.balance_of_public(amm.address).simulate({ from: this.defaultAccountAddress }), - await tokenOut.methods.balance_of_public(amm.address).simulate({ from: this.defaultAccountAddress }), - amountIn, - ) + const { result: tokenInBalance } = await tokenIn.methods + .balance_of_public(amm.address) + .simulate({ from: this.defaultAccountAddress }); + const { result: tokenOutBalance } = await tokenOut.methods + .balance_of_public(amm.address) + .simulate({ from: this.defaultAccountAddress }); + const { result: amountOutMin } = await amm.methods + .get_amount_out_for_exact_in(tokenInBalance, tokenOutBalance, amountIn) .simulate({ from: this.defaultAccountAddress }); const swapExactTokensInteraction = amm.methods @@ -89,7 +91,8 @@ export class AmmBot extends BaseBot { this.log.verbose(`Sending transaction`, logCtx); this.log.info(`Tx. Balances: ${jsonStringify(balances)}`, { ...logCtx, balances }); - return swapExactTokensInteraction.send({ ...opts, wait: NO_WAIT }); + const { txHash } = await swapExactTokensInteraction.send({ ...opts, wait: NO_WAIT }); + return txHash; } protected override async onTxMined(receipt: TxReceipt, logCtx: object): Promise { @@ -110,15 +113,17 @@ export class AmmBot extends BaseBot { } private async getPublicBalanceFor(address: AztecAddress, from?: AztecAddress): Promise { - return { - token0: await this.token0.methods.balance_of_public(address).simulate({ from: from ?? address }), - token1: await this.token1.methods.balance_of_public(address).simulate({ from: from ?? address }), - }; + const { result: token0 } = await this.token0.methods.balance_of_public(address).simulate({ from: from ?? address }); + const { result: token1 } = await this.token1.methods.balance_of_public(address).simulate({ from: from ?? address }); + return { token0, token1 }; } private async getPrivateBalanceFor(address: AztecAddress, from?: AztecAddress): Promise { - return { - token0: await this.token0.methods.balance_of_private(address).simulate({ from: from ?? address }), - token1: await this.token1.methods.balance_of_private(address).simulate({ from: from ?? address }), - }; + const { result: token0 } = await this.token0.methods + .balance_of_private(address) + .simulate({ from: from ?? address }); + const { result: token1 } = await this.token1.methods + .balance_of_private(address) + .simulate({ from: from ?? address }); + return { token0, token1 }; } } diff --git a/yarn-project/bot/src/bot.ts b/yarn-project/bot/src/bot.ts index dce40d2194ad..c2128b2a219e 100644 --- a/yarn-project/bot/src/bot.ts +++ b/yarn-project/bot/src/bot.ts @@ -76,7 +76,8 @@ export class Bot extends BaseBot { await batch.simulate({ from: this.defaultAccountAddress }); this.log.verbose(`Sending transaction`, logCtx); - return batch.send({ ...opts, wait: NO_WAIT }); + const { txHash } = await batch.send({ ...opts, wait: NO_WAIT }); + return txHash; } public async getBalances() { diff --git a/yarn-project/bot/src/cross_chain_bot.ts b/yarn-project/bot/src/cross_chain_bot.ts index 52c59a54f58d..2a3ab8848ddb 100644 --- a/yarn-project/bot/src/cross_chain_bot.ts +++ b/yarn-project/bot/src/cross_chain_bot.ts @@ -140,7 +140,8 @@ export class CrossChainBot extends BaseBot { const opts = await this.getSendMethodOpts(batch); this.log.verbose(`Sending cross-chain batch with ${calls.length} calls`, logCtx); - return batch.send({ ...opts, wait: NO_WAIT }); + const { txHash } = await batch.send({ ...opts, wait: NO_WAIT }); + return txHash; } protected override async onTxMined(receipt: TxReceipt, logCtx: object): Promise { diff --git a/yarn-project/bot/src/factory.ts b/yarn-project/bot/src/factory.ts index e96007c71160..f37bffd1031c 100644 --- a/yarn-project/bot/src/factory.ts +++ b/yarn-project/bot/src/factory.ts @@ -222,7 +222,7 @@ export class BotFactory { const gasSettings = GasSettings.default({ maxFeesPerGas }); await this.withNoMinTxsPerBlock(async () => { - const txHash = await deployMethod.send({ + const { txHash } = await deployMethod.send({ from: AztecAddress.ZERO, fee: { gasSettings, paymentMethod }, wait: NO_WAIT, @@ -280,6 +280,8 @@ export class BotFactory { tokenInstance = await deploy.getInstance(deployOpts); token = PrivateTokenContract.at(tokenInstance.address, this.wallet); await this.wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey); + // The contract constructor initializes private storage vars that need the contract's own nullifier key. + deployOpts.additionalScopes = [tokenInstance.address]; } else { throw new Error(`Unsupported token contract type: ${this.config.contract}`); } @@ -291,7 +293,7 @@ export class BotFactory { await deploy.register(); } else { this.log.info(`Deploying token contract at ${address.toString()}`); - const txHash = await deploy.send({ ...deployOpts, wait: NO_WAIT }); + const { txHash } = await deploy.send({ ...deployOpts, wait: NO_WAIT }); this.log.info(`Sent tx for token setup with hash ${txHash.toString()}`); await this.withNoMinTxsPerBlock(async () => { await waitForTx(this.aztecNode, txHash, { timeout: this.config.txMinedWaitSeconds }); @@ -332,7 +334,7 @@ export class BotFactory { const amm = AMMContract.at(instance.address, this.wallet); this.log.info(`AMM deployed at ${amm.address}`); - const minterReceipt = await lpToken.methods + const { receipt: minterReceipt } = await lpToken.methods .set_minter(amm.address, true) .send({ from: deployer, wait: { timeout: this.config.txMinedWaitSeconds } }); this.log.info(`Set LP token minter to AMM txHash=${minterReceipt.txHash.toString()}`); @@ -351,9 +353,18 @@ export class BotFactory { ): Promise { const getPrivateBalances = () => Promise.all([ - token0.methods.balance_of_private(liquidityProvider).simulate({ from: liquidityProvider }), - token1.methods.balance_of_private(liquidityProvider).simulate({ from: liquidityProvider }), - lpToken.methods.balance_of_private(liquidityProvider).simulate({ from: liquidityProvider }), + token0.methods + .balance_of_private(liquidityProvider) + .simulate({ from: liquidityProvider }) + .then(r => r.result), + token1.methods + .balance_of_private(liquidityProvider) + .simulate({ from: liquidityProvider }) + .then(r => r.result), + lpToken.methods + .balance_of_private(liquidityProvider) + .simulate({ from: liquidityProvider }) + .then(r => r.result), ]); const authwitNonce = Fr.random(); @@ -394,14 +405,14 @@ export class BotFactory { .getFunctionCall(), }); - const mintReceipt = await new BatchCall(this.wallet, [ + const { receipt: mintReceipt } = await new BatchCall(this.wallet, [ token0.methods.mint_to_private(liquidityProvider, MINT_BALANCE), token1.methods.mint_to_private(liquidityProvider, MINT_BALANCE), ]).send({ from: liquidityProvider, wait: { timeout: this.config.txMinedWaitSeconds } }); this.log.info(`Sent mint tx: ${mintReceipt.txHash.toString()}`); - const addLiquidityReceipt = await amm.methods + const { receipt: addLiquidityReceipt } = await amm.methods .add_liquidity(amount0Max, amount1Max, amount0Min, amount1Min, authwitNonce) .send({ from: liquidityProvider, @@ -432,7 +443,7 @@ export class BotFactory { } else { this.log.info(`Deploying contract ${name} at ${address.toString()}`); await this.withNoMinTxsPerBlock(async () => { - const txHash = await deploy.send({ ...deployOpts, wait: NO_WAIT }); + const { txHash } = await deploy.send({ ...deployOpts, wait: NO_WAIT }); this.log.info(`Sent contract ${name} setup tx with hash ${txHash.toString()}`); return waitForTx(this.aztecNode, txHash, { timeout: this.config.txMinedWaitSeconds }); }); @@ -474,8 +485,14 @@ export class BotFactory { return; } + // PrivateToken's mint accesses contract-level private storage vars (admin, total_supply). + const additionalScopes = isStandardToken ? undefined : [token.address]; await this.withNoMinTxsPerBlock(async () => { - const txHash = await new BatchCall(token.wallet, calls).send({ from: minter, wait: NO_WAIT }); + const { txHash } = await new BatchCall(token.wallet, calls).send({ + from: minter, + additionalScopes, + wait: NO_WAIT, + }); this.log.info(`Sent token mint tx with hash ${txHash.toString()}`); return waitForTx(this.aztecNode, txHash, { timeout: this.config.txMinedWaitSeconds }); }); diff --git a/yarn-project/bot/src/utils.ts b/yarn-project/bot/src/utils.ts index 1bd0b7f6b743..807d34be95ab 100644 --- a/yarn-project/bot/src/utils.ts +++ b/yarn-project/bot/src/utils.ts @@ -15,8 +15,8 @@ export async function getBalances( who: AztecAddress, from?: AztecAddress, ): Promise<{ privateBalance: bigint; publicBalance: bigint }> { - const privateBalance = await token.methods.balance_of_private(who).simulate({ from: from ?? who }); - const publicBalance = await token.methods.balance_of_public(who).simulate({ from: from ?? who }); + const { result: privateBalance } = await token.methods.balance_of_private(who).simulate({ from: from ?? who }); + const { result: publicBalance } = await token.methods.balance_of_public(who).simulate({ from: from ?? who }); return { privateBalance, publicBalance }; } @@ -25,7 +25,7 @@ export async function getPrivateBalance( who: AztecAddress, from?: AztecAddress, ): Promise { - const privateBalance = await token.methods.get_balance(who).simulate({ from: from ?? who }); + const { result: privateBalance } = await token.methods.get_balance(who).simulate({ from: from ?? who }); return privateBalance; } diff --git a/yarn-project/cli-wallet/src/cmds/create_account.ts b/yarn-project/cli-wallet/src/cmds/create_account.ts index 64b730b95aa1..2e317c6a7799 100644 --- a/yarn-project/cli-wallet/src/cmds/create_account.ts +++ b/yarn-project/cli-wallet/src/cmds/create_account.ts @@ -83,10 +83,13 @@ export async function createAccount( }; const deployMethod = await account.getDeployMethod(); - const { estimatedGas, stats } = await deployMethod.simulate({ + const sim = await deployMethod.simulate({ ...deployAccountOpts, fee: { ...deployAccountOpts.fee, estimateGas: true }, }); + // estimateGas: true guarantees these fields are present + const estimatedGas = sim.estimatedGas!; + const stats = sim.stats!; if (feeOpts.estimateOnly) { if (json) { @@ -109,7 +112,7 @@ export async function createAccount( if (!json) { log(`\nWaiting for account contract deployment...`); } - const result = await deployMethod.send({ + const sendOpts = { ...deployAccountOpts, fee: deployAccountOpts.fee ? { @@ -117,18 +120,20 @@ export async function createAccount( gasSettings: estimatedGas, } : undefined, - wait: wait ? { timeout: DEFAULT_TX_TIMEOUT_S, returnReceipt: true } : NO_WAIT, - }); - const isReceipt = (data: TxReceipt | TxHash): data is TxReceipt => 'txHash' in data; - if (isReceipt(result)) { - txReceipt = result; - txHash = result.txHash; + }; + if (wait) { + const { receipt } = await deployMethod.send({ + ...sendOpts, + wait: { timeout: DEFAULT_TX_TIMEOUT_S, returnReceipt: true }, + }); + txReceipt = receipt; + txHash = receipt.txHash; out.txReceipt = { status: txReceipt.status, transactionFee: txReceipt.transactionFee, }; } else { - txHash = result; + ({ txHash } = await deployMethod.send({ ...sendOpts, wait: NO_WAIT })); } debugLogger.debug(`Account contract tx sent with hash ${txHash.toString()}`); out.txHash = txHash; diff --git a/yarn-project/cli-wallet/src/cmds/deploy.ts b/yarn-project/cli-wallet/src/cmds/deploy.ts index 0de9615aa276..edc7e5db29a9 100644 --- a/yarn-project/cli-wallet/src/cmds/deploy.ts +++ b/yarn-project/cli-wallet/src/cmds/deploy.ts @@ -71,10 +71,13 @@ export async function deploy( skipInstancePublication, }; - const { estimatedGas, stats } = await deploy.simulate({ + const sim = await deploy.simulate({ ...deployOpts, fee: { ...deployOpts.fee, estimateGas: true }, }); + // estimateGas: true guarantees these fields are present + const estimatedGas = sim.estimatedGas!; + const stats = sim.stats!; if (feeOpts.estimateOnly) { if (json) { @@ -98,7 +101,7 @@ export async function deploy( const instance = await deploy.getInstance(); if (wait) { - const receipt = await deploy.send({ ...deployOpts, wait: { timeout, returnReceipt: true } }); + const { receipt } = await deploy.send({ ...deployOpts, wait: { timeout, returnReceipt: true } }); const txHash = receipt.txHash; debugLogger.debug(`Deploy tx sent with hash ${txHash.toString()}`); out.hash = txHash; @@ -121,7 +124,7 @@ export async function deploy( }; } } else { - const txHash = await deploy.send({ ...deployOpts, wait: NO_WAIT }); + const { txHash } = await deploy.send({ ...deployOpts, wait: NO_WAIT }); debugLogger.debug(`Deploy tx sent with hash ${txHash.toString()}`); out.hash = txHash; diff --git a/yarn-project/cli-wallet/src/cmds/deploy_account.ts b/yarn-project/cli-wallet/src/cmds/deploy_account.ts index f18037e7cbb6..4667fa6f12c6 100644 --- a/yarn-project/cli-wallet/src/cmds/deploy_account.ts +++ b/yarn-project/cli-wallet/src/cmds/deploy_account.ts @@ -63,10 +63,13 @@ export async function deployAccount( }; const deployMethod = await account.getDeployMethod(); - const { estimatedGas, stats } = await deployMethod.simulate({ + const sim = await deployMethod.simulate({ ...deployAccountOpts, fee: { ...deployAccountOpts.fee, estimateGas: true }, }); + // estimateGas: true guarantees these fields are present + const estimatedGas = sim.estimatedGas!; + const stats = sim.stats!; if (feeOpts.estimateOnly) { if (json) { @@ -89,7 +92,7 @@ export async function deployAccount( if (!json) { log(`\nWaiting for account contract deployment...`); } - const result = await deployMethod.send({ + const sendOpts = { ...deployAccountOpts, fee: deployAccountOpts.fee ? { @@ -97,18 +100,20 @@ export async function deployAccount( gasSettings: estimatedGas, } : undefined, - wait: wait ? { timeout: DEFAULT_TX_TIMEOUT_S, returnReceipt: true } : NO_WAIT, - }); - const isReceipt = (data: TxReceipt | TxHash): data is TxReceipt => 'txHash' in data; - if (isReceipt(result)) { - txReceipt = result; - txHash = result.txHash; + }; + if (wait) { + const { receipt } = await deployMethod.send({ + ...sendOpts, + wait: { timeout: DEFAULT_TX_TIMEOUT_S, returnReceipt: true }, + }); + txReceipt = receipt; + txHash = receipt.txHash; out.txReceipt = { status: txReceipt.status, transactionFee: txReceipt.transactionFee, }; } else { - txHash = result; + ({ txHash } = await deployMethod.send({ ...sendOpts, wait: NO_WAIT })); } debugLogger.debug(`Account contract tx sent with hash ${txHash.toString()}`); out.txHash = txHash; diff --git a/yarn-project/cli-wallet/src/cmds/send.ts b/yarn-project/cli-wallet/src/cmds/send.ts index 4059db13a93b..4cc3c69b4505 100644 --- a/yarn-project/cli-wallet/src/cmds/send.ts +++ b/yarn-project/cli-wallet/src/cmds/send.ts @@ -37,10 +37,13 @@ export async function send( authWitnesses, }; - const { estimatedGas, stats } = await call.simulate({ + const sim = await call.simulate({ ...sendOptions, fee: { ...sendOptions.fee, estimateGas: true }, }); + // estimateGas: true guarantees these fields are present + const estimatedGas = sim.estimatedGas!; + const stats = sim.stats!; if (feeOpts.estimateOnly) { return; @@ -52,7 +55,7 @@ export async function send( if (wait) { try { - const receipt = await call.send({ + const { receipt } = await call.send({ ...sendOptions, fee: { ...sendOptions.fee, gasSettings: estimatedGas }, wait: { timeout: DEFAULT_TX_TIMEOUT_S }, @@ -74,7 +77,7 @@ export async function send( throw err; } } else { - const txHash = await call.send({ + const { txHash } = await call.send({ ...sendOptions, fee: { ...sendOptions.fee, gasSettings: estimatedGas }, wait: NO_WAIT, diff --git a/yarn-project/cli-wallet/src/cmds/simulate.ts b/yarn-project/cli-wallet/src/cmds/simulate.ts index 2443428df708..aec161b4ab33 100644 --- a/yarn-project/cli-wallet/src/cmds/simulate.ts +++ b/yarn-project/cli-wallet/src/cmds/simulate.ts @@ -38,7 +38,7 @@ export async function simulate( }); if (verbose) { await printAuthorizations( - simulationResult.offchainEffects!, + simulationResult.offchainEffects, async (address: AztecAddress) => { const metadata = await wallet.getContractMetadata(address); if (!metadata.instance) { diff --git a/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts b/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts index db57a7b52d9b..e38eb09f7c9f 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/account_deployments.test.ts @@ -91,8 +91,8 @@ describe('Deployment benchmark', () => { if (process.env.SANITY_CHECKS) { // Ensure we paid a fee - const tx = await deploymentInteraction.send({ ...options, wait: { returnReceipt: true } }); - expect(tx.transactionFee!).toBeGreaterThan(0n); + const { receipt } = await deploymentInteraction.send({ ...options, wait: { returnReceipt: true } }); + expect(receipt.transactionFee!).toBeGreaterThan(0n); } }); } diff --git a/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts b/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts index 22ca27be3eee..44a5652b484f 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/amm.test.ts @@ -199,7 +199,7 @@ describe('AMM benchmark', () => { ); if (process.env.SANITY_CHECKS) { - const tx = await addLiquidityInteraction.send({ from: benchysAddress }); + const { receipt: tx } = await addLiquidityInteraction.send({ from: benchysAddress }); expect(tx.transactionFee!).toBeGreaterThan(0n); } diff --git a/yarn-project/end-to-end/src/bench/client_flows/bridging.test.ts b/yarn-project/end-to-end/src/bench/client_flows/bridging.test.ts index 0800c709ea82..27aa73ef8e39 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/bridging.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/bridging.test.ts @@ -106,7 +106,7 @@ describe('Bridging benchmark', () => { if (process.env.SANITY_CHECKS) { // Ensure we paid a fee - const tx = await claimInteraction.send(options); + const { receipt: tx } = await claimInteraction.send(options); expect(tx.transactionFee!).toBeGreaterThan(0n); // 4. Check the balance diff --git a/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts b/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts index 46503ec9abec..7b997404b6e1 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/client_flows_benchmark.ts @@ -197,11 +197,15 @@ export class ClientFlowsBenchmark { /** Admin mints bananaCoin tokens privately to the target address and redeems them. */ async mintPrivateBananas(amount: bigint, address: AztecAddress) { - const balanceBefore = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address }); + const { result: balanceBefore } = await this.bananaCoin.methods + .balance_of_private(address) + .simulate({ from: address }); await mintTokensToPrivate(this.bananaCoin, this.adminAddress, address, amount); - const balanceAfter = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address }); + const { result: balanceAfter } = await this.bananaCoin.methods + .balance_of_private(address) + .simulate({ from: address }); expect(balanceAfter).toEqual(balanceBefore + amount); } @@ -277,13 +281,12 @@ export class ClientFlowsBenchmark { async applyDeployBananaToken() { this.logger.info('Applying banana token deployment'); - const { contract: bananaCoin, instance: bananaCoinInstance } = await BananaCoin.deploy( - this.adminWallet, - this.adminAddress, - 'BC', - 'BC', - 18n, - ).send({ from: this.adminAddress, wait: { returnReceipt: true } }); + const { + receipt: { contract: bananaCoin, instance: bananaCoinInstance }, + } = await BananaCoin.deploy(this.adminWallet, this.adminAddress, 'BC', 'BC', 18n).send({ + from: this.adminAddress, + wait: { returnReceipt: true }, + }); this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`); this.bananaCoin = bananaCoin; this.bananaCoinInstance = bananaCoinInstance; @@ -291,13 +294,12 @@ export class ClientFlowsBenchmark { async applyDeployCandyBarToken() { this.logger.info('Applying candy bar token deployment'); - const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TokenContract.deploy( - this.adminWallet, - this.adminAddress, - 'CBC', - 'CBC', - 18n, - ).send({ from: this.adminAddress, wait: { returnReceipt: true } }); + const { + receipt: { contract: candyBarCoin, instance: candyBarCoinInstance }, + } = await TokenContract.deploy(this.adminWallet, this.adminAddress, 'CBC', 'CBC', 18n).send({ + from: this.adminAddress, + wait: { returnReceipt: true }, + }); this.logger.info(`CandyBarCoin deployed at ${candyBarCoin.address}`); this.candyBarCoin = candyBarCoin; this.candyBarCoinInstance = candyBarCoinInstance; @@ -309,11 +311,12 @@ export class ClientFlowsBenchmark { expect((await this.context.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true); const bananaCoin = this.bananaCoin; - const { contract: bananaFPC, instance: bananaFPCInstance } = await FPCContract.deploy( - this.adminWallet, - bananaCoin.address, - this.adminAddress, - ).send({ from: this.adminAddress, wait: { returnReceipt: true } }); + const { + receipt: { contract: bananaFPC, instance: bananaFPCInstance }, + } = await FPCContract.deploy(this.adminWallet, bananaCoin.address, this.adminAddress).send({ + from: this.adminAddress, + wait: { returnReceipt: true }, + }); this.logger.info(`BananaPay deployed at ${bananaFPC.address}`); @@ -376,14 +379,15 @@ export class ClientFlowsBenchmark { public async applyDeployAmm() { this.logger.info('Applying AMM deployment'); - const { contract: liquidityToken, instance: liquidityTokenInstance } = await TokenContract.deploy( - this.adminWallet, - this.adminAddress, - 'LPT', - 'LPT', - 18n, - ).send({ from: this.adminAddress, wait: { returnReceipt: true } }); - const { contract: amm, instance: ammInstance } = await AMMContract.deploy( + const { + receipt: { contract: liquidityToken, instance: liquidityTokenInstance }, + } = await TokenContract.deploy(this.adminWallet, this.adminAddress, 'LPT', 'LPT', 18n).send({ + from: this.adminAddress, + wait: { returnReceipt: true }, + }); + const { + receipt: { contract: amm, instance: ammInstance }, + } = await AMMContract.deploy( this.adminWallet, this.bananaCoin.address, this.candyBarCoin.address, diff --git a/yarn-project/end-to-end/src/bench/client_flows/deployments.test.ts b/yarn-project/end-to-end/src/bench/client_flows/deployments.test.ts index 124e0b0cbbae..f75f4d011751 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/deployments.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/deployments.test.ts @@ -86,8 +86,8 @@ describe('Deployment benchmark', () => { if (process.env.SANITY_CHECKS) { // Ensure we paid a fee - const tx = await deploymentInteraction.send({ ...options, wait: { returnReceipt: true } }); - expect(tx.transactionFee!).toBeGreaterThan(0n); + const { receipt } = await deploymentInteraction.send({ ...options, wait: { returnReceipt: true } }); + expect(receipt.transactionFee!).toBeGreaterThan(0n); } }); }); diff --git a/yarn-project/end-to-end/src/bench/client_flows/storage_proof.test.ts b/yarn-project/end-to-end/src/bench/client_flows/storage_proof.test.ts index 00d431a4bc40..c46f17ccf444 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/storage_proof.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/storage_proof.test.ts @@ -34,7 +34,7 @@ describe('Storage proof benchmark', () => { await t.applyFPCSetup(); await t.applyDeploySponsoredFPC(); - const deployed = await StorageProofTestContract.deploy(t.adminWallet).send({ + const { receipt: deployed } = await StorageProofTestContract.deploy(t.adminWallet).send({ from: t.adminAddress, wait: { returnReceipt: true }, }); @@ -106,7 +106,7 @@ describe('Storage proof benchmark', () => { ); if (process.env.SANITY_CHECKS) { - const tx = await interaction.send(options); + const { receipt: tx } = await interaction.send(options); expect(tx.transactionFee!).toBeGreaterThan(0n); expect(tx.hasExecutionSucceeded()).toBe(true); } diff --git a/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts b/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts index 77c8149072b7..df7222e067db 100644 --- a/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts +++ b/yarn-project/end-to-end/src/bench/client_flows/transfers.test.ts @@ -151,7 +151,7 @@ describe('Transfer benchmark', () => { if (process.env.SANITY_CHECKS) { // Ensure we paid a fee - const tx = await transferInteraction.send(options); + const { receipt: tx } = await transferInteraction.send(options); expect(tx.transactionFee!).toBeGreaterThan(0n); // Sanity checks @@ -179,7 +179,7 @@ describe('Transfer benchmark', () => { */ expect(txEffects!.data.noteHashes.length).toBe(2 + (benchmarkingPaymentMethod === 'private_fpc' ? 2 : 0)); - const senderBalance = await asset.methods + const { result: senderBalance } = await asset.methods .balance_of_private(benchysAddress) .simulate({ from: benchysAddress }); expect(senderBalance).toEqual(expectedChange); diff --git a/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts b/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts index 385076c83cdf..7149ec20637c 100644 --- a/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts +++ b/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts @@ -152,9 +152,9 @@ describe('e2e_node_rpc_perf', () => { })); logger.info('Deploying token contract...'); - tokenContract = await TokenContract.deploy(wallet, ownerAddress, 'TestToken', 'TST', 18n).send({ + ({ contract: tokenContract } = await TokenContract.deploy(wallet, ownerAddress, 'TestToken', 'TST', 18n).send({ from: ownerAddress, - }); + })); contractAddress = tokenContract.address; logger.info(`Token contract deployed at ${contractAddress}`); diff --git a/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts b/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts index 54d51c3ce6da..e69ffed1efc2 100644 --- a/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts +++ b/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts @@ -65,12 +65,12 @@ describe('transaction benchmarks', () => { } = t); // Create the two transactions - const privateBalance = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); + const { result: privateBalance } = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); const privateSendAmount = privateBalance / 10n; expect(privateSendAmount).toBeGreaterThan(0n); const privateInteraction = provenAsset.methods.transfer(recipient, privateSendAmount); - const publicBalance = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); + const { result: publicBalance } = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); const publicSendAmount = publicBalance / 10n; expect(publicSendAmount).toBeGreaterThan(0n); const publicInteraction = provenAsset.methods.transfer_in_public(sender, recipient, publicSendAmount, 0); diff --git a/yarn-project/end-to-end/src/bench/utils.ts b/yarn-project/end-to-end/src/bench/utils.ts index 370baefc8b6c..7daa924782df 100644 --- a/yarn-project/end-to-end/src/bench/utils.ts +++ b/yarn-project/end-to-end/src/bench/utils.ts @@ -25,7 +25,7 @@ export async function benchmarkSetup( ) { const context = await setup(1, { ...opts, telemetryConfig: { benchmark: true } }); const defaultAccountAddress = context.accounts[0]; - const contract = await BenchmarkingContract.deploy(context.wallet).send({ from: defaultAccountAddress }); + const { contract } = await BenchmarkingContract.deploy(context.wallet).send({ from: defaultAccountAddress }); context.logger.info(`Deployed benchmarking contract at ${contract.address}`); const sequencer = (context.aztecNode as AztecNodeService).getSequencer()!; const telemetry = context.telemetryClient as BenchmarkTelemetryClient; @@ -149,7 +149,12 @@ export async function sendTxs( context.logger.info(`Creating ${txCount} txs`); const [from] = context.accounts; context.logger.info(`Sending ${txCount} txs`); - return Promise.all(calls.map(call => call.send({ from, wait: NO_WAIT }))); + return Promise.all( + calls.map(async call => { + const { txHash } = await call.send({ from, wait: NO_WAIT }); + return txHash; + }), + ); } export async function waitTxs(txs: TxHash[], context: EndToEndContext, txWaitOpts?: WaitOpts) { diff --git a/yarn-project/end-to-end/src/composed/docs_examples.test.ts b/yarn-project/end-to-end/src/composed/docs_examples.test.ts index fe843da8ff56..45611db7c898 100644 --- a/yarn-project/end-to-end/src/composed/docs_examples.test.ts +++ b/yarn-project/end-to-end/src/composed/docs_examples.test.ts @@ -34,7 +34,7 @@ describe('docs_examples', () => { const newAccountAddress = newAccountManager.address; const defaultAccountAddress = prefundedAccount.address; - const deployedContract = await TokenContract.deploy( + const { contract: deployedContract } = await TokenContract.deploy( wallet, // wallet instance defaultAccountAddress, // account 'TokenName', // constructor arg1 @@ -47,7 +47,9 @@ describe('docs_examples', () => { await contract.methods.mint_to_public(newAccountAddress, 1).send({ from: defaultAccountAddress }); // docs:start:simulate_function - const balance = await contract.methods.balance_of_public(newAccountAddress).simulate({ from: newAccountAddress }); + const { result: balance } = await contract.methods + .balance_of_public(newAccountAddress) + .simulate({ from: newAccountAddress }); expect(balance).toEqual(1n); // docs:end:simulate_function }); diff --git a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts index 951c3e0152c4..7bd8d64e0fad 100644 --- a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts @@ -71,10 +71,10 @@ describe('e2e_local_network_example', () => { ////////////// QUERYING THE TOKEN BALANCE FOR EACH ACCOUNT ////////////// - let aliceBalance = await tokenContract.methods.balance_of_private(alice).simulate({ from: alice }); + let { result: aliceBalance } = await tokenContract.methods.balance_of_private(alice).simulate({ from: alice }); logger.info(`Alice's balance ${aliceBalance}`); - let bobBalance = await tokenContract.methods.balance_of_private(bob).simulate({ from: bob }); + let { result: bobBalance } = await tokenContract.methods.balance_of_private(bob).simulate({ from: bob }); logger.info(`Bob's balance ${bobBalance}`); expect(aliceBalance).toBe(initialSupply); @@ -88,10 +88,10 @@ describe('e2e_local_network_example', () => { await tokenContract.methods.transfer(bob, transferQuantity).send({ from: alice }); // Check the new balances - aliceBalance = await tokenContract.methods.balance_of_private(alice).simulate({ from: alice }); + ({ result: aliceBalance } = await tokenContract.methods.balance_of_private(alice).simulate({ from: alice })); logger.info(`Alice's balance ${aliceBalance}`); - bobBalance = await tokenContract.methods.balance_of_private(bob).simulate({ from: bob }); + ({ result: bobBalance } = await tokenContract.methods.balance_of_private(bob).simulate({ from: bob })); logger.info(`Bob's balance ${bobBalance}`); expect(aliceBalance).toBe(initialSupply - transferQuantity); @@ -108,10 +108,10 @@ describe('e2e_local_network_example', () => { await mintTokensToPrivate(tokenContract, bob, bob, mintQuantity); // Check the new balances - aliceBalance = await tokenContract.methods.balance_of_private(alice).simulate({ from: alice }); + ({ result: aliceBalance } = await tokenContract.methods.balance_of_private(alice).simulate({ from: alice })); logger.info(`Alice's balance ${aliceBalance}`); - bobBalance = await tokenContract.methods.balance_of_private(bob).simulate({ from: bob }); + ({ result: bobBalance } = await tokenContract.methods.balance_of_private(bob).simulate({ from: bob })); logger.info(`Bob's balance ${bobBalance}`); expect(aliceBalance).toBe(initialSupply - transferQuantity); @@ -188,7 +188,7 @@ describe('e2e_local_network_example', () => { const maxFeesPerGas = (await node.getCurrentMinFees()).mul(1.5); const gasSettings = GasSettings.default({ maxFeesPerGas }); const paymentMethod = new PrivateFeePaymentMethod(bananaFPCAddress, alice, wallet, gasSettings); - const receiptForAlice = await bananaCoin.methods + const { receipt: receiptForAlice } = await bananaCoin.methods .transfer(bob, amountTransferToBob) .send({ from: alice, fee: { paymentMethod } }); // docs:end:private_fpc_payment @@ -196,11 +196,11 @@ describe('e2e_local_network_example', () => { logger.info(`Transaction fee: ${transactionFee}`); // Check the balances - const aliceBalance = await bananaCoin.methods.balance_of_private(alice).simulate({ from: alice }); + const { result: aliceBalance } = await bananaCoin.methods.balance_of_private(alice).simulate({ from: alice }); logger.info(`Alice's balance: ${aliceBalance}`); expect(aliceBalance).toEqual(mintAmount - transactionFee - amountTransferToBob); - const bobBalance = await bananaCoin.methods.balance_of_private(bob).simulate({ from: bob }); + const { result: bobBalance } = await bananaCoin.methods.balance_of_private(bob).simulate({ from: bob }); logger.info(`Bob's balance: ${bobBalance}`); expect(bobBalance).toEqual(amountTransferToBob); @@ -214,16 +214,16 @@ describe('e2e_local_network_example', () => { // const sponsoredPaymentMethod = await SponsoredFeePaymentMethod.new(pxe); const initialFPCFeeJuice = await getFeeJuiceBalance(sponsoredFPC, node); - const receiptForBob = await bananaCoin.methods + const { receipt: receiptForBob } = await bananaCoin.methods .transfer(alice, amountTransferToAlice) .send({ from: bob, fee: { paymentMethod: sponsoredPaymentMethod } }); // docs:end:sponsored_fpc_payment // Check the balances - const aliceNewBalance = await bananaCoin.methods.balance_of_private(alice).simulate({ from: alice }); + const { result: aliceNewBalance } = await bananaCoin.methods.balance_of_private(alice).simulate({ from: alice }); logger.info(`Alice's new balance: ${aliceNewBalance}`); expect(aliceNewBalance).toEqual(aliceBalance + amountTransferToAlice); - const bobNewBalance = await bananaCoin.methods.balance_of_private(bob).simulate({ from: bob }); + const { result: bobNewBalance } = await bananaCoin.methods.balance_of_private(bob).simulate({ from: bob }); logger.info(`Bob's new balance: ${bobNewBalance}`); expect(bobNewBalance).toEqual(bobBalance - amountTransferToAlice); diff --git a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts index 40a53ad5f254..3f60809d3f8f 100644 --- a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts @@ -68,7 +68,9 @@ describe('Aztec persistence', () => { owner = initialFundedAccounts[0]; ownerAddress = owner.address; - const { contract, instance } = await TokenBlacklistContract.deploy(wallet, ownerAddress).send({ + const { + receipt: { contract, instance }, + } = await TokenBlacklistContract.deploy(wallet, ownerAddress).send({ from: ownerAddress, wait: { returnReceipt: true }, }); @@ -84,7 +86,7 @@ describe('Aztec persistence', () => { const secret = Fr.random(); - const mintTxReceipt = await contract.methods + const { receipt: mintTxReceipt } = await contract.methods .mint_private(1000n, await computeSecretHash(secret)) .send({ from: ownerAddress }); @@ -139,19 +141,29 @@ describe('Aztec persistence', () => { it('correctly restores private notes', async () => { // test for >0 instead of exact value so test isn't dependent on run order await expect( - contract.methods.balance_of_private(ownerAddress).simulate({ from: ownerAddress }), + contract.methods + .balance_of_private(ownerAddress) + .simulate({ from: ownerAddress }) + .then(r => r.result), ).resolves.toBeGreaterThan(0n); }); it('correctly restores public storage', async () => { - await expect(contract.methods.total_supply().simulate({ from: ownerAddress })).resolves.toBeGreaterThan(0n); + await expect( + contract.methods + .total_supply() + .simulate({ from: ownerAddress }) + .then(r => r.result), + ).resolves.toBeGreaterThan(0n); }); it('tracks new notes for the owner', async () => { - const balance = await contract.methods.balance_of_private(ownerAddress).simulate({ from: ownerAddress }); + const { result: balance } = await contract.methods + .balance_of_private(ownerAddress) + .simulate({ from: ownerAddress }); const secret = Fr.random(); - const mintTxReceipt = await contract.methods + const { receipt: mintTxReceipt } = await contract.methods .mint_private(1000n, await computeSecretHash(secret)) .send({ from: ownerAddress }); await addPendingShieldNoteToPXE( @@ -165,9 +177,12 @@ describe('Aztec persistence', () => { await contract.methods.redeem_shield(ownerAddress, 1000n, secret).send({ from: ownerAddress }); - await expect(contract.methods.balance_of_private(ownerAddress).simulate({ from: ownerAddress })).resolves.toEqual( - balance + 1000n, - ); + await expect( + contract.methods + .balance_of_private(ownerAddress) + .simulate({ from: ownerAddress }) + .then(r => r.result), + ).resolves.toEqual(balance + 1000n); }); it('allows spending of private notes', async () => { @@ -175,13 +190,13 @@ describe('Aztec persistence', () => { const otherAccount = await context.wallet.createSchnorrAccount(account.secret, account.salt); const otherAddress = otherAccount.address; - const initialOwnerBalance = await contract.methods + const { result: initialOwnerBalance } = await contract.methods .balance_of_private(ownerAddress) .simulate({ from: ownerAddress }); await contract.methods.transfer(ownerAddress, otherAddress, 500n, 0).send({ from: ownerAddress }); - const [ownerBalance, targetBalance] = await Promise.all([ + const [{ result: ownerBalance }, { result: targetBalance }] = await Promise.all([ contract.methods.balance_of_private(ownerAddress).simulate({ from: ownerAddress }), contract.methods.balance_of_private(otherAddress).simulate({ from: otherAddress }), ]); @@ -224,16 +239,24 @@ describe('Aztec persistence', () => { it("pxe does not have owner's private notes", async () => { await context.wallet.registerContract(contractInstance, TokenBlacklistContract.artifact); const contract = TokenBlacklistContract.at(contractAddress, wallet); - await expect(contract.methods.balance_of_private(ownerAddress).simulate({ from: ownerAddress })).resolves.toEqual( - 0n, - ); + await expect( + contract.methods + .balance_of_private(ownerAddress) + .simulate({ from: ownerAddress }) + .then(r => r.result), + ).resolves.toEqual(0n); }); it('has access to public storage', async () => { await context.wallet.registerContract(contractInstance, TokenBlacklistContract.artifact); const contract = TokenBlacklistContract.at(contractAddress, wallet); - await expect(contract.methods.total_supply().simulate({ from: ownerAddress })).resolves.toBeGreaterThan(0n); + await expect( + contract.methods + .total_supply() + .simulate({ from: ownerAddress }) + .then(r => r.result), + ).resolves.toBeGreaterThan(0n); }); it('pxe restores notes after registering the owner', async () => { @@ -245,7 +268,10 @@ describe('Aztec persistence', () => { // check that notes total more than 0 so that this test isn't dependent on run order await expect( - contract.methods.balance_of_private(ownerAddress).simulate({ from: ownerAddress }), + contract.methods + .balance_of_private(ownerAddress) + .simulate({ from: ownerAddress }) + .then(r => r.result), ).resolves.toBeGreaterThan(0n); }); }); @@ -274,7 +300,7 @@ describe('Aztec persistence', () => { // mint some tokens with a secret we know and redeem later on a separate PXE secret = Fr.random(); mintAmount = 1000n; - const mintTxReceipt = await contract.methods + const { receipt: mintTxReceipt } = await contract.methods .mint_private(mintAmount, await computeSecretHash(secret)) .send({ from: ownerAddress }); mintTxHash = mintTxReceipt.txHash; @@ -301,9 +327,12 @@ describe('Aztec persistence', () => { }); it("restores owner's public balance", async () => { - await expect(contract.methods.balance_of_public(ownerAddress).simulate({ from: ownerAddress })).resolves.toEqual( - revealedAmount, - ); + await expect( + contract.methods + .balance_of_public(ownerAddress) + .simulate({ from: ownerAddress }) + .then(r => r.result), + ).resolves.toEqual(revealedAmount); }); it('allows consuming transparent note created on another PXE', async () => { @@ -317,12 +346,12 @@ describe('Aztec persistence', () => { aztecNode, ); - const balanceBeforeRedeem = await contract.methods + const { result: balanceBeforeRedeem } = await contract.methods .balance_of_private(ownerAddress) .simulate({ from: ownerAddress }); await contract.methods.redeem_shield(ownerAddress, mintAmount, secret).send({ from: ownerAddress }); - const balanceAfterRedeem = await contract.methods + const { result: balanceAfterRedeem } = await contract.methods .balance_of_private(ownerAddress) .simulate({ from: ownerAddress }); diff --git a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts index 923b14ea06f8..3a4b9932e270 100644 --- a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts @@ -100,7 +100,13 @@ describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => { // Deploy L2 token contract // docs:start:deploy-l2-token - const l2TokenContract = await TokenContract.deploy(wallet, ownerAztecAddress, 'L2 Token', 'L2', 18).send({ + const { contract: l2TokenContract } = await TokenContract.deploy( + wallet, + ownerAztecAddress, + 'L2 Token', + 'L2', + 18, + ).send({ from: ownerAztecAddress, }); logger.info(`L2 token contract deployed at ${l2TokenContract.address}`); @@ -130,7 +136,7 @@ describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => { // docs:end:deploy-portal // Deploy L2 bridge contract // docs:start:deploy-l2-bridge - const l2BridgeContract = await TokenBridgeContract.deploy( + const { contract: l2BridgeContract } = await TokenBridgeContract.deploy( wallet, l2TokenContract.address, l1PortalContractAddress, @@ -175,7 +181,7 @@ describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => { await l2BridgeContract.methods .claim_public(ownerAztecAddress, MINT_AMOUNT, claim.claimSecret, claim.messageLeafIndex) .send({ from: ownerAztecAddress }); - const balance = await l2TokenContract.methods + const { result: balance } = await l2TokenContract.methods .balance_of_public(ownerAztecAddress) .simulate({ from: ownerAztecAddress }); logger.info(`Public L2 balance of ${ownerAztecAddress} is ${balance}`); @@ -206,12 +212,12 @@ describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => { l2BridgeContract.address, EthAddress.ZERO, ); - const l2TxReceipt = await l2BridgeContract.methods + const { receipt: l2TxReceipt } = await l2BridgeContract.methods .exit_to_l1_public(EthAddress.fromString(ownerEthAddress), withdrawAmount, EthAddress.ZERO, authwitNonce) .send({ from: ownerAztecAddress }); await waitForProven(node, l2TxReceipt, { provenTimeout: 500 }); - const newL2Balance = await l2TokenContract.methods + const { result: newL2Balance } = await l2TokenContract.methods .balance_of_public(ownerAztecAddress) .simulate({ from: ownerAztecAddress }); logger.info(`New L2 balance of ${ownerAztecAddress} is ${newL2Balance}`); diff --git a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts index 78db818d3e80..279b42a40de6 100644 --- a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts +++ b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts @@ -279,7 +279,7 @@ describe('HA Full Setup', () => { const sender = ownerAddress; logger.info(`Deploying contract from ${sender}`); - const receipt = await deployer.deploy(ownerAddress, sender, 1).send({ + const { receipt } = await deployer.deploy(ownerAddress, sender, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(1)), skipClassPublication: true, @@ -400,7 +400,7 @@ describe('HA Full Setup', () => { // Send a transaction to trigger block building which will also trigger voting logger.info('Sending transaction to trigger block building...'); const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); - const receipt = await deployer.deploy(ownerAddress, ownerAddress, 42).send({ + const { receipt } = await deployer.deploy(ownerAddress, ownerAddress, 42).send({ from: ownerAddress, contractAddressSalt: Fr.random(), wait: { returnReceipt: true }, @@ -516,7 +516,7 @@ describe('HA Full Setup', () => { logger.info(`Active nodes: ${haNodeServices.length - killedNodes.length}/${NODE_COUNT}`); const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); - const receipt = await deployer.deploy(ownerAddress, ownerAddress, i + 100).send({ + const { receipt } = await deployer.deploy(ownerAddress, ownerAddress, i + 100).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(i + 100)), skipClassPublication: true, diff --git a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts index ce44c4ecd9c4..ff0bf8f94e9b 100644 --- a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts +++ b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts @@ -400,7 +400,10 @@ describe('e2e_multi_validator_node', () => { }); const settledTransactions = await Promise.all( - sentTransactionPromises.map(async sentTransactionPromise => waitForTx(aztecNode, await sentTransactionPromise)), + sentTransactionPromises.map(async sentTransactionPromise => { + const { txHash } = await sentTransactionPromise; + return waitForTx(aztecNode, txHash); + }), ); await Promise.all( diff --git a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts index 2ce5cf1fef9d..6b985b3a0242 100644 --- a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts +++ b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts @@ -138,7 +138,7 @@ describe('End-to-end tests for devnet', () => { const l2AccountDeployMethod = await l2AccountManager.getDeployMethod(); - const txReceipt = await l2AccountDeployMethod.send({ + const { receipt: txReceipt } = await l2AccountDeployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod: new FeeJuicePaymentMethodWithClaim(l2AccountAddress, { @@ -172,7 +172,9 @@ describe('End-to-end tests for devnet', () => { expect(txReceipt.isMined() && txReceipt.hasExecutionSucceeded()).toBe(true); const feeJuice = FeeJuiceContract.at((await node.getNodeInfo()).protocolContractAddresses.feeJuice, wallet); - const balance = await feeJuice.methods.balance_of_public(l2AccountAddress).simulate({ from: l2AccountAddress }); + const { result: balance } = await feeJuice.methods + .balance_of_public(l2AccountAddress) + .simulate({ from: l2AccountAddress }); expect(balance).toEqual(amount - txReceipt.transactionFee!); }); @@ -253,7 +255,7 @@ describe('End-to-end tests for devnet', () => { async function advanceChainWithEmptyBlocks(wallet: TestWallet) { const [fundedAccountAddress] = await registerInitialLocalNetworkAccountsInWallet(wallet); - const test = await TestContract.deploy(wallet).send({ + const { contract: test } = await TestContract.deploy(wallet).send({ from: fundedAccountAddress, universalDeploy: true, skipClassPublication: true, diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index e7c6b83ebe8b..fb18c816774d 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -97,7 +97,9 @@ describe('e2e_2_pxes', () => { const deployChildContractViaServerA = async () => { logger.info(`Deploying Child contract...`); - const { instance } = await ChildContract.deploy(walletA).send({ + const { + receipt: { instance }, + } = await ChildContract.deploy(walletA).send({ from: accountAAddress, wait: { returnReceipt: true }, }); diff --git a/yarn-project/end-to-end/src/e2e_abi_types.test.ts b/yarn-project/end-to-end/src/e2e_abi_types.test.ts index d970d9c105b2..a7702f78c720 100644 --- a/yarn-project/end-to-end/src/e2e_abi_types.test.ts +++ b/yarn-project/end-to-end/src/e2e_abi_types.test.ts @@ -29,19 +29,19 @@ describe('AbiTypes', () => { wallet, accounts: [defaultAccountAddress], } = await setup(1)); - abiTypesContract = await AbiTypesContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: abiTypesContract } = await AbiTypesContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(() => teardown()); it('passes public parameters', async () => { - const minResult = await abiTypesContract.methods + const { result: minResult } = await abiTypesContract.methods .return_public_parameters(false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN }) .simulate({ from: defaultAccountAddress }); expect(minResult).toEqual([false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN }]); - const maxResult = await abiTypesContract.methods + const { result: maxResult } = await abiTypesContract.methods .return_public_parameters(true, MAX_FIELD_VALUE, U64_MAX, I64_MAX, { w: MAX_FIELD_VALUE, x: true, @@ -60,13 +60,13 @@ describe('AbiTypes', () => { }); it('passes private parameters', async () => { - const minResult = await abiTypesContract.methods + const { result: minResult } = await abiTypesContract.methods .return_private_parameters(false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN }) .simulate({ from: defaultAccountAddress }); expect(minResult).toEqual([false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN }]); - const maxResult = await abiTypesContract.methods + const { result: maxResult } = await abiTypesContract.methods .return_private_parameters(true, MAX_FIELD_VALUE, U64_MAX, I64_MAX, { w: MAX_FIELD_VALUE, x: true, @@ -85,13 +85,13 @@ describe('AbiTypes', () => { }); it('passes utility parameters', async () => { - const minResult = await abiTypesContract.methods + const { result: minResult } = await abiTypesContract.methods .return_utility_parameters(false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN }) .simulate({ from: defaultAccountAddress }); expect(minResult).toEqual([false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN }]); - const maxResult = await abiTypesContract.methods + const { result: maxResult } = await abiTypesContract.methods .return_utility_parameters(true, MAX_FIELD_VALUE, U64_MAX, I64_MAX, { w: MAX_FIELD_VALUE, x: true, diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index 85285d0a4fb1..a4e0338f4cfa 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -65,7 +65,7 @@ const itShouldBehaveLikeAnAccountContract = ( await deployMethod.send({ from: AztecAddress.ZERO }); } - child = await ChildContract.deploy(wallet).send({ from: address }); + ({ contract: child } = await ChildContract.deploy(wallet).send({ from: address })); }); afterAll(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_amm.test.ts b/yarn-project/end-to-end/src/e2e_amm.test.ts index 79f640236665..b92c5e9dc683 100644 --- a/yarn-project/end-to-end/src/e2e_amm.test.ts +++ b/yarn-project/end-to-end/src/e2e_amm.test.ts @@ -49,9 +49,9 @@ describe('AMM', () => { ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: liquidityToken } = await deployToken(wallet, adminAddress, 0n, logger)); - amm = await AMMContract.deploy(wallet, token0.address, token1.address, liquidityToken.address).send({ + ({ contract: amm } = await AMMContract.deploy(wallet, token0.address, token1.address, liquidityToken.address).send({ from: adminAddress, - }); + })); // TODO(#9480): consider deploying the token by some factory when the AMM is deployed, and making the AMM be the // minter there. @@ -81,15 +81,15 @@ describe('AMM', () => { async function getAmmBalances(): Promise { return { - token0: await token0.methods.balance_of_public(amm.address).simulate({ from: adminAddress }), - token1: await token1.methods.balance_of_public(amm.address).simulate({ from: adminAddress }), + token0: (await token0.methods.balance_of_public(amm.address).simulate({ from: adminAddress })).result, + token1: (await token1.methods.balance_of_public(amm.address).simulate({ from: adminAddress })).result, }; } async function getWalletBalances(lp: AztecAddress): Promise { return { - token0: await token0.methods.balance_of_private(lp).simulate({ from: lp }), - token1: await token1.methods.balance_of_private(lp).simulate({ from: lp }), + token0: (await token0.methods.balance_of_private(lp).simulate({ from: lp })).result, + token1: (await token1.methods.balance_of_private(lp).simulate({ from: lp })).result, }; } @@ -146,11 +146,13 @@ describe('AMM', () => { // Liquidity tokens should also be minted for the liquidity provider, as well as locked at the zero address. const expectedLiquidityTokens = (INITIAL_AMM_TOTAL_SUPPLY * 99n) / 100n; expect( - await liquidityToken.methods - .balance_of_private(liquidityProviderAddress) - .simulate({ from: liquidityProviderAddress }), + ( + await liquidityToken.methods + .balance_of_private(liquidityProviderAddress) + .simulate({ from: liquidityProviderAddress }) + ).result, ).toEqual(expectedLiquidityTokens); - expect(await liquidityToken.methods.total_supply().simulate({ from: adminAddress })).toEqual( + expect((await liquidityToken.methods.total_supply().simulate({ from: adminAddress })).result).toEqual( INITIAL_AMM_TOTAL_SUPPLY, ); }); @@ -162,7 +164,8 @@ describe('AMM', () => { const ammBalancesBefore = await getAmmBalances(); const lpBalancesBefore = await getWalletBalances(otherLiquidityProviderAddress); - const liquidityTokenSupplyBefore = await liquidityToken.methods.total_supply().simulate({ from: adminAddress }); + const liquidityTokenSupplyBefore = (await liquidityToken.methods.total_supply().simulate({ from: adminAddress })) + .result; // The pool currently has the same number of tokens for token0 and token1, since that is the ratio the first // liquidity provider used. Our maximum values have a different ratio (6:5 instead of 1:1), so we will end up @@ -214,11 +217,15 @@ describe('AMM', () => { (liquidityTokenSupplyBefore * (ammBalancesBefore.token0 + expectedAmount0)) / ammBalancesBefore.token0; const expectedLiquidityTokens = expectedTotalSupply - INITIAL_AMM_TOTAL_SUPPLY; - expect(await liquidityToken.methods.total_supply().simulate({ from: adminAddress })).toEqual(expectedTotalSupply); + expect((await liquidityToken.methods.total_supply().simulate({ from: adminAddress })).result).toEqual( + expectedTotalSupply, + ); expect( - await liquidityToken.methods - .balance_of_private(otherLiquidityProviderAddress) - .simulate({ from: otherLiquidityProviderAddress }), + ( + await liquidityToken.methods + .balance_of_private(otherLiquidityProviderAddress) + .simulate({ from: otherLiquidityProviderAddress }) + ).result, ).toEqual(expectedLiquidityTokens); }); @@ -239,9 +246,11 @@ describe('AMM', () => { // We compute the expected amount out and set it as the minimum. In a real-life scenario we'd choose a slightly // lower value to account for slippage, but since we're the only actor interacting with the AMM we can afford to // just pass the exact value. Of course any lower value would also suffice. - const amountOutMin = await amm.methods - .get_amount_out_for_exact_in(ammBalancesBefore.token0, ammBalancesBefore.token1, amountIn) - .simulate({ from: swapperAddress }); + const amountOutMin = ( + await amm.methods + .get_amount_out_for_exact_in(ammBalancesBefore.token0, ammBalancesBefore.token1, amountIn) + .simulate({ from: swapperAddress }) + ).result; const swapExactTokensInteraction = amm.methods .swap_exact_tokens_for_tokens(token0.address, token1.address, amountIn, amountOutMin, nonceForAuthwits) @@ -264,9 +273,11 @@ describe('AMM', () => { // query the contract for how much token0 we'd get if we sent our entire token1 balance, and then request exactly // that amount. This would fail in a real-life scenario since we'd need to account for slippage, but we can do it // in this test environment since there's nobody else interacting with the AMM. - const amountOut = await amm.methods - .get_amount_out_for_exact_in(ammBalancesBefore.token1, ammBalancesBefore.token0, swapperBalancesBefore.token1) - .simulate({ from: swapperAddress }); + const amountOut = ( + await amm.methods + .get_amount_out_for_exact_in(ammBalancesBefore.token1, ammBalancesBefore.token0, swapperBalancesBefore.token1) + .simulate({ from: swapperAddress }) + ).result; const amountInMax = swapperBalancesBefore.token1; // Swaps also transfer tokens into the AMM, so we provide an authwit for the full amount in (any change will be @@ -299,9 +310,11 @@ describe('AMM', () => { it('remove liquidity', async () => { // We now withdraw all of the tokens of one of the liquidity providers by burning their entire liquidity token // balance. - const liquidityTokenBalance = await liquidityToken.methods - .balance_of_private(otherLiquidityProviderAddress) - .simulate({ from: otherLiquidityProviderAddress }); + const liquidityTokenBalance = ( + await liquidityToken.methods + .balance_of_private(otherLiquidityProviderAddress) + .simulate({ from: otherLiquidityProviderAddress }) + ).result; // Because private burning requires first transferring the tokens into the AMM, we again need to provide an // authwit. @@ -328,9 +341,11 @@ describe('AMM', () => { // The liquidity provider should have no remaining liquidity tokens, and should have recovered the value they // originally deposited. expect( - await liquidityToken.methods - .balance_of_private(otherLiquidityProviderAddress) - .simulate({ from: otherLiquidityProviderAddress }), + ( + await liquidityToken.methods + .balance_of_private(otherLiquidityProviderAddress) + .simulate({ from: otherLiquidityProviderAddress }) + ).result, ).toEqual(0n); // We now assert that the liquidity provider ended up with more tokens than they began with. These extra tokens diff --git a/yarn-project/end-to-end/src/e2e_authwit.test.ts b/yarn-project/end-to-end/src/e2e_authwit.test.ts index adccc438291a..e978ab49e233 100644 --- a/yarn-project/end-to-end/src/e2e_authwit.test.ts +++ b/yarn-project/end-to-end/src/e2e_authwit.test.ts @@ -32,8 +32,8 @@ describe('e2e_authwit_tests', () => { } = await setup(2)); await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); - auth = await AuthWitTestContract.deploy(wallet).send({ from: account1Address }); - authwitProxy = await GenericProxyContract.deploy(wallet).send({ from: account1Address }); + ({ contract: auth } = await AuthWitTestContract.deploy(wallet).send({ from: account1Address })); + ({ contract: authwitProxy } = await GenericProxyContract.deploy(wallet).send({ from: account1Address })); }); describe('Private', () => { diff --git a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts index 07782ca8dd71..b40af1162298 100644 --- a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts +++ b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts @@ -36,11 +36,13 @@ describe('e2e_avm_simulator', () => { let secondAvmContract: AvmTestContract; beforeEach(async () => { - ({ contract: avmContract, instance: avmContractInstance } = await AvmTestContract.deploy(wallet).send({ + ({ + receipt: { contract: avmContract, instance: avmContractInstance }, + } = await AvmTestContract.deploy(wallet).send({ from: defaultAccountAddress, wait: { returnReceipt: true }, })); - secondAvmContract = await AvmTestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: secondAvmContract } = await AvmTestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); describe('Assertions & error enriching', () => { @@ -117,16 +119,18 @@ describe('e2e_avm_simulator', () => { describe('Storage', () => { it('Modifies storage (Field)', async () => { await avmContract.methods.set_storage_single(20n).send({ from: defaultAccountAddress }); - expect(await avmContract.methods.read_storage_single().simulate({ from: defaultAccountAddress })).toEqual(20n); + expect( + (await avmContract.methods.read_storage_single().simulate({ from: defaultAccountAddress })).result, + ).toEqual(20n); }); it('Modifies storage (Map)', async () => { const address = AztecAddress.fromBigInt(9090n); await avmContract.methods.set_storage_map(address, 100).send({ from: defaultAccountAddress }); await avmContract.methods.add_storage_map(address, 100).send({ from: defaultAccountAddress }); - expect(await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).toEqual( - 200n, - ); + expect( + (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, + ).toEqual(200n); }); it('Preserves storage across enqueued public calls', async () => { @@ -137,15 +141,15 @@ describe('e2e_avm_simulator', () => { avmContract.methods.add_storage_map(address, 100), ]).send({ from: defaultAccountAddress }); // On a separate tx, we check the result. - expect(await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).toEqual( - 200n, - ); + expect( + (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, + ).toEqual(200n); }); }); describe('Contract instance', () => { it('Works', async () => { - const tx = await avmContract.methods + const { receipt: tx } = await avmContract.methods .test_get_contract_instance_matches( avmContract.address, avmContractInstance.deployer, @@ -160,17 +164,21 @@ describe('e2e_avm_simulator', () => { describe('Nullifiers', () => { // Nullifier will not yet be siloed by the kernel. it('Emit and check in the same tx', async () => { - const tx = await avmContract.methods.emit_nullifier_and_check(123456).send({ from: defaultAccountAddress }); + const { receipt: tx } = await avmContract.methods + .emit_nullifier_and_check(123456) + .send({ from: defaultAccountAddress }); expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); }); // Nullifier will have been siloed by the kernel, but we check against the unsiloed one. it('Emit and check in separate tx', async () => { const nullifier = new Fr(123456); - let tx = await avmContract.methods.new_nullifier(nullifier).send({ from: defaultAccountAddress }); + let { receipt: tx } = await avmContract.methods.new_nullifier(nullifier).send({ from: defaultAccountAddress }); expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - tx = await avmContract.methods.assert_nullifier_exists(nullifier).send({ from: defaultAccountAddress }); + ({ receipt: tx } = await avmContract.methods + .assert_nullifier_exists(nullifier) + .send({ from: defaultAccountAddress })); expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); }); @@ -204,7 +212,9 @@ describe('e2e_avm_simulator', () => { it('Nested CALL instruction to non-existent contract returns failure, but caller can recover', async () => { // The nested call reverts (returns failure), but the caller doesn't HAVE to rethrow. - const tx = await avmContract.methods.nested_call_to_nothing_recovers().send({ from: defaultAccountAddress }); + const { receipt: tx } = await avmContract.methods + .nested_call_to_nothing_recovers() + .send({ from: defaultAccountAddress }); expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); }); it('Should NOT be able to emit the same unsiloed nullifier from the same contract', async () => { @@ -218,7 +228,7 @@ describe('e2e_avm_simulator', () => { it('Should be able to emit different unsiloed nullifiers from the same contract', async () => { const nullifier = new Fr(1); - const tx = await avmContract.methods + const { receipt: tx } = await avmContract.methods .create_different_nullifier_in_nested_call(avmContract.address, nullifier) .send({ from: defaultAccountAddress }); expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); @@ -226,7 +236,7 @@ describe('e2e_avm_simulator', () => { it('Should be able to emit the same unsiloed nullifier from two different contracts', async () => { const nullifier = new Fr(1); - const tx = await avmContract.methods + const { receipt: tx } = await avmContract.methods .create_same_nullifier_in_nested_call(secondAvmContract.address, nullifier) .send({ from: defaultAccountAddress }); expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); @@ -234,7 +244,7 @@ describe('e2e_avm_simulator', () => { it('Should be able to emit different unsiloed nullifiers from two different contracts', async () => { const nullifier = new Fr(1); - const tx = await avmContract.methods + const { receipt: tx } = await avmContract.methods .create_different_nullifier_in_nested_call(secondAvmContract.address, nullifier) .send({ from: defaultAccountAddress }); expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); @@ -246,14 +256,16 @@ describe('e2e_avm_simulator', () => { let avmContract: AvmInitializerTestContract; beforeEach(async () => { - avmContract = await AvmInitializerTestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: avmContract } = await AvmInitializerTestContract.deploy(wallet).send({ + from: defaultAccountAddress, + })); }); describe('Storage', () => { it('Read immutable (initialized) storage (Field)', async () => { - expect(await avmContract.methods.read_storage_immutable().simulate({ from: defaultAccountAddress })).toEqual( - 42n, - ); + expect( + (await avmContract.methods.read_storage_immutable().simulate({ from: defaultAccountAddress })).result, + ).toEqual(42n); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts index 97e8bbb19c23..76f015066d44 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts @@ -23,7 +23,7 @@ describe('e2e_blacklist_token_contract access control', () => { await t.crossTimestampOfChange(); - expect(await t.asset.methods.get_roles(t.adminAddress).simulate({ from: t.adminAddress })).toEqual( + expect((await t.asset.methods.get_roles(t.adminAddress).simulate({ from: t.adminAddress })).result).toEqual( adminMinterRole.toNoirStruct(), ); }); @@ -34,7 +34,7 @@ describe('e2e_blacklist_token_contract access control', () => { await t.crossTimestampOfChange(); - expect(await t.asset.methods.get_roles(t.otherAddress).simulate({ from: t.adminAddress })).toEqual( + expect((await t.asset.methods.get_roles(t.otherAddress).simulate({ from: t.adminAddress })).result).toEqual( adminRole.toNoirStruct(), ); }); @@ -45,7 +45,7 @@ describe('e2e_blacklist_token_contract access control', () => { await t.crossTimestampOfChange(); - expect(await t.asset.methods.get_roles(t.otherAddress).simulate({ from: t.adminAddress })).toEqual( + expect((await t.asset.methods.get_roles(t.otherAddress).simulate({ from: t.adminAddress })).result).toEqual( noRole.toNoirStruct(), ); }); @@ -58,7 +58,7 @@ describe('e2e_blacklist_token_contract access control', () => { await t.crossTimestampOfChange(); - expect(await t.asset.methods.get_roles(t.blacklistedAddress).simulate({ from: t.adminAddress })).toEqual( + expect((await t.asset.methods.get_roles(t.blacklistedAddress).simulate({ from: t.adminAddress })).result).toEqual( blacklistRole.toNoirStruct(), ); }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts index 22cad7213ca5..5fc0640a8079 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts @@ -107,20 +107,24 @@ export class BlacklistTokenContractTest { await publicDeployAccounts(this.wallet, [this.adminAddress, this.otherAddress, this.blacklistedAddress]); this.logger.verbose(`Deploying TokenContract...`); - this.asset = await TokenBlacklistContract.deploy(this.wallet, this.adminAddress).send({ + ({ contract: this.asset } = await TokenBlacklistContract.deploy(this.wallet, this.adminAddress).send({ from: this.adminAddress, - }); + })); this.logger.verbose(`Token deployed to ${this.asset.address}`); this.logger.verbose(`Deploying bad account...`); - this.badAccount = await InvalidAccountContract.deploy(this.wallet).send({ from: this.adminAddress }); + ({ contract: this.badAccount } = await InvalidAccountContract.deploy(this.wallet).send({ + from: this.adminAddress, + })); this.logger.verbose(`Deployed to ${this.badAccount.address}.`); // Deploy a proxy contract for "on behalf of other" tests. The note owner must be the tx sender // (so their notes are in scope), but msg_sender in the target must differ from the note owner // to trigger authwit validation. The proxy forwards calls so that msg_sender != tx sender. this.logger.verbose(`Deploying generic proxy...`); - this.authwitProxy = await GenericProxyContract.deploy(this.wallet).send({ from: this.adminAddress }); + ({ contract: this.authwitProxy } = await GenericProxyContract.deploy(this.wallet).send({ + from: this.adminAddress, + })); this.logger.verbose(`Deployed to ${this.authwitProxy.address}.`); await this.crossTimestampOfChange(); @@ -133,9 +137,9 @@ export class BlacklistTokenContractTest { [this.adminAddress, this.otherAddress, this.blacklistedAddress], ); - expect(await this.asset.methods.get_roles(this.adminAddress).simulate({ from: this.adminAddress })).toEqual( - new Role().withAdmin().toNoirStruct(), - ); + expect( + (await this.asset.methods.get_roles(this.adminAddress).simulate({ from: this.adminAddress })).result, + ).toEqual(new Role().withAdmin().toNoirStruct()); } async setup() { @@ -189,9 +193,9 @@ export class BlacklistTokenContractTest { await this.crossTimestampOfChange(); - expect(await this.asset.methods.get_roles(this.adminAddress).simulate({ from: this.adminAddress })).toEqual( - adminMinterRole.toNoirStruct(), - ); + expect( + (await this.asset.methods.get_roles(this.adminAddress).simulate({ from: this.adminAddress })).result, + ).toEqual(adminMinterRole.toNoirStruct()); this.logger.verbose(`Minting ${amount} publicly...`); await asset.methods.mint_public(this.adminAddress, amount).send({ from: this.adminAddress }); @@ -199,7 +203,7 @@ export class BlacklistTokenContractTest { this.logger.verbose(`Minting ${amount} privately...`); const secret = Fr.random(); const secretHash = await computeSecretHash(secret); - const receipt = await asset.methods.mint_private(amount, secretHash).send({ from: this.adminAddress }); + const { receipt } = await asset.methods.mint_private(amount, secretHash).send({ from: this.adminAddress }); await this.addPendingShieldNoteToPXE(asset, this.adminAddress, amount, secretHash, receipt.txHash); await asset.methods.redeem_shield(this.adminAddress, amount, secret).send({ from: this.adminAddress }); @@ -207,20 +211,20 @@ export class BlacklistTokenContractTest { tokenSim.mintPublic(this.adminAddress, amount); - const publicBalance = await asset.methods + const { result: publicBalance } = await asset.methods .balance_of_public(this.adminAddress) .simulate({ from: this.adminAddress }); this.logger.verbose(`Public balance of wallet 0: ${publicBalance}`); expect(publicBalance).toEqual(this.tokenSim.balanceOfPublic(this.adminAddress)); tokenSim.mintPrivate(this.adminAddress, amount); - const privateBalance = await asset.methods + const { result: privateBalance } = await asset.methods .balance_of_private(this.adminAddress) .simulate({ from: this.adminAddress }); this.logger.verbose(`Private balance of wallet 0: ${privateBalance}`); expect(privateBalance).toEqual(tokenSim.balanceOfPrivate(this.adminAddress)); - const totalSupply = await asset.methods.total_supply().simulate({ from: this.adminAddress }); + const { result: totalSupply } = await asset.methods.total_supply().simulate({ from: this.adminAddress }); this.logger.verbose(`Total supply: ${totalSupply}`); expect(totalSupply).toEqual(tokenSim.totalSupply); } diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts index 6028b6173922..9b8b28204e15 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts @@ -27,7 +27,10 @@ describe('e2e_blacklist_token_contract burn', () => { describe('public', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.burn_public(adminAddress, amount, 0).send({ from: adminAddress }); @@ -36,7 +39,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const authwitNonce = Fr.random(); @@ -61,7 +67,10 @@ describe('e2e_blacklist_token_contract burn', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = 0; await expect( @@ -70,7 +79,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); const authwitNonce = 1; @@ -82,7 +94,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = Fr.random(); await expect( @@ -91,7 +106,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -109,7 +127,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -138,7 +159,10 @@ describe('e2e_blacklist_token_contract burn', () => { describe('private', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.burn(adminAddress, amount, 0).send({ from: adminAddress }); @@ -146,7 +170,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -166,7 +193,10 @@ describe('e2e_blacklist_token_contract burn', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); await expect(asset.methods.burn(adminAddress, amount, 0).simulate({ from: adminAddress })).rejects.toThrow( @@ -175,7 +205,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); await expect(asset.methods.burn(adminAddress, amount, 1).simulate({ from: adminAddress })).rejects.toThrow( @@ -184,7 +217,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -199,7 +235,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('burn on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -218,7 +257,10 @@ describe('e2e_blacklist_token_contract burn', () => { }); it('on behalf of other (invalid designated caller)', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts index f1386cfa812a..3e704d342355 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts @@ -86,9 +86,11 @@ describe('e2e_blacklist_token_contract mint', () => { describe('Mint flow', () => { it('mint_private as minter and redeem as recipient', async () => { - const balanceBefore = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balanceBefore } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); - const receipt = await asset.methods.mint_private(amount, secretHash).send({ from: adminAddress }); + const { receipt } = await asset.methods.mint_private(amount, secretHash).send({ from: adminAddress }); txHash = receipt.txHash; await t.addPendingShieldNoteToPXE(asset, adminAddress, amount, secretHash, txHash); @@ -96,7 +98,9 @@ describe('e2e_blacklist_token_contract mint', () => { await asset.methods.redeem_shield(adminAddress, amount, secret).send({ from: adminAddress }); tokenSim.mintPrivate(adminAddress, amount); - const balanceAfter = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balanceAfter } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); expect(balanceAfter).toBe(balanceBefore + amount); }); }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts index b09cb1d9b9c2..7ac49c276345 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts @@ -31,11 +31,14 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { }); it('on behalf of self', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balancePub = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePub / 2n; expect(amount).toBeGreaterThan(0n); - const receipt = await asset.methods.shield(adminAddress, amount, secretHash, 0).send({ from: adminAddress }); + const { receipt } = await asset.methods.shield(adminAddress, amount, secretHash, 0).send({ from: adminAddress }); // Redeem it await t.addPendingShieldNoteToPXE(asset, adminAddress, amount, secretHash, receipt.txHash); @@ -47,7 +50,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { }); it('on behalf of other', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balancePub = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePub / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -61,7 +67,7 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { ); await validateActionInteraction.send(); - const receipt = await action.send({ from: otherAddress }); + const { receipt } = await action.send({ from: otherAddress }); // Check that replaying the shield should fail! await expect( @@ -79,7 +85,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { describe('failure cases', () => { it('on behalf of self (more than balance)', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balancePub = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePub + 1n; expect(amount).toBeGreaterThan(0n); @@ -89,7 +98,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { }); it('on behalf of self (invalid authwit nonce)', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balancePub = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePub + 1n; expect(amount).toBeGreaterThan(0n); @@ -101,7 +113,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { }); it('on behalf of other (more than balance)', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balancePub = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePub + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -119,7 +134,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { }); it('on behalf of other (wrong designated caller)', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balancePub = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePub + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -137,7 +155,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { }); it('on behalf of other (without approval)', async () => { - const balance = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts index 87fc616cd1e3..88bbbf428fd5 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts @@ -26,7 +26,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { }); it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const tokenTransferInteraction = asset.methods.transfer(adminAddress, otherAddress, amount, 0); @@ -35,7 +38,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { }); it('transfer to self', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); @@ -44,7 +50,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -64,7 +73,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); @@ -74,7 +86,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { }); it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); @@ -86,8 +101,14 @@ describe('e2e_blacklist_token_contract transfer private', () => { }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); - const balance1 = await asset.methods.balance_of_private(otherAddress).simulate({ from: otherAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); + const balance1 = await asset.methods + .balance_of_private(otherAddress) + .simulate({ from: otherAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -99,8 +120,18 @@ describe('e2e_blacklist_token_contract transfer private', () => { await expect( simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }), ).rejects.toThrow('Assertion failed: Balance too low'); - expect(await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); - expect(await asset.methods.balance_of_private(otherAddress).simulate({ from: otherAddress })).toEqual(balance1); + expect( + await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result), + ).toEqual(balance0); + expect( + await asset.methods + .balance_of_private(otherAddress) + .simulate({ from: otherAddress }) + .then(r => r.result), + ).toEqual(balance1); }); it.skip('transfer into account to overflow', () => { @@ -111,7 +142,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { }); it('transfer on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -130,7 +164,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -148,7 +185,12 @@ describe('e2e_blacklist_token_contract transfer private', () => { await expect( simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }), ).rejects.toThrow(`Unknown auth witness for message hash ${expectedMessageHash.toString()}`); - expect(await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); + expect( + await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result), + ).toEqual(balance0); }); it('transfer from a blacklisted account', async () => { diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts index c5d23f421bbd..2862a3c735e7 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts @@ -24,7 +24,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { }); it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_public(adminAddress, otherAddress, amount, 0).send({ from: adminAddress }); @@ -33,7 +36,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { }); it('transfer to self', async () => { - const balance = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_public(adminAddress, adminAddress, amount, 0).send({ from: adminAddress }); @@ -42,7 +48,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const authwitNonce = Fr.random(); @@ -68,7 +77,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = 0; await expect( @@ -79,7 +91,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { }); it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 - 1n; const authwitNonce = 1; await expect( @@ -92,7 +107,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { }); it('transfer on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = Fr.random(); await expect( @@ -103,8 +121,14 @@ describe('e2e_blacklist_token_contract transfer public', () => { }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); - const balance1 = await asset.methods.balance_of_public(otherAddress).simulate({ from: otherAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); + const balance1 = await asset.methods + .balance_of_public(otherAddress) + .simulate({ from: otherAddress }) + .then(r => r.result); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -121,13 +145,29 @@ describe('e2e_blacklist_token_contract transfer public', () => { // Perform the transfer await expect(action.simulate({ from: otherAddress })).rejects.toThrow(U128_UNDERFLOW_ERROR); - expect(await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); - expect(await asset.methods.balance_of_public(otherAddress).simulate({ from: otherAddress })).toEqual(balance1); + expect( + await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result), + ).toEqual(balance0); + expect( + await asset.methods + .balance_of_public(otherAddress) + .simulate({ from: otherAddress }) + .then(r => r.result), + ).toEqual(balance1); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); - const balance1 = await asset.methods.balance_of_public(otherAddress).simulate({ from: otherAddress }); + const balance0 = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); + const balance1 = await asset.methods + .balance_of_public(otherAddress) + .simulate({ from: otherAddress }) + .then(r => r.result); const amount = balance0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -145,8 +185,18 @@ describe('e2e_blacklist_token_contract transfer public', () => { // Perform the transfer await expect(action.simulate({ from: otherAddress })).rejects.toThrow(/unauthorized/); - expect(await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); - expect(await asset.methods.balance_of_public(otherAddress).simulate({ from: otherAddress })).toEqual(balance1); + expect( + await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result), + ).toEqual(balance0); + expect( + await asset.methods + .balance_of_public(otherAddress) + .simulate({ from: otherAddress }) + .then(r => r.result), + ).toEqual(balance1); }); it.skip('transfer into account to overflow', () => { diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts index ae10ada9661d..9547b5b992dd 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts @@ -26,7 +26,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { }); it('on behalf of self', async () => { - const balancePriv = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balancePriv = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePriv / 2n; expect(amount).toBeGreaterThan(0n); @@ -36,7 +39,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { }); it('on behalf of other', async () => { - const balancePriv0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balancePriv0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePriv0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -56,7 +62,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { describe('failure cases', () => { it('on behalf of self (more than balance)', async () => { - const balancePriv = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balancePriv = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); @@ -66,7 +75,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { }); it('on behalf of self (invalid authwit nonce)', async () => { - const balancePriv = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balancePriv = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); @@ -78,7 +90,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { }); it('on behalf of other (more than balance)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balancePriv0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePriv0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -93,7 +108,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { }); it('on behalf of other (invalid designated caller)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const balancePriv0 = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }) + .then(r => r.result); const amount = balancePriv0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index 21aa382720ac..23b17b5d98f6 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -16,6 +16,7 @@ import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import type { SequencerClient } from '@aztec/sequencer-client'; import type { TestSequencerClient } from '@aztec/sequencer-client/test'; import { getProofSubmissionDeadlineEpoch } from '@aztec/stdlib/epoch-helpers'; +import { GasFees } from '@aztec/stdlib/gas'; import { computeSiloedPrivateLogFirstField } from '@aztec/stdlib/hash'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; @@ -84,7 +85,7 @@ describe('e2e_block_building', () => { // so many so that we don't end up hitting a reorg or timing out the tx wait(). const TX_COUNT = 16; - const contract = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + const { contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); logger.info(`Deployed stateful test contract at ${contract.address}`); // We add a delay to every public tx processing @@ -165,7 +166,7 @@ describe('e2e_block_building', () => { it('assembles a block with multiple txs with public fns', async () => { // First deploy the contract - const contract = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + const { contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); // Assemble N contract deployment txs // We need to create them sequentially since we cannot have parallel calls to a circuit @@ -194,8 +195,8 @@ describe('e2e_block_building', () => { // Skipped since we only use it to manually test number of invocations to world-state. it.skip('builds blocks with multiple public fns after multiple nullifier insertions', async () => { // First deploy the contracts - const contract = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); - const another = await TestContract.deploy(wallet).send({ from: ownerAddress }); + const { contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + const { contract: another } = await TestContract.deploy(wallet).send({ from: ownerAddress }); await aztecNodeAdmin.setConfig({ minTxsPerBlock: 16, maxTxsPerBlock: 16 }); @@ -243,12 +244,23 @@ describe('e2e_block_building', () => { [minterAddress, true], ); - const [deployTxReceipt, callTxReceipt] = await Promise.all([ - deployMethod.send({ from: ownerAddress, wait: { returnReceipt: true } }), - callInteraction.send({ from: ownerAddress }), + // Use priority fees to guarantee ordering: deploy tx gets higher priority so the + // sequencer places it before the call tx in the block. + const highPriority = new GasFees(100, 100); + const lowPriority = new GasFees(1, 1); + + const [deployResult, callResult] = await Promise.all([ + deployMethod.send({ + from: ownerAddress, + fee: { gasSettings: { maxPriorityFeesPerGas: highPriority } }, + }), + callInteraction.send({ + from: ownerAddress, + fee: { gasSettings: { maxPriorityFeesPerGas: lowPriority } }, + }), ]); - expect(deployTxReceipt.blockNumber).toEqual(callTxReceipt.blockNumber); + expect(deployResult.receipt.blockNumber).toEqual(callResult.receipt.blockNumber); }); }); @@ -263,7 +275,7 @@ describe('e2e_block_building', () => { wallet, accounts: [ownerAddress], } = await setup(1)); - contract = await TestContract.deploy(wallet).send({ from: ownerAddress }); + ({ contract } = await TestContract.deploy(wallet).send({ from: ownerAddress })); logger.info(`Test contract deployed at ${contract.address}`); }); @@ -391,7 +403,7 @@ describe('e2e_block_building', () => { } = await setup(1)); logger.info(`Deploying test contract`); - testContract = await TestContract.deploy(wallet).send({ from: ownerAddress }); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: ownerAddress })); }, 60_000); afterAll(() => teardown()); @@ -495,9 +507,11 @@ describe('e2e_block_building', () => { })); logger.info('Deploying token contract'); - const token = await TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18).send({ - from: ownerAddress, - }); + const { contract: token } = await TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18).send( + { + from: ownerAddress, + }, + ); logger.info('Updating txs per block to 4'); await aztecNodeAdmin.setConfig({ minTxsPerBlock: 4, maxTxsPerBlock: 4 }); @@ -530,7 +544,7 @@ describe('e2e_block_building', () => { accounts: [ownerAddress], } = context); - const testContract = await TestContract.deploy(wallet).send({ from: ownerAddress }); + const { contract: testContract } = await TestContract.deploy(wallet).send({ from: ownerAddress }); logger.warn(`Test contract deployed at ${testContract.address}`); // We want the sequencer to wait until both txs have arrived (so minTxsPerBlock=2), but agree to build @@ -549,7 +563,8 @@ describe('e2e_block_building', () => { ]); const batches = times(2, makeBatch); - const txHashes = await Promise.all(batches.map(batch => batch.send({ from: ownerAddress, wait: NO_WAIT }))); + const txHashResults = await Promise.all(batches.map(batch => batch.send({ from: ownerAddress, wait: NO_WAIT }))); + const txHashes = txHashResults.map(({ txHash }) => txHash); logger.warn(`Sent two txs to test contract`, { txs: txHashes.map(hash => hash.toString()) }); await Promise.race(txHashes.map(txHash => waitForTx(aztecNode, txHash, { timeout: 60 }))); @@ -581,7 +596,7 @@ describe('e2e_block_building', () => { accounts: [ownerAddress], } = await setup(1)); - contract = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + ({ contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress })); initialBlockNumber = await aztecNode.getBlockNumber(); logger.info(`Stateful test contract deployed at ${contract.address}`); @@ -605,15 +620,15 @@ describe('e2e_block_building', () => { // Send a tx to the contract that creates a note. This tx will be reorgd but re-included, // since it is being built against a proven block number. logger.info('Sending initial tx'); - const tx1 = await contract.methods.create_note(ownerAddress, 20).send({ from: ownerAddress }); + const { receipt: tx1 } = await contract.methods.create_note(ownerAddress, 20).send({ from: ownerAddress }); expect(tx1.blockNumber).toEqual(initialBlockNumber + 1); - expect(await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).toEqual(21n); + expect((await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).result).toEqual(21n); // And send a second one, which won't be re-included. logger.info('Sending second tx'); - const tx2 = await contract.methods.create_note(ownerAddress, 30).send({ from: ownerAddress }); + const { receipt: tx2 } = await contract.methods.create_note(ownerAddress, 30).send({ from: ownerAddress }); expect(tx2.blockNumber).toEqual(initialBlockNumber + 2); - expect(await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).toEqual(51n); + expect((await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).result).toEqual(51n); logger.info('Advancing past the proof submission window'); @@ -648,12 +663,12 @@ describe('e2e_block_building', () => { expect(newTx1Receipt.blockHash).not.toEqual(tx1.blockHash); // PXE should have cleared out the 30-note from tx2, but reapplied the 20-note from tx1 - expect(await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).toEqual(21n); + expect((await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).result).toEqual(21n); // And we should be able to send a new tx on the new chain logger.info('Sending new tx on reorgd chain'); - const tx3 = await contract.methods.create_note(ownerAddress, 10).send({ from: ownerAddress }); - expect(await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).toEqual(31n); + const { receipt: tx3 } = await contract.methods.create_note(ownerAddress, 10).send({ from: ownerAddress }); + expect((await contract.methods.summed_values(ownerAddress).simulate({ from: ownerAddress })).result).toEqual(31n); expect(tx3.blockNumber).toBeGreaterThanOrEqual(newTx1Receipt.blockNumber! + 1); }); }); diff --git a/yarn-project/end-to-end/src/e2e_card_game.test.ts b/yarn-project/end-to-end/src/e2e_card_game.test.ts index 56e05017370b..6f387d27e51c 100644 --- a/yarn-project/end-to-end/src/e2e_card_game.test.ts +++ b/yarn-project/end-to-end/src/e2e_card_game.test.ts @@ -104,7 +104,7 @@ describe('e2e_card_game', () => { const deployContract = async () => { logger.debug(`Deploying L2 contract...`); - contract = await CardGameContract.deploy(wallet).send({ from: firstPlayer }); + ({ contract } = await CardGameContract.deploy(wallet).send({ from: firstPlayer })); logger.info(`L2 contract deployed at ${contract.address}`); }; @@ -113,7 +113,9 @@ describe('e2e_card_game', () => { // docs:start:send_tx await contract.methods.buy_pack(seed).send({ from: firstPlayer }); // docs:end:send_tx - const collection = await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }); + const { result: collection } = await contract.methods + .view_collection_cards(firstPlayer, 0) + .simulate({ from: firstPlayer }); const expected = await getPackedCards(0, seed); expect(boundedVecToArray(collection)).toMatchObject(expected); }); @@ -128,7 +130,7 @@ describe('e2e_card_game', () => { contract.methods.buy_pack(seed).send({ from: secondPlayer }), ]); firstPlayerCollection = boundedVecToArray( - await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }), + (await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer })).result, ); }); @@ -143,11 +145,13 @@ describe('e2e_card_game', () => { .send({ from: secondPlayer }), ).rejects.toThrow(`Not all cards were removed`); - const collection = await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }); + const { result: collection } = await contract.methods + .view_collection_cards(firstPlayer, 0) + .simulate({ from: firstPlayer }); expect(boundedVecToArray(collection)).toHaveLength(1); expect(boundedVecToArray(collection)).toMatchObject([firstPlayerCollection[1]]); - expect((await contract.methods.view_game(GAME_ID).simulate({ from: firstPlayer })) as Game).toMatchObject({ + expect((await contract.methods.view_game(GAME_ID).simulate({ from: firstPlayer })).result as Game).toMatchObject({ players: [ { address: firstPlayer, @@ -169,9 +173,8 @@ describe('e2e_card_game', () => { it('should start games', async () => { const secondPlayerCollection = boundedVecToArray( - (await contract.methods - .view_collection_cards(secondPlayer, 0) - .simulate({ from: secondPlayer })) as NoirBoundedVec, + (await contract.methods.view_collection_cards(secondPlayer, 0).simulate({ from: secondPlayer })) + .result as NoirBoundedVec, ); await Promise.all([ @@ -185,7 +188,7 @@ describe('e2e_card_game', () => { await contract.methods.start_game(GAME_ID).send({ from: firstPlayer }); - expect((await contract.methods.view_game(GAME_ID).simulate({ from: firstPlayer })) as Game).toMatchObject({ + expect((await contract.methods.view_game(GAME_ID).simulate({ from: firstPlayer })).result as Game).toMatchObject({ players: expect.arrayContaining([ { address: firstPlayer, @@ -220,15 +223,15 @@ describe('e2e_card_game', () => { ]); firstPlayerCollection = boundedVecToArray( - await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }), + (await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer })).result, ); secondPlayerCollection = boundedVecToArray( - await contract.methods.view_collection_cards(secondPlayer, 0).simulate({ from: secondPlayer }), + (await contract.methods.view_collection_cards(secondPlayer, 0).simulate({ from: secondPlayer })).result, ); thirdPlayerCOllection = boundedVecToArray( - await contract.methods.view_collection_cards(thirdPlayer, 0).simulate({ from: thirdPlayer }), + (await contract.methods.view_collection_cards(thirdPlayer, 0).simulate({ from: thirdPlayer })).result, ); }); @@ -240,7 +243,7 @@ describe('e2e_card_game', () => { } async function playGame(playerDecks: { address: AztecAddress; deck: Card[] }[], id = GAME_ID) { - const initialGameState = (await contract.methods.view_game(id).simulate({ from: firstPlayer })) as Game; + const initialGameState = (await contract.methods.view_game(id).simulate({ from: firstPlayer })).result as Game; const players = initialGameState.players.map(player => player.address); const cards = players.map( player => playerDecks.find(playerDeckEntry => playerDeckEntry.address.equals(player))!.deck, @@ -254,7 +257,7 @@ describe('e2e_card_game', () => { } } - const finalGameState = (await contract.methods.view_game(id).simulate({ from: firstPlayer })) as Game; + const finalGameState = (await contract.methods.view_game(id).simulate({ from: firstPlayer })).result as Game; expect(finalGameState.finished).toBe(true); return finalGameState; @@ -285,7 +288,8 @@ describe('e2e_card_game', () => { await contract.methods.claim_cards(GAME_ID, game.rounds_cards.map(cardToField)).send({ from: winner }); const winnerCollection = boundedVecToArray( - (await contract.methods.view_collection_cards(winner, 0).simulate({ from: winner })) as NoirBoundedVec, + (await contract.methods.view_collection_cards(winner, 0).simulate({ from: winner })) + .result as NoirBoundedVec, ); const winnerGameDeck = [winnerCollection[0], winnerCollection[3]]; diff --git a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts index 10bf16f3e987..e34cedae2e97 100644 --- a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts +++ b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts @@ -110,7 +110,9 @@ describe('e2e_contract_updates', () => { } sequencer = maybeSequencer; - ({ contract, instance } = await UpdatableContract.deploy(wallet, constructorArgs[0]).send({ + ({ + receipt: { contract, instance }, + } = await UpdatableContract.deploy(wallet, constructorArgs[0]).send({ from: defaultAccountAddress, contractAddressSalt: salt, wait: { returnReceipt: true }, @@ -126,9 +128,10 @@ describe('e2e_contract_updates', () => { it('should update the contract', async () => { expect( - await contract.methods.get_private_value(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + (await contract.methods.get_private_value(defaultAccountAddress).simulate({ from: defaultAccountAddress })) + .result, ).toEqual(INITIAL_UPDATABLE_CONTRACT_VALUE); - expect(await contract.methods.get_public_value().simulate({ from: defaultAccountAddress })).toEqual( + expect((await contract.methods.get_public_value().simulate({ from: defaultAccountAddress })).result).toEqual( INITIAL_UPDATABLE_CONTRACT_VALUE, ); await contract.methods.update_to(updatedContractClassId).send({ from: defaultAccountAddress }); @@ -141,18 +144,19 @@ describe('e2e_contract_updates', () => { await updatedContract.methods.set_private_value().send({ from: defaultAccountAddress }); // Read state that was changed by the previous tx expect( - await updatedContract.methods.get_private_value(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + (await updatedContract.methods.get_private_value(defaultAccountAddress).simulate({ from: defaultAccountAddress })) + .result, ).toEqual(UPDATED_CONTRACT_PUBLIC_VALUE); // Call a public method with a new implementation await updatedContract.methods.set_public_value().send({ from: defaultAccountAddress }); - expect(await updatedContract.methods.get_public_value().simulate({ from: defaultAccountAddress })).toEqual( + expect((await updatedContract.methods.get_public_value().simulate({ from: defaultAccountAddress })).result).toEqual( UPDATED_CONTRACT_PUBLIC_VALUE, ); }); it('should change the update delay and then update the contract', async () => { - expect(await contract.methods.get_update_delay().simulate({ from: defaultAccountAddress })).toEqual( + expect((await contract.methods.get_update_delay().simulate({ from: defaultAccountAddress })).result).toEqual( BigInt(DEFAULT_TEST_UPDATE_DELAY), ); @@ -161,7 +165,7 @@ describe('e2e_contract_updates', () => { .set_update_delay(BigInt(DEFAULT_TEST_UPDATE_DELAY) + 1n) .send({ from: defaultAccountAddress }); - expect(await contract.methods.get_update_delay().simulate({ from: defaultAccountAddress })).toEqual( + expect((await contract.methods.get_update_delay().simulate({ from: defaultAccountAddress })).result).toEqual( BigInt(DEFAULT_TEST_UPDATE_DELAY) + 1n, ); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts index ec5ecbe78b57..3f12389109ac 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts @@ -34,7 +34,7 @@ describe('e2e_cross_chain_messaging l1_to_l2', () => { await t.setup(); ({ logger: log, crossChainTestHarness, wallet, user1Address, aztecNode } = t); - testContract = await TestContract.deploy(wallet).send({ from: user1Address }); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: user1Address })); }, 300_000); afterEach(async () => { @@ -255,7 +255,7 @@ describe('e2e_cross_chain_messaging l1_to_l2', () => { // We send a transaction, this advances the chain and the message MIGHT be consumed in the new block. // If it does get consumed then we check that the block contains the message. // If it fails we check that the block doesn't contain the message - const receipt = await consume().send({ from: user1Address, wait: { dontThrowOnRevert: true } }); + const { receipt } = await consume().send({ from: user1Address, wait: { dontThrowOnRevert: true } }); if (receipt.executionResult === TxExecutionResult.SUCCESS) { // The block the transaction included should be for the message checkpoint number // and be the first block in the checkpoint diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts index 7432bd33d4f3..d747d3ef6666 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts @@ -43,7 +43,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { version = BigInt(await rollup.getVersion()); - contract = await TestContract.deploy(wallet).send({ from: user1Address }); + ({ contract } = await TestContract.deploy(wallet).send({ from: user1Address })); }); afterAll(async () => { @@ -60,7 +60,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { // Configure the node to be able to rollup only 1 tx. await aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); - const txReceipt = await new BatchCall(wallet, [ + const { receipt: txReceipt } = await new BatchCall(wallet, [ contract.methods.create_l2_to_l1_message_arbitrary_recipient_private(contents[0], recipient), contract.methods.create_l2_to_l1_message_arbitrary_recipient_public(contents[1], recipient), ]).send({ from: user1Address }); @@ -92,7 +92,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { await aztecNodeAdmin.setConfig({ minTxsPerBlock: 2 }); // Send the 2 txs. - const [noMessageReceipt, withMessageReceipt] = await Promise.all([ + const [{ receipt: noMessageReceipt }, { receipt: withMessageReceipt }] = await Promise.all([ contract.methods.emit_nullifier(Fr.random()).send({ from: user1Address }), contract.methods .create_l2_to_l1_message_arbitrary_recipient_private(content, recipient) @@ -119,7 +119,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { const call0 = createBatchCall(wallet, tx0.recipients, tx0.contents); const call1 = createBatchCall(wallet, tx1.recipients, tx1.contents); - const [l2TxReceipt0, l2TxReceipt1] = await Promise.all([ + const [{ receipt: l2TxReceipt0 }, { receipt: l2TxReceipt1 }] = await Promise.all([ call0.send({ from: user1Address }), call1.send({ from: user1Address }), ]); @@ -173,7 +173,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { const call1 = createBatchCall(wallet, tx1.recipients, tx1.contents); const call2 = createBatchCall(wallet, tx2.recipients, tx2.contents); - const [l2TxReceipt0, l2TxReceipt1, l2TxReceipt2] = await Promise.all([ + const [{ receipt: l2TxReceipt0 }, { receipt: l2TxReceipt1 }, { receipt: l2TxReceipt2 }] = await Promise.all([ call0.send({ from: user1Address }), call1.send({ from: user1Address }), call2.send({ from: user1Address }), diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index e82734a14b15..7da34cf384a2 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -43,7 +43,7 @@ describe('e2e_crowdfunding_and_claim', () => { let crowdfundingContract: CrowdfundingContract; let claimContract: ClaimContract; - let crowdfundingSecretKey; + let crowdfundingSecretKey: Fr; let crowdfundingPublicKeys: PublicKeys; let cheatCodes: CheatCodes; let deadline: number; // end of crowdfunding period @@ -62,22 +62,22 @@ describe('e2e_crowdfunding_and_claim', () => { // We set the deadline to a week from now deadline = (await cheatCodes.eth.timestamp()) + 7 * 24 * 60 * 60; - donationToken = await TokenContract.deploy( + ({ contract: donationToken } = await TokenContract.deploy( wallet, operatorAddress, donationTokenMetadata.name, donationTokenMetadata.symbol, donationTokenMetadata.decimals, - ).send({ from: operatorAddress }); + ).send({ from: operatorAddress })); logger.info(`Donation Token deployed to ${donationToken.address}`); - rewardToken = await TokenContract.deploy( + ({ contract: rewardToken } = await TokenContract.deploy( wallet, operatorAddress, rewardTokenMetadata.name, rewardTokenMetadata.symbol, rewardTokenMetadata.decimals, - ).send({ from: operatorAddress }); + ).send({ from: operatorAddress })); logger.info(`Reward Token deployed to ${rewardToken.address}`); // We deploy the Crowdfunding contract as an escrow contract (i.e. with populated public keys that make it @@ -94,12 +94,20 @@ describe('e2e_crowdfunding_and_claim', () => { ); const crowdfundingInstance = await crowdfundingDeployment.getInstance(); await wallet.registerContract(crowdfundingInstance, CrowdfundingContract.artifact, crowdfundingSecretKey); - crowdfundingContract = await crowdfundingDeployment.send({ from: operatorAddress }); + ({ contract: crowdfundingContract } = await crowdfundingDeployment.send({ + from: operatorAddress, + // The contract constructor initializes private storage vars that need the contract's own nullifier key. + additionalScopes: [crowdfundingInstance.address], + })); logger.info(`Crowdfunding contract deployed at ${crowdfundingContract.address}`); - claimContract = await ClaimContract.deploy(wallet, crowdfundingContract.address, rewardToken.address).send({ + ({ contract: claimContract } = await ClaimContract.deploy( + wallet, + crowdfundingContract.address, + rewardToken.address, + ).send({ from: operatorAddress, - }); + })); logger.info(`Claim contract deployed at ${claimContract.address}`); await rewardToken.methods.set_minter(claimContract.address, true).send({ from: operatorAddress }); @@ -129,7 +137,7 @@ describe('e2e_crowdfunding_and_claim', () => { // The donor should have exactly one note const pageIndex = 0; - const notes = await crowdfundingContract.methods + const { result: notes } = await crowdfundingContract.methods .get_donation_notes(donor1Address, pageIndex) .simulate({ from: donor1Address }); expect(notes.len).toEqual(1n); @@ -142,10 +150,12 @@ describe('e2e_crowdfunding_and_claim', () => { } // Since the RWT is minted 1:1 with the DNT, the balance of the reward token should be equal to the donation amount - const balanceRWT = await rewardToken.methods.balance_of_public(donor1Address).simulate({ from: operatorAddress }); + const { result: balanceRWT } = await rewardToken.methods + .balance_of_public(donor1Address) + .simulate({ from: operatorAddress }); expect(balanceRWT).toEqual(donationAmount); - const balanceDNTBeforeWithdrawal = await donationToken.methods + const { result: balanceDNTBeforeWithdrawal } = await donationToken.methods .balance_of_private(operatorAddress) .simulate({ from: operatorAddress }); expect(balanceDNTBeforeWithdrawal).toEqual(0n); @@ -153,7 +163,7 @@ describe('e2e_crowdfunding_and_claim', () => { // 3) At last, we withdraw the raised funds from the crowdfunding contract to the operator's address await crowdfundingContract.methods.withdraw(donationAmount).send({ from: operatorAddress }); - const balanceDNTAfterWithdrawal = await donationToken.methods + const { result: balanceDNTAfterWithdrawal } = await donationToken.methods .balance_of_private(operatorAddress) .simulate({ from: operatorAddress }); @@ -184,7 +194,7 @@ describe('e2e_crowdfunding_and_claim', () => { // The donor should have exactly one note const pageIndex = 0; - const notes = await crowdfundingContract.methods + const { result: notes } = await crowdfundingContract.methods .get_donation_notes(donorAddress, pageIndex) .simulate({ from: donorAddress }); expect(notes.len).toEqual(1n); @@ -221,7 +231,13 @@ describe('e2e_crowdfunding_and_claim', () => { deadline, ); - otherCrowdfundingContract = await otherCrowdfundingDeployment.send({ from: operatorAddress }); + const otherCrowdfundingInstance = await otherCrowdfundingDeployment.getInstance(); + await wallet.registerContract(otherCrowdfundingInstance, CrowdfundingContract.artifact, crowdfundingSecretKey); + ({ contract: otherCrowdfundingContract } = await otherCrowdfundingDeployment.send({ + from: operatorAddress, + // The contract constructor initializes private storage vars that need the contract's own nullifier key. + additionalScopes: [otherCrowdfundingInstance.address], + })); logger.info(`Crowdfunding contract deployed at ${otherCrowdfundingContract.address}`); } @@ -241,11 +257,11 @@ describe('e2e_crowdfunding_and_claim', () => { // 3) Get the donation note const pageIndex = 0; - const notes = await otherCrowdfundingContract.methods + const { result: notes2 } = await otherCrowdfundingContract.methods .get_donation_notes(donor1Address, pageIndex) .simulate({ from: donor1Address }); - expect(notes.len).toEqual(1n); - const otherContractNote = notes.storage[0]; + expect(notes2.len).toEqual(1n); + const otherContractNote = notes2.storage[0]; // 4) Try to claim rewards using note from other contract await expect( diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts index fc5a57f84fe6..37da34dd7f3c 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts @@ -37,7 +37,7 @@ describe('e2e_deploy_contract contract class registration', () => { ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup()); artifact = StatefulTestContract.artifact; publicationTxReceipt = await publishContractClass(wallet, artifact).then(c => - c.send({ from: defaultAccountAddress }), + c.send({ from: defaultAccountAddress }).then(({ receipt }) => receipt), ); contractClass = await getContractClassFromArtifact(artifact); expect(await aztecNode.getContractClass(contractClass.id)).toBeDefined(); @@ -47,7 +47,7 @@ describe('e2e_deploy_contract contract class registration', () => { describe('publishing a contract class', () => { it('emits public bytecode', async () => { - const publicationTxReceipt = await publishContractClass(wallet, TestContract.artifact).then(c => + const { receipt: publicationTxReceipt } = await publishContractClass(wallet, TestContract.artifact).then(c => c.send({ from: defaultAccountAddress }), ); const logs = await aztecNode.getContractClassLogs({ txHash: publicationTxReceipt.txHash }); @@ -149,19 +149,23 @@ describe('e2e_deploy_contract contract class registration', () => { it('calls a public function with no init check on the deployed instance', async () => { const whom = await AztecAddress.random(); await contract.methods.increment_public_value_no_init_check(whom, 10).send({ from: defaultAccountAddress }); - const stored = await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress }); + const { result: stored } = await contract.methods + .get_public_value(whom) + .simulate({ from: defaultAccountAddress }); expect(stored).toEqual(10n); }); it('refuses to call a public function with init check if the instance is not initialized', async () => { const whom = await AztecAddress.random(); - const receipt = await contract.methods + const { receipt } = await contract.methods .increment_public_value(whom, 10) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); // Meanwhile we check we didn't increment the value - expect(await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress })).toEqual(0n); + expect( + (await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress })).result, + ).toEqual(0n); }); it('refuses to initialize the instance with wrong args via a private function', async () => { @@ -174,7 +178,9 @@ describe('e2e_deploy_contract contract class registration', () => { await contract.methods.constructor(...initArgs).send({ from: defaultAccountAddress }); const whom = await AztecAddress.random(); await contract.methods.increment_public_value(whom, 10).send({ from: defaultAccountAddress }); - const stored = await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress }); + const { result: stored } = await contract.methods + .get_public_value(whom) + .simulate({ from: defaultAccountAddress }); expect(stored).toEqual(10n); }); @@ -195,18 +201,22 @@ describe('e2e_deploy_contract contract class registration', () => { it('refuses to initialize the instance with wrong args via a public function', async () => { const whom = await AztecAddress.random(); - const receipt = await contract.methods + const { receipt } = await contract.methods .public_constructor(whom, 43) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); - expect(await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress })).toEqual(0n); + expect( + (await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress })).result, + ).toEqual(0n); }); it('initializes the contract and calls a public function', async () => { await contract.methods.public_constructor(...initArgs).send({ from: defaultAccountAddress }); const whom = await AztecAddress.random(); await contract.methods.increment_public_value(whom, 10).send({ from: defaultAccountAddress }); - const stored = await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress }); + const { result: stored } = await contract.methods + .get_public_value(whom) + .simulate({ from: defaultAccountAddress }); expect(stored).toEqual(10n); }); @@ -228,7 +238,7 @@ describe('e2e_deploy_contract contract class registration', () => { // Register the instance to be deployed in the pxe await wallet.registerContract(instance, artifact); // Set up the contract that calls the deployer (which happens to be the TestContract) and call it - const deployer = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + const { contract: deployer } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); await deployer.methods.publish_contract_instance(instance.address).send({ from: defaultAccountAddress }); }); @@ -243,7 +253,7 @@ describe('e2e_deploy_contract contract class registration', () => { ).rejects.toThrow(/not deployed/); // This time, don't throw on revert and confirm that the tx is included // despite reverting in app logic because of the call to a non-existent contract - const tx = await instance.methods + const { receipt: tx } = await instance.methods .increment_public_value_no_init_check(whom, 10) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); expect(tx.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts index 3d81fda867be..ed7cfba703fb 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts @@ -40,12 +40,14 @@ describe('e2e_deploy_contract deploy method', () => { const owner = defaultAccountAddress; logger.debug(`Deploying stateful test contract`); // docs:start:deploy_basic - const contract = await StatefulTestContract.deploy(wallet, owner, 42).send({ from: defaultAccountAddress }); + const { contract } = await StatefulTestContract.deploy(wallet, owner, 42).send({ from: defaultAccountAddress }); // docs:end:deploy_basic - expect(await contract.methods.summed_values(owner).simulate({ from: defaultAccountAddress })).toEqual(42n); + expect((await contract.methods.summed_values(owner).simulate({ from: defaultAccountAddress })).result).toEqual(42n); logger.debug(`Calling public method on stateful test contract at ${contract.address.toString()}`); await contract.methods.increment_public_value(owner, 84).send({ from: defaultAccountAddress }); - expect(await contract.methods.get_public_value(owner).simulate({ from: defaultAccountAddress })).toEqual(84n); + expect((await contract.methods.get_public_value(owner).simulate({ from: defaultAccountAddress })).result).toEqual( + 84n, + ); // docs:start:verify_deployment const metadata = await wallet.getContractMetadata(contract.address); const classMetadata = await wallet.getContractClassMetadata(metadata.instance!.currentContractClassId); @@ -58,28 +60,30 @@ describe('e2e_deploy_contract deploy method', () => { const owner = defaultAccountAddress; // docs:start:deploy_universal const opts = { universalDeploy: true, from: defaultAccountAddress }; - const contract = await StatefulTestContract.deploy(wallet, owner, 42).send(opts); + const { contract } = await StatefulTestContract.deploy(wallet, owner, 42).send(opts); // docs:end:deploy_universal - expect(await contract.methods.summed_values(owner).simulate({ from: defaultAccountAddress })).toEqual(42n); + expect((await contract.methods.summed_values(owner).simulate({ from: defaultAccountAddress })).result).toEqual(42n); await contract.methods.increment_public_value(owner, 84).send({ from: defaultAccountAddress }); - expect(await contract.methods.get_public_value(owner).simulate({ from: defaultAccountAddress })).toEqual(84n); + expect((await contract.methods.get_public_value(owner).simulate({ from: defaultAccountAddress })).result).toEqual( + 84n, + ); }); it('publicly deploys and calls a public function from the constructor', async () => { const owner = defaultAccountAddress; // docs:start:deploy_token - const token = await TokenContract.deploy(wallet, owner, 'TOKEN', 'TKN', 18).send({ + const { contract: token } = await TokenContract.deploy(wallet, owner, 'TOKEN', 'TKN', 18).send({ from: defaultAccountAddress, }); // docs:end:deploy_token - expect(await token.methods.is_minter(owner).simulate({ from: defaultAccountAddress })).toEqual(true); + expect((await token.methods.is_minter(owner).simulate({ from: defaultAccountAddress })).result).toEqual(true); }); it('publicly deploys and initializes via a public function', async () => { const owner = defaultAccountAddress; logger.debug(`Deploying contract via a public constructor`); // docs:start:deploy_with_opts - const contract = await StatefulTestContract.deployWithOpts( + const { contract } = await StatefulTestContract.deployWithOpts( { wallet, method: 'public_constructor' }, owner, 42, @@ -87,29 +91,31 @@ describe('e2e_deploy_contract deploy method', () => { from: defaultAccountAddress, }); // docs:end:deploy_with_opts - expect(await contract.methods.get_public_value(owner).simulate({ from: defaultAccountAddress })).toEqual(42n); + expect((await contract.methods.get_public_value(owner).simulate({ from: defaultAccountAddress })).result).toEqual( + 42n, + ); logger.debug(`Calling a private function to ensure the contract was properly initialized`); await contract.methods.create_note(owner, 30).send({ from: defaultAccountAddress }); - expect(await contract.methods.summed_values(owner).simulate({ from: defaultAccountAddress })).toEqual(30n); + expect((await contract.methods.summed_values(owner).simulate({ from: defaultAccountAddress })).result).toEqual(30n); }); it('deploys a contract with a default initializer not named constructor', async () => { logger.debug(`Deploying contract with a default initializer named initialize`); const opts = { skipClassPublication: true, skipInstancePublication: true, from: defaultAccountAddress }; - const contract = await CounterContract.deploy(wallet, 10, defaultAccountAddress).send(opts); + const { contract } = await CounterContract.deploy(wallet, 10, defaultAccountAddress).send(opts); logger.debug(`Calling a function to ensure the contract was properly initialized`); await contract.methods.increment_twice(defaultAccountAddress).send({ from: defaultAccountAddress }); - expect(await contract.methods.get_counter(defaultAccountAddress).simulate({ from: defaultAccountAddress })).toEqual( - 12n, - ); + expect( + (await contract.methods.get_counter(defaultAccountAddress).simulate({ from: defaultAccountAddress })).result, + ).toEqual(12n); }); it('publicly deploys a contract with no constructor', async () => { logger.debug(`Deploying contract with no constructor`); - const contract = await NoConstructorContract.deploy(wallet).send({ from: defaultAccountAddress }); + const { contract } = await NoConstructorContract.deploy(wallet).send({ from: defaultAccountAddress }); const arbitraryValue = 42; logger.debug(`Call a public function to check that it was publicly deployed`); - const receipt = await contract.methods.emit_public(arbitraryValue).send({ from: defaultAccountAddress }); + const { receipt } = await contract.methods.emit_public(arbitraryValue).send({ from: defaultAccountAddress }); const logs = await aztecNode.getPublicLogs({ txHash: receipt.txHash }); expect(logs.logs[0].log.getEmittedFields()).toEqual([new Fr(arbitraryValue)]); }); @@ -162,7 +168,10 @@ describe('e2e_deploy_contract deploy method', () => { const publicCallTxPromise = publicCall.send({ from: defaultAccountAddress, wait: { timeout: 600 } }); logger.debug('Deploying a contract and calling a public function in the same block'); - const [deployTxReceipt, publicCallTxReceipt] = await Promise.all([deployTxPromise, publicCallTxPromise]); + const [{ receipt: deployTxReceipt }, { receipt: publicCallTxReceipt }] = await Promise.all([ + deployTxPromise, + publicCallTxPromise, + ]); expect(deployTxReceipt.blockNumber).toEqual(publicCallTxReceipt.blockNumber); }, 300_000); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts index 55f638be25f6..9d16aeb08bb0 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts @@ -36,7 +36,7 @@ describe('e2e_deploy_contract legacy', () => { deployer: defaultAccountAddress, }); const deployer = new ContractDeployer(TestContractArtifact, wallet); - const receipt = await deployer + const { receipt } = await deployer .deploy() .send({ from: defaultAccountAddress, contractAddressSalt: salt, wait: { returnReceipt: true } }); expect(receipt.contract.address).toEqual(deploymentData.address); @@ -65,7 +65,7 @@ describe('e2e_deploy_contract legacy', () => { for (let index = 0; index < 2; index++) { logger.info(`Deploying contract ${index + 1}...`); - const receipt = await deployer + const { receipt } = await deployer .deploy() .send({ from: defaultAccountAddress, contractAddressSalt: Fr.random(), wait: { returnReceipt: true } }); logger.info(`Sending TX to contract ${index + 1}...`); @@ -113,8 +113,8 @@ describe('e2e_deploy_contract legacy', () => { expect(goodTxPromiseResult.status).toBe('fulfilled'); expect(badTxReceiptResult.status).toBe('fulfilled'); // but reverted - const goodTxReceipt = goodTxPromiseResult.status === 'fulfilled' ? goodTxPromiseResult.value : null; - const badTxReceipt = badTxReceiptResult.status === 'fulfilled' ? badTxReceiptResult.value : null; + const goodTxReceipt = goodTxPromiseResult.status === 'fulfilled' ? goodTxPromiseResult.value.receipt : null; + const badTxReceipt = badTxReceiptResult.status === 'fulfilled' ? badTxReceiptResult.value.receipt : null; // Both the good and bad transactions are included expect(goodTxReceipt).toBeDefined(); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts index f1af8d9c9adf..a6814602e130 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts @@ -31,7 +31,7 @@ describe('e2e_deploy_contract private initialization', () => { // The function has a noinitcheck flag so it can be called without initialization. it('executes a noinitcheck function in an uninitialized contract', async () => { const contract = await t.registerContract(wallet, TestContract); - const receipt = await contract.methods.emit_nullifier(10).send({ from: defaultAccountAddress }); + const { receipt } = await contract.methods.emit_nullifier(10).send({ from: defaultAccountAddress }); const txEffects = await aztecNode.getTxEffect(receipt.txHash); const expected = await siloNullifier(contract.address, new Fr(10)); @@ -45,11 +45,11 @@ describe('e2e_deploy_contract private initialization', () => { const contract = await t.registerContract(wallet, NoConstructorContract); await expect( contract.methods.is_private_mutable_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), - ).resolves.toEqual(false); + ).resolves.toEqual(expect.objectContaining({ result: false })); await contract.methods.initialize_private_mutable(42).send({ from: defaultAccountAddress }); await expect( contract.methods.is_private_mutable_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), - ).resolves.toEqual(true); + ).resolves.toEqual(expect.objectContaining({ result: true })); }); // Tests privately initializing an undeployed contract. Also requires pxe registration in advance. @@ -60,10 +60,10 @@ describe('e2e_deploy_contract private initialization', () => { logger.info(`Calling the constructor for ${contract.address}`); await contract.methods.constructor(...initArgs).send({ from: defaultAccountAddress }); logger.info(`Checking if the constructor was run for ${contract.address}`); - expect(await contract.methods.summed_values(owner).simulate({ from: owner })).toEqual(42n); + expect((await contract.methods.summed_values(owner).simulate({ from: owner })).result).toEqual(42n); logger.info(`Calling a private function that requires initialization on ${contract.address}`); await contract.methods.create_note(owner, 10).send({ from: defaultAccountAddress }); - expect(await contract.methods.summed_values(owner).simulate({ from: owner })).toEqual(52n); + expect((await contract.methods.summed_values(owner).simulate({ from: owner })).result).toEqual(52n); }); // Tests privately initializing multiple undeployed contracts on the same tx through an account contract. @@ -75,8 +75,8 @@ describe('e2e_deploy_contract private initialization', () => { ); const calls = contracts.map((c, i) => c.methods.constructor(...initArgs[i])); await new BatchCall(wallet, calls).send({ from: defaultAccountAddress }); - expect(await contracts[0].methods.summed_values(owner).simulate({ from: owner })).toEqual(42n); - expect(await contracts[1].methods.summed_values(owner).simulate({ from: owner })).toEqual(52n); + expect((await contracts[0].methods.summed_values(owner).simulate({ from: owner })).result).toEqual(42n); + expect((await contracts[1].methods.summed_values(owner).simulate({ from: owner })).result).toEqual(52n); }); it('initializes and calls a private function in a single tx', async () => { @@ -89,7 +89,7 @@ describe('e2e_deploy_contract private initialization', () => { ]); logger.info(`Executing constructor and private function in batch at ${contract.address}`); await batch.send({ from: defaultAccountAddress }); - expect(await contract.methods.summed_values(owner).simulate({ from: owner })).toEqual(52n); + expect((await contract.methods.summed_values(owner).simulate({ from: owner })).result).toEqual(52n); }); it('refuses to initialize a contract twice', async () => { diff --git a/yarn-project/end-to-end/src/e2e_double_spend.test.ts b/yarn-project/end-to-end/src/e2e_double_spend.test.ts index 6b4e2053b380..3cc69dec717d 100644 --- a/yarn-project/end-to-end/src/e2e_double_spend.test.ts +++ b/yarn-project/end-to-end/src/e2e_double_spend.test.ts @@ -25,7 +25,7 @@ describe('e2e_double_spend', () => { logger, } = await setup(1)); - contract = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); logger.info(`Test contract deployed at ${contract.address}`); }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts index e4740dde721d..220face468aa 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts @@ -238,7 +238,7 @@ describe('e2e_epochs/epochs_invalidate_block', () => { // Send a few transactions so the sequencer builds multiple blocks in the checkpoint // We'll later check that the first tx at least was picked up and mined logger.warn('Sending multiple transactions to trigger block building'); - const [sentTx] = await timesAsync(8, i => + const [{ txHash: sentTx }] = await timesAsync(8, i => testContract.methods.emit_nullifier(BigInt(i + 1)).send({ from: context.accounts[0], wait: NO_WAIT }), ); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts index 50154c9bdb0b..3c6e274138d7 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts @@ -117,8 +117,8 @@ describe('e2e_epochs/epochs_mbps', () => { // Unlike emit_nullifier (which has #[noinitcheck]), cross-chain methods require a deployed contract. if (deployCrossChainContract) { logger.warn(`Deploying cross-chain test contract before stopping initial sequencer`); - crossChainContract = await TestContract.deploy(wallet).send({ from }); - logger.warn(`Cross-chain test contract deployed at ${crossChainContract.address}`); + ({ contract: crossChainContract } = await TestContract.deploy(wallet).send({ from })); + logger.warn(`Cross-chain test contract deployed at ${crossChainContract!.address}`); } // Halt block building in initial aztec node, which was not set up as a validator. diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts index 699930ba4395..59a2788286b0 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts @@ -46,7 +46,7 @@ describe('e2e_epochs/epochs_proof_public_cross_chain', () => { // Deploy a contract that consumes L1 to L2 messages await context.aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); logger.warn(`Deploying test contract`); - const testContract = await TestContract.deploy(context.wallet).send({ from: context.accounts[0] }); + const { contract: testContract } = await TestContract.deploy(context.wallet).send({ from: context.accounts[0] }); logger.warn(`Test contract deployed at ${testContract.address}`); // Send an l1 to l2 message to be consumed from the contract @@ -63,7 +63,7 @@ describe('e2e_epochs/epochs_proof_public_cross_chain', () => { // And we consume the message using the test contract. It's important that we don't wait for the membership witness // to be available, since we want to test the scenario where the message becomes available on the same block the tx lands. logger.warn(`Consuming message ${message.content.toString()} from the contract at ${testContract.address}`); - const txReceipt = await testContract.methods + const { receipt: txReceipt } = await testContract.methods .consume_message_from_arbitrary_sender_public( message.content, secret, @@ -89,7 +89,7 @@ describe('e2e_epochs/epochs_proof_public_cross_chain', () => { expect(provenBlockNumber).toBeGreaterThanOrEqual(txReceipt.blockNumber!); // Should not be able to consume the message again. - const failedReceipt = await testContract.methods + const { receipt: failedReceipt } = await testContract.methods .consume_message_from_arbitrary_sender_public( message.content, secret, diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index d6efb8165374..c3051b449b5a 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -41,11 +41,17 @@ describe('e2e_escrow_contract', () => { const escrowDeployment = EscrowContract.deployWithPublicKeys(escrowPublicKeys, wallet, owner); const escrowInstance = await escrowDeployment.getInstance(); await wallet.registerContract(escrowInstance, EscrowContract.artifact, escrowSecretKey); - escrowContract = await escrowDeployment.send({ from: owner }); + // The contract constructor initializes private storage vars that need the contract's own nullifier key. + ({ contract: escrowContract } = await escrowDeployment.send({ + from: owner, + additionalScopes: [escrowInstance.address], + })); logger.info(`Escrow contract deployed at ${escrowContract.address}`); // Deploy Token contract and mint funds for the escrow contract - token = await TokenContract.deploy(wallet, owner, 'TokenName', 'TokenSymbol', 18).send({ from: owner }); + ({ contract: token } = await TokenContract.deploy(wallet, owner, 'TokenName', 'TokenSymbol', 18).send({ + from: owner, + })); await mintTokensToPrivate(token, owner, escrowContract.address, 100n); diff --git a/yarn-project/end-to-end/src/e2e_event_logs.test.ts b/yarn-project/end-to-end/src/e2e_event_logs.test.ts index 4645fc1dcc77..64d89526709f 100644 --- a/yarn-project/end-to-end/src/e2e_event_logs.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_logs.test.ts @@ -47,7 +47,7 @@ describe('Logs', () => { await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); log.warn(`Deploying test contract`); - testLogContract = await TestLogContract.deploy(wallet).send({ from: account1Address }); + ({ contract: testLogContract } = await TestLogContract.deploy(wallet).send({ from: account1Address })); }); afterAll(() => teardown()); @@ -57,9 +57,12 @@ describe('Logs', () => { const preimages = makeTuple(5, makeTuple.bind(undefined, 4, Fr.random)) as Tuple, 5>; const txs = await Promise.all( - preimages.map(preimage => - testLogContract.methods.emit_encrypted_events(account2Address, preimage).send({ from: account1Address }), - ), + preimages.map(async preimage => { + const { receipt } = await testLogContract.methods + .emit_encrypted_events(account2Address, preimage) + .send({ from: account1Address }); + return receipt; + }), ); const firstBlockNumber = Math.min(...txs.map(tx => tx.blockNumber!)); @@ -124,13 +127,13 @@ describe('Logs', () => { const preimage = makeTuple(5, makeTuple.bind(undefined, 4, Fr.random)) as Tuple, 5>; let i = 0; - const firstTx = await testLogContract.methods + const { receipt: firstTx } = await testLogContract.methods .emit_unencrypted_events(preimage[i]) .send({ from: account1Address }); await timesParallel(3, () => testLogContract.methods.emit_unencrypted_events(preimage[++i]).send({ from: account1Address }), ); - const lastTx = await testLogContract.methods + const { receipt: lastTx } = await testLogContract.methods .emit_unencrypted_events(preimage[++i]) .send({ from: account1Address }); @@ -181,7 +184,9 @@ describe('Logs', () => { const c = await AztecAddress.random(); const extra = Fr.random(); - const tx = await testLogContract.methods.emit_nested_event(a, b, c, extra).send({ from: account1Address }); + const { receipt: tx } = await testLogContract.methods + .emit_nested_event(a, b, c, extra) + .send({ from: account1Address }); const collectedEvents = await getPublicEvents( aztecNode, @@ -212,7 +217,7 @@ describe('Logs', () => { const tx1NumLogs = 10; { // Call the private function that emits two encrypted logs per call and recursively nests 4 times - const tx = await testLogContract.methods + const { receipt: tx } = await testLogContract.methods .emit_encrypted_events_nested(account2Address, 4) .send({ from: account1Address }); @@ -231,7 +236,7 @@ describe('Logs', () => { const tx2NumLogs = 6; { // Call the private function that emits two encrypted logs per call and recursively nests 2 times - const tx = await testLogContract.methods + const { receipt: tx } = await testLogContract.methods .emit_encrypted_events_nested(account2Address, 2) .send({ from: account1Address }); diff --git a/yarn-project/end-to-end/src/e2e_event_only.test.ts b/yarn-project/end-to-end/src/e2e_event_only.test.ts index 7dd0c3859451..d2b036f601a0 100644 --- a/yarn-project/end-to-end/src/e2e_event_only.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_only.test.ts @@ -26,14 +26,16 @@ describe('EventOnly', () => { accounts: [defaultAccountAddress], } = await setup(1)); await ensureAccountContractsPublished(wallet, [defaultAccountAddress]); - eventOnlyContract = await EventOnlyContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: eventOnlyContract } = await EventOnlyContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(() => teardown()); it('emits and retrieves a private event for a contract with no notes', async () => { const value = Fr.random(); - const tx = await eventOnlyContract.methods.emit_event_for_msg_sender(value).send({ from: defaultAccountAddress }); + const { receipt: tx } = await eventOnlyContract.methods + .emit_event_for_msg_sender(value) + .send({ from: defaultAccountAddress }); const events = await wallet.getPrivateEvents(EventOnlyContract.events.TestEvent, { contractAddress: eventOnlyContract.address, diff --git a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts index 78e3be77ee02..18240f671298 100644 --- a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts +++ b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts @@ -25,7 +25,7 @@ describe('e2e_expiration_timestamp', () => { aztecNode, accounts: [defaultAccountAddress], } = await setup()); - contract = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index b93a429b2265..1323bd1ba00a 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -89,7 +89,7 @@ describe('e2e_fees account_init', () => { const [bobsInitialGas] = await t.getGasBalanceFn(bobsAddress); expect(bobsInitialGas).toEqual(mintAmount); - const tx = await bobsDeployMethod.send({ from: AztecAddress.ZERO, wait: { returnReceipt: true } }); + const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, wait: { returnReceipt: true } }); expect(tx.transactionFee!).toBeGreaterThan(0n); await expect(t.getGasBalanceFn(bobsAddress)).resolves.toEqual([bobsInitialGas - tx.transactionFee!]); @@ -98,7 +98,7 @@ describe('e2e_fees account_init', () => { it('pays natively in the Fee Juice by bridging funds themselves', async () => { const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(bobsAddress); const paymentMethod = new FeeJuicePaymentMethodWithClaim(bobsAddress, claim); - const tx = await bobsDeployMethod.send({ + const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: { returnReceipt: true }, @@ -118,7 +118,7 @@ describe('e2e_fees account_init', () => { const maxFeesPerGas = (await aztecNode.getCurrentMinFees()).mul(1.5); const gasSettings = GasSettings.default({ maxFeesPerGas }); const paymentMethod = new PrivateFeePaymentMethod(bananaFPC.address, bobsAddress, wallet, gasSettings); - const tx = await bobsDeployMethod.send({ + const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: { returnReceipt: true }, @@ -147,7 +147,7 @@ describe('e2e_fees account_init', () => { const maxFeesPerGas = (await aztecNode.getCurrentMinFees()).mul(1.5); const gasSettings = GasSettings.default({ maxFeesPerGas }); const paymentMethod = new PublicFeePaymentMethod(bananaFPC.address, bobsAddress, wallet, gasSettings); - const tx = await bobsDeployMethod.send({ + const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, skipInstancePublication: false, fee: { paymentMethod }, @@ -180,7 +180,7 @@ describe('e2e_fees account_init', () => { await t.mintPrivateBananas(mintedBananas, bobsAddress); const [aliceBalanceBefore] = await t.getGasBalanceFn(aliceAddress); - const tx = await SchnorrAccountContractInterface.deployWithPublicKeys( + const { receipt: tx } = await SchnorrAccountContractInterface.deployWithPublicKeys( bobsPublicKeys, wallet, bobsSigningPubKey.x, diff --git a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts index 0c4c54c5032c..440f1949acf8 100644 --- a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts @@ -84,7 +84,7 @@ describe('e2e_fees failures', () => { const currentSequencerRewards = await t.getCoinbaseSequencerRewards(); - const txReceipt = await bananaCoin.methods + const { receipt: txReceipt } = await bananaCoin.methods .transfer_in_public(aliceAddress, sequencerAddress, outrageousPublicAmountAliceDoesNotHave, 0) .send({ from: aliceAddress, @@ -187,7 +187,7 @@ describe('e2e_fees failures', () => { ); // if we skip simulation, it includes the failed TX - const txReceipt = await bananaCoin.methods + const { receipt: txReceipt } = await bananaCoin.methods .transfer_in_public(aliceAddress, sequencerAddress, outrageousPublicAmountAliceDoesNotHave, 0) .send({ from: aliceAddress, @@ -285,7 +285,7 @@ describe('e2e_fees failures', () => { }), ).rejects.toThrow(); - const receipt = await bananaCoin.methods + const { receipt } = await bananaCoin.methods .mint_to_public(aliceAddress, 1n) // random operation .send({ from: aliceAddress, diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts index f90dfadf2e7c..16889aef501f 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts @@ -43,7 +43,9 @@ describe('e2e_fees Fee Juice payments', () => { describe('without initial funds', () => { beforeAll(async () => { - expect(await feeJuiceContract.methods.balance_of_public(bobAddress).simulate({ from: bobAddress })).toEqual(0n); + expect( + (await feeJuiceContract.methods.balance_of_public(bobAddress).simulate({ from: bobAddress })).result, + ).toEqual(0n); }); it('fails to simulate a tx', async () => { @@ -63,10 +65,12 @@ describe('e2e_fees Fee Juice payments', () => { it('claims bridged funds and pays with them on the same tx', async () => { const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(bobAddress); const paymentMethod = new FeeJuicePaymentMethodWithClaim(bobAddress, claim); - const receipt = await feeJuiceContract.methods + const { receipt } = await feeJuiceContract.methods .check_balance(0n) .send({ from: bobAddress, fee: { gasSettings, paymentMethod } }); - const endBalance = await feeJuiceContract.methods.balance_of_public(bobAddress).simulate({ from: bobAddress }); + const { result: endBalance } = await feeJuiceContract.methods + .balance_of_public(bobAddress) + .simulate({ from: bobAddress }); expect(endBalance).toBeGreaterThan(0n); expect(endBalance).toBeLessThan(claim.claimAmount); @@ -76,28 +80,30 @@ describe('e2e_fees Fee Juice payments', () => { describe('with initial funds', () => { it('sends tx with payment in Fee Juice with public calls', async () => { - const initialBalance = await feeJuiceContract.methods + const { result: initialBalance } = await feeJuiceContract.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); - const { transactionFee } = await bananaCoin.methods + const { + receipt: { transactionFee }, + } = await bananaCoin.methods .transfer_in_public(aliceAddress, bobAddress, 1n, 0n) .send({ fee: { gasSettings }, from: aliceAddress }); expect(transactionFee).toBeGreaterThan(0n); - const endBalance = await feeJuiceContract.methods + const { result: endBalance } = await feeJuiceContract.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); expect(endBalance).toBeLessThan(initialBalance); }); it('sends tx fee payment in Fee Juice with no public calls', async () => { - const initialBalance = await feeJuiceContract.methods + const { result: initialBalance } = await feeJuiceContract.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); - const { transactionFee } = await bananaCoin.methods - .transfer(bobAddress, 1n) - .send({ fee: { gasSettings }, from: aliceAddress }); + const { + receipt: { transactionFee }, + } = await bananaCoin.methods.transfer(bobAddress, 1n).send({ fee: { gasSettings }, from: aliceAddress }); expect(transactionFee).toBeGreaterThan(0n); - const endBalance = await feeJuiceContract.methods + const { result: endBalance } = await feeJuiceContract.methods .balance_of_public(aliceAddress) .simulate({ from: aliceAddress }); expect(endBalance).toBeLessThan(initialBalance); diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts index 5ac0ec444727..83fe2d1b837b 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts @@ -26,7 +26,7 @@ describe('e2e_fees fee settings', () => { await t.setup(); ({ aliceAddress, wallet, gasSettings, cheatCodes, aztecNode } = t); - testContract = await TestContract.deploy(wallet).send({ from: aliceAddress }); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: aliceAddress })); gasSettings = { ...gasSettings, maxFeesPerGas: undefined }; }); diff --git a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts index f163d566681d..a4019b3b1c45 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts @@ -204,11 +204,15 @@ export class FeesTest { /** Alice mints bananaCoin tokens privately to the target address and redeems them. */ async mintPrivateBananas(amount: bigint, address: AztecAddress) { - const balanceBefore = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address }); + const { result: balanceBefore } = await this.bananaCoin.methods + .balance_of_private(address) + .simulate({ from: address }); await mintTokensToPrivate(this.bananaCoin, this.aliceAddress, address, amount); - const balanceAfter = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address }); + const { result: balanceAfter } = await this.bananaCoin.methods + .balance_of_private(address) + .simulate({ from: address }); expect(balanceAfter).toEqual(balanceBefore + amount); } @@ -270,7 +274,7 @@ export class FeesTest { async applyDeployBananaToken() { this.logger.info('Applying deploy banana token setup'); - const bananaCoin = await BananaCoin.deploy(this.wallet, this.aliceAddress, 'BC', 'BC', 18n).send({ + const { contract: bananaCoin } = await BananaCoin.deploy(this.wallet, this.aliceAddress, 'BC', 'BC', 18n).send({ from: this.aliceAddress, }); this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`); @@ -291,7 +295,7 @@ export class FeesTest { expect((await this.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true); const bananaCoin = this.bananaCoin; - const bananaFPC = await FPCContract.deploy(this.wallet, bananaCoin.address, this.fpcAdmin).send({ + const { contract: bananaFPC } = await FPCContract.deploy(this.wallet, bananaCoin.address, this.fpcAdmin).send({ from: this.aliceAddress, }); diff --git a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts index 417cdb495cd0..b456cd167784 100644 --- a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts @@ -88,9 +88,13 @@ describe('e2e_fees gas_estimation', () => { paymentMethod?: FeePaymentMethod, ) => Promise.all( - [GasSettings.from({ ...gasSettings, ...limits }), gasSettings].map(gasSettings => - makeTransferRequest().send({ from: aliceAddress, fee: { gasSettings, paymentMethod } }), - ), + [GasSettings.from({ ...gasSettings, ...limits }), gasSettings].map(async gasSettings => { + const { receipt } = await makeTransferRequest().send({ + from: aliceAddress, + fee: { gasSettings, paymentMethod }, + }); + return receipt; + }), ); const logGasEstimate = (estimatedGas: Pick) => @@ -100,10 +104,11 @@ describe('e2e_fees gas_estimation', () => { }); it('estimates gas with Fee Juice payment method', async () => { - const { estimatedGas } = await makeTransferRequest().simulate({ + const sim = await makeTransferRequest().simulate({ from: aliceAddress, fee: { gasSettings, estimateGas: true, estimatedGasPadding: 0 }, }); + const estimatedGas = sim.estimatedGas!; logGasEstimate(estimatedGas); const sequencer = t.context.sequencer!.getSequencer(); @@ -143,10 +148,11 @@ describe('e2e_fees gas_estimation', () => { ); const paymentMethod = new PublicFeePaymentMethod(bananaFPC.address, aliceAddress, wallet, gasSettingsForEstimation); - const { estimatedGas } = await makeTransferRequest().simulate({ + const sim2 = await makeTransferRequest().simulate({ from: aliceAddress, fee: { paymentMethod, estimatedGasPadding: 0, estimateGas: true }, }); + const estimatedGas = sim2.estimatedGas!; logGasEstimate(estimatedGas); const [withEstimate, withoutEstimate] = await sendTransfers(estimatedGas, paymentMethod); @@ -184,7 +190,7 @@ describe('e2e_fees gas_estimation', () => { }; }; - const { estimatedGas } = await deployMethod().simulate({ + const sim3 = await deployMethod().simulate({ from: aliceAddress, skipClassPublication: true, fee: { @@ -192,12 +198,13 @@ describe('e2e_fees gas_estimation', () => { estimatedGasPadding: 0, }, }); + const estimatedGas = sim3.estimatedGas!; logGasEstimate(estimatedGas); - const [withEstimate, withoutEstimate] = (await Promise.all([ + const [{ receipt: withEstimate }, { receipt: withoutEstimate }] = (await Promise.all([ deployMethod().send(deployOpts(estimatedGas)), deployMethod().send(deployOpts()), - ])) as unknown as DeployTxReceipt[]; + ])) as unknown as { receipt: DeployTxReceipt }[]; // Estimation should yield that teardown has no cost, so should send the tx with zero for teardown expect(withEstimate.transactionFee!).toEqual(withoutEstimate.transactionFee!); diff --git a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts index ebb72b1f9b3e..9563d02815da 100644 --- a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts @@ -155,7 +155,7 @@ describe('e2e_fees private_payment', () => { * increase Alice's private banana balance by feeAmount by finalizing partial note */ const newlyMintedBananas = 10n; - const tx = await bananaCoin.methods.mint_to_private(aliceAddress, newlyMintedBananas).send({ + const { receipt: tx } = await bananaCoin.methods.mint_to_private(aliceAddress, newlyMintedBananas).send({ from: aliceAddress, fee: { paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceAddress, wallet, gasSettings), @@ -200,12 +200,14 @@ describe('e2e_fees private_payment', () => { * increase Alice's private banana balance by feeAmount by finalizing partial note */ const amountTransferredToPrivate = 1n; - const tx = await bananaCoin.methods.transfer_to_private(aliceAddress, amountTransferredToPrivate).send({ - from: aliceAddress, - fee: { - paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceAddress, wallet, gasSettings), - }, - }); + const { receipt: tx } = await bananaCoin.methods + .transfer_to_private(aliceAddress, amountTransferredToPrivate) + .send({ + from: aliceAddress, + fee: { + paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceAddress, wallet, gasSettings), + }, + }); const feeAmount = tx.transactionFee!; @@ -249,7 +251,7 @@ describe('e2e_fees private_payment', () => { * increase sequencer/fee recipient/FPC admin private banana balance by feeAmount by finalizing partial note * increase Alice's private banana balance by feeAmount by finalizing partial note */ - const tx = await new BatchCall(wallet, [ + const { receipt: tx } = await new BatchCall(wallet, [ bananaCoin.methods.transfer(bobAddress, amountTransferredInPrivate), bananaCoin.methods.transfer_to_private(aliceAddress, amountTransferredToPrivate), ]).send({ @@ -283,7 +285,7 @@ describe('e2e_fees private_payment', () => { it('rejects txs that dont have enough balance to cover gas costs', async () => { // deploy a copy of bananaFPC but don't fund it! - const bankruptFPC = await FPCContract.deploy(wallet, bananaCoin.address, aliceAddress).send({ + const { contract: bankruptFPC } = await FPCContract.deploy(wallet, bananaCoin.address, aliceAddress).send({ from: aliceAddress, }); diff --git a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts index 51e9109a90dc..b059938777db 100644 --- a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts @@ -59,12 +59,14 @@ describe('e2e_fees public_payment', () => { it('pays fees for tx that make public transfer', async () => { const bananasToSendToBob = 10n; - const tx = await bananaCoin.methods.transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0).send({ - from: aliceAddress, - fee: { - paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceAddress, wallet, gasSettings), - }, - }); + const { receipt: tx } = await bananaCoin.methods + .transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0) + .send({ + from: aliceAddress, + fee: { + paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceAddress, wallet, gasSettings), + }, + }); const feeAmount = tx.transactionFee!; diff --git a/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts index aac9aaa557ee..ec9726d9d129 100644 --- a/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts @@ -56,13 +56,15 @@ describe('e2e_fees sponsored_public_payment', () => { it('pays fees for tx that makes a public transfer', async () => { // docs:start:sponsored_fpc_simple const bananasToSendToBob = 10n; - const tx = await bananaCoin.methods.transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0).send({ - from: aliceAddress, - fee: { - gasSettings, - paymentMethod: new SponsoredFeePaymentMethod(sponsoredFPC.address), - }, - }); + const { receipt: tx } = await bananaCoin.methods + .transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0) + .send({ + from: aliceAddress, + fee: { + gasSettings, + paymentMethod: new SponsoredFeePaymentMethod(sponsoredFPC.address), + }, + }); // docs:end:sponsored_fpc_simple const feeAmount = tx.transactionFee!; diff --git a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts index d424b78be5f1..4cdd919dacad 100644 --- a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts +++ b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts @@ -51,9 +51,9 @@ describe('Kernelless simulation', () => { ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: liquidityToken } = await deployToken(wallet, adminAddress, 0n, logger)); - amm = await AMMContract.deploy(wallet, token0.address, token1.address, liquidityToken.address).send({ + ({ contract: amm } = await AMMContract.deploy(wallet, token0.address, token1.address, liquidityToken.address).send({ from: adminAddress, - }); + })); await liquidityToken.methods.set_minter(amm.address, true).send({ from: adminAddress }); @@ -75,15 +75,15 @@ describe('Kernelless simulation', () => { async function getWalletBalances(lpAddress: AztecAddress): Promise { return { - token0: await token0.methods.balance_of_private(lpAddress).simulate({ from: lpAddress }), - token1: await token1.methods.balance_of_private(lpAddress).simulate({ from: lpAddress }), + token0: (await token0.methods.balance_of_private(lpAddress).simulate({ from: lpAddress })).result, + token1: (await token1.methods.balance_of_private(lpAddress).simulate({ from: lpAddress })).result, }; } async function getAmmBalances(): Promise { return { - token0: await token0.methods.balance_of_public(amm.address).simulate({ from: adminAddress }), - token1: await token1.methods.balance_of_public(amm.address).simulate({ from: adminAddress }), + token0: (await token0.methods.balance_of_public(amm.address).simulate({ from: adminAddress })).result, + token1: (await token1.methods.balance_of_public(amm.address).simulate({ from: adminAddress })).result, }; } @@ -224,7 +224,7 @@ describe('Kernelless simulation', () => { const nonceForAuthwits = Fr.random(); - const amountOutMin = await amm.methods + const { result: amountOutMin } = await amm.methods .get_amount_out_for_exact_in(ammBalancesBefore.token0, ammBalancesBefore.token1, amountIn) .simulate({ from: swapperAddress }); @@ -237,10 +237,12 @@ describe('Kernelless simulation', () => { ); wallet.enableSimulatedSimulations(); - const { estimatedGas: swapKernellessGas } = await swapExactTokensInteraction.simulate({ - from: swapperAddress, - includeMetadata: true, - }); + const swapKernellessGas = ( + await swapExactTokensInteraction.simulate({ + from: swapperAddress, + includeMetadata: true, + }) + ).estimatedGas!; const swapAuthwit = await wallet.createAuthWit(swapperAddress, { caller: amm.address, @@ -248,11 +250,13 @@ describe('Kernelless simulation', () => { }); wallet.disableSimulatedSimulations(); - const { estimatedGas: swapWithKernelsGas } = await swapExactTokensInteraction.simulate({ - from: swapperAddress, - includeMetadata: true, - authWitnesses: [swapAuthwit], - }); + const swapWithKernelsGas = ( + await swapExactTokensInteraction.simulate({ + from: swapperAddress, + includeMetadata: true, + authWitnesses: [swapAuthwit], + }) + ).estimatedGas!; logger.info(`Kernelless gas: L2=${swapKernellessGas.gasLimits.l2Gas} DA=${swapKernellessGas.gasLimits.daGas}`); logger.info( @@ -268,7 +272,9 @@ describe('Kernelless simulation', () => { let pendingNoteHashesContract: PendingNoteHashesContract; beforeAll(async () => { - pendingNoteHashesContract = await PendingNoteHashesContract.deploy(wallet).send({ from: adminAddress }); + ({ contract: pendingNoteHashesContract } = await PendingNoteHashesContract.deploy(wallet).send({ + from: adminAddress, + })); }); it('squashing produces same gas estimates as with-kernels path', async () => { @@ -283,16 +289,20 @@ describe('Kernelless simulation', () => { ); wallet.enableSimulatedSimulations(); - const { estimatedGas: kernellessGas } = await interaction.simulate({ - from: adminAddress, - includeMetadata: true, - }); + const kernellessGas = ( + await interaction.simulate({ + from: adminAddress, + includeMetadata: true, + }) + ).estimatedGas!; wallet.disableSimulatedSimulations(); - const { estimatedGas: withKernelsGas } = await interaction.simulate({ - from: adminAddress, - includeMetadata: true, - }); + const withKernelsGas = ( + await interaction.simulate({ + from: adminAddress, + includeMetadata: true, + }) + ).estimatedGas!; logger.info(`Kernelless gas: L2=${kernellessGas.gasLimits.l2Gas} DA=${kernellessGas.gasLimits.daGas}`); logger.info(`With kernels gas: L2=${withKernelsGas.gasLimits.l2Gas} DA=${withKernelsGas.gasLimits.daGas}`); @@ -306,7 +316,9 @@ describe('Kernelless simulation', () => { let pendingNoteHashesContract: PendingNoteHashesContract; beforeAll(async () => { - pendingNoteHashesContract = await PendingNoteHashesContract.deploy(wallet).send({ from: adminAddress }); + ({ contract: pendingNoteHashesContract } = await PendingNoteHashesContract.deploy(wallet).send({ + from: adminAddress, + })); }); it('verifies settled read requests against the note hash tree', async () => { diff --git a/yarn-project/end-to-end/src/e2e_keys.test.ts b/yarn-project/end-to-end/src/e2e_keys.test.ts index 82ecf79ca366..9e56bb423b87 100644 --- a/yarn-project/end-to-end/src/e2e_keys.test.ts +++ b/yarn-project/end-to-end/src/e2e_keys.test.ts @@ -45,7 +45,7 @@ describe('Keys', () => { initialFundedAccounts, } = await setup(1)); - testContract = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); secret = initialFundedAccounts[0].secret; }); @@ -125,7 +125,7 @@ describe('Keys', () => { const expectedOvskApp = await computeAppSecretKey(ovskM, testContract.address, 'ov'); // Get the ovsk_app via the test contract - const ovskAppBigInt = await testContract.methods + const { result: ovskAppBigInt } = await testContract.methods .get_ovsk_app(ovpkMHash) .simulate({ from: defaultAccountAddress }); const ovskApp = new Fr(ovskAppBigInt); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 5c143383ebb1..22c1964fe1f8 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -39,11 +39,13 @@ describe('e2e_lending_contract', () => { const deployContracts = async () => { logger.info(`Deploying price feed contract...`); - const priceFeedContract = await PriceFeedContract.deploy(wallet).send({ from: defaultAccountAddress }); + const { contract: priceFeedContract } = await PriceFeedContract.deploy(wallet).send({ + from: defaultAccountAddress, + }); logger.info(`Price feed deployed to ${priceFeedContract.address}`); logger.info(`Deploying collateral asset feed contract...`); - const collateralAsset = await TokenContract.deploy( + const { contract: collateralAsset } = await TokenContract.deploy( wallet, defaultAccountAddress, 'TokenName', @@ -53,13 +55,19 @@ describe('e2e_lending_contract', () => { logger.info(`Collateral asset deployed to ${collateralAsset.address}`); logger.info(`Deploying stable coin contract...`); - const stableCoin = await TokenContract.deploy(wallet, defaultAccountAddress, 'TokenName', 'TokenSymbol', 18).send({ + const { contract: stableCoin } = await TokenContract.deploy( + wallet, + defaultAccountAddress, + 'TokenName', + 'TokenSymbol', + 18, + ).send({ from: defaultAccountAddress, }); logger.info(`Stable coin asset deployed to ${stableCoin.address}`); logger.info(`Deploying L2 public contract...`); - const lendingContract = await LendingContract.deploy(wallet).send({ from: defaultAccountAddress }); + const { contract: lendingContract } = await LendingContract.deploy(wallet).send({ from: defaultAccountAddress }); logger.info(`CDP deployed at ${lendingContract.address}`); await collateralAsset.methods.set_minter(lendingContract.address, true).send({ from: defaultAccountAddress }); diff --git a/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts b/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts index a158c05540f7..bb9df36ca251 100644 --- a/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts +++ b/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts @@ -29,9 +29,9 @@ describe('e2e_mempool_limit', () => { throw new Error('Aztec node admin API must be available for this test'); } - token = await TokenContract.deploy(wallet, defaultAccountAddress, 'TEST', 'T', 18).send({ + ({ contract: token } = await TokenContract.deploy(wallet, defaultAccountAddress, 'TEST', 'T', 18).send({ from: defaultAccountAddress, - }); + })); await token.methods.mint_to_public(defaultAccountAddress, 10n ** 18n).send({ from: defaultAccountAddress }); }); diff --git a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts index 35dccd29e152..47ec290401f2 100644 --- a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts @@ -114,7 +114,7 @@ describe('e2e_multi_validator_node', () => { const sender = ownerAddress; logger.info(`Deploying contract from ${sender}`); - const tx = await deployer.deploy(ownerAddress, sender, 1).send({ + const { receipt: tx } = await deployer.deploy(ownerAddress, sender, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(1)), skipClassPublication: true, @@ -177,7 +177,7 @@ describe('e2e_multi_validator_node', () => { logger.info(`Deploying contract from ${sender}`); const deployer = new ContractDeployer(artifact, wallet); - const tx = await deployer.deploy(ownerAddress, sender, 1).send({ + const { receipt: tx } = await deployer.deploy(ownerAddress, sender, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(1)), skipClassPublication: true, diff --git a/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts b/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts index e31f66cfb61d..38d8ce4ee3f4 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts @@ -38,7 +38,7 @@ describe('e2e_multiple_blobs', () => { } = await setup(1)); aztecNodeAdmin = maybeAztecNodeAdmin!; - contract = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(() => teardown()); @@ -71,10 +71,10 @@ describe('e2e_multiple_blobs', () => { expect(provenTxs.length).toBe(TX_COUNT); // Send them simultaneously to be picked up by the sequencer - const txHashes = await Promise.all(provenTxs.map(tx => tx.send({ from: defaultAccountAddress, wait: NO_WAIT }))); + const sendResults = await Promise.all(provenTxs.map(tx => tx.send({ from: defaultAccountAddress, wait: NO_WAIT }))); // Wait for all to be mined const receipts = await Promise.all( - txHashes.map(txHash => { + sendResults.map(({ txHash }) => { return waitForTx(aztecNode, txHash); }), ); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts index 27449075dfe9..aab6d6fb59c4 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts @@ -15,8 +15,8 @@ describe('e2e_nested_contract manual', () => { }); beforeEach(async () => { - importerContract = await ImportTestContract.deploy(wallet).send({ from: defaultAccountAddress }); - testContract = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: importerContract } = await ImportTestContract.deploy(wallet).send({ from: defaultAccountAddress })); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts index ac9512f43421..0e19664a5662 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts @@ -19,8 +19,8 @@ describe('e2e_nested_contract manual_enqueue', () => { }); beforeEach(async () => { - parentContract = await ParentContract.deploy(wallet).send({ from: defaultAccountAddress }); - childContract = await ChildContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: parentContract } = await ParentContract.deploy(wallet).send({ from: defaultAccountAddress })); + ({ contract: childContract } = await ChildContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts index 3b47116fcb96..a699ea8f1764 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts @@ -48,7 +48,7 @@ describe('e2e_nested_contract manual', () => { parentContract.methods.enqueue_call_to_child(childContract.address, pubSetValueSelector, 40n), ]; - const tx = await new BatchCall(wallet, actions).send({ from: defaultAccountAddress }); + const { receipt: tx } = await new BatchCall(wallet, actions).send({ from: defaultAccountAddress }); const extendedLogs = ( await aztecNode.getPublicLogs({ fromBlock: tx.blockNumber!, diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts index 5632daf6c133..769db81c1ba0 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts @@ -65,9 +65,11 @@ export class NestedContractTest { async applyManual() { this.logger.info('Deploying parent and child contracts'); - const parentContract = await ParentContract.deploy(this.wallet).send({ from: this.defaultAccountAddress }); - const childContract = await ChildContract.deploy(this.wallet).send({ from: this.defaultAccountAddress }); - this.parentContract = parentContract; - this.childContract = childContract; + ({ contract: this.parentContract } = await ParentContract.deploy(this.wallet).send({ + from: this.defaultAccountAddress, + })); + ({ contract: this.childContract } = await ChildContract.deploy(this.wallet).send({ + from: this.defaultAccountAddress, + })); } } diff --git a/yarn-project/end-to-end/src/e2e_nft.test.ts b/yarn-project/end-to-end/src/e2e_nft.test.ts index 35a2e8c7310d..7e7f8da1079a 100644 --- a/yarn-project/end-to-end/src/e2e_nft.test.ts +++ b/yarn-project/end-to-end/src/e2e_nft.test.ts @@ -33,7 +33,9 @@ describe('NFT', () => { ({ teardown, wallet, accounts } = await setup(4)); [adminAddress, minterAddress, user1Address, user2Address] = accounts; - nftContract = await NFTContract.deploy(wallet, adminAddress, 'FROG', 'FRG').send({ from: adminAddress }); + ({ contract: nftContract } = await NFTContract.deploy(wallet, adminAddress, 'FROG', 'FRG').send({ + from: adminAddress, + })); }); afterAll(() => teardown()); @@ -41,13 +43,15 @@ describe('NFT', () => { // NOTE: This test is sequential and each test case depends on the previous one it('sets minter', async () => { await nftContract.methods.set_minter(minterAddress, true).send({ from: adminAddress }); - const isMinterAMinter = await nftContract.methods.is_minter(minterAddress).simulate({ from: minterAddress }); + const { result: isMinterAMinter } = await nftContract.methods + .is_minter(minterAddress) + .simulate({ from: minterAddress }); expect(isMinterAMinter).toBe(true); }); it('minter mints to a user', async () => { await nftContract.methods.mint(user1Address, TOKEN_ID).send({ from: minterAddress }); - const ownerAfterMint = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user1Address }); + const { result: ownerAfterMint } = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user1Address }); expect(ownerAfterMint).toEqual(user1Address); }); @@ -57,7 +61,7 @@ describe('NFT', () => { const recipient = user2Address; await nftContract.methods.transfer_to_private(recipient, TOKEN_ID).send({ from: user1Address }); - const publicOwnerAfter = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user1Address }); + const { result: publicOwnerAfter } = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user1Address }); expect(publicOwnerAfter).toEqual(AztecAddress.ZERO); }); @@ -74,19 +78,21 @@ describe('NFT', () => { it('transfers to public', async () => { await nftContract.methods.transfer_to_public(user1Address, user2Address, TOKEN_ID, 0).send({ from: user1Address }); - const publicOwnerAfter = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user1Address }); + const { result: publicOwnerAfter } = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user1Address }); expect(publicOwnerAfter).toEqual(user2Address); }); it('transfers in public', async () => { await nftContract.methods.transfer_in_public(user2Address, user1Address, TOKEN_ID, 0).send({ from: user2Address }); - const publicOwnerAfter = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user2Address }); + const { result: publicOwnerAfter } = await nftContract.methods.owner_of(TOKEN_ID).simulate({ from: user2Address }); expect(publicOwnerAfter).toEqual(user1Address); }); const getPrivateNfts = async (owner: AztecAddress) => { - const [nfts, pageLimitReached] = await nftContract.methods.get_private_nfts(owner, 0).simulate({ from: owner }); + const { + result: [nfts, pageLimitReached], + } = await nftContract.methods.get_private_nfts(owner, 0).simulate({ from: owner }); if (pageLimitReached) { throw new Error('Page limit reached and pagination not implemented in test'); } diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index d8192b71827c..c48c9f291a53 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -34,7 +34,7 @@ describe('e2e_note_getter', () => { let contract: NoteGetterContract; beforeAll(async () => { - contract = await NoteGetterContract.deploy(wallet).send({ from: defaultAddress }); + ({ contract } = await NoteGetterContract.deploy(wallet).send({ from: defaultAddress })); }); it('inserts notes from 0-9, then makes multiple queries specifying the total suite of comparators', async () => { @@ -47,7 +47,14 @@ describe('e2e_note_getter', () => { // We insert a note with value 5 twice to better test the comparators await contract.methods.insert_note(5).send({ from: defaultAddress }); - const [returnEq, returnNeq, returnLt, returnGt, returnLte, returnGte] = await Promise.all([ + const [ + { result: returnEq }, + { result: returnNeq }, + { result: returnLt }, + { result: returnGt }, + { result: returnLte }, + { result: returnGte }, + ] = await Promise.all([ contract.methods.read_note_values(defaultAddress, Comparator.EQ, 5).simulate({ from: defaultAddress }), contract.methods.read_note_values(defaultAddress, Comparator.NEQ, 5).simulate({ from: defaultAddress }), contract.methods.read_note_values(defaultAddress, Comparator.LT, 5).simulate({ from: defaultAddress }), @@ -78,7 +85,7 @@ describe('e2e_note_getter', () => { const makeTxHybrid = false; beforeAll(async () => { - contract = await TestContract.deploy(wallet).send({ from: defaultAddress }); + ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAddress })); owner = defaultAddress; }); @@ -93,10 +100,10 @@ describe('e2e_note_getter', () => { }); async function assertNoteIsReturned(storageSlot: number, expectedValue: number, activeOrNullified: boolean) { - const viewNotesResult = await contract.methods + const { result: viewNotesResult } = await contract.methods .call_view_notes(owner, storageSlot, activeOrNullified) .simulate({ from: defaultAddress }); - const getNotesResult = await contract.methods + const { result: getNotesResult } = await contract.methods .call_get_notes(owner, storageSlot, activeOrNullified) .simulate({ from: defaultAddress }); @@ -155,10 +162,10 @@ describe('e2e_note_getter', () => { await contract.methods.call_destroy_note(owner, storageSlot).send({ from: defaultAddress }); // We now fetch multiple notes, and get both the active and the nullified one. - const viewNotesManyResult = await contract.methods + const { result: viewNotesManyResult } = await contract.methods .call_view_notes_many(owner, storageSlot, activeOrNullified) .simulate({ from: defaultAddress }); - const getNotesManyResult = await contract.methods + const { result: getNotesManyResult } = await contract.methods .call_get_notes_many(owner, storageSlot, activeOrNullified) .simulate({ from: defaultAddress }); diff --git a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts index 624433699dd6..9968050c18b7 100644 --- a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts +++ b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts @@ -33,12 +33,34 @@ describe('e2e_offchain_effect', () => { accounts: [defaultAccountAddress], aztecNode, } = await setup(1)); - contract1 = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress }); - contract2 = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: contract1 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); + ({ contract: contract2 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(() => teardown()); + it('should return offchain effects from send()', async () => { + const effects = Array(2) + .fill(null) + .map(() => ({ + data: [Fr.random(), Fr.random(), Fr.random(), Fr.random(), Fr.random()], + // eslint-disable-next-line camelcase + next_contract: contract1.address, + })); + + const { receipt, offchainEffects } = await contract1.methods + .emit_offchain_effects(effects) + .send({ from: defaultAccountAddress }); + + expect(receipt.hasExecutionSucceeded()).toBe(true); + // Effects are popped from the end of the BoundedVec, so they come out reversed + expect(offchainEffects).toHaveLength(2); + expect(offchainEffects[0].contractAddress).toEqual(contract1.address); + expect(offchainEffects[0].data).toEqual(effects[1].data); + expect(offchainEffects[1].contractAddress).toEqual(contract1.address); + expect(offchainEffects[1].data).toEqual(effects[0].data); + }); + it('should emit offchain effects', async () => { const effects = Array(3) .fill(null) @@ -164,7 +186,9 @@ describe('e2e_offchain_effect', () => { .simulate({ from: defaultAccountAddress }); // Get the note value - const noteValue = await contract1.methods.get_note_value(owner).simulate({ from: defaultAccountAddress }); + const { result: noteValue } = await contract1.methods + .get_note_value(owner) + .simulate({ from: defaultAccountAddress }); expect(noteValue).toBe(value); }); }); diff --git a/yarn-project/end-to-end/src/e2e_orderbook.test.ts b/yarn-project/end-to-end/src/e2e_orderbook.test.ts index 1ac98d5ae223..22efa02edd17 100644 --- a/yarn-project/end-to-end/src/e2e_orderbook.test.ts +++ b/yarn-project/end-to-end/src/e2e_orderbook.test.ts @@ -52,9 +52,9 @@ describe('Orderbook', () => { ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); - orderbook = await OrderbookContract.deploy(wallet, token0.address, token1.address).send({ + ({ contract: orderbook } = await OrderbookContract.deploy(wallet, token0.address, token1.address).send({ from: adminAddress, - }); + })); // Mint tokens to maker and taker await mintTokensToPrivate(token0, adminAddress, makerAddress, bidAmount); @@ -95,7 +95,9 @@ describe('Orderbook', () => { orderId = orderCreatedEvents[0].event.order_id; // Get order from orderbook and verify details - const [order, isFulfilled] = await orderbook.methods.get_order(orderId).simulate({ from: adminAddress }); + const { + result: [order, isFulfilled], + } = await orderbook.methods.get_order(orderId).simulate({ from: adminAddress }); expect(order.bid_amount).toEqual(bidAmount); expect(order.ask_amount).toEqual(askAmount); expect(order.bid_token_is_zero).toBeTrue(); @@ -103,10 +105,12 @@ describe('Orderbook', () => { // At this point, bidAmount of token0 should be transferred to the public balance of the orderbook and maker // should have 0. - const orderbookBalances0 = await token0.methods + const { result: orderbookBalances0 } = await token0.methods .balance_of_public(orderbook.address) .simulate({ from: makerAddress }); - const makerBalances0 = await token0.methods.balance_of_private(makerAddress).simulate({ from: makerAddress }); + const { result: makerBalances0 } = await token0.methods + .balance_of_private(makerAddress) + .simulate({ from: makerAddress }); expect(orderbookBalances0).toEqual(bidAmount); expect(makerBalances0).toEqual(0n); }); @@ -142,10 +146,18 @@ describe('Orderbook', () => { expect(orderFulfilledEvents[0].event.order_id).toEqual(orderId); // Verify balances after order fulfillment - const makerBalances0 = await token0.methods.balance_of_private(makerAddress).simulate({ from: makerAddress }); - const makerBalances1 = await token1.methods.balance_of_private(makerAddress).simulate({ from: makerAddress }); - const takerBalances0 = await token0.methods.balance_of_private(takerAddress).simulate({ from: takerAddress }); - const takerBalances1 = await token1.methods.balance_of_private(takerAddress).simulate({ from: takerAddress }); + const { result: makerBalances0 } = await token0.methods + .balance_of_private(makerAddress) + .simulate({ from: makerAddress }); + const { result: makerBalances1 } = await token1.methods + .balance_of_private(makerAddress) + .simulate({ from: makerAddress }); + const { result: takerBalances0 } = await token0.methods + .balance_of_private(takerAddress) + .simulate({ from: takerAddress }); + const { result: takerBalances1 } = await token1.methods + .balance_of_private(takerAddress) + .simulate({ from: takerAddress }); // Full maker token 0 balance should be transferred to taker and hence maker should have 0 expect(makerBalances0).toEqual(0n); @@ -157,7 +169,9 @@ describe('Orderbook', () => { expect(takerBalances1).toEqual(0n); // Verify that the order is fulfilled - const [_, isFulfilled] = await orderbook.methods.get_order(orderId).simulate({ from: adminAddress }); + const { + result: [_, isFulfilled], + } = await orderbook.methods.get_order(orderId).simulate({ from: adminAddress }); expect(isFulfilled).toBeTrue(); }); }); diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index fb310765f04e..56f8df05058a 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -56,8 +56,8 @@ describe('e2e_ordering', () => { let pubSetValueSelector: FunctionSelector; beforeEach(async () => { - parent = await ParentContract.deploy(wallet).send({ from: defaultAccountAddress }); - child = await ChildContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: parent } = await ParentContract.deploy(wallet).send({ from: defaultAccountAddress })); + ({ contract: child } = await ChildContract.deploy(wallet).send({ from: defaultAccountAddress })); pubSetValueSelector = await child.methods.pub_set_value.selector(); }, TIMEOUT); diff --git a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts index a1964ef8f74b..786b2c9aa7a5 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts @@ -285,7 +285,7 @@ describe('e2e_p2p_add_rollup', () => { const aliceAddress = aliceAccountManager.address; - const testContract = await TestContract.deploy(wallet).send({ from: aliceAddress }); + const { contract: testContract } = await TestContract.deploy(wallet).send({ from: aliceAddress }); const [secret, secretHash] = await generateClaimSecret(); @@ -304,7 +304,7 @@ describe('e2e_p2p_add_rollup', () => { // We poll isL1ToL2MessageSynced endpoint until the message is available await retryUntil(async () => await node.isL1ToL2MessageSynced(msgHash), 'message sync', 10); - const receipt = await testContract.methods + const { receipt } = await testContract.methods .create_l2_to_l1_message_arbitrary_recipient_private(contentOutFromRollup, ethRecipient) .send({ from: aliceAddress }); diff --git a/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts b/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts index bdb752da9f00..1f2120f28177 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts @@ -323,8 +323,9 @@ export class P2PNetworkTest { throw new Error('Call setupAccount before deploying spam contract'); } - const spamContract = await SpamContract.deploy(this.wallet).send({ from: this.defaultAccountAddress! }); - this.spamContract = spamContract; + ({ contract: this.spamContract } = await SpamContract.deploy(this.wallet).send({ + from: this.defaultAccountAddress!, + })); } async removeInitialNode() { diff --git a/yarn-project/end-to-end/src/e2e_p2p/shared.ts b/yarn-project/end-to-end/src/e2e_p2p/shared.ts index 5b3450673e24..a74488fef1c0 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/shared.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/shared.ts @@ -41,7 +41,7 @@ export const submitComplexTxsTo = async ( const spamCount = 15; for (let i = 0; i < numTxs; i++) { const method = spamContract.methods.spam(seed + BigInt(i * spamCount), spamCount, !!opts.callPublic); - const txHash = await method.send({ from, wait: NO_WAIT }); + const { txHash } = await method.send({ from, wait: NO_WAIT }); logger.info(`Tx sent with hash ${txHash.toString()}`); txs.push(txHash); } diff --git a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts index 104d7ef3b215..8742a20129a0 100644 --- a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts +++ b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts @@ -43,7 +43,8 @@ describe('partial notes', () => { it('mint to private', async () => { await mintTokensToPrivate(token0, adminAddress, liquidityProviderAddress, INITIAL_TOKEN_BALANCE); expect( - await token0.methods.balance_of_private(liquidityProviderAddress).simulate({ from: liquidityProviderAddress }), + (await token0.methods.balance_of_private(liquidityProviderAddress).simulate({ from: liquidityProviderAddress })) + .result, ).toEqual(INITIAL_TOKEN_BALANCE); }); }); diff --git a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts index 3b01932f8edf..9982087e83dd 100644 --- a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts @@ -75,7 +75,7 @@ describe('e2e_pending_note_hashes_contract', () => { const deployContract = async () => { logger.debug(`Deploying L2 contract...`); - contract = await PendingNoteHashesContract.deploy(wallet).send({ from: owner }); + ({ contract } = await PendingNoteHashesContract.deploy(wallet).send({ from: owner })); logger.info(`L2 contract deployed at ${contract.address}`); return contract; }; diff --git a/yarn-project/end-to-end/src/e2e_phase_check.test.ts b/yarn-project/end-to-end/src/e2e_phase_check.test.ts index 03ba19047c61..581611cbbd71 100644 --- a/yarn-project/end-to-end/src/e2e_phase_check.test.ts +++ b/yarn-project/end-to-end/src/e2e_phase_check.test.ts @@ -35,7 +35,7 @@ describe('Phase check', () => { accounts: [defaultAccountAddress], } = await setup(1, { genesisPublicData: [genesisBalanceEntry] })); - contract = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); sponsoredFPC = await SponsoredFPCNoEndSetupContract.deploy(wallet).register({ contractAddressSalt: new Fr(SPONSORED_FPC_SALT), }); diff --git a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts index 86809063a08c..6a60739c2d36 100644 --- a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts @@ -25,7 +25,7 @@ describe('e2e_voting_contract', () => { accounts: [owner], } = await setup(1)); - votingContract = await PrivateVotingContract.deploy(wallet, owner).send({ from: owner }); + ({ contract: votingContract } = await PrivateVotingContract.deploy(wallet, owner).send({ from: owner })); logger.info(`Counter contract deployed at ${votingContract.address}`); }); @@ -40,7 +40,7 @@ describe('e2e_voting_contract', () => { await votingContract.methods.start_vote(electionId).send({ from: owner }); await votingContract.methods.cast_vote(electionId, candidate).send({ from: owner }); - expect(await votingContract.methods.get_tally(electionId, candidate).simulate({ from: owner })).toBe(1n); + expect((await votingContract.methods.get_tally(electionId, candidate).simulate({ from: owner })).result).toBe(1n); // We try voting again, but our TX is dropped due to trying to emit duplicate nullifiers // first confirm that it fails simulation diff --git a/yarn-project/end-to-end/src/e2e_prover/client.test.ts b/yarn-project/end-to-end/src/e2e_prover/client.test.ts index 7ff197d01a71..aef6fcd86af6 100644 --- a/yarn-project/end-to-end/src/e2e_prover/client.test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/client.test.ts @@ -71,12 +71,14 @@ describe('client_prover', () => { ); // Create the two transactions - const privateBalance = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); + const { result: privateBalance } = await provenAsset.methods + .balance_of_private(sender) + .simulate({ from: sender }); const privateSendAmount = privateBalance / 10n; expect(privateSendAmount).toBeGreaterThan(0n); const privateInteraction = provenAsset.methods.transfer(recipient, privateSendAmount); - const publicBalance = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); + const { result: publicBalance } = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); const publicSendAmount = publicBalance / 10n; expect(publicSendAmount).toBeGreaterThan(0n); const publicInteraction = provenAsset.methods.transfer_in_public(sender, recipient, publicSendAmount, 0); diff --git a/yarn-project/end-to-end/src/e2e_prover/full.test.ts b/yarn-project/end-to-end/src/e2e_prover/full.test.ts index eb3dc3e82529..7d70a5b443d2 100644 --- a/yarn-project/end-to-end/src/e2e_prover/full.test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/full.test.ts @@ -87,12 +87,14 @@ describe('full_prover', () => { ); // Create the two transactions - const privateBalance = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); + const { result: privateBalance } = await provenAsset.methods + .balance_of_private(sender) + .simulate({ from: sender }); const privateSendAmount = privateBalance / 10n; expect(privateSendAmount).toBeGreaterThan(0n); const privateInteraction = provenAsset.methods.transfer(recipient, privateSendAmount); - const publicBalance = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); + const { result: publicBalance } = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); const publicSendAmount = publicBalance / 10n; expect(publicSendAmount).toBeGreaterThan(0n); const publicInteraction = provenAsset.methods.transfer_in_public(sender, recipient, publicSendAmount, 0); @@ -180,12 +182,12 @@ describe('full_prover', () => { return; } // Create the two transactions - const privateBalance = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); + const { result: privateBalance } = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); const privateSendAmount = privateBalance / 20n; expect(privateSendAmount).toBeGreaterThan(0n); const firstPrivateInteraction = provenAsset.methods.transfer(recipient, privateSendAmount); - const publicBalance = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); + const { result: publicBalance } = await provenAsset.methods.balance_of_public(sender).simulate({ from: sender }); const publicSendAmount = publicBalance / 10n; expect(publicSendAmount).toBeGreaterThan(0n); const publicInteraction = provenAsset.methods.transfer_in_public(sender, recipient, publicSendAmount, 0); diff --git a/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts b/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts index 50a8db649dd6..02db37673052 100644 --- a/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts +++ b/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts @@ -53,7 +53,7 @@ describe('e2e_pruned_blocks', () => { aztecProofSubmissionEpochs: 1024, // effectively do not reorg })); - token = await TokenContract.deploy(wallet, admin, 'TEST', '$TST', 18).send({ from: admin }); + ({ contract: token } = await TokenContract.deploy(wallet, admin, 'TEST', '$TST', 18).send({ from: admin })); logger.info(`L2 token contract deployed at ${token.address}`); }); @@ -76,7 +76,9 @@ describe('e2e_pruned_blocks', () => { // mint transaction that the node will drop the block corresponding to the first mint, resulting in errors if PXE // tried to access any historical information related to it (which it shouldn't). - const firstMintReceipt = await token.methods.mint_to_private(sender, MINT_AMOUNT / 2n).send({ from: admin }); + const { receipt: firstMintReceipt } = await token.methods + .mint_to_private(sender, MINT_AMOUNT / 2n) + .send({ from: admin }); const firstMintTxEffect = await aztecNode.getTxEffect(firstMintReceipt.txHash); // mint_to_private should create just one new note with the minted amount @@ -122,7 +124,9 @@ describe('e2e_pruned_blocks', () => { await token.methods.transfer(recipient, MINT_AMOUNT).send({ from: sender }); - expect(await token.methods.balance_of_private(recipient).simulate({ from: recipient })).toEqual(MINT_AMOUNT); - expect(await token.methods.balance_of_private(sender).simulate({ from: sender })).toEqual(0n); + expect((await token.methods.balance_of_private(recipient).simulate({ from: recipient })).result).toEqual( + MINT_AMOUNT, + ); + expect((await token.methods.balance_of_private(sender).simulate({ from: sender })).result).toEqual(0n); }); }); diff --git a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts index a5ed696875eb..daed07568294 100644 --- a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts @@ -60,7 +60,7 @@ describe(`deploys and transfers a private only token`, () => { ); const tokenInstance = await tokenDeployment.getInstance(); await wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey); - const token = await tokenDeployment.send({ + const { contract: token } = await tokenDeployment.send({ from: deployerAddress, universalDeploy: true, skipInstancePublication: true, @@ -76,8 +76,12 @@ describe(`deploys and transfers a private only token`, () => { logger.info(`Transfer completed`); - const balanceDeployer = await token.methods.get_balance(deployerAddress).simulate({ from: deployerAddress }); - const balanceRecipient = await token.methods.get_balance(recipientAddress).simulate({ from: recipientAddress }); + const { result: balanceDeployer } = await token.methods + .get_balance(deployerAddress) + .simulate({ from: deployerAddress }); + const { result: balanceRecipient } = await token.methods + .get_balance(recipientAddress) + .simulate({ from: recipientAddress }); logger.info(`Deployer balance: ${balanceDeployer}, Recipient balance: ${balanceRecipient}`); diff --git a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts index c84eeadc62b0..5c8e4e2fdfc2 100644 --- a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts +++ b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts @@ -21,7 +21,7 @@ describe('e2e scope isolation', () => { ({ teardown, wallet, accounts } = await setup(3)); [alice, bob, charlie] = accounts; - contract = await ScopeTestContract.deploy(wallet).send({ from: alice }); + ({ contract } = await ScopeTestContract.deploy(wallet).send({ from: alice })); // Alice and bob create a note for themselves (used by multiple tests below) await contract.methods.create_note(alice, Number(ALICE_NOTE_VALUE)).send({ from: alice }); @@ -32,7 +32,7 @@ describe('e2e scope isolation', () => { describe('external private', () => { it('owner can read own notes', async () => { - const value = await contract.methods.read_note(alice).simulate({ from: alice }); + const { result: value } = await contract.methods.read_note(alice).simulate({ from: alice }); expect(value).toEqual(ALICE_NOTE_VALUE); }); @@ -47,8 +47,8 @@ describe('e2e scope isolation', () => { }); it('each account can access their isolated state on a shared wallet', async () => { - const aliceValue = await contract.methods.read_note(alice).simulate({ from: alice }); - const bobValue = await contract.methods.read_note(bob).simulate({ from: bob }); + const { result: aliceValue } = await contract.methods.read_note(alice).simulate({ from: alice }); + const { result: bobValue } = await contract.methods.read_note(bob).simulate({ from: bob }); expect(aliceValue).toEqual(ALICE_NOTE_VALUE); expect(bobValue).toEqual(BOB_NOTE_VALUE); @@ -57,7 +57,7 @@ describe('e2e scope isolation', () => { describe('external utility', () => { it('owner can read own notes', async () => { - const value = await contract.methods.read_note_utility(alice).simulate({ from: alice }); + const { result: value } = await contract.methods.read_note_utility(alice).simulate({ from: alice }); expect(value).toEqual(ALICE_NOTE_VALUE); }); @@ -74,8 +74,8 @@ describe('e2e scope isolation', () => { }); it('each account can access their isolated state on a shared wallet', async () => { - const aliceValue = await contract.methods.read_note_utility(alice).simulate({ from: alice }); - const bobValue = await contract.methods.read_note_utility(bob).simulate({ from: bob }); + const { result: aliceValue } = await contract.methods.read_note_utility(alice).simulate({ from: alice }); + const { result: bobValue } = await contract.methods.read_note_utility(bob).simulate({ from: bob }); expect(aliceValue).toEqual(ALICE_NOTE_VALUE); expect(bobValue).toEqual(BOB_NOTE_VALUE); diff --git a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts index b223bc086f1f..8795dc257a6f 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts @@ -112,7 +112,7 @@ describe('e2e_gov_proposal', () => { // Deploy a test contract to send msgs via the outbox, since this increases // gas cost of a proposal, which has triggered oog errors in the past. - testContract = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); logger.warn(`Deployed test contract at ${testContract.address}`); await cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); @@ -169,11 +169,12 @@ describe('e2e_gov_proposal', () => { // since we wait for the txs to be mined, and do so `roundDuration` times. // Simultaneously, we should be voting for the proposal in every slot. for (let i = 0; i < roundDuration; i++) { - const txHashes = await timesAsync(TXS_PER_BLOCK, () => - testContract.methods + const txHashes = await timesAsync(TXS_PER_BLOCK, async () => { + const { txHash } = await testContract.methods .create_l2_to_l1_message_arbitrary_recipient_private(Fr.random(), EthAddress.random()) - .send({ from: defaultAccountAddress, wait: NO_WAIT }), - ); + .send({ from: defaultAccountAddress, wait: NO_WAIT }); + return txHash; + }); await Promise.all( txHashes.map((hash, j) => { logger.info(`Waiting for tx ${i}-${j}: ${hash} to be mined`); diff --git a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts index 09deed9db69d..667728c4056b 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts @@ -130,7 +130,7 @@ describe('e2e_reload_keystore', () => { // Send a tx and verify the block uses the initial coinbase const deployer = new ContractDeployer(artifact, wallet); - const sentTx1 = await deployer.deploy(ownerAddress, ownerAddress, 1).send({ + const { txHash: sentTx1 } = await deployer.deploy(ownerAddress, ownerAddress, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(1), skipClassPublication: true, @@ -197,7 +197,7 @@ describe('e2e_reload_keystore', () => { // Whichever validator is the proposer, its coinbase must be from the reloaded keystore. const allNewCoinbasesLower = newCoinbases.map(c => c.toString().toLowerCase()); - const sentTx2 = await deployer.deploy(ownerAddress, ownerAddress, 2).send({ + const { txHash: sentTx2 } = await deployer.deploy(ownerAddress, ownerAddress, 2).send({ from: ownerAddress, contractAddressSalt: new Fr(2), skipClassPublication: true, diff --git a/yarn-project/end-to-end/src/e2e_simple.test.ts b/yarn-project/end-to-end/src/e2e_simple.test.ts index 0fcedb023202..1dbfe5861776 100644 --- a/yarn-project/end-to-end/src/e2e_simple.test.ts +++ b/yarn-project/end-to-end/src/e2e_simple.test.ts @@ -72,7 +72,7 @@ describe('e2e_simple', () => { const deployer = new ContractDeployer(artifact, wallet); const sender = ownerAddress; - const txReceipt = await deployer.deploy(ownerAddress, sender, 1).send({ + const { receipt: txReceipt } = await deployer.deploy(ownerAddress, sender, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(1)), skipClassPublication: true, diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index c5b8d6f0635b..6d2f58a7f37d 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -33,7 +33,7 @@ describe('e2e_state_vars', () => { wallet, accounts: [defaultAccountAddress], } = await setup(1)); - contract = await StateVarsContract.deploy(wallet).send({ from: defaultAccountAddress }); + ({ contract } = await StateVarsContract.deploy(wallet).send({ from: defaultAccountAddress })); }); afterAll(() => teardown()); @@ -51,7 +51,7 @@ describe('e2e_state_vars', () => { await contract.methods.initialize_public_immutable(1).send({ from: defaultAccountAddress }); - const read = await contract.methods.get_public_immutable().simulate({ from: defaultAccountAddress }); + const { result: read } = await contract.methods.get_public_immutable().simulate({ from: defaultAccountAddress }); expect(read).toEqual({ account: defaultAccountAddress, value: read.value }); }); @@ -62,11 +62,13 @@ describe('e2e_state_vars', () => { // 2. A constrained private function that calls another private function that reads. // The indirect, adds 1 to the point to ensure that we are returning the correct value. - const [a, b, c] = await new BatchCall(wallet, [ - contract.methods.get_public_immutable_constrained_private(), - contract.methods.get_public_immutable_constrained_private_indirect(), - contract.methods.get_public_immutable(), - ]).simulate({ from: defaultAccountAddress }); + const [a, b, c] = ( + await new BatchCall(wallet, [ + contract.methods.get_public_immutable_constrained_private(), + contract.methods.get_public_immutable_constrained_private_indirect(), + contract.methods.get_public_immutable(), + ]).simulate({ from: defaultAccountAddress }) + ).map((r: any) => r.result); expect(a).toEqual(c); expect(b).toEqual({ account: c.account, value: c.value + 1n }); @@ -79,11 +81,13 @@ describe('e2e_state_vars', () => { // 2. A constrained public function that calls another public function that reads. // The indirect, adds 1 to the point to ensure that we are returning the correct value. - const [a, b, c] = await new BatchCall(wallet, [ - contract.methods.get_public_immutable_constrained_public(), - contract.methods.get_public_immutable_constrained_public_indirect(), - contract.methods.get_public_immutable(), - ]).simulate({ from: defaultAccountAddress }); + const [a, b, c] = ( + await new BatchCall(wallet, [ + contract.methods.get_public_immutable_constrained_public(), + contract.methods.get_public_immutable_constrained_public_indirect(), + contract.methods.get_public_immutable(), + ]).simulate({ from: defaultAccountAddress }) + ).map((r: any) => r.result); expect(a).toEqual(c); expect(b).toEqual({ account: c.account, value: c.value + 1n }); @@ -95,10 +99,10 @@ describe('e2e_state_vars', () => { // Reads the value using a utility function checking the return values with: // 1. A constrained public function that reads 5 times directly (going beyond the previous 4 Field return value) - const a = await contract.methods + const { result: a } = await contract.methods .get_public_immutable_constrained_public_multiple() .simulate({ from: defaultAccountAddress }); - const c = await contract.methods.get_public_immutable().simulate({ from: defaultAccountAddress }); + const { result: c } = await contract.methods.get_public_immutable().simulate({ from: defaultAccountAddress }); expect(a).toEqual([c, c, c, c, c]); }); @@ -115,9 +119,11 @@ describe('e2e_state_vars', () => { describe('PrivateMutable', () => { it('fail to read uninitialized PrivateMutable', async () => { expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(false); await expect( contract.methods.get_private_mutable(defaultAccountAddress).simulate({ from: defaultAccountAddress }), @@ -126,12 +132,14 @@ describe('e2e_state_vars', () => { it('initialize PrivateMutable', async () => { expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(false); // Send the transaction and wait for it to be mined (wait function throws if the tx is not mined) - const txReceipt = await contract.methods + const { receipt: txReceipt } = await contract.methods .initialize_private(RANDOMNESS, VALUE) .send({ from: defaultAccountAddress }); @@ -140,50 +148,60 @@ describe('e2e_state_vars', () => { // 1 for the tx, another for the initializer expect(txEffects?.data.nullifiers.length).toEqual(2); expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); }); it('fail to reinitialize', async () => { expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); await expect( contract.methods.initialize_private(RANDOMNESS, VALUE).send({ from: defaultAccountAddress }), ).rejects.toThrow(); expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); }); it('read initialized PrivateMutable', async () => { expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); - const { value } = await contract.methods - .get_private_mutable(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }); + const { + result: { value }, + } = await contract.methods.get_private_mutable(defaultAccountAddress).simulate({ from: defaultAccountAddress }); expect(value).toEqual(VALUE); }); it('replace with same value', async () => { expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); - const noteBefore = await contract.methods + const { result: noteBefore } = await contract.methods .get_private_mutable(defaultAccountAddress) .simulate({ from: defaultAccountAddress }); - const txReceipt = await contract.methods + const { receipt: txReceipt } = await contract.methods .update_private_mutable(RANDOMNESS, VALUE) .send({ from: defaultAccountAddress }); @@ -193,7 +211,7 @@ describe('e2e_state_vars', () => { // 1 for the tx, another for the nullifier of the previous note expect(txEffects?.data.nullifiers.length).toEqual(2); - const noteAfter = await contract.methods + const { result: noteAfter } = await contract.methods .get_private_mutable(defaultAccountAddress) .simulate({ from: defaultAccountAddress }); @@ -202,11 +220,13 @@ describe('e2e_state_vars', () => { it('replace PrivateMutable with other values', async () => { expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); - const txReceipt = await contract.methods + const { receipt: txReceipt } = await contract.methods .update_private_mutable(RANDOMNESS + 2n, VALUE + 1n) .send({ from: defaultAccountAddress }); @@ -216,22 +236,26 @@ describe('e2e_state_vars', () => { // 1 for the tx, another for the nullifier of the previous note expect(txEffects?.data.nullifiers.length).toEqual(2); - const { value } = await contract.methods - .get_private_mutable(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }); + const { + result: { value }, + } = await contract.methods.get_private_mutable(defaultAccountAddress).simulate({ from: defaultAccountAddress }); expect(value).toEqual(VALUE + 1n); }); it('replace PrivateMutable dependent on prior value', async () => { expect( - await contract.methods - .is_private_mutable_initialized(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_private_mutable_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); - const noteBefore = await contract.methods + const { result: noteBefore } = await contract.methods .get_private_mutable(defaultAccountAddress) .simulate({ from: defaultAccountAddress }); - const txReceipt = await contract.methods.increase_private_value().send({ from: defaultAccountAddress }); + const { receipt: txReceipt } = await contract.methods + .increase_private_value() + .send({ from: defaultAccountAddress }); const txEffects = await aztecNode.getTxEffect(txReceipt.txHash); @@ -239,9 +263,9 @@ describe('e2e_state_vars', () => { // 1 for the tx, another for the nullifier of the previous note expect(txEffects?.data.nullifiers.length).toEqual(2); - const { value } = await contract.methods - .get_private_mutable(defaultAccountAddress) - .simulate({ from: defaultAccountAddress }); + const { + result: { value }, + } = await contract.methods.get_private_mutable(defaultAccountAddress).simulate({ from: defaultAccountAddress }); expect(value).toEqual(noteBefore.value + 1n); }); }); @@ -249,7 +273,11 @@ describe('e2e_state_vars', () => { describe('PrivateImmutable', () => { it('fail to read uninitialized PrivateImmutable', async () => { expect( - await contract.methods.is_priv_imm_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_priv_imm_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(false); await expect( contract.methods.view_private_immutable(defaultAccountAddress).simulate({ from: defaultAccountAddress }), @@ -258,9 +286,13 @@ describe('e2e_state_vars', () => { it('initialize PrivateImmutable', async () => { expect( - await contract.methods.is_priv_imm_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_priv_imm_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(false); - const txReceipt = await contract.methods + const { receipt: txReceipt } = await contract.methods .initialize_private_immutable(RANDOMNESS, VALUE) .send({ from: defaultAccountAddress }); @@ -270,27 +302,45 @@ describe('e2e_state_vars', () => { // 1 for the tx, another for the initializer expect(txEffects?.data.nullifiers.length).toEqual(2); expect( - await contract.methods.is_priv_imm_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_priv_imm_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); }); it('fail to reinitialize', async () => { expect( - await contract.methods.is_priv_imm_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_priv_imm_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); await expect( contract.methods.initialize_private_immutable(RANDOMNESS, VALUE).send({ from: defaultAccountAddress }), ).rejects.toThrow(); expect( - await contract.methods.is_priv_imm_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_priv_imm_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); }); it('read initialized PrivateImmutable', async () => { expect( - await contract.methods.is_priv_imm_initialized(defaultAccountAddress).simulate({ from: defaultAccountAddress }), + ( + await contract.methods + .is_priv_imm_initialized(defaultAccountAddress) + .simulate({ from: defaultAccountAddress }) + ).result, ).toEqual(true); - const { value } = await contract.methods + const { + result: { value }, + } = await contract.methods .view_private_immutable(defaultAccountAddress) .simulate({ from: defaultAccountAddress }); expect(value).toEqual(VALUE); @@ -310,9 +360,9 @@ describe('e2e_state_vars', () => { beforeAll(async () => { // We use the auth contract here because has a nice, clear, simple implementation of Delayed Public Mutable - authContract = await AuthContract.deploy(wallet, defaultAccountAddress).send({ + ({ contract: authContract } = await AuthContract.deploy(wallet, defaultAccountAddress).send({ from: defaultAccountAddress, - }); + })); if (aztecSlotDuration !== 72) { throw new Error( diff --git a/yarn-project/end-to-end/src/e2e_static_calls.test.ts b/yarn-project/end-to-end/src/e2e_static_calls.test.ts index 9576d39f7845..1e2cc3117f1b 100644 --- a/yarn-project/end-to-end/src/e2e_static_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_static_calls.test.ts @@ -21,8 +21,8 @@ describe('e2e_static_calls', () => { accounts: [owner], } = await setup()); sender = owner; - parentContract = await StaticParentContract.deploy(wallet).send({ from: owner }); - childContract = await StaticChildContract.deploy(wallet).send({ from: owner }); + ({ contract: parentContract } = await StaticParentContract.deploy(wallet).send({ from: owner })); + ({ contract: childContract } = await StaticChildContract.deploy(wallet).send({ from: owner })); // We create a note in the set, such that later reads doesn't fail due to get_notes returning 0 notes await childContract.methods.private_set_value(42n, owner, sender).send({ from: owner }); diff --git a/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts b/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts index cdee4c492b29..70c6ce8b0b8f 100644 --- a/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts +++ b/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts @@ -13,7 +13,7 @@ describe('Storage proof', () => { beforeAll(async () => { ctx = await setup(1); - contract = await StorageProofTestContract.deploy(ctx.wallet).send({ from: ctx.accounts[0] }); + ({ contract } = await StorageProofTestContract.deploy(ctx.wallet).send({ from: ctx.accounts[0] })); }); afterAll(async () => { @@ -26,7 +26,7 @@ describe('Storage proof', () => { ctx.logger.info('Sending storage proof TX...'); - const receipt = await contract.methods + const { receipt } = await contract.methods .storage_proof(ethAddress, slotKey, slotContents, root) .with({ capsules }) .send({ from: ctx.accounts[0] }); diff --git a/yarn-project/end-to-end/src/e2e_synching.test.ts b/yarn-project/end-to-end/src/e2e_synching.test.ts index 76a54cd05832..c93560f43064 100644 --- a/yarn-project/end-to-end/src/e2e_synching.test.ts +++ b/yarn-project/end-to-end/src/e2e_synching.test.ts @@ -203,7 +203,7 @@ class TestVariant { ); this.contractAddresses.push(accountManager.address); const deployMethod = await accountManager.getDeployMethod(); - const txHash = await deployMethod.send({ + const { txHash } = await deployMethod.send({ from: deployAccount, skipClassPublication: true, skipInstancePublication: true, @@ -218,7 +218,9 @@ class TestVariant { for (let i = 0; i < this.txCount; i++) { const recipient = this.accounts[(i + 1) % this.txCount]; const tk = TokenContract.at(this.token.address, this.wallet); - txHashes.push(await tk.methods.transfer(recipient, 1n).send({ from: this.accounts[i], wait: NO_WAIT })); + txHashes.push( + (await tk.methods.transfer(recipient, 1n).send({ from: this.accounts[i], wait: NO_WAIT })).txHash, + ); } return txHashes; } else if (this.txComplexity == TxComplexity.PublicTransfer) { @@ -229,7 +231,7 @@ class TestVariant { const recipient = this.accounts[(i + 1) % this.txCount]; const tk = TokenContract.at(this.token.address, this.wallet); txHashes.push( - await tk.methods.transfer_in_public(sender, recipient, 1n, 0).send({ from: sender, wait: NO_WAIT }), + (await tk.methods.transfer_in_public(sender, recipient, 1n, 0).send({ from: sender, wait: NO_WAIT })).txHash, ); } return txHashes; @@ -247,7 +249,7 @@ class TestVariant { ]); this.seed += 100n; - txHashes.push(await batch.send({ from: this.accounts[0], wait: NO_WAIT })); + txHashes.push((await batch.send({ from: this.accounts[0], wait: NO_WAIT })).txHash); } return txHashes; } else { @@ -340,10 +342,16 @@ describe('e2e_synching', () => { variant.setWallet(wallet); // Deploy a token, such that we could use it - const token = await TokenContract.deploy(wallet, defaultAccountAddress, 'TestToken', 'TST', 18n).send({ + const { contract: token } = await TokenContract.deploy( + wallet, + defaultAccountAddress, + 'TestToken', + 'TST', + 18n, + ).send({ from: defaultAccountAddress, }); - const spam = await SpamContract.deploy(wallet).send({ from: defaultAccountAddress }); + const { contract: spam } = await SpamContract.deploy(wallet).send({ from: defaultAccountAddress }); variant.setToken(token); variant.setSpam(spam); @@ -542,15 +550,21 @@ describe('e2e_synching', () => { const defaultAccountAddress = (await variant.deployAccounts(opts.initialFundedAccounts!.slice(0, 1)))[0]; contracts.push( - await TokenContract.deploy(wallet, defaultAccountAddress, 'TestToken', 'TST', 18n).send({ - from: defaultAccountAddress, - }), + ( + await TokenContract.deploy(wallet, defaultAccountAddress, 'TestToken', 'TST', 18n).send({ + from: defaultAccountAddress, + }) + ).contract, + ); + contracts.push( + (await SchnorrHardcodedAccountContract.deploy(wallet).send({ from: defaultAccountAddress })).contract, ); - contracts.push(await SchnorrHardcodedAccountContract.deploy(wallet).send({ from: defaultAccountAddress })); contracts.push( - await TokenContract.deploy(wallet, defaultAccountAddress, 'TestToken', 'TST', 18n).send({ - from: defaultAccountAddress, - }), + ( + await TokenContract.deploy(wallet, defaultAccountAddress, 'TestToken', 'TST', 18n).send({ + from: defaultAccountAddress, + }) + ).contract, ); await watcher.stop(); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts index cab2d394475f..50ac4a7f36be 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts @@ -18,17 +18,19 @@ describe('e2e_token_contract access control', () => { it('Set admin', async () => { await t.asset.methods.set_admin(t.account1Address).send({ from: t.adminAddress }); - expect(await t.asset.methods.get_admin().simulate({ from: t.adminAddress })).toBe(t.account1Address.toBigInt()); + expect((await t.asset.methods.get_admin().simulate({ from: t.adminAddress })).result).toBe( + t.account1Address.toBigInt(), + ); }); it('Add minter as admin', async () => { await t.asset.methods.set_minter(t.account1Address, true).send({ from: t.account1Address }); - expect(await t.asset.methods.is_minter(t.account1Address).simulate({ from: t.adminAddress })).toBe(true); + expect((await t.asset.methods.is_minter(t.account1Address).simulate({ from: t.adminAddress })).result).toBe(true); }); it('Revoke minter as admin', async () => { await t.asset.methods.set_minter(t.account1Address, false).send({ from: t.account1Address }); - expect(await t.asset.methods.is_minter(t.account1Address).simulate({ from: t.adminAddress })).toBe(false); + expect((await t.asset.methods.is_minter(t.account1Address).simulate({ from: t.adminAddress })).result).toBe(false); }); describe('failure cases', () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts index 1c9b670771ca..b9760a983627 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts @@ -27,7 +27,7 @@ describe('e2e_token_contract burn', () => { describe('public', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.burn_public(adminAddress, amount, 0).send({ from: adminAddress }); @@ -36,7 +36,7 @@ describe('e2e_token_contract burn', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const authwitNonce = Fr.random(); @@ -61,7 +61,9 @@ describe('e2e_token_contract burn', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 1n; const authwitNonce = 0; await expect( @@ -70,7 +72,9 @@ describe('e2e_token_contract burn', () => { }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); const authwitNonce = 1; @@ -82,7 +86,9 @@ describe('e2e_token_contract burn', () => { }); it('burn on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 1n; const authwitNonce = Fr.random(); await expect( @@ -91,7 +97,9 @@ describe('e2e_token_contract burn', () => { }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -109,7 +117,9 @@ describe('e2e_token_contract burn', () => { }); it('burn on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -132,7 +142,9 @@ describe('e2e_token_contract burn', () => { describe('private', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.burn_private(adminAddress, amount, 0).send({ from: adminAddress }); @@ -140,7 +152,9 @@ describe('e2e_token_contract burn', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -160,7 +174,9 @@ describe('e2e_token_contract burn', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); await expect( @@ -169,7 +185,9 @@ describe('e2e_token_contract burn', () => { }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); await expect( @@ -180,7 +198,9 @@ describe('e2e_token_contract burn', () => { }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -195,7 +215,9 @@ describe('e2e_token_contract burn', () => { }); it('burn on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -214,7 +236,9 @@ describe('e2e_token_contract burn', () => { }); it('on behalf of other (invalid designated caller)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balancePriv0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePriv0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts index bc6a1251a833..e7479801a3a6 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts @@ -25,10 +25,12 @@ describe('e2e_token_contract minting', () => { await asset.methods.mint_to_public(adminAddress, amount).send({ from: adminAddress }); tokenSim.mintPublic(adminAddress, amount); - expect(await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).toEqual( + expect((await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).result).toEqual( tokenSim.balanceOfPublic(adminAddress), ); - expect(await asset.methods.total_supply().simulate({ from: adminAddress })).toEqual(tokenSim.totalSupply); + expect((await asset.methods.total_supply().simulate({ from: adminAddress })).result).toEqual( + tokenSim.totalSupply, + ); }); describe('failure cases', () => { @@ -61,10 +63,12 @@ describe('e2e_token_contract minting', () => { await asset.methods.mint_to_private(adminAddress, amount).send({ from: adminAddress }); tokenSim.mintPrivate(adminAddress, amount); - expect(await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).toEqual( + expect((await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).result).toEqual( tokenSim.balanceOfPrivate(adminAddress), ); - expect(await asset.methods.total_supply().simulate({ from: adminAddress })).toEqual(tokenSim.totalSupply); + expect((await asset.methods.total_supply().simulate({ from: adminAddress })).result).toEqual( + tokenSim.totalSupply, + ); }); describe('failure cases', () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts index a986ab6799ba..ffa5688df3b5 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts @@ -23,7 +23,9 @@ describe('e2e_token_contract private transfer recursion', () => { // itself to consume them all (since it retrieves 2 notes on the first pass and 8 in each subsequent pass). const totalNotes = 16; const totalBalance = await mintNotes(wallet, adminAddress, adminAddress, asset, Array(totalNotes).fill(10n)); - const txReceipt = await asset.methods.transfer(account1Address, totalBalance).send({ from: adminAddress }); + const { receipt: txReceipt } = await asset.methods + .transfer(account1Address, totalBalance) + .send({ from: adminAddress }); const txEffects = await node.getTxEffect(txReceipt.txHash); // We should have nullified all notes, plus an extra nullifier for the transaction and one for the event commitment. @@ -59,7 +61,7 @@ describe('e2e_token_contract private transfer recursion', () => { const totalBalance = await mintNotes(wallet, adminAddress, adminAddress, asset, noteAmounts); const toSend = totalBalance - expectedChange; - const txReceipt = await asset.methods.transfer(account1Address, toSend).send({ from: adminAddress }); + const { receipt: txReceipt } = await asset.methods.transfer(account1Address, toSend).send({ from: adminAddress }); const txEffects = await node.getTxEffect(txReceipt.txHash); // We should have nullified all notes, plus an extra nullifier for the transaction and one for the event commitment. @@ -67,7 +69,9 @@ describe('e2e_token_contract private transfer recursion', () => { // We should have created two new notes, one for the recipient and one for the sender (with the change) expect(txEffects!.data.noteHashes.length).toBe(2); - const senderBalance = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: senderBalance } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); expect(senderBalance).toEqual(expectedChange); const events = await wallet.getPrivateEvents(TokenContract.events.Transfer, { @@ -93,7 +97,9 @@ describe('e2e_token_contract private transfer recursion', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts index a564a5610fed..185ac4231e8e 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts @@ -22,34 +22,40 @@ describe('e2e_token_contract reading constants', () => { }); it('check name private', async () => { - const name = readFieldCompressedString(await t.asset.methods.private_get_name().simulate({ from: t.adminAddress })); + const name = readFieldCompressedString( + (await t.asset.methods.private_get_name().simulate({ from: t.adminAddress })).result, + ); expect(name).toBe(TOKEN_NAME); }); it('check name public', async () => { - const name = readFieldCompressedString(await t.asset.methods.public_get_name().simulate({ from: t.adminAddress })); + const name = readFieldCompressedString( + (await t.asset.methods.public_get_name().simulate({ from: t.adminAddress })).result, + ); expect(name).toBe(TOKEN_NAME); }); it('check symbol private', async () => { const sym = readFieldCompressedString( - await t.asset.methods.private_get_symbol().simulate({ from: t.adminAddress }), + (await t.asset.methods.private_get_symbol().simulate({ from: t.adminAddress })).result, ); expect(sym).toBe(TOKEN_SYMBOL); }); it('check symbol public', async () => { - const sym = readFieldCompressedString(await t.asset.methods.public_get_symbol().simulate({ from: t.adminAddress })); + const sym = readFieldCompressedString( + (await t.asset.methods.public_get_symbol().simulate({ from: t.adminAddress })).result, + ); expect(sym).toBe(TOKEN_SYMBOL); }); it('check decimals private', async () => { - const dec = await t.asset.methods.private_get_decimals().simulate({ from: t.adminAddress }); + const { result: dec } = await t.asset.methods.private_get_decimals().simulate({ from: t.adminAddress }); expect(dec).toBe(TOKEN_DECIMALS); }); it('check decimals public', async () => { - const dec = await t.asset.methods.public_get_decimals().simulate({ from: t.adminAddress }); + const { result: dec } = await t.asset.methods.public_get_decimals().simulate({ from: t.adminAddress }); expect(dec).toBe(TOKEN_DECIMALS); }); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts index ebfde8461643..bbc7f024fd19 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts @@ -81,24 +81,28 @@ export class TokenContractTest { await publicDeployAccounts(this.wallet, [this.adminAddress, this.account1Address]); this.logger.verbose(`Deploying TokenContract...`); - this.asset = await TokenContract.deploy( + ({ contract: this.asset } = await TokenContract.deploy( this.wallet, this.adminAddress, TokenContractTest.TOKEN_NAME, TokenContractTest.TOKEN_SYMBOL, TokenContractTest.TOKEN_DECIMALS, - ).send({ from: this.adminAddress }); + ).send({ from: this.adminAddress })); this.logger.verbose(`Token deployed to ${this.asset.address}`); this.logger.verbose(`Deploying bad account...`); - this.badAccount = await InvalidAccountContract.deploy(this.wallet).send({ from: this.adminAddress }); + ({ contract: this.badAccount } = await InvalidAccountContract.deploy(this.wallet).send({ + from: this.adminAddress, + })); this.logger.verbose(`Deployed to ${this.badAccount.address}.`); // Deploy a proxy contract for "on behalf of other" tests. The note owner must be the tx sender // (so their notes are in scope), but msg_sender in the target must differ from the note owner // to trigger authwit validation. The proxy forwards calls so that msg_sender != tx sender. this.logger.verbose(`Deploying generic proxy...`); - this.authwitProxy = await GenericProxyContract.deploy(this.wallet).send({ from: this.adminAddress }); + ({ contract: this.authwitProxy } = await GenericProxyContract.deploy(this.wallet).send({ + from: this.adminAddress, + })); this.logger.verbose(`Deployed to ${this.authwitProxy.address}.`); this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [ @@ -106,7 +110,7 @@ export class TokenContractTest { this.account1Address, ]); - expect(await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).toBe( + expect((await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).result).toBe( this.adminAddress.toBigInt(), ); } @@ -140,7 +144,9 @@ export class TokenContractTest { await asset.methods.mint_to_public(adminAddress, amount).send({ from: adminAddress }); tokenSim.mintPublic(adminAddress, amount); - const publicBalance = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: publicBalance } = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }); this.logger.verbose(`Public balance of wallet 0: ${publicBalance}`); expect(publicBalance).toEqual(this.tokenSim.balanceOfPublic(adminAddress)); @@ -148,11 +154,13 @@ export class TokenContractTest { await mintTokensToPrivate(asset, adminAddress, adminAddress, amount); tokenSim.mintPrivate(adminAddress, amount); - const privateBalance = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: privateBalance } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); this.logger.verbose(`Private balance of wallet 0: ${privateBalance}`); expect(privateBalance).toEqual(tokenSim.balanceOfPrivate(adminAddress)); - const totalSupply = await asset.methods.total_supply().simulate({ from: adminAddress }); + const { result: totalSupply } = await asset.methods.total_supply().simulate({ from: adminAddress }); this.logger.verbose(`Total supply: ${totalSupply}`); expect(totalSupply).toEqual(tokenSim.totalSupply); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts index d801532f8478..564707a74c77 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts @@ -24,11 +24,11 @@ describe('e2e_token_contract transfer private', () => { }); it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); - const txReceipt = await asset.methods.transfer(account1Address, amount).send({ from: adminAddress }); + const { receipt: txReceipt } = await asset.methods.transfer(account1Address, amount).send({ from: adminAddress }); tokenSim.transferPrivate(adminAddress, account1Address, amount); const events = await wallet.getPrivateEvents(TokenContract.events.Transfer, { @@ -53,7 +53,7 @@ describe('e2e_token_contract transfer private', () => { }); it('transfer less than balance to non-deployed account', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); @@ -68,7 +68,7 @@ describe('e2e_token_contract transfer private', () => { }); it('transfer to self', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer(adminAddress, amount).send({ from: adminAddress }); @@ -77,7 +77,9 @@ describe('e2e_token_contract transfer private', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); await expect(asset.methods.transfer(account1Address, amount).simulate({ from: adminAddress })).rejects.toThrow( diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts index 6177d2845832..385c912cec06 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts @@ -25,7 +25,7 @@ describe('e2e_token_contract transfer private', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -45,7 +45,9 @@ describe('e2e_token_contract transfer private', () => { describe('failure cases', () => { it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); await expect( @@ -61,8 +63,12 @@ describe('e2e_token_contract transfer private', () => { }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); - const balance1 = await asset.methods.balance_of_private(account1Address).simulate({ from: account1Address }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); + const { result: balance1 } = await asset.methods + .balance_of_private(account1Address) + .simulate({ from: account1Address }); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -74,10 +80,12 @@ describe('e2e_token_contract transfer private', () => { await expect( simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }), ).rejects.toThrow('Assertion failed: Balance too low'); - expect(await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); - expect(await asset.methods.balance_of_private(account1Address).simulate({ from: account1Address })).toEqual( - balance1, + expect((await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).result).toEqual( + balance0, ); + expect( + (await asset.methods.balance_of_private(account1Address).simulate({ from: account1Address })).result, + ).toEqual(balance1); }); it.skip('transfer into account to overflow', () => { @@ -88,7 +96,9 @@ describe('e2e_token_contract transfer private', () => { }); it('transfer on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -107,7 +117,9 @@ describe('e2e_token_contract transfer private', () => { }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -125,11 +137,15 @@ describe('e2e_token_contract transfer private', () => { await expect( simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }), ).rejects.toThrow(`Unknown auth witness for message hash ${expectedMessageHash.toString()}`); - expect(await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); + expect((await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).result).toEqual( + balance0, + ); }); it('transfer on behalf of other, cancelled authwit', async () => { - const balance0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balance0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts index 689a99d61bc9..f50c89d80b5a 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts @@ -43,7 +43,7 @@ describe('e2e_token_contract transfer public', () => { }); it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_in_public(adminAddress, account1Address, amount, 0).send({ from: adminAddress }); @@ -52,7 +52,7 @@ describe('e2e_token_contract transfer public', () => { }); it('transfer to self', async () => { - const balance = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_in_public(adminAddress, adminAddress, amount, 0).send({ from: adminAddress }); @@ -61,7 +61,7 @@ describe('e2e_token_contract transfer public', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const authwitNonce = Fr.random(); @@ -90,7 +90,7 @@ describe('e2e_token_contract transfer public', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 + 1n; const authwitNonce = 0; await expect( @@ -101,7 +101,7 @@ describe('e2e_token_contract transfer public', () => { }); it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 - 1n; const authwitNonce = 1; await expect( @@ -114,7 +114,7 @@ describe('e2e_token_contract transfer public', () => { }); it('transfer on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 + 1n; const authwitNonce = Fr.random(); await expect( @@ -125,8 +125,10 @@ describe('e2e_token_contract transfer public', () => { }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); - const balance1 = await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance1 } = await asset.methods + .balance_of_public(account1Address) + .simulate({ from: account1Address }); const amount = balance0 + 1n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -145,15 +147,19 @@ describe('e2e_token_contract transfer public', () => { U128_UNDERFLOW_ERROR, ); - expect(await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); - expect(await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address })).toEqual( - balance1, + expect((await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).result).toEqual( + balance0, ); + expect( + (await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address })).result, + ).toEqual(balance1); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); - const balance1 = await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance1 } = await asset.methods + .balance_of_public(account1Address) + .simulate({ from: account1Address }); const amount = balance0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -171,15 +177,19 @@ describe('e2e_token_contract transfer public', () => { // Perform the transfer await expect(action.simulate({ from: account1Address })).rejects.toThrow(/unauthorized/); - expect(await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); - expect(await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address })).toEqual( - balance1, + expect((await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).result).toEqual( + balance0, ); + expect( + (await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address })).result, + ).toEqual(balance1); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); - const balance1 = await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance1 } = await asset.methods + .balance_of_public(account1Address) + .simulate({ from: account1Address }); const amount = balance0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -196,14 +206,16 @@ describe('e2e_token_contract transfer public', () => { // Perform the transfer await expect(action.simulate({ from: account1Address })).rejects.toThrow(/unauthorized/); - expect(await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).toEqual(balance0); - expect(await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address })).toEqual( - balance1, + expect((await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress })).result).toEqual( + balance0, ); + expect( + (await asset.methods.balance_of_public(account1Address).simulate({ from: account1Address })).result, + ).toEqual(balance1); }); it('transfer on behalf of other, cancelled authwit', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const authwitNonce = Fr.random(); @@ -232,7 +244,7 @@ describe('e2e_token_contract transfer public', () => { }); it('transfer on behalf of other, cancelled authwit, flow 2', async () => { - const balance0 = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balance0 } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const authwitNonce = Fr.random(); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts index 051ba9370fce..2688fea57172 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts @@ -22,7 +22,7 @@ describe('e2e_token_contract transfer_to_private', () => { }); it('to self', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balancePub } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balancePub / 2n; expect(amount).toBeGreaterThan(0n); @@ -34,7 +34,7 @@ describe('e2e_token_contract transfer_to_private', () => { }); it('to someone else', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balancePub } = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); const amount = balancePub / 2n; expect(amount).toBeGreaterThan(0n); @@ -47,7 +47,9 @@ describe('e2e_token_contract transfer_to_private', () => { describe('failure cases', () => { it('to self (more than balance)', async () => { - const balancePub = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress }); + const { result: balancePub } = await asset.methods + .balance_of_public(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePub + 1n; expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts index 5394130c2429..1ff6f31ef53b 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts @@ -26,7 +26,9 @@ describe('e2e_token_contract transfer_to_public', () => { }); it('on behalf of self', async () => { - const balancePriv = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balancePriv } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePriv / 2n; expect(amount).toBeGreaterThan(0n); @@ -36,7 +38,9 @@ describe('e2e_token_contract transfer_to_public', () => { }); it('on behalf of other', async () => { - const balancePriv0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balancePriv0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePriv0 / 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -56,7 +60,9 @@ describe('e2e_token_contract transfer_to_public', () => { describe('failure cases', () => { it('on behalf of self (more than balance)', async () => { - const balancePriv = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balancePriv } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); @@ -66,7 +72,9 @@ describe('e2e_token_contract transfer_to_public', () => { }); it('on behalf of self (invalid authwit nonce)', async () => { - const balancePriv = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balancePriv } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); @@ -78,7 +86,9 @@ describe('e2e_token_contract transfer_to_public', () => { }); it('on behalf of other (more than balance)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balancePriv0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePriv0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -93,7 +103,9 @@ describe('e2e_token_contract transfer_to_public', () => { }); it('on behalf of other (invalid designated caller)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress }); + const { result: balancePriv0 } = await asset.methods + .balance_of_private(adminAddress) + .simulate({ from: adminAddress }); const amount = balancePriv0 + 2n; const authwitNonce = Fr.random(); expect(amount).toBeGreaterThan(0n); diff --git a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts index 6dad123c594a..59f38bfeedea 100644 --- a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts @@ -106,7 +106,9 @@ export class FullProverTest { await publicDeployAccounts(this.wallet, this.accounts.slice(0, 2)); this.logger.info('Applying base setup: deploying token contract'); - const { contract: asset, instance } = await TokenContract.deploy( + const { + receipt: { contract: asset, instance }, + } = await TokenContract.deploy( this.wallet, this.accounts[0], FullProverTest.TOKEN_NAME, @@ -121,7 +123,7 @@ export class FullProverTest { this.tokenSim = new TokenSimulator(this.fakeProofsAsset, this.wallet, this.accounts[0], this.logger, this.accounts); - expect(await this.fakeProofsAsset.methods.get_admin().simulate({ from: this.accounts[0] })).toBe( + expect((await this.fakeProofsAsset.methods.get_admin().simulate({ from: this.accounts[0] })).result).toBe( this.accounts[0].toBigInt(), ); } @@ -310,16 +312,20 @@ export class FullProverTest { } = this; tokenSim.mintPublic(address, publicAmount); - const publicBalance = await fakeProofsAsset.methods.balance_of_public(address).simulate({ from: address }); + const { result: publicBalance } = await fakeProofsAsset.methods + .balance_of_public(address) + .simulate({ from: address }); this.logger.verbose(`Public balance of wallet 0: ${publicBalance}`); expect(publicBalance).toEqual(this.tokenSim.balanceOfPublic(address)); tokenSim.mintPrivate(address, publicAmount); - const privateBalance = await fakeProofsAsset.methods.balance_of_private(address).simulate({ from: address }); + const { result: privateBalance } = await fakeProofsAsset.methods + .balance_of_private(address) + .simulate({ from: address }); this.logger.verbose(`Private balance of wallet 0: ${privateBalance}`); expect(privateBalance).toEqual(tokenSim.balanceOfPrivate(address)); - const totalSupply = await fakeProofsAsset.methods.total_supply().simulate({ from: address }); + const { result: totalSupply } = await fakeProofsAsset.methods.total_supply().simulate({ from: address }); this.logger.verbose(`Total supply: ${totalSupply}`); expect(totalSupply).toEqual(tokenSim.totalSupply); } diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index abfd4da901e0..fb9ab8d9d88f 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -753,7 +753,9 @@ export function getBalancesFn( ): (...addresses: (AztecAddress | { address: AztecAddress })[]) => Promise { const balances = async (...addressLikes: (AztecAddress | { address: AztecAddress })[]) => { const addresses = addressLikes.map(addressLike => ('address' in addressLike ? addressLike.address : addressLike)); - const b = await Promise.all(addresses.map(address => method(address).simulate({ from: address }))); + const b = await Promise.all( + addresses.map(async address => (await method(address).simulate({ from: address })).result), + ); const debugString = `${symbol} balances: ${addresses.map((address, i) => `${address}: ${b[i]}`).join(', ')}`; logger.verbose(debugString); return b; @@ -871,7 +873,7 @@ export async function publicDeployAccounts( const batch = new BatchCall(wallet, calls); - const txReceipt = await batch.send({ from: accountsToDeploy[0] }); + const { receipt: txReceipt } = await batch.send({ from: accountsToDeploy[0] }); if (waitUntilProven) { if (!node) { throw new Error('Need to provide an AztecNode to wait for proven.'); diff --git a/yarn-project/end-to-end/src/fixtures/token_utils.ts b/yarn-project/end-to-end/src/fixtures/token_utils.ts index 47e9c67e78ba..ede82e6966c2 100644 --- a/yarn-project/end-to-end/src/fixtures/token_utils.ts +++ b/yarn-project/end-to-end/src/fixtures/token_utils.ts @@ -6,7 +6,9 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token'; export async function deployToken(wallet: Wallet, admin: AztecAddress, initialAdminBalance: bigint, logger: Logger) { logger.info(`Deploying Token contract...`); - const { contract, instance } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({ + const { + receipt: { contract, instance }, + } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({ from: admin, wait: { returnReceipt: true }, }); @@ -38,7 +40,7 @@ export async function expectTokenBalance( ) { // Then check the balance const contractWithWallet = TokenContract.at(token.address, wallet); - const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner }); + const { result: balance } = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner }); logger.info(`Account ${owner} balance: ${balance}`); expect(balance).toBe(expectedBalance); } diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index 9eaf2473b961..b9f1893bf500 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -73,7 +73,7 @@ describe('guides/writing_an_account_contract', () => { const address = account.address; logger.info(`Deployed account contract at ${address}`); - const token = await TokenContract.deploy(wallet, fundedAccount, 'TokenName', 'TokenSymbol', 18).send({ + const { contract: token } = await TokenContract.deploy(wallet, fundedAccount, 'TokenName', 'TokenSymbol', 18).send({ from: fundedAccount, }); logger.info(`Deployed token contract at ${token.address}`); @@ -81,7 +81,7 @@ describe('guides/writing_an_account_contract', () => { const mintAmount = 50n; await token.methods.mint_to_private(address, mintAmount).send({ from: fundedAccount }); - const balance = await token.methods.balance_of_private(address).simulate({ from: address }); + const { result: balance } = await token.methods.balance_of_private(address).simulate({ from: address }); logger.info(`Balance of wallet is now ${balance}`); expect(balance).toEqual(50n); diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index be4564b2a67d..c1b2b39780eb 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -73,22 +73,26 @@ export async function deployAndInitializeTokenAndBridgeContracts( }); // deploy l2 token - const token = await TokenContract.deploy(wallet, owner, 'TokenName', 'TokenSymbol', 18).send({ from: owner }); + const { contract: token } = await TokenContract.deploy(wallet, owner, 'TokenName', 'TokenSymbol', 18).send({ + from: owner, + }); // deploy l2 token bridge and attach to the portal - const bridge = await TokenBridgeContract.deploy(wallet, token.address, tokenPortalAddress).send({ from: owner }); + const { contract: bridge } = await TokenBridgeContract.deploy(wallet, token.address, tokenPortalAddress).send({ + from: owner, + }); - if ((await token.methods.get_admin().simulate({ from: owner })) !== owner.toBigInt()) { + if ((await token.methods.get_admin().simulate({ from: owner })).result !== owner.toBigInt()) { throw new Error(`Token admin is not ${owner}`); } - if (!(await bridge.methods.get_config().simulate({ from: owner })).token.equals(token.address)) { + if (!(await bridge.methods.get_config().simulate({ from: owner })).result.token.equals(token.address)) { throw new Error(`Bridge token is not ${token.address}`); } // make the bridge a minter on the token: await token.methods.set_minter(bridge.address, true).send({ from: owner }); - if ((await token.methods.is_minter(bridge.address).simulate({ from: owner })) === 1n) { + if ((await token.methods.is_minter(bridge.address).simulate({ from: owner })).result === 1n) { throw new Error(`Bridge is not a minter`); } @@ -269,7 +273,7 @@ export class CrossChainTestHarness { authwitNonce: Fr = Fr.ZERO, authWitness: AuthWitness, ): Promise { - const withdrawReceipt = await this.l2Bridge.methods + const { receipt: withdrawReceipt } = await this.l2Bridge.methods .exit_to_l1_private(this.l2Token.address, this.ethAccount, withdrawAmount, EthAddress.ZERO, authwitNonce) .send({ authWitnesses: [authWitness], from: this.ownerAddress }); @@ -277,7 +281,7 @@ export class CrossChainTestHarness { } async withdrawPublicFromAztecToL1(withdrawAmount: bigint, authwitNonce: Fr = Fr.ZERO): Promise { - const withdrawReceipt = await this.l2Bridge.methods + const { receipt: withdrawReceipt } = await this.l2Bridge.methods .exit_to_l1_public(this.ethAccount, withdrawAmount, EthAddress.ZERO, authwitNonce) .send({ from: this.ownerAddress }); @@ -285,7 +289,7 @@ export class CrossChainTestHarness { } async getL2PrivateBalanceOf(owner: AztecAddress) { - return await this.l2Token.methods.balance_of_private(owner).simulate({ from: owner }); + return (await this.l2Token.methods.balance_of_private(owner).simulate({ from: owner })).result; } async expectPrivateBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) { @@ -295,7 +299,7 @@ export class CrossChainTestHarness { } async getL2PublicBalanceOf(owner: AztecAddress) { - return await this.l2Token.methods.balance_of_public(owner).simulate({ from: this.ownerAddress }); + return (await this.l2Token.methods.balance_of_public(owner).simulate({ from: this.ownerAddress })).result; } async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) { diff --git a/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts b/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts index 4062e7def159..2e8426fa1351 100644 --- a/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts @@ -131,7 +131,7 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness { } async getL2PublicBalanceOf(owner: AztecAddress) { - return await this.feeJuice.methods.balance_of_public(owner).simulate({ from: owner }); + return (await this.feeJuice.methods.balance_of_public(owner).simulate({ from: owner })).result; } async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) { diff --git a/yarn-project/end-to-end/src/shared/submit-transactions.ts b/yarn-project/end-to-end/src/shared/submit-transactions.ts index 5bb2a7316a8c..b8b6c5c1a11e 100644 --- a/yarn-project/end-to-end/src/shared/submit-transactions.ts +++ b/yarn-project/end-to-end/src/shared/submit-transactions.ts @@ -19,7 +19,7 @@ export const submitTxsTo = async ( times(numTxs, async () => { const accountManager = await wallet.createSchnorrAccount(Fr.random(), Fr.random(), GrumpkinScalar.random()); const deployMethod = await accountManager.getDeployMethod(); - const txHash = await deployMethod.send({ from: submitter, wait: NO_WAIT }); + const { txHash } = await deployMethod.send({ from: submitter, wait: NO_WAIT }); logger.info(`Tx sent with hash ${txHash}`); const receipt: TxReceipt = await wallet.getTxReceipt(txHash); diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index 7f25e1a2b4eb..6795cc1bf180 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -130,7 +130,9 @@ export const uniswapL1L2TestSuite = ( client: l1Client, }); // deploy l2 uniswap contract and attach to portal - uniswapL2Contract = await UniswapContract.deploy(wallet, uniswapPortalAddress).send({ from: ownerAddress }); + ({ contract: uniswapL2Contract } = await UniswapContract.deploy(wallet, uniswapPortalAddress).send({ + from: ownerAddress, + })); const registryAddress = (await aztecNode.getNodeInfo()).l1ContractAddresses.registryAddress; @@ -195,7 +197,7 @@ export const uniswapL1L2TestSuite = ( logger.info('Withdrawing weth to L1 and sending message to swap to dai'); const [secretForDepositingSwappedDai, secretHashForDepositingSwappedDai] = await generateClaimSecret(); - const l2UniswapInteractionReceipt = await uniswapL2Contract.methods + const { receipt: l2UniswapInteractionReceipt } = await uniswapL2Contract.methods .swap_private( wethCrossChainHarness.l2Token.address, wethCrossChainHarness.l2Bridge.address, @@ -787,7 +789,7 @@ export const uniswapL1L2TestSuite = ( logger.info('Withdrawing weth to L1 and sending message to swap to dai'); const [, secretHashForDepositingSwappedDai] = await generateClaimSecret(); - const withdrawReceipt = await uniswapL2Contract.methods + const { receipt: withdrawReceipt } = await uniswapL2Contract.methods .swap_private( wethCrossChainHarness.l2Token.address, wethCrossChainHarness.l2Bridge.address, @@ -915,7 +917,7 @@ export const uniswapL1L2TestSuite = ( // Call swap_public on L2 const secretHashForDepositingSwappedDai = Fr.random(); - const withdrawReceipt = await uniswapL2Contract.methods + const { receipt: withdrawReceipt } = await uniswapL2Contract.methods .swap_public( ownerAddress, wethCrossChainHarness.l2Bridge.address, diff --git a/yarn-project/end-to-end/src/simulators/lending_simulator.ts b/yarn-project/end-to-end/src/simulators/lending_simulator.ts index fe10d7ed2276..404bb3d5ad8d 100644 --- a/yarn-project/end-to-end/src/simulators/lending_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/lending_simulator.ts @@ -186,14 +186,16 @@ export class LendingSimulator { expect(this.borrowed).toEqual(this.stableCoin.totalSupply - this.mintedOutside); - const asset = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address }); + const { result: asset } = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address }); const interestAccumulator = asset['interest_accumulator']; expect(interestAccumulator).toEqual(this.accumulator); expect(asset['last_updated_ts']).toEqual(BigInt(this.time)); for (const key of [this.account.address, AztecAddress.fromField(await this.account.key())]) { - const privatePos = await this.lendingContract.methods.get_position(key).simulate({ from: this.account.address }); + const { result: privatePos } = await this.lendingContract.methods + .get_position(key) + .simulate({ from: this.account.address }); expect(new Fr(privatePos['collateral'])).toEqual(this.collateral[key.toString()] ?? Fr.ZERO); expect(new Fr(privatePos['static_debt'])).toEqual(this.staticDebt[key.toString()] ?? Fr.ZERO); expect(privatePos['debt']).toEqual( diff --git a/yarn-project/end-to-end/src/simulators/token_simulator.ts b/yarn-project/end-to-end/src/simulators/token_simulator.ts index f29f6403a4d2..a2065beb4426 100644 --- a/yarn-project/end-to-end/src/simulators/token_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/token_simulator.ts @@ -109,7 +109,9 @@ export class TokenSimulator { await Promise.all( chunk(calls, 5).map(batch => new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress })), ) - ).flat(); + ) + .flat() + .map(r => r.result); expect(results[0]).toEqual(this.totalSupply); // Check that all our balances match @@ -123,7 +125,9 @@ export class TokenSimulator { const wallet = this.lookupProvider.get(address.toString()); const asset = wallet ? this.token.withWallet(wallet) : this.token; - const actualPrivateBalance = await asset.methods.balance_of_private(address).simulate({ from: address }); + const { result: actualPrivateBalance } = await asset.methods + .balance_of_private(address) + .simulate({ from: address }); expect(actualPrivateBalance).toEqual(this.balanceOfPrivate(address)); } } diff --git a/yarn-project/end-to-end/src/spartan/1tps.test.ts b/yarn-project/end-to-end/src/spartan/1tps.test.ts index b771d4621308..6d939deb5886 100644 --- a/yarn-project/end-to-end/src/spartan/1tps.test.ts +++ b/yarn-project/end-to-end/src/spartan/1tps.test.ts @@ -63,7 +63,8 @@ describe('token transfer test', () => { it('can get info', async () => { const name = readFieldCompressedString( - await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress }), + (await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress })) + .result, ); expect(name).toBe(testAccounts.tokenName); }); @@ -74,16 +75,20 @@ describe('token transfer test', () => { for (const acc of testAccounts.accounts) { expect(MINT_AMOUNT).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(acc) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(acc) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); } expect(0n).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(recipient) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(recipient) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); const defaultAccountAddress = testAccounts.accounts[0]; @@ -128,7 +133,7 @@ describe('token transfer test', () => { }), ); - const recipientBalance = await testAccounts.tokenContract.methods + const { result: recipientBalance } = await testAccounts.tokenContract.methods .balance_of_public(recipient) .simulate({ from: testAccounts.tokenAdminAddress }); logger.info(`recipientBalance: ${recipientBalance}`); diff --git a/yarn-project/end-to-end/src/spartan/4epochs.test.ts b/yarn-project/end-to-end/src/spartan/4epochs.test.ts index b2dcdd2ca987..a0d42328fb7a 100644 --- a/yarn-project/end-to-end/src/spartan/4epochs.test.ts +++ b/yarn-project/end-to-end/src/spartan/4epochs.test.ts @@ -68,7 +68,8 @@ describe('token transfer test', () => { it('can get info', async () => { const name = readFieldCompressedString( - await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress }), + (await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress })) + .result, ); expect(name).toBe(testAccounts.tokenName); logger.info(`Token name verified: ${name}`); @@ -85,18 +86,22 @@ describe('token transfer test', () => { for (const acc of testAccounts.accounts) { expect(MINT_AMOUNT).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(acc) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(acc) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); } logger.info('Minted tokens'); expect(0n).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(recipient) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(recipient) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); // For each round, make both private and public transfers @@ -132,16 +137,20 @@ describe('token transfer test', () => { for (const acc of testAccounts.accounts) { expect(MINT_AMOUNT - ROUNDS * transferAmount).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(acc) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(acc) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); } expect(ROUNDS * transferAmount * BigInt(testAccounts.accounts.length)).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(recipient) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(recipient) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); }); }); diff --git a/yarn-project/end-to-end/src/spartan/n_tps.test.ts b/yarn-project/end-to-end/src/spartan/n_tps.test.ts index 95405e1b9e84..5bbdb2a94136 100644 --- a/yarn-project/end-to-end/src/spartan/n_tps.test.ts +++ b/yarn-project/end-to-end/src/spartan/n_tps.test.ts @@ -279,10 +279,10 @@ describe('sustained N TPS test', () => { logger.info('Deploying benchmark contract...'); const sponsor = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress()); - benchmarkContract = await BenchmarkingContract.deploy(localTestAccounts[0].wallet).send({ + ({ contract: benchmarkContract } = await BenchmarkingContract.deploy(localTestAccounts[0].wallet).send({ from: localTestAccounts[0].recipientAddress, fee: { paymentMethod: sponsor }, - }); + })); logger.info('Benchmark contract deployed', { address: benchmarkContract.address.toString() }); logger.info('Installing chaos mesh chart', { diff --git a/yarn-project/end-to-end/src/spartan/n_tps_prove.test.ts b/yarn-project/end-to-end/src/spartan/n_tps_prove.test.ts index 0e20ccefc471..59d7d567a208 100644 --- a/yarn-project/end-to-end/src/spartan/n_tps_prove.test.ts +++ b/yarn-project/end-to-end/src/spartan/n_tps_prove.test.ts @@ -302,10 +302,10 @@ describe(`prove ${TARGET_TPS}TPS test`, () => { ); logger.info('Deploying benchmark contract...'); - benchmarkContract = await AvmGadgetsTestContract.deploy(wallets[0]).send({ + ({ contract: benchmarkContract } = await AvmGadgetsTestContract.deploy(wallets[0]).send({ from: accountAddresses[0], fee: { paymentMethod: sponsor }, - }); + })); logger.info('Test setup complete'); }); diff --git a/yarn-project/end-to-end/src/spartan/reorg.test.ts b/yarn-project/end-to-end/src/spartan/reorg.test.ts index 946f4f4a3b1a..e01d4ee06f20 100644 --- a/yarn-project/end-to-end/src/spartan/reorg.test.ts +++ b/yarn-project/end-to-end/src/spartan/reorg.test.ts @@ -32,16 +32,20 @@ const debugLogger = createLogger('e2e:spartan-test:reorg'); async function checkBalances(testAccounts: TestAccounts, mintAmount: bigint, totalAmountTransferred: bigint) { for (const acc of testAccounts.accounts) { expect( - await testAccounts.tokenContract.methods - .balance_of_public(acc) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(acc) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ).toBe(mintAmount - totalAmountTransferred); } expect( - await testAccounts.tokenContract.methods - .balance_of_public(testAccounts.recipientAddress) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(testAccounts.recipientAddress) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ).toBe(totalAmountTransferred * BigInt(testAccounts.accounts.length)); } diff --git a/yarn-project/end-to-end/src/spartan/reqresp_effectiveness.test.ts b/yarn-project/end-to-end/src/spartan/reqresp_effectiveness.test.ts index 11f3e1b220d7..802509ce0a69 100644 --- a/yarn-project/end-to-end/src/spartan/reqresp_effectiveness.test.ts +++ b/yarn-project/end-to-end/src/spartan/reqresp_effectiveness.test.ts @@ -72,7 +72,8 @@ describe('reqresp effectiveness under tx drop', () => { testAccounts = await deploySponsoredTestAccountsWithTokens(wallet, aztecNode, MINT_AMOUNT, logger); recipient = testAccounts.recipientAddress; const name = readFieldCompressedString( - await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress }), + (await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress })) + .result, ); expect(name).toBe(testAccounts.tokenName); }); diff --git a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts index 0c9f988ffdcd..0f0a63458835 100644 --- a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts +++ b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts @@ -130,7 +130,8 @@ async function deployAccountWithDiagnostics( const deployMethod = await account.getDeployMethod(); let txHash; try { - txHash = await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: NO_WAIT }); + const deployResult = await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: NO_WAIT }); + txHash = deployResult.txHash; await waitForTx(aztecNode, txHash, { timeout: 2400 }); logger.info(`${accountLabel} deployed at ${account.address}`); } catch (error) { @@ -298,13 +299,9 @@ async function deployTokenAndMint( logger: Logger, ) { logger.verbose(`Deploying TokenContract...`); - const { contract: tokenContract } = await TokenContract.deploy( - wallet, - admin, - TOKEN_NAME, - TOKEN_SYMBOL, - TOKEN_DECIMALS, - ).send({ + const { + receipt: { contract: tokenContract }, + } = await TokenContract.deploy(wallet, admin, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS).send({ from: admin, fee: { paymentMethod, diff --git a/yarn-project/end-to-end/src/spartan/transfer.test.ts b/yarn-project/end-to-end/src/spartan/transfer.test.ts index b3fda8fb1186..7db4b2c0e2aa 100644 --- a/yarn-project/end-to-end/src/spartan/transfer.test.ts +++ b/yarn-project/end-to-end/src/spartan/transfer.test.ts @@ -52,7 +52,8 @@ describe('token transfer test', () => { it('can get info', async () => { const name = readFieldCompressedString( - await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress }), + (await testAccounts.tokenContract.methods.private_get_name().simulate({ from: testAccounts.tokenAdminAddress })) + .result, ); expect(name).toBe(testAccounts.tokenName); }); @@ -63,16 +64,20 @@ describe('token transfer test', () => { for (const a of testAccounts.accounts) { expect(MINT_AMOUNT).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(a) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(a) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); } expect(0n).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(recipient) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(recipient) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); // For each round, make both private and public transfers @@ -94,14 +99,16 @@ describe('token transfer test', () => { for (const a of testAccounts.accounts) { expect(MINT_AMOUNT - ROUNDS * transferAmount).toBe( - await testAccounts.tokenContract.methods.balance_of_public(a).simulate({ from: a }), + (await testAccounts.tokenContract.methods.balance_of_public(a).simulate({ from: a })).result, ); } expect(ROUNDS * transferAmount * BigInt(testAccounts.accounts.length)).toBe( - await testAccounts.tokenContract.methods - .balance_of_public(recipient) - .simulate({ from: testAccounts.tokenAdminAddress }), + ( + await testAccounts.tokenContract.methods + .balance_of_public(recipient) + .simulate({ from: testAccounts.tokenAdminAddress }) + ).result, ); }); }); diff --git a/yarn-project/stdlib/src/tx/simulated_tx.ts b/yarn-project/stdlib/src/tx/simulated_tx.ts index 3ad4e7b73c4e..5fb1ef4b8bd4 100644 --- a/yarn-project/stdlib/src/tx/simulated_tx.ts +++ b/yarn-project/stdlib/src/tx/simulated_tx.ts @@ -12,9 +12,11 @@ import { Gas } from '../gas/gas.js'; import type { GasUsed } from '../gas/gas_used.js'; import { PrivateKernelTailCircuitPublicInputs } from '../kernel/private_kernel_tail_circuit_public_inputs.js'; import { ChonkProof } from '../proofs/chonk_proof.js'; +import type { OffchainEffect } from './offchain_effect.js'; import { PrivateCallExecutionResult, PrivateExecutionResult, + collectOffchainEffects, collectSortedContractClassLogs, } from './private_execution_result.js'; import { type SimulationStats, SimulationStatsSchema } from './profiling.js'; @@ -84,6 +86,11 @@ export class TxSimulationResult { public stats?: SimulationStats, ) {} + /** Returns offchain effects collected from private execution. */ + get offchainEffects(): OffchainEffect[] { + return collectOffchainEffects(this.privateExecutionResult); + } + get gasUsed(): GasUsed { return ( this.publicOutput?.gasUsed ?? { @@ -106,7 +113,7 @@ export class TxSimulationResult { .transform(TxSimulationResult.from); } - static from(fields: Omit, 'gasUsed'>) { + static from(fields: Omit, 'gasUsed' | 'offchainEffects'>) { return new TxSimulationResult( fields.privateExecutionResult, fields.publicInputs, diff --git a/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts b/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts index 406d4942e75d..a769d5907f2c 100644 --- a/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts +++ b/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts @@ -1,6 +1,11 @@ import type { Account } from '@aztec/aztec.js/account'; import type { CallIntent, IntentInnerHash } from '@aztec/aztec.js/authorization'; -import { type InteractionWaitOptions, NO_WAIT, type SendReturn } from '@aztec/aztec.js/contracts'; +import { + type InteractionWaitOptions, + NO_WAIT, + type SendReturn, + extractOffchainOutput, +} from '@aztec/aztec.js/contracts'; import type { FeePaymentMethod } from '@aztec/aztec.js/fee'; import { waitForTx } from '@aztec/aztec.js/node'; import type { @@ -37,7 +42,7 @@ import { decodeFromAbi, } from '@aztec/stdlib/abi'; import type { AuthWitness } from '@aztec/stdlib/auth-witness'; -import type { AztecAddress } from '@aztec/stdlib/aztec-address'; +import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { type ContractInstanceWithAddress, computePartialAddress, @@ -95,6 +100,12 @@ export abstract class BaseWallet implements Wallet { return from.isZero() ? [] : [from]; } + protected scopesFrom(from: AztecAddress, additionalScopes: AztecAddress[] = []): AztecAddress[] { + const allScopes = from.isZero() ? additionalScopes : [from, ...additionalScopes]; + const scopeSet = new Set(allScopes.map(address => address.toString())); + return [...scopeSet].map(AztecAddress.fromString); + } + protected abstract getAccountFromAddress(address: AztecAddress): Promise; abstract getAccounts(): Promise[]>; @@ -356,7 +367,7 @@ export abstract class BaseWallet implements Wallet { remainingPayload, opts.from, feeOptions, - this.scopesFor(opts.from), + this.scopesFrom(opts.from, opts.additionalScopes), opts.skipTxValidation, opts.skipFeeEnforcement ?? true, ) @@ -372,7 +383,7 @@ export abstract class BaseWallet implements Wallet { return this.pxe.profileTx(txRequest, { profileMode: opts.profileMode, skipProofGeneration: opts.skipProofGeneration ?? true, - scopes: this.scopesFor(opts.from), + scopes: this.scopesFrom(opts.from, opts.additionalScopes), }); } @@ -382,7 +393,8 @@ export abstract class BaseWallet implements Wallet { ): Promise> { const feeOptions = await this.completeFeeOptions(opts.from, executionPayload.feePayer, opts.fee?.gasSettings); const txRequest = await this.createTxExecutionRequestFromPayloadAndFee(executionPayload, opts.from, feeOptions); - const provenTx = await this.pxe.proveTx(txRequest, this.scopesFor(opts.from)); + const provenTx = await this.pxe.proveTx(txRequest, this.scopesFrom(opts.from, opts.additionalScopes)); + const offchainOutput = extractOffchainOutput(provenTx.getOffchainEffects()); const tx = await provenTx.toTx(); const txHash = tx.getTxHash(); if (await this.aztecNode.getTxEffect(txHash)) { @@ -396,7 +408,7 @@ export abstract class BaseWallet implements Wallet { // If wait is NO_WAIT, return txHash immediately if (opts.wait === NO_WAIT) { - return txHash as SendReturn; + return { txHash, ...offchainOutput } as SendReturn; } // Otherwise, wait for the full receipt (default behavior on wait: undefined) @@ -408,7 +420,7 @@ export abstract class BaseWallet implements Wallet { await displayDebugLogs(receipt.debugLogs, this.getContractName.bind(this)); } - return receipt as SendReturn; + return { receipt, ...offchainOutput } as SendReturn; } /**