@aztec/end-to-end 0.0.1-commit.7b86788 → 0.0.1-commit.7cbc774

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +27 -0
  2. package/dest/bench/client_flows/benchmark.d.ts +15 -1
  3. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  4. package/dest/bench/client_flows/benchmark.js +17 -0
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
  6. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  7. package/dest/bench/client_flows/client_flows_benchmark.js +33 -36
  8. package/dest/bench/utils.d.ts +1 -1
  9. package/dest/bench/utils.d.ts.map +1 -1
  10. package/dest/bench/utils.js +8 -3
  11. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +5 -4
  12. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  13. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +28 -19
  14. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +15 -4
  15. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  16. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +39 -7
  17. package/dest/e2e_deploy_contract/deploy_test.d.ts +3 -3
  18. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  19. package/dest/e2e_deploy_contract/deploy_test.js +2 -1
  20. package/dest/e2e_epochs/epochs_test.d.ts +25 -2
  21. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  22. package/dest/e2e_epochs/epochs_test.js +88 -14
  23. package/dest/e2e_fees/fees_test.d.ts +5 -2
  24. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  25. package/dest/e2e_fees/fees_test.js +44 -11
  26. package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
  27. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  28. package/dest/e2e_nested_contract/nested_contract_test.js +6 -7
  29. package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
  30. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  31. package/dest/e2e_p2p/inactivity_slash_test.js +5 -3
  32. package/dest/e2e_p2p/p2p_network.d.ts +13 -11
  33. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  34. package/dest/e2e_p2p/p2p_network.js +65 -43
  35. package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
  36. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
  37. package/dest/e2e_p2p/reqresp/utils.js +42 -13
  38. package/dest/e2e_p2p/shared.d.ts +25 -7
  39. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  40. package/dest/e2e_p2p/shared.js +73 -50
  41. package/dest/e2e_token_contract/token_contract_test.d.ts +3 -3
  42. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  43. package/dest/e2e_token_contract/token_contract_test.js +15 -13
  44. package/dest/fixtures/authwit_proxy.d.ts +3 -3
  45. package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
  46. package/dest/fixtures/authwit_proxy.js +4 -0
  47. package/dest/fixtures/e2e_prover_test.d.ts +6 -5
  48. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  49. package/dest/fixtures/e2e_prover_test.js +13 -17
  50. package/dest/fixtures/fixtures.d.ts +73 -1
  51. package/dest/fixtures/fixtures.d.ts.map +1 -1
  52. package/dest/fixtures/fixtures.js +68 -0
  53. package/dest/fixtures/get_bb_config.d.ts +1 -1
  54. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  55. package/dest/fixtures/get_bb_config.js +5 -5
  56. package/dest/fixtures/ha_setup.d.ts +2 -2
  57. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  58. package/dest/fixtures/ha_setup.js +1 -1
  59. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  60. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  61. package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
  62. package/dest/fixtures/setup.d.ts +44 -12
  63. package/dest/fixtures/setup.d.ts.map +1 -1
  64. package/dest/fixtures/setup.js +138 -29
  65. package/dest/fixtures/setup_p2p_test.d.ts +10 -6
  66. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  67. package/dest/fixtures/setup_p2p_test.js +8 -8
  68. package/dest/fixtures/token_utils.d.ts +1 -1
  69. package/dest/fixtures/token_utils.d.ts.map +1 -1
  70. package/dest/fixtures/token_utils.js +2 -5
  71. package/dest/fixtures/utils.d.ts +2 -2
  72. package/dest/fixtures/utils.d.ts.map +1 -1
  73. package/dest/fixtures/utils.js +1 -1
  74. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  75. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  76. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  77. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  78. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  79. package/dest/forward-compatibility/wallet_service.js +109 -0
  80. package/dest/install_legacy_contracts.d.cts +10 -0
  81. package/dest/install_legacy_contracts.d.cts.map +1 -0
  82. package/dest/legacy-jest-resolver.d.cts +3 -0
  83. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  84. package/dest/shared/cross_chain_test_harness.d.ts +4 -2
  85. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  86. package/dest/shared/cross_chain_test_harness.js +22 -18
  87. package/dest/shared/gas_portal_test_harness.d.ts +8 -5
  88. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  89. package/dest/shared/gas_portal_test_harness.js +19 -10
  90. package/dest/shared/jest_setup.js +32 -1
  91. package/dest/shared/submit-transactions.d.ts +1 -1
  92. package/dest/shared/submit-transactions.d.ts.map +1 -1
  93. package/dest/shared/submit-transactions.js +1 -1
  94. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  95. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  96. package/dest/shared/uniswap_l1_l2.js +60 -39
  97. package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
  98. package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
  99. package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
  100. package/dest/simulators/lending_simulator.d.ts +10 -3
  101. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  102. package/dest/simulators/lending_simulator.js +26 -14
  103. package/dest/simulators/token_simulator.d.ts +1 -1
  104. package/dest/simulators/token_simulator.d.ts.map +1 -1
  105. package/dest/simulators/token_simulator.js +2 -2
  106. package/dest/spartan/setup_test_wallets.d.ts +4 -2
  107. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  108. package/dest/spartan/setup_test_wallets.js +72 -39
  109. package/dest/spartan/tx_metrics.d.ts +18 -4
  110. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  111. package/dest/spartan/tx_metrics.js +74 -21
  112. package/dest/spartan/utils/config.d.ts +9 -32
  113. package/dest/spartan/utils/config.d.ts.map +1 -1
  114. package/dest/spartan/utils/config.js +1 -0
  115. package/dest/spartan/utils/index.d.ts +2 -1
  116. package/dest/spartan/utils/index.d.ts.map +1 -1
  117. package/dest/spartan/utils/index.js +2 -0
  118. package/dest/spartan/utils/nodes.js +2 -2
  119. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  120. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  121. package/dest/spartan/utils/pod_logs.js +74 -0
  122. package/dest/test-wallet/test_wallet.d.ts +25 -23
  123. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  124. package/dest/test-wallet/test_wallet.js +146 -87
  125. package/dest/test-wallet/utils.d.ts +3 -3
  126. package/dest/test-wallet/utils.d.ts.map +1 -1
  127. package/dest/test-wallet/utils.js +2 -7
  128. package/dest/test-wallet/wallet_worker_script.js +2 -2
  129. package/dest/test-wallet/worker_wallet.d.ts +5 -4
  130. package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
  131. package/dest/test-wallet/worker_wallet.js +5 -1
  132. package/dest/test-wallet/worker_wallet_schema.d.ts +110 -224
  133. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
  134. package/dest/test-wallet/worker_wallet_schema.js +14 -2
  135. package/package.json +49 -46
  136. package/src/bench/client_flows/benchmark.ts +19 -0
  137. package/src/bench/client_flows/client_flows_benchmark.ts +60 -41
  138. package/src/bench/utils.ts +9 -3
  139. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +42 -24
  140. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +49 -11
  141. package/src/e2e_deploy_contract/deploy_test.ts +3 -2
  142. package/src/e2e_epochs/epochs_test.ts +99 -11
  143. package/src/e2e_fees/fees_test.ts +49 -9
  144. package/src/e2e_nested_contract/nested_contract_test.ts +9 -5
  145. package/src/e2e_p2p/inactivity_slash_test.ts +5 -3
  146. package/src/e2e_p2p/p2p_network.ts +82 -60
  147. package/src/e2e_p2p/reqresp/utils.ts +51 -12
  148. package/src/e2e_p2p/shared.ts +92 -64
  149. package/src/e2e_token_contract/token_contract_test.ts +28 -10
  150. package/src/fixtures/authwit_proxy.ts +4 -0
  151. package/src/fixtures/e2e_prover_test.ts +22 -19
  152. package/src/fixtures/fixtures.ts +86 -0
  153. package/src/fixtures/get_bb_config.ts +7 -6
  154. package/src/fixtures/ha_setup.ts +4 -2
  155. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  156. package/src/fixtures/setup.ts +176 -34
  157. package/src/fixtures/setup_p2p_test.ts +13 -9
  158. package/src/fixtures/token_utils.ts +1 -2
  159. package/src/fixtures/utils.ts +2 -0
  160. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  161. package/src/forward-compatibility/wallet_service.ts +104 -0
  162. package/src/guides/up_quick_start.sh +0 -2
  163. package/src/install_legacy_contracts.cjs +75 -0
  164. package/src/legacy-jest-resolver.cjs +112 -0
  165. package/src/shared/cross_chain_test_harness.ts +27 -13
  166. package/src/shared/gas_portal_test_harness.ts +21 -11
  167. package/src/shared/jest_setup.ts +36 -1
  168. package/src/shared/submit-transactions.ts +1 -4
  169. package/src/shared/uniswap_l1_l2.ts +77 -50
  170. package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
  171. package/src/simulators/lending_simulator.ts +32 -14
  172. package/src/simulators/token_simulator.ts +6 -2
  173. package/src/spartan/setup_test_wallets.ts +91 -37
  174. package/src/spartan/tx_metrics.ts +82 -24
  175. package/src/spartan/utils/config.ts +1 -0
  176. package/src/spartan/utils/index.ts +3 -0
  177. package/src/spartan/utils/nodes.ts +2 -2
  178. package/src/spartan/utils/pod_logs.ts +99 -0
  179. package/src/test-wallet/test_wallet.ts +174 -104
  180. package/src/test-wallet/utils.ts +3 -7
  181. package/src/test-wallet/wallet_worker_script.ts +2 -2
  182. package/src/test-wallet/worker_wallet.ts +9 -4
  183. package/src/test-wallet/worker_wallet_schema.ts +2 -2
@@ -21,7 +21,11 @@ import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging';
21
21
  import { jest } from '@jest/globals';
22
22
  import { type GetContractReturnType, getContract, parseEther, toFunctionSelector } from 'viem';
23
23
 
24
- import { type EndToEndContext, ensureAccountContractsPublished } from '../fixtures/utils.js';
24
+ import {
25
+ type EndToEndContext,
26
+ ensureAccountContractsPublished,
27
+ ensureAuthRegistryPublished,
28
+ } from '../fixtures/utils.js';
25
29
  import type { TestWallet } from '../test-wallet/test_wallet.js';
26
30
  import { CrossChainTestHarness } from './cross_chain_test_harness.js';
27
31
 
@@ -32,7 +36,7 @@ import { CrossChainTestHarness } from './cross_chain_test_harness.js';
32
36
  // anvil --fork-url https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c --fork-block-number 17514288 --chain-id 31337
33
37
  // For CI, this is configured in `run_tests.sh` and `docker-compose-images.yml`
34
38
 
35
- const TIMEOUT = 360_000;
39
+ const TIMEOUT = 15 * 60 * 1000;
36
40
 
37
41
  export const uniswapL1L2TestSuite = (
38
42
  setup: () => Promise<EndToEndContext>,
@@ -98,6 +102,7 @@ export const uniswapL1L2TestSuite = (
98
102
  ownerEthAddress = EthAddress.fromString((await l1Client.getAddresses())[0]);
99
103
 
100
104
  await ensureAccountContractsPublished(wallet, [ownerAddress, sponsorAddress]);
105
+ await ensureAuthRegistryPublished(wallet, ownerAddress);
101
106
 
102
107
  logger.info('Deploying DAI Portal, initializing and deploying l2 contract...');
103
108
  daiCrossChainHarness = await CrossChainTestHarness.new(
@@ -130,7 +135,9 @@ export const uniswapL1L2TestSuite = (
130
135
  client: l1Client,
131
136
  });
132
137
  // deploy l2 uniswap contract and attach to portal
133
- uniswapL2Contract = await UniswapContract.deploy(wallet, uniswapPortalAddress).send({ from: ownerAddress });
138
+ ({ contract: uniswapL2Contract } = await UniswapContract.deploy(wallet, uniswapPortalAddress).send({
139
+ from: ownerAddress,
140
+ }));
134
141
 
135
142
  const registryAddress = (await aztecNode.getNodeInfo()).l1ContractAddresses.registryAddress;
136
143
 
@@ -152,7 +159,6 @@ export const uniswapL1L2TestSuite = (
152
159
  await cleanup();
153
160
  });
154
161
 
155
- // docs:start:uniswap_private
156
162
  it('should uniswap trade on L1 from L2 funds privately (swaps WETH -> DAI)', async () => {
157
163
  const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
158
164
 
@@ -195,7 +201,7 @@ export const uniswapL1L2TestSuite = (
195
201
  logger.info('Withdrawing weth to L1 and sending message to swap to dai');
196
202
  const [secretForDepositingSwappedDai, secretHashForDepositingSwappedDai] = await generateClaimSecret();
197
203
 
198
- const l2UniswapInteractionReceipt = await uniswapL2Contract.methods
204
+ const { receipt: l2UniswapInteractionReceipt } = await uniswapL2Contract.methods
199
205
  .swap_private(
200
206
  wethCrossChainHarness.l2Token.address,
201
207
  wethCrossChainHarness.l2Bridge.address,
@@ -249,10 +255,13 @@ export const uniswapL1L2TestSuite = (
249
255
  // ensure that uniswap contract didn't eat the funds.
250
256
  await wethCrossChainHarness.expectPublicBalanceOnL2(uniswapL2Contract.address, 0n);
251
257
 
252
- // Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
253
- const block = await aztecNode.getBlock(l2UniswapInteractionReceipt.blockNumber!);
254
- const epoch = await rollup.getEpochNumberForCheckpoint(block!.checkpointNumber);
255
- await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
258
+ // Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
259
+ // before we can ask the witness helper for a covering root.
260
+ const minedReceipt = await aztecNode.getTxReceipt(l2UniswapInteractionReceipt.txHash);
261
+ if (minedReceipt.epochNumber === undefined) {
262
+ throw new Error('L2 Uniswap interaction tx is not yet in an epoch');
263
+ }
264
+ await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
256
265
  await waitForProven(aztecNode, l2UniswapInteractionReceipt, { provenTimeout: 300 });
257
266
 
258
267
  // 5. Consume L2 to L1 message by calling uniswapPortal.swap_private()
@@ -260,17 +269,21 @@ export const uniswapL1L2TestSuite = (
260
269
  const daiL1BalanceOfPortalBeforeSwap = await daiCrossChainHarness.getL1BalanceOf(
261
270
  daiCrossChainHarness.tokenPortalAddress,
262
271
  );
263
- const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPrivateLeaf);
264
- const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
272
+ // Fetch the outbox roots once and share them between the two witnesses in this epoch.
273
+ const epochRoots = await wethCrossChainHarness.outboxContract.getRoots(minedReceipt.epochNumber);
274
+ const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, swapPrivateLeaf, minedReceipt))!;
275
+ const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
276
+ const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, withdrawLeaf, minedReceipt))!;
265
277
 
266
- const swapPrivateL2MessageIndex = swapResult!.leafIndex;
267
- const swapPrivateSiblingPath = swapResult!.siblingPath;
278
+ const swapPrivateL2MessageIndex = swapResult.leafIndex;
279
+ const swapPrivateSiblingPath = swapResult.siblingPath;
268
280
 
269
- const withdrawL2MessageIndex = withdrawResult!.leafIndex;
270
- const withdrawSiblingPath = withdrawResult!.siblingPath;
281
+ const withdrawL2MessageIndex = withdrawResult.leafIndex;
282
+ const withdrawSiblingPath = withdrawResult.siblingPath;
271
283
 
272
284
  const withdrawMessageMetadata = {
273
285
  _epoch: BigInt(epoch),
286
+ _numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
274
287
  _leafIndex: BigInt(withdrawL2MessageIndex),
275
288
  _path: withdrawSiblingPath
276
289
  .toBufferArray()
@@ -279,6 +292,7 @@ export const uniswapL1L2TestSuite = (
279
292
 
280
293
  const swapPrivateMessageMetadata = {
281
294
  _epoch: BigInt(epoch),
295
+ _numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
282
296
  _leafIndex: BigInt(swapPrivateL2MessageIndex),
283
297
  _path: swapPrivateSiblingPath
284
298
  .toBufferArray()
@@ -336,10 +350,8 @@ export const uniswapL1L2TestSuite = (
336
350
  logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
337
351
  logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
338
352
  });
339
- // docs:end:uniswap_private
340
353
 
341
354
  // TODO(#7463): reenable look into this failure https://github.com/AztecProtocol/aztec-packages/actions/runs/9912612912/job/27388320150?pr=7462
342
- // // docs:start:uniswap_public
343
355
  // it('should uniswap trade on L1 from L2 funds publicly (swaps WETH -> DAI)', async () => {
344
356
  // const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
345
357
 
@@ -572,7 +584,6 @@ export const uniswapL1L2TestSuite = (
572
584
  // logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
573
585
  // logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
574
586
  // });
575
- // // docs:end:uniswap_public
576
587
 
577
588
  // Edge cases for the private flow:
578
589
  // note - tests for uniswapPortal.sol and minting asset on L2 are covered in other tests.
@@ -787,7 +798,7 @@ export const uniswapL1L2TestSuite = (
787
798
  logger.info('Withdrawing weth to L1 and sending message to swap to dai');
788
799
 
789
800
  const [, secretHashForDepositingSwappedDai] = await generateClaimSecret();
790
- const withdrawReceipt = await uniswapL2Contract.methods
801
+ const { receipt: withdrawReceipt } = await uniswapL2Contract.methods
791
802
  .swap_private(
792
803
  wethCrossChainHarness.l2Token.address,
793
804
  wethCrossChainHarness.l2Bridge.address,
@@ -838,19 +849,33 @@ export const uniswapL1L2TestSuite = (
838
849
  chainId: new Fr(l1Client.chain.id),
839
850
  });
840
851
 
841
- const block = await aztecNode.getBlock(withdrawReceipt.blockNumber!);
842
- const epoch = await rollup.getEpochNumberForCheckpoint(block!.checkpointNumber);
843
- const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPrivateLeaf);
844
- const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
852
+ // ensure that user's funds were burnt
853
+ await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
854
+
855
+ // Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
856
+ // before we can ask the witness helper for a covering root.
857
+ const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
858
+ if (minedReceipt.epochNumber === undefined) {
859
+ throw new Error('Withdraw tx is not yet in an epoch');
860
+ }
861
+ await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
862
+ await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
863
+
864
+ // Fetch the outbox roots once and share them between the two witnesses in this epoch.
865
+ const epochRoots = await wethCrossChainHarness.outboxContract.getRoots(minedReceipt.epochNumber);
866
+ const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, swapPrivateLeaf, minedReceipt))!;
867
+ const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
868
+ const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, withdrawLeaf, minedReceipt))!;
845
869
 
846
- const swapPrivateL2MessageIndex = swapResult!.leafIndex;
847
- const swapPrivateSiblingPath = swapResult!.siblingPath;
870
+ const swapPrivateL2MessageIndex = swapResult.leafIndex;
871
+ const swapPrivateSiblingPath = swapResult.siblingPath;
848
872
 
849
- const withdrawL2MessageIndex = withdrawResult!.leafIndex;
850
- const withdrawSiblingPath = withdrawResult!.siblingPath;
873
+ const withdrawL2MessageIndex = withdrawResult.leafIndex;
874
+ const withdrawSiblingPath = withdrawResult.siblingPath;
851
875
 
852
876
  const withdrawMessageMetadata = {
853
877
  _epoch: BigInt(epoch),
878
+ _numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
854
879
  _leafIndex: BigInt(withdrawL2MessageIndex),
855
880
  _path: withdrawSiblingPath
856
881
  .toBufferArray()
@@ -859,19 +884,13 @@ export const uniswapL1L2TestSuite = (
859
884
 
860
885
  const swapPrivateMessageMetadata = {
861
886
  _epoch: BigInt(epoch),
887
+ _numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
862
888
  _leafIndex: BigInt(swapPrivateL2MessageIndex),
863
889
  _path: swapPrivateSiblingPath
864
890
  .toBufferArray()
865
891
  .map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
866
892
  };
867
893
 
868
- // ensure that user's funds were burnt
869
- await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
870
-
871
- // Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
872
- await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
873
- await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
874
-
875
894
  // On L1 call swap_public!
876
895
  logger.info('call swap_public on L1');
877
896
  const swapArgs = [
@@ -915,7 +934,7 @@ export const uniswapL1L2TestSuite = (
915
934
 
916
935
  // Call swap_public on L2
917
936
  const secretHashForDepositingSwappedDai = Fr.random();
918
- const withdrawReceipt = await uniswapL2Contract.methods
937
+ const { receipt: withdrawReceipt } = await uniswapL2Contract.methods
919
938
  .swap_public(
920
939
  ownerAddress,
921
940
  wethCrossChainHarness.l2Bridge.address,
@@ -971,19 +990,33 @@ export const uniswapL1L2TestSuite = (
971
990
  chainId: new Fr(l1Client.chain.id),
972
991
  });
973
992
 
974
- const block = await aztecNode.getBlock(withdrawReceipt.blockNumber!);
975
- const epoch = await rollup.getEpochNumberForCheckpoint(block!.checkpointNumber);
976
- const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPublicLeaf);
977
- const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
993
+ // check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
994
+ await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
995
+
996
+ // Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
997
+ // before we can ask the witness helper for a covering root.
998
+ const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
999
+ if (minedReceipt.epochNumber === undefined) {
1000
+ throw new Error('Withdraw tx is not yet in an epoch');
1001
+ }
1002
+ await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
1003
+ await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
1004
+
1005
+ // Fetch the outbox roots once and share them between the two witnesses in this epoch.
1006
+ const epochRoots = await wethCrossChainHarness.outboxContract.getRoots(minedReceipt.epochNumber);
1007
+ const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, swapPublicLeaf, minedReceipt))!;
1008
+ const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
1009
+ const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, withdrawLeaf, minedReceipt))!;
978
1010
 
979
- const swapPublicL2MessageIndex = swapResult!.leafIndex;
980
- const swapPublicSiblingPath = swapResult!.siblingPath;
1011
+ const swapPublicL2MessageIndex = swapResult.leafIndex;
1012
+ const swapPublicSiblingPath = swapResult.siblingPath;
981
1013
 
982
- const withdrawL2MessageIndex = withdrawResult!.leafIndex;
983
- const withdrawSiblingPath = withdrawResult!.siblingPath;
1014
+ const withdrawL2MessageIndex = withdrawResult.leafIndex;
1015
+ const withdrawSiblingPath = withdrawResult.siblingPath;
984
1016
 
985
1017
  const withdrawMessageMetadata = {
986
1018
  _epoch: BigInt(epoch),
1019
+ _numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
987
1020
  _leafIndex: BigInt(withdrawL2MessageIndex),
988
1021
  _path: withdrawSiblingPath
989
1022
  .toBufferArray()
@@ -992,19 +1025,13 @@ export const uniswapL1L2TestSuite = (
992
1025
 
993
1026
  const swapPublicMessageMetadata = {
994
1027
  _epoch: BigInt(epoch),
1028
+ _numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
995
1029
  _leafIndex: BigInt(swapPublicL2MessageIndex),
996
1030
  _path: swapPublicSiblingPath
997
1031
  .toBufferArray()
998
1032
  .map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
999
1033
  };
1000
1034
 
1001
- // check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
1002
- await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
1003
-
1004
- // Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
1005
- await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
1006
- await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
1007
-
1008
1035
  // Call swap_private on L1
1009
1036
  logger.info('Execute withdraw and swap on the uniswapPortal!');
1010
1037
 
@@ -0,0 +1,23 @@
1
+ import type { Fr } from '@aztec/aztec.js/fields';
2
+ import type { AztecNode } from '@aztec/aztec.js/node';
3
+ import { retryUntil } from '@aztec/foundation/retry';
4
+
5
+ /**
6
+ * Waits until the archiver has seen the L1 to L2 message and indexed it. Unlike
7
+ * {@link waitForL1ToL2MessageReady} from `@aztec/aztec.js/messaging`, this does not
8
+ * require the L2 chain to have advanced to the message's checkpoint — it only confirms
9
+ * the message has been picked up from L1. Use this in tests that explicitly produce L2
10
+ * blocks afterwards to make the message consumable.
11
+ */
12
+ export function waitForL1ToL2MessageSeen(
13
+ node: Pick<AztecNode, 'getL1ToL2MessageCheckpoint'>,
14
+ l1ToL2MessageHash: Fr,
15
+ opts: { timeoutSeconds: number },
16
+ ) {
17
+ return retryUntil(
18
+ async () => (await node.getL1ToL2MessageCheckpoint(l1ToL2MessageHash)) !== undefined,
19
+ `L1 to L2 message ${l1ToL2MessageHash.toString()} seen`,
20
+ opts.timeoutSeconds,
21
+ 1,
22
+ );
23
+ }
@@ -7,6 +7,7 @@ import { SlotNumber } from '@aztec/foundation/branded-types';
7
7
  import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
8
8
  import type { TestDateProvider } from '@aztec/foundation/timer';
9
9
  import type { LendingContract } from '@aztec/noir-contracts.js/Lending';
10
+ import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
10
11
 
11
12
  import type { TokenSimulator } from './token_simulator.js';
12
13
 
@@ -92,30 +93,45 @@ export class LendingSimulator {
92
93
  public stableCoin: TokenSimulator,
93
94
  ) {}
94
95
 
95
- async prepare() {
96
+ prepare() {
96
97
  this.accumulator = BASE;
97
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()) + BigInt(this.ethereumSlotDuration));
98
- this.time = Number(await this.rollup.getTimestampForSlot(slot));
98
+ this.time = 0;
99
99
  }
100
100
 
101
- async progressSlots(diff: number, dateProvider?: TestDateProvider) {
101
+ /**
102
+ * Advances the simulator's accumulator and clock to match a block timestamp observed on chain.
103
+ * Call this BEFORE applying any accumulator-sensitive mutation (borrow/repay) so the mutation
104
+ * sees the same accumulator as the contract did during execution.
105
+ */
106
+ observeBlockTimestamp(ts: number) {
107
+ const diff = ts - this.time;
108
+ if (diff > 0) {
109
+ this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(diff)), BASE);
110
+ }
111
+ this.time = ts;
112
+ }
113
+
114
+ async progressSlots(diff: number, _dateProvider?: TestDateProvider, node?: AztecNode & AztecNodeDebug) {
102
115
  if (diff <= 1) {
103
116
  return;
104
117
  }
105
118
 
106
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()));
119
+ const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
107
120
  const targetSlot = SlotNumber(slot + diff);
108
121
  const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
109
- const timeDiff = ts - this.time;
110
- this.time = ts;
111
122
 
112
- // Mine ethereum blocks such that the next block will be in a new slot
113
- await this.cc.eth.warp(this.time - this.ethereumSlotDuration);
114
- if (dateProvider) {
115
- dateProvider.setTime(this.time * 1000);
123
+ // Queue-aware warp under AutomineSequencer: atomic warp + mineBlock that advances L2 time to the
124
+ // target slot. The cheat code routes through the AutomineSequencer queue when one is installed,
125
+ // and otherwise falls back to a manual warp + mineBlock loop.
126
+ if (node) {
127
+ await this.cc.warpL2TimeAtLeastTo(node, ts);
128
+ } else {
129
+ await this.cc.eth.warp(ts - this.ethereumSlotDuration);
116
130
  }
131
+
132
+ // Mark the latest checkpoint as proven so the rollup does not reorg pending checkpoints when
133
+ // time jumps far enough forward to cross an unproven epoch boundary.
117
134
  await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber());
118
- this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE);
119
135
  }
120
136
 
121
137
  depositPrivate(from: AztecAddress, onBehalfOf: Fr, amount: bigint) {
@@ -186,14 +202,16 @@ export class LendingSimulator {
186
202
 
187
203
  expect(this.borrowed).toEqual(this.stableCoin.totalSupply - this.mintedOutside);
188
204
 
189
- const asset = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address });
205
+ const { result: asset } = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address });
190
206
 
191
207
  const interestAccumulator = asset['interest_accumulator'];
192
208
  expect(interestAccumulator).toEqual(this.accumulator);
193
209
  expect(asset['last_updated_ts']).toEqual(BigInt(this.time));
194
210
 
195
211
  for (const key of [this.account.address, AztecAddress.fromField(await this.account.key())]) {
196
- const privatePos = await this.lendingContract.methods.get_position(key).simulate({ from: this.account.address });
212
+ const { result: privatePos } = await this.lendingContract.methods
213
+ .get_position(key)
214
+ .simulate({ from: this.account.address });
197
215
  expect(new Fr(privatePos['collateral'])).toEqual(this.collateral[key.toString()] ?? Fr.ZERO);
198
216
  expect(new Fr(privatePos['static_debt'])).toEqual(this.staticDebt[key.toString()] ?? Fr.ZERO);
199
217
  expect(privatePos['debt']).toEqual(
@@ -109,7 +109,9 @@ export class TokenSimulator {
109
109
  await Promise.all(
110
110
  chunk(calls, 5).map(batch => new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress })),
111
111
  )
112
- ).flat();
112
+ )
113
+ .flatMap(r => r.result)
114
+ .map(r => r.result);
113
115
  expect(results[0]).toEqual(this.totalSupply);
114
116
 
115
117
  // Check that all our balances match
@@ -123,7 +125,9 @@ export class TokenSimulator {
123
125
  const wallet = this.lookupProvider.get(address.toString());
124
126
  const asset = wallet ? this.token.withWallet(wallet) : this.token;
125
127
 
126
- const actualPrivateBalance = await asset.methods.balance_of_private(address).simulate({ from: address });
128
+ const { result: actualPrivateBalance } = await asset.methods
129
+ .balance_of_private(address)
130
+ .simulate({ from: address });
127
131
  expect(actualPrivateBalance).toEqual(this.balanceOfPrivate(address));
128
132
  }
129
133
  }
@@ -1,16 +1,18 @@
1
1
  import { generateSchnorrAccounts } from '@aztec/accounts/testing';
2
+ import { NO_FROM } from '@aztec/aztec.js/account';
2
3
  import { AztecAddress } from '@aztec/aztec.js/addresses';
3
4
  import { NO_WAIT } from '@aztec/aztec.js/contracts';
4
5
  import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
5
6
  import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
6
7
  import { type FeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
7
8
  import { Fr } from '@aztec/aztec.js/fields';
9
+ import { waitForL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
8
10
  import { type AztecNode, createAztecNodeClient, waitForTx } from '@aztec/aztec.js/node';
9
11
  import type { Wallet } from '@aztec/aztec.js/wallet';
10
12
  import { createEthereumChain } from '@aztec/ethereum/chain';
11
13
  import { createExtendedL1Client } from '@aztec/ethereum/client';
12
14
  import type { Logger } from '@aztec/foundation/log';
13
- import { retryUntil } from '@aztec/foundation/retry';
15
+ import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
14
16
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
15
17
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
16
18
  import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
@@ -89,7 +91,7 @@ export async function deploySponsoredTestAccountsWithTokens(
89
91
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
90
92
  const recipientDeployMethod = await recipientAccount.getDeployMethod();
91
93
  await recipientDeployMethod.send({
92
- from: AztecAddress.ZERO,
94
+ from: NO_FROM,
93
95
  fee: { paymentMethod },
94
96
  wait: { timeout: 2400 },
95
97
  });
@@ -97,7 +99,7 @@ export async function deploySponsoredTestAccountsWithTokens(
97
99
  fundedAccounts.map(async a => {
98
100
  const deployMethod = await a.getDeployMethod();
99
101
  await deployMethod.send({
100
- from: AztecAddress.ZERO,
102
+ from: NO_FROM,
101
103
  fee: { paymentMethod },
102
104
  wait: { timeout: 2400 },
103
105
  }); // increase timeout on purpose in order to account for two empty epochs
@@ -129,53 +131,91 @@ export async function deploySponsoredTestAccountsWithTokens(
129
131
  }
130
132
 
131
133
  async function deployAccountWithDiagnostics(
132
- account: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any },
134
+ account: { getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>; address: any },
133
135
  paymentMethod: SponsoredFeePaymentMethod,
134
136
  aztecNode: AztecNode,
135
137
  logger: Logger,
136
138
  accountLabel: string,
139
+ estimateGas?: boolean,
137
140
  ): Promise<void> {
138
141
  const deployMethod = await account.getDeployMethod();
139
- let txHash;
140
- try {
141
- txHash = await deployMethod.send({
142
- from: AztecAddress.ZERO,
143
- fee: { paymentMethod },
144
- wait: NO_WAIT,
145
- });
146
- await waitForTx(aztecNode, txHash, { timeout: 2400 });
147
- logger.info(`${accountLabel} deployed at ${account.address}`);
148
- } catch (error) {
149
- const blockNumber = await aztecNode.getBlockNumber();
150
- let receipt;
151
- try {
152
- receipt = await aztecNode.getTxReceipt(txHash);
153
- } catch {
154
- receipt = 'unavailable';
155
- }
156
- logger.error(`${accountLabel} deployment failed`, {
157
- txHash: txHash.toString(),
158
- receipt: JSON.stringify(receipt),
159
- currentBlockNumber: blockNumber,
160
- error: String(error),
161
- });
162
- throw error;
142
+ let gasSettings: any;
143
+ if (estimateGas) {
144
+ const sim = await deployMethod.simulate({ from: NO_FROM, fee: { paymentMethod } });
145
+ gasSettings = sim.estimatedGas;
146
+ logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
163
147
  }
148
+
149
+ // Track the tx hash across retries so we don't re-send when the previous tx is still pending.
150
+ let sentTxHash: { txHash: any } | undefined;
151
+
152
+ await retry(
153
+ async () => {
154
+ // Check if already deployed (handles case where previous attempt succeeded but waitForTx timed out)
155
+ const existing = await aztecNode.getContract(account.address);
156
+ if (existing) {
157
+ logger.info(`${accountLabel} already deployed at ${account.address}, skipping`);
158
+ return;
159
+ }
160
+
161
+ // If we already sent a tx, check if it was dropped before deciding to re-send.
162
+ if (sentTxHash) {
163
+ const prevReceipt = await aztecNode.getTxReceipt(sentTxHash.txHash);
164
+ if (prevReceipt.isDropped()) {
165
+ logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} was dropped, re-sending`);
166
+ sentTxHash = undefined;
167
+ } else {
168
+ logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} still pending, waiting again...`);
169
+ }
170
+ }
171
+
172
+ if (!sentTxHash) {
173
+ const deployResult = await deployMethod.send({
174
+ from: NO_FROM,
175
+ fee: { paymentMethod, gasSettings },
176
+ wait: NO_WAIT,
177
+ });
178
+ sentTxHash = { txHash: deployResult.txHash };
179
+ logger.info(`${accountLabel} tx sent`, { txHash: sentTxHash.txHash.toString() });
180
+ }
181
+
182
+ const receipt = await waitForTx(aztecNode, sentTxHash.txHash, { timeout: 600 });
183
+ if (receipt.isDropped()) {
184
+ sentTxHash = undefined;
185
+ throw new Error(`${accountLabel} tx was dropped, retrying...`);
186
+ }
187
+ logger.info(`${accountLabel} deployed at ${account.address}`);
188
+ },
189
+ `deploy ${accountLabel}`,
190
+ makeBackoff([1, 2, 4, 8, 16]),
191
+ logger,
192
+ );
164
193
  }
165
194
 
166
195
  async function deployAccountsInBatches(
167
- accounts: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any }[],
196
+ accounts: {
197
+ getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>;
198
+ address: any;
199
+ }[],
168
200
  paymentMethod: SponsoredFeePaymentMethod,
169
201
  aztecNode: AztecNode,
170
202
  logger: Logger,
171
203
  labelPrefix: string,
172
204
  batchSize = 2,
205
+ estimateGas?: boolean,
173
206
  ): Promise<void> {
174
207
  for (let i = 0; i < accounts.length; i += batchSize) {
175
208
  const batch = accounts.slice(i, i + batchSize);
176
209
  await Promise.all(
177
210
  batch.map((account, idx) =>
178
- deployAccountWithDiagnostics(account, paymentMethod, aztecNode, logger, `${labelPrefix}${i + idx + 1}`),
211
+ deployAccountWithDiagnostics(
212
+ account,
213
+ paymentMethod,
214
+ aztecNode,
215
+ logger,
216
+ `${labelPrefix}${i + idx + 1}`,
217
+ estimateGas,
218
+ ),
179
219
  ),
180
220
  );
181
221
  }
@@ -186,6 +226,7 @@ export async function deploySponsoredTestAccounts(
186
226
  aztecNode: AztecNode,
187
227
  logger: Logger,
188
228
  numberOfFundedWallets = 1,
229
+ opts?: { estimateGas?: boolean },
189
230
  ): Promise<TestAccountsWithoutTokens> {
190
231
  const [recipient, ...funded] = await generateSchnorrAccounts(numberOfFundedWallets + 1);
191
232
  const recipientAccount = await wallet.createSchnorrAccount(recipient.secret, recipient.salt);
@@ -195,8 +236,23 @@ export async function deploySponsoredTestAccounts(
195
236
 
196
237
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
197
238
 
198
- await deployAccountWithDiagnostics(recipientAccount, paymentMethod, aztecNode, logger, 'Recipient account');
199
- await deployAccountsInBatches(fundedAccounts, paymentMethod, aztecNode, logger, 'Funded account ', 2);
239
+ await deployAccountWithDiagnostics(
240
+ recipientAccount,
241
+ paymentMethod,
242
+ aztecNode,
243
+ logger,
244
+ 'Recipient account',
245
+ opts?.estimateGas,
246
+ );
247
+ await deployAccountsInBatches(
248
+ fundedAccounts,
249
+ paymentMethod,
250
+ aztecNode,
251
+ logger,
252
+ 'Funded account ',
253
+ 2,
254
+ opts?.estimateGas,
255
+ );
200
256
 
201
257
  return {
202
258
  aztecNode,
@@ -234,7 +290,7 @@ export async function deployTestAccountsWithTokens(
234
290
  fundedAccounts.map(async (a, i) => {
235
291
  const paymentMethod = new FeeJuicePaymentMethodWithClaim(a.address, claims[i]);
236
292
  const deployMethod = await a.getDeployMethod();
237
- await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod } });
293
+ await deployMethod.send({ from: NO_FROM, fee: { paymentMethod } });
238
294
  logger.info(`Account deployed at ${a.address}`);
239
295
  }),
240
296
  );
@@ -277,9 +333,7 @@ async function bridgeL1FeeJuice(
277
333
  const portal = await L1FeeJuicePortalManager.new(aztecNode, l1Client, log);
278
334
  const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
279
335
 
280
- const isSynced = async () =>
281
- (await aztecNode.getL1ToL2MessageBlock(Fr.fromHexString(claim.messageHash))) !== undefined;
282
- await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 0.5);
336
+ await waitForL1ToL2MessageReady(aztecNode, Fr.fromHexString(claim.messageHash), { timeoutSeconds: 24 });
283
337
 
284
338
  log.info(`Created a claim for ${amount} L1 fee juice to ${recipient}.`, claim);
285
339
  return claim;
@@ -321,7 +375,7 @@ async function deployTokenAndMint(
321
375
  fee: {
322
376
  paymentMethod,
323
377
  },
324
- wait: { timeout: 600, returnReceipt: true },
378
+ wait: { timeout: 600 },
325
379
  });
326
380
 
327
381
  const tokenAddress = tokenContract.address;