@aztec/end-to-end 1.2.1 → 2.0.0-nightly.20250813

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 (119) hide show
  1. package/dest/bench/client_flows/benchmark.d.ts +2 -2
  2. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/benchmark.js +4 -2
  4. package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  6. package/dest/bench/client_flows/client_flows_benchmark.js +33 -15
  7. package/dest/bench/utils.d.ts.map +1 -1
  8. package/dest/bench/utils.js +7 -4
  9. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +11 -3
  10. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  11. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +59 -24
  12. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +3 -2
  13. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  14. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +13 -10
  15. package/dest/e2e_deploy_contract/deploy_test.d.ts +1 -1
  16. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  17. package/dest/e2e_deploy_contract/deploy_test.js +7 -6
  18. package/dest/e2e_epochs/epochs_test.d.ts +16 -2
  19. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  20. package/dest/e2e_epochs/epochs_test.js +65 -7
  21. package/dest/e2e_fees/bridging_race.notest.js +3 -1
  22. package/dest/e2e_fees/fees_test.d.ts +5 -4
  23. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  24. package/dest/e2e_fees/fees_test.js +44 -59
  25. package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
  26. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  27. package/dest/e2e_nested_contract/nested_contract_test.js +17 -12
  28. package/dest/e2e_p2p/p2p_network.d.ts +7 -4
  29. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  30. package/dest/e2e_p2p/p2p_network.js +43 -22
  31. package/dest/e2e_p2p/shared.d.ts +3 -3
  32. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  33. package/dest/e2e_p2p/shared.js +16 -12
  34. package/dest/e2e_token_contract/token_contract_test.d.ts +8 -4
  35. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  36. package/dest/e2e_token_contract/token_contract_test.js +48 -23
  37. package/dest/fixtures/e2e_prover_test.d.ts +1 -1
  38. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  39. package/dest/fixtures/e2e_prover_test.js +27 -10
  40. package/dest/fixtures/setup_p2p_test.d.ts +4 -1
  41. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  42. package/dest/fixtures/setup_p2p_test.js +39 -8
  43. package/dest/fixtures/snapshot_manager.d.ts +3 -1
  44. package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
  45. package/dest/fixtures/snapshot_manager.js +20 -17
  46. package/dest/fixtures/token_utils.d.ts +3 -3
  47. package/dest/fixtures/token_utils.d.ts.map +1 -1
  48. package/dest/fixtures/token_utils.js +14 -10
  49. package/dest/fixtures/utils.d.ts +23 -8
  50. package/dest/fixtures/utils.d.ts.map +1 -1
  51. package/dest/fixtures/utils.js +88 -56
  52. package/dest/integration_l1_publisher/write_json.d.ts +8 -0
  53. package/dest/integration_l1_publisher/write_json.d.ts.map +1 -0
  54. package/dest/integration_l1_publisher/write_json.js +57 -0
  55. package/dest/sample-dapp/connect.d.mts +2 -0
  56. package/dest/sample-dapp/connect.d.mts.map +1 -0
  57. package/dest/sample-dapp/connect.js +1 -1
  58. package/dest/sample-dapp/contracts.d.mts +3 -0
  59. package/dest/sample-dapp/contracts.d.mts.map +1 -0
  60. package/dest/sample-dapp/contracts.js +1 -1
  61. package/dest/sample-dapp/deploy.d.mts +3 -0
  62. package/dest/sample-dapp/deploy.d.mts.map +1 -0
  63. package/dest/sample-dapp/deploy.js +4 -1
  64. package/dest/sample-dapp/index.d.mts +2 -0
  65. package/dest/sample-dapp/index.d.mts.map +1 -0
  66. package/dest/sample-dapp/index.js +18 -8
  67. package/dest/shared/cross_chain_test_harness.d.ts +6 -3
  68. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  69. package/dest/shared/cross_chain_test_harness.js +50 -20
  70. package/dest/shared/gas_portal_test_harness.d.ts +3 -3
  71. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  72. package/dest/shared/gas_portal_test_harness.js +21 -6
  73. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  74. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  75. package/dest/shared/uniswap_l1_l2.js +45 -22
  76. package/dest/simulators/lending_simulator.d.ts +1 -1
  77. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  78. package/dest/simulators/lending_simulator.js +6 -2
  79. package/dest/simulators/token_simulator.d.ts +2 -1
  80. package/dest/simulators/token_simulator.d.ts.map +1 -1
  81. package/dest/simulators/token_simulator.js +12 -4
  82. package/dest/spartan/setup_test_wallets.d.ts +7 -0
  83. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  84. package/dest/spartan/setup_test_wallets.js +96 -11
  85. package/dest/spartan/utils.d.ts +23 -3
  86. package/dest/spartan/utils.d.ts.map +1 -1
  87. package/dest/spartan/utils.js +9 -6
  88. package/package.json +36 -36
  89. package/src/bench/client_flows/benchmark.ts +8 -3
  90. package/src/bench/client_flows/client_flows_benchmark.ts +23 -14
  91. package/src/bench/utils.ts +5 -4
  92. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +47 -26
  93. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +14 -9
  94. package/src/e2e_deploy_contract/deploy_test.ts +7 -7
  95. package/src/e2e_epochs/epochs_test.ts +97 -25
  96. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  97. package/src/e2e_fees/fees_test.ts +55 -82
  98. package/src/e2e_nested_contract/nested_contract_test.ts +16 -11
  99. package/src/e2e_p2p/p2p_network.ts +51 -26
  100. package/src/e2e_p2p/shared.ts +14 -12
  101. package/src/e2e_token_contract/token_contract_test.ts +38 -36
  102. package/src/fixtures/e2e_prover_test.ts +17 -10
  103. package/src/fixtures/setup_p2p_test.ts +51 -9
  104. package/src/fixtures/snapshot_manager.ts +24 -17
  105. package/src/fixtures/token_utils.ts +14 -9
  106. package/src/fixtures/utils.ts +116 -57
  107. package/src/guides/up_quick_start.sh +1 -1
  108. package/src/integration_l1_publisher/write_json.ts +74 -0
  109. package/src/sample-dapp/connect.mjs +1 -1
  110. package/src/sample-dapp/contracts.mjs +1 -1
  111. package/src/sample-dapp/deploy.mjs +3 -3
  112. package/src/sample-dapp/index.mjs +11 -8
  113. package/src/shared/cross_chain_test_harness.ts +31 -18
  114. package/src/shared/gas_portal_test_harness.ts +17 -7
  115. package/src/shared/uniswap_l1_l2.ts +28 -24
  116. package/src/simulators/lending_simulator.ts +3 -3
  117. package/src/simulators/token_simulator.ts +12 -3
  118. package/src/spartan/setup_test_wallets.ts +130 -19
  119. package/src/spartan/utils.ts +10 -3
@@ -25,22 +25,23 @@ import {
25
25
  sleep,
26
26
  waitForPXE,
27
27
  } from '@aztec/aztec.js';
28
- import { deployInstance, registerContractClass } from '@aztec/aztec.js/deployment';
29
- import { AnvilTestWatcher, CheatCodes } from '@aztec/aztec.js/testing';
28
+ import { publishContractClass, publishInstance } from '@aztec/aztec.js/deployment';
29
+ import { AnvilTestWatcher, CheatCodes } from '@aztec/aztec/testing';
30
30
  import { createBlobSinkClient } from '@aztec/blob-sink/client';
31
31
  import { type BlobSinkServer, createBlobSinkServer } from '@aztec/blob-sink/server';
32
32
  import { GENESIS_ARCHIVE_ROOT, SPONSORED_FPC_SALT } from '@aztec/constants';
33
33
  import {
34
34
  type DeployL1ContractsArgs,
35
35
  type DeployL1ContractsReturnType,
36
+ FeeAssetArtifact,
36
37
  NULL_KEY,
37
38
  type Operator,
39
+ RollupContract,
38
40
  createExtendedL1Client,
39
41
  deployL1Contracts,
40
42
  deployMulticall3,
41
43
  getL1ContractsConfigEnvVars,
42
44
  isAnvilTestChain,
43
- l1Artifacts,
44
45
  } from '@aztec/ethereum';
45
46
  import { DelayedTxUtils, EthCheatCodesWithState, startAnvil } from '@aztec/ethereum/test';
46
47
  import { SecretValue } from '@aztec/foundation/config';
@@ -50,14 +51,14 @@ import { Fr } from '@aztec/foundation/fields';
50
51
  import { tryRmDir } from '@aztec/foundation/fs';
51
52
  import { withLogNameSuffix } from '@aztec/foundation/log';
52
53
  import { retryUntil } from '@aztec/foundation/retry';
53
- import { TestDateProvider } from '@aztec/foundation/timer';
54
+ import { DateProvider, TestDateProvider } from '@aztec/foundation/timer';
54
55
  import type { DataStoreConfig } from '@aztec/kv-store/config';
55
56
  import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
56
57
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
57
58
  import type { P2PClientDeps } from '@aztec/p2p';
58
59
  import { MockGossipSubNetwork, getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
59
60
  import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
60
- import { type ProverNode, type ProverNodeConfig, createProverNode } from '@aztec/prover-node';
61
+ import { type ProverNode, type ProverNodeConfig, type ProverNodeDeps, createProverNode } from '@aztec/prover-node';
61
62
  import {
62
63
  type PXEService,
63
64
  type PXEServiceConfig,
@@ -68,7 +69,11 @@ import type { SequencerClient } from '@aztec/sequencer-client';
68
69
  import type { TestSequencerClient } from '@aztec/sequencer-client/test';
69
70
  import { MemoryCircuitRecorder, SimulatorRecorderWrapper, WASMSimulator } from '@aztec/simulator/client';
70
71
  import { FileCircuitRecorder } from '@aztec/simulator/testing';
71
- import { getContractClassFromArtifact, getContractInstanceFromDeployParams } from '@aztec/stdlib/contract';
72
+ import {
73
+ type ContractInstanceWithAddress,
74
+ getContractClassFromArtifact,
75
+ getContractInstanceFromInstantiationParams,
76
+ } from '@aztec/stdlib/contract';
72
77
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
73
78
  import { tryStop } from '@aztec/stdlib/interfaces/server';
74
79
  import type { P2PClientType } from '@aztec/stdlib/p2p';
@@ -252,8 +257,9 @@ async function setupWithRemoteEnvironment(
252
257
  deployL1ContractsValues,
253
258
  config,
254
259
  initialFundedAccounts,
260
+ wallets,
255
261
  wallet: wallets[0],
256
- wallets: wallets.slice(0, numberOfAccounts),
262
+ accounts: wallets.slice(0, numberOfAccounts).map(w => w.getAddress()),
257
263
  logger,
258
264
  cheatCodes,
259
265
  prefilledPublicData: undefined,
@@ -308,6 +314,8 @@ export type SetupOptions = {
308
314
  automineL1Setup?: boolean;
309
315
  /** How many accounts to seed and unlock in anvil. */
310
316
  anvilAccounts?: number;
317
+ /** Port to start anvil (defaults to 8545) */
318
+ anvilPort?: number;
311
319
  } & Partial<AztecNodeConfig>;
312
320
 
313
321
  /** Context for an end-to-end test as returned by the `setup` function */
@@ -328,10 +336,12 @@ export type EndToEndContext = {
328
336
  config: AztecNodeConfig;
329
337
  /** The data for the initial funded accounts. */
330
338
  initialFundedAccounts: InitialAccountData[];
339
+ /* Wallets created for the initial funded accounts, with secret keys. */
340
+ wallets: AccountWalletWithSecretKey[];
331
341
  /** The first wallet to be used. */
332
342
  wallet: AccountWalletWithSecretKey;
333
- /** The wallets to be used. */
334
- wallets: AccountWalletWithSecretKey[];
343
+ /** The accounts to be used. */
344
+ accounts: AztecAddress[];
335
345
  /** Logger instance named as the current test. */
336
346
  logger: Logger;
337
347
  /** The cheat codes. */
@@ -399,7 +409,11 @@ export async function setup(
399
409
  );
400
410
  }
401
411
 
402
- const res = await startAnvil({ l1BlockTime: opts.ethereumSlotDuration, accounts: opts.anvilAccounts });
412
+ const res = await startAnvil({
413
+ l1BlockTime: opts.ethereumSlotDuration,
414
+ accounts: opts.anvilAccounts,
415
+ port: opts.anvilPort,
416
+ });
403
417
  anvil = res.anvil;
404
418
  config.l1RpcUrls = [res.rpcUrl];
405
419
  }
@@ -418,7 +432,7 @@ export async function setup(
418
432
  }
419
433
 
420
434
  if (opts.l1StartTime) {
421
- await ethCheatCodes.warp(opts.l1StartTime);
435
+ await ethCheatCodes.warp(opts.l1StartTime, { resetBlockInterval: true });
422
436
  }
423
437
 
424
438
  let publisherPrivKey = undefined;
@@ -479,22 +493,24 @@ export async function setup(
479
493
  if (opts.fundRewardDistributor) {
480
494
  // Mints block rewards for 10000 blocks to the rewardDistributor contract
481
495
 
482
- const rewardDistributor = getContract({
483
- address: deployL1ContractsValues.l1ContractAddresses.rewardDistributorAddress.toString(),
484
- abi: l1Artifacts.rewardDistributor.contractAbi,
485
- client: deployL1ContractsValues.l1Client,
486
- });
496
+ const rollup = new RollupContract(
497
+ deployL1ContractsValues.l1Client,
498
+ deployL1ContractsValues.l1ContractAddresses.rollupAddress,
499
+ );
487
500
 
488
- const blockReward = await rewardDistributor.read.BLOCK_REWARD();
501
+ const blockReward = await rollup.getBlockReward();
489
502
  const mintAmount = 10_000n * (blockReward as bigint);
490
503
 
491
504
  const feeJuice = getContract({
492
505
  address: deployL1ContractsValues.l1ContractAddresses.feeJuiceAddress.toString(),
493
- abi: l1Artifacts.feeAsset.contractAbi,
506
+ abi: FeeAssetArtifact.contractAbi,
494
507
  client: deployL1ContractsValues.l1Client,
495
508
  });
496
509
 
497
- const rewardDistributorMintTxHash = await feeJuice.write.mint([rewardDistributor.address, mintAmount], {} as any);
510
+ const rewardDistributorMintTxHash = await feeJuice.write.mint(
511
+ [deployL1ContractsValues.l1ContractAddresses.rewardDistributorAddress.toString(), mintAmount],
512
+ {} as any,
513
+ );
498
514
  await deployL1ContractsValues.l1Client.waitForTransactionReceipt({ hash: rewardDistributorMintTxHash });
499
515
  logger.info(`Funding rewardDistributor in ${rewardDistributorMintTxHash}`);
500
516
  }
@@ -507,7 +523,7 @@ export async function setup(
507
523
  if (opts.l2StartTime) {
508
524
  // This should only be used in synching test or when you need to have a stable
509
525
  // timestamp for the first l2 block.
510
- await ethCheatCodes.warp(opts.l2StartTime);
526
+ await ethCheatCodes.warp(opts.l2StartTime, { resetBlockInterval: true });
511
527
  }
512
528
 
513
529
  const dateProvider = new TestDateProvider();
@@ -566,6 +582,25 @@ export async function setup(
566
582
  p2pClientDeps = { p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork) };
567
583
  }
568
584
 
585
+ // Transactions built against the genesis state must be included in block 1, otherwise they are dropped.
586
+ // To avoid test failures from dropped transactions, we ensure progression beyond genesis before proceeding.
587
+ // For account deployments, we set minTxsPerBlock=1 and deploy accounts sequentially for guaranteed success.
588
+ // If no accounts need deployment, we await an empty block to confirm network progression. After either path
589
+ // completes, we restore the original minTxsPerBlock setting. The deployment and waiting for empty block is
590
+ // handled by the if-else branches on line 632.
591
+ // For more details on why the tx would be dropped see `validate_include_by_timestamp` function in
592
+ // `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
593
+ //
594
+ // Note: If the following seems too convoluted or if it starts making problems, we could drop the "progressing
595
+ // past genesis via an account contract deployment" optimization and just call flush() on the sequencer and wait
596
+ // for an empty block to be mined. This would simplify it all quite a bit but the setup would be slower for tests
597
+ // deploying accounts.
598
+ const originalMinTxsPerBlock = config.minTxsPerBlock;
599
+ if (originalMinTxsPerBlock === undefined) {
600
+ throw new Error('minTxsPerBlock is undefined in e2e test setup');
601
+ }
602
+ config.minTxsPerBlock = numberOfAccounts === 0 ? 0 : 1;
603
+
569
604
  config.p2pEnabled = opts.mockGossipSubNetwork || config.p2pEnabled;
570
605
  config.p2pIp = opts.p2pIp ?? config.p2pIp ?? '127.0.0.1';
571
606
  const aztecNode = await AztecNodeService.createAndSync(
@@ -612,33 +647,22 @@ export async function setup(
612
647
  await cheatCodes.rollup.debugRollup();
613
648
  }
614
649
 
615
- const sequencer = sequencerClient!.getSequencer();
616
- const minTxsPerBlock = config.minTxsPerBlock;
617
-
618
- if (minTxsPerBlock === undefined) {
619
- throw new Error('minTxsPerBlock is undefined in e2e test setup');
620
- }
621
-
622
- // Transactions built against the genesis state must be included in block 1, otherwise they are dropped.
623
- // To avoid test failures from dropped transactions, we ensure progression beyond genesis before proceeding.
624
- // For account deployments, we set minTxsPerBlock=1 and deploy accounts sequentially for guaranteed success.
625
- // If no accounts need deployment, we await an empty block to confirm network progression. After either path
626
- // completes, we restore the original minTxsPerBlock setting.
627
- // For more details on why the tx would be dropped see `validate_include_by_timestamp` function in
628
- // `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
650
+ // Below we continue with what we described in the long comment on line 571.
629
651
  let accountManagers: AccountManager[] = [];
630
652
  if (numberOfAccounts === 0) {
631
- // We wait until block 1 is mined to ensure that the network has progressed past genesis.
632
- sequencer.updateConfig({ minTxsPerBlock: 0 });
653
+ logger.info('No accounts are being deployed, waiting for an empty block 1 to be mined');
633
654
  while ((await pxe.getBlockNumber()) === 0) {
634
655
  await sleep(2000);
635
656
  }
636
657
  } else {
637
- sequencer.updateConfig({ minTxsPerBlock: 1 });
658
+ logger.info(
659
+ `${numberOfAccounts} accounts are being deployed. Reliably progressing past genesis by setting minTxsPerBlock to 1 and waiting for the accounts to be deployed`,
660
+ );
638
661
  accountManagers = await deployFundedSchnorrAccounts(pxe, initialFundedAccounts.slice(0, numberOfAccounts));
639
662
  }
640
663
 
641
- sequencer.updateConfig({ minTxsPerBlock });
664
+ // Now we restore the original minTxsPerBlock setting.
665
+ sequencerClient!.getSequencer().updateConfig({ minTxsPerBlock: originalMinTxsPerBlock });
642
666
 
643
667
  const wallets = await Promise.all(accountManagers.map(account => account.getWallet()));
644
668
  if (initialFundedAccounts.length < numberOfAccounts) {
@@ -689,8 +713,9 @@ export async function setup(
689
713
  sequencer: sequencerClient,
690
714
  teardown,
691
715
  telemetryClient: telemetry,
692
- wallet: wallets[0],
693
716
  wallets,
717
+ wallet: wallets[0],
718
+ accounts: wallets.map(w => w.getAddress()),
694
719
  watcher,
695
720
  };
696
721
  } catch (err) {
@@ -708,7 +733,7 @@ export async function setup(
708
733
  */
709
734
 
710
735
  // docs:start:public_deploy_accounts
711
- export async function ensureAccountsPubliclyDeployed(sender: Wallet, accountsToDeploy: Wallet[]) {
736
+ export async function ensureAccountContractsPublished(sender: Wallet, accountsToDeploy: Wallet[]) {
712
737
  // We have to check whether the accounts are already deployed. This can happen if the test runs against
713
738
  // the sandbox and the test accounts exist
714
739
  const accountsAndAddresses = await Promise.all(
@@ -716,7 +741,7 @@ export async function ensureAccountsPubliclyDeployed(sender: Wallet, accountsToD
716
741
  const address = account.getAddress();
717
742
  return {
718
743
  address,
719
- deployed: (await sender.getContractMetadata(address)).isContractPubliclyDeployed,
744
+ deployed: (await sender.getContractMetadata(address)).isContractPublished,
720
745
  };
721
746
  }),
722
747
  );
@@ -729,11 +754,13 @@ export async function ensureAccountsPubliclyDeployed(sender: Wallet, accountsToD
729
754
  ).map(contractMetadata => contractMetadata.contractInstance);
730
755
  const contractClass = await getContractClassFromArtifact(SchnorrAccountContractArtifact);
731
756
  if (!(await sender.getContractClassMetadata(contractClass.id, true)).isContractClassPubliclyRegistered) {
732
- await (await registerContractClass(sender, SchnorrAccountContractArtifact)).send().wait();
757
+ await (await publishContractClass(sender, SchnorrAccountContractArtifact))
758
+ .send({ from: accountsToDeploy[0].getAddress() })
759
+ .wait();
733
760
  }
734
- const requests = await Promise.all(instances.map(async instance => await deployInstance(sender, instance!)));
761
+ const requests = await Promise.all(instances.map(async instance => await publishInstance(sender, instance!)));
735
762
  const batch = new BatchCall(sender, requests);
736
- await batch.send().wait();
763
+ await batch.send({ from: accountsToDeploy[0].getAddress() }).wait();
737
764
  }
738
765
  // docs:end:public_deploy_accounts
739
766
 
@@ -773,11 +800,12 @@ export type BalancesFn = ReturnType<typeof getBalancesFn>;
773
800
  export function getBalancesFn(
774
801
  symbol: string,
775
802
  method: ContractMethod,
803
+ from: AztecAddress,
776
804
  logger: any,
777
805
  ): (...addresses: (AztecAddress | { address: AztecAddress })[]) => Promise<bigint[]> {
778
806
  const balances = async (...addressLikes: (AztecAddress | { address: AztecAddress })[]) => {
779
807
  const addresses = addressLikes.map(addressLike => ('address' in addressLike ? addressLike.address : addressLike));
780
- const b = await Promise.all(addresses.map(address => method(address).simulate()));
808
+ const b = await Promise.all(addresses.map(address => method(address).simulate({ from })));
781
809
  const debugString = `${symbol} balances: ${addresses.map((address, i) => `${address}: ${b[i]}`).join(', ')}`;
782
810
  logger.verbose(debugString);
783
811
  return b;
@@ -812,15 +840,26 @@ export async function expectMappingDelta<K, V extends number | bigint>(
812
840
  expect(diffs).toEqual(expectedDiffs);
813
841
  }
814
842
 
843
+ /**
844
+ * Computes the address of the "canonical" SponosoredFPCContract. This is not a protocol contract
845
+ * but by conventions its address is computed with a salt of 0.
846
+ * @returns The address of the sponsored FPC contract
847
+ */
848
+ export function getSponsoredFPCInstance(): Promise<ContractInstanceWithAddress> {
849
+ return Promise.resolve(
850
+ getContractInstanceFromInstantiationParams(SponsoredFPCContract.artifact, {
851
+ salt: new Fr(SPONSORED_FPC_SALT),
852
+ }),
853
+ );
854
+ }
855
+
815
856
  /**
816
857
  * Computes the address of the "canonical" SponosoredFPCContract. This is not a protocol contract
817
858
  * but by conventions its address is computed with a salt of 0.
818
859
  * @returns The address of the sponsored FPC contract
819
860
  */
820
861
  export async function getSponsoredFPCAddress() {
821
- const sponsoredFPCInstance = await getContractInstanceFromDeployParams(SponsoredFPCContract.artifact, {
822
- salt: new Fr(SPONSORED_FPC_SALT),
823
- });
862
+ const sponsoredFPCInstance = await getSponsoredFPCInstance();
824
863
  return sponsoredFPCInstance.address;
825
864
  }
826
865
 
@@ -828,7 +867,7 @@ export async function getSponsoredFPCAddress() {
828
867
  * Deploy a sponsored FPC contract to a running instance.
829
868
  */
830
869
  export async function setupSponsoredFPC(pxe: PXE) {
831
- const instance = await getContractInstanceFromDeployParams(SponsoredFPCContract.artifact, {
870
+ const instance = await getContractInstanceFromInstantiationParams(SponsoredFPCContract.artifact, {
832
871
  salt: new Fr(SPONSORED_FPC_SALT),
833
872
  });
834
873
 
@@ -837,6 +876,14 @@ export async function setupSponsoredFPC(pxe: PXE) {
837
876
  return instance;
838
877
  }
839
878
 
879
+ /**
880
+ * Registers the SponsoredFPC in this PXE instance
881
+ * @param pxe - The pxe client
882
+ */
883
+ export async function registerSponsoredFPC(pxe: PXE): Promise<void> {
884
+ await pxe.registerContract({ instance: await getSponsoredFPCInstance(), artifact: SponsoredFPCContract.artifact });
885
+ }
886
+
840
887
  export async function waitForProvenChain(node: AztecNode, targetBlock?: number, timeoutSec = 60, intervalSec = 1) {
841
888
  targetBlock ??= await node.getBlockNumber();
842
889
 
@@ -852,13 +899,14 @@ export function createAndSyncProverNode(
852
899
  proverNodePrivateKey: `0x${string}`,
853
900
  aztecNodeConfig: AztecNodeConfig,
854
901
  proverNodeConfig: Partial<ProverNodeConfig> & Pick<DataStoreConfig, 'dataDirectory'>,
855
- aztecNode: AztecNode,
902
+ aztecNode: AztecNode | undefined,
856
903
  prefilledPublicData: PublicDataTreeLeaf[] = [],
904
+ proverNodeDeps: ProverNodeDeps = {},
857
905
  ) {
858
906
  return withLogNameSuffix('prover-node', async () => {
859
907
  // Disable stopping the aztec node as the prover coordination test will kill it otherwise
860
908
  // This is only required when stopping the prover node for testing
861
- const aztecNodeTxProvider = {
909
+ const aztecNodeTxProvider = aztecNode && {
862
910
  getTxByHash: aztecNode.getTxByHash.bind(aztecNode),
863
911
  getTxsByHash: aztecNode.getTxsByHash.bind(aztecNode),
864
912
  stop: () => Promise.resolve(),
@@ -868,12 +916,12 @@ export function createAndSyncProverNode(
868
916
 
869
917
  // Creating temp store and archiver for simulated prover node
870
918
  const archiverConfig = { ...aztecNodeConfig, dataDirectory: proverNodeConfig.dataDirectory };
871
- const archiver = await createArchiver(archiverConfig, blobSinkClient, { blockUntilSync: true });
919
+ const archiver = await createArchiver(archiverConfig, { blobSinkClient }, { blockUntilSync: true });
872
920
 
873
921
  // Prover node config is for simulated proofs
874
922
  const proverConfig: ProverNodeConfig = {
875
923
  ...aztecNodeConfig,
876
- proverCoordinationNodeUrls: [],
924
+ txCollectionNodeRpcUrls: [],
877
925
  realProofs: false,
878
926
  proverAgentCount: 2,
879
927
  publisherPrivateKey: new SecretValue(proverNodePrivateKey),
@@ -883,15 +931,21 @@ export function createAndSyncProverNode(
883
931
  txGatheringIntervalMs: 1000,
884
932
  txGatheringBatchSize: 10,
885
933
  txGatheringMaxParallelRequestsPerNode: 10,
934
+ txGatheringTimeoutMs: 24_000,
886
935
  proverNodeFailedEpochStore: undefined,
887
936
  ...proverNodeConfig,
888
937
  };
889
938
 
890
- const l1TxUtils = createDelayedL1TxUtils(aztecNodeConfig, proverNodePrivateKey, 'prover-node');
939
+ const l1TxUtils = createDelayedL1TxUtils(
940
+ aztecNodeConfig,
941
+ proverNodePrivateKey,
942
+ 'prover-node',
943
+ proverNodeDeps.dateProvider,
944
+ );
891
945
 
892
946
  const proverNode = await createProverNode(
893
947
  proverConfig,
894
- { aztecNodeTxProvider, archiver: archiver as Archiver, l1TxUtils },
948
+ { ...proverNodeDeps, aztecNodeTxProvider, archiver: archiver as Archiver, l1TxUtils },
895
949
  { prefilledPublicData },
896
950
  );
897
951
  getLogger().info(`Created and synced prover node`, { publisherAddress: l1TxUtils.client.account!.address });
@@ -900,11 +954,16 @@ export function createAndSyncProverNode(
900
954
  });
901
955
  }
902
956
 
903
- function createDelayedL1TxUtils(aztecNodeConfig: AztecNodeConfig, privateKey: `0x${string}`, logName: string) {
957
+ function createDelayedL1TxUtils(
958
+ aztecNodeConfig: AztecNodeConfig,
959
+ privateKey: `0x${string}`,
960
+ logName: string,
961
+ dateProvider?: DateProvider,
962
+ ) {
904
963
  const l1Client = createExtendedL1Client(aztecNodeConfig.l1RpcUrls, privateKey, foundry);
905
964
 
906
965
  const log = createLogger(logName);
907
- const l1TxUtils = new DelayedTxUtils(l1Client, log, aztecNodeConfig);
966
+ const l1TxUtils = new DelayedTxUtils(l1Client, log, dateProvider, aztecNodeConfig);
908
967
  l1TxUtils.enableDelayer(aztecNodeConfig.ethereumSlotDuration);
909
968
  return l1TxUtils;
910
969
  }
@@ -31,7 +31,7 @@ echo "Deployed contract at $TOKEN_ADDRESS"
31
31
 
32
32
  # docs:start:mint-private
33
33
  MINT_AMOUNT=69
34
- aztec-wallet send mint_to_private -ca last --args accounts:test0 accounts:alice $MINT_AMOUNT -f test0
34
+ aztec-wallet send mint_to_private -ca last --args accounts:alice $MINT_AMOUNT -f test0
35
35
  # docs:end:mint-private
36
36
 
37
37
  # docs:start:get-balance
@@ -0,0 +1,74 @@
1
+ import { AztecAddress, Fr, type L2Block } from '@aztec/aztec.js';
2
+ import { BatchedBlob, Blob } from '@aztec/blob-lib';
3
+ import { EthAddress } from '@aztec/foundation/eth-address';
4
+
5
+ import { writeFile } from 'fs/promises';
6
+
7
+ const AZTEC_GENERATE_TEST_DATA = !!process.env.AZTEC_GENERATE_TEST_DATA;
8
+
9
+ /**
10
+ * Creates a json object that can be used to test the solidity contract.
11
+ * The json object must be put into
12
+ */
13
+ export async function writeJson(
14
+ fileName: string,
15
+ block: L2Block,
16
+ l1ToL2Content: Fr[],
17
+ blobs: Blob[],
18
+ batchedBlob: BatchedBlob,
19
+ recipientAddress: AztecAddress,
20
+ deployerAddress: `0x${string}`,
21
+ ): Promise<void> {
22
+ if (!AZTEC_GENERATE_TEST_DATA) {
23
+ return;
24
+ }
25
+ // Path relative to the package.json in the end-to-end folder
26
+ const path = `../../l1-contracts/test/fixtures/${fileName}.json`;
27
+
28
+ const asHex = (value: Fr | Buffer | EthAddress | AztecAddress, size = 64) => {
29
+ const buffer = Buffer.isBuffer(value) ? value : value.toBuffer();
30
+ return `0x${buffer.toString('hex').padStart(size, '0')}`;
31
+ };
32
+
33
+ const jsonObject = {
34
+ populate: {
35
+ l1ToL2Content: l1ToL2Content.map(asHex),
36
+ recipient: asHex(recipientAddress.toField()),
37
+ sender: deployerAddress,
38
+ },
39
+ messages: {
40
+ l2ToL1Messages: block.body.txEffects.flatMap(txEffect => txEffect.l2ToL1Msgs).map(asHex),
41
+ },
42
+ block: {
43
+ // The json formatting in forge is a bit brittle, so we convert Fr to a number in the few values below.
44
+ // This should not be a problem for testing as long as the values are not larger than u32.
45
+ archive: asHex(block.archive.root),
46
+ blobCommitments: Blob.getPrefixedEthBlobCommitments(blobs),
47
+ batchedBlobInputs: batchedBlob.getEthBlobEvaluationInputs(),
48
+ blockNumber: block.number,
49
+ body: `0x${block.body.toBuffer().toString('hex')}`,
50
+ header: {
51
+ lastArchiveRoot: asHex(block.header.lastArchive.root),
52
+ contentCommitment: {
53
+ blobsHash: asHex(block.header.contentCommitment.blobsHash),
54
+ inHash: asHex(block.header.contentCommitment.inHash),
55
+ outHash: asHex(block.header.contentCommitment.outHash),
56
+ },
57
+ slotNumber: Number(block.header.globalVariables.slotNumber),
58
+ timestamp: Number(block.header.globalVariables.timestamp),
59
+ coinbase: asHex(block.header.globalVariables.coinbase, 40),
60
+ feeRecipient: asHex(block.header.globalVariables.feeRecipient),
61
+ gasFees: {
62
+ feePerDaGas: Number(block.header.globalVariables.gasFees.feePerDaGas),
63
+ feePerL2Gas: Number(block.header.globalVariables.gasFees.feePerL2Gas),
64
+ },
65
+ totalManaUsed: block.header.totalManaUsed.toNumber(),
66
+ },
67
+ headerHash: asHex(block.header.toPropose().hash()),
68
+ numTxs: block.body.txEffects.length,
69
+ },
70
+ };
71
+
72
+ const output = JSON.stringify(jsonObject, null, 2);
73
+ await writeFile(path, output, 'utf8');
74
+ }
@@ -4,7 +4,7 @@ import { createPXEClient } from '@aztec/aztec.js';
4
4
  const { PXE_URL = 'http://localhost:8080' } = process.env;
5
5
 
6
6
  async function main() {
7
- const pxe = await createPXEClient(PXE_URL);
7
+ const pxe = createPXEClient(PXE_URL);
8
8
  const { l1ChainId } = await pxe.getNodeInfo();
9
9
  console.log(`Connected to chain ${l1ChainId}`);
10
10
  }
@@ -7,7 +7,7 @@ import { readFileSync } from 'fs';
7
7
  const TokenContractArtifact = TokenContract.artifact;
8
8
 
9
9
  // docs:start:get-tokens
10
- export async function getToken(wallet) {
10
+ export function getToken(wallet) {
11
11
  const addresses = JSON.parse(readFileSync('addresses.json'));
12
12
  return Contract.at(AztecAddress.fromString(addresses.token), TokenContractArtifact, wallet);
13
13
  }
@@ -1,11 +1,11 @@
1
1
  // docs:start:deploy-imports
2
2
  import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
3
- import { Contract, createPXEClient, loadContractArtifact, waitForPXE } from '@aztec/aztec.js';
3
+ import { Contract, createPXEClient, waitForPXE } from '@aztec/aztec.js';
4
4
  // docs:end:deploy-imports
5
5
  // docs:start:import_artifact
6
6
  import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
7
+
7
8
  // docs:end:import_artifact
8
- import { TokenContract } from '@aztec/noir-contracts.js/Token';
9
9
 
10
10
  import { writeFileSync } from 'fs';
11
11
  import { fileURLToPath } from 'url';
@@ -21,7 +21,7 @@ async function main() {
21
21
  const ownerAddress = ownerWallet.getAddress();
22
22
 
23
23
  const token = await Contract.deploy(ownerWallet, TokenContractArtifact, [ownerAddress, 'TokenName', 'TKN', 18])
24
- .send()
24
+ .send({ from: ownerAddress })
25
25
  .deployed();
26
26
 
27
27
  console.log(`Token deployed at ${token.address.toString()}`);
@@ -25,7 +25,7 @@ async function showPrivateBalances(pxe) {
25
25
 
26
26
  for (const account of accounts) {
27
27
  // highlight-next-line:showPrivateBalances
28
- const balance = await token.methods.balance_of_private(account.address).simulate();
28
+ const balance = await token.methods.balance_of_private(account.address).simulate({ from: account.address });
29
29
  console.log(`Balance of ${account.address}: ${balance}`);
30
30
  }
31
31
  }
@@ -40,8 +40,10 @@ async function mintPrivateFunds(pxe) {
40
40
 
41
41
  // We mint tokens to the owner
42
42
  const mintAmount = 20n;
43
- const from = ownerWallet.getAddress(); // we are setting from to owner here because we need a sender to calculate the tag
44
- await token.methods.mint_to_private(from, ownerWallet.getAddress(), mintAmount).send().wait();
43
+ await token.methods
44
+ .mint_to_private(ownerWallet.getAddress(), mintAmount)
45
+ .send({ from: ownerWallet.getAddress() })
46
+ .wait();
45
47
 
46
48
  await showPrivateBalances(pxe);
47
49
  }
@@ -54,7 +56,7 @@ async function transferPrivateFunds(pxe) {
54
56
 
55
57
  await showPrivateBalances(pxe);
56
58
  console.log(`Sending transaction, awaiting transaction to be mined`);
57
- const receipt = await token.methods.transfer(recipient.getAddress(), 1).send().wait();
59
+ const receipt = await token.methods.transfer(recipient.getAddress(), 1).send({ from: owner.getAddress() }).wait();
58
60
 
59
61
  console.log(`Transaction ${receipt.txHash} has been mined on block ${receipt.blockNumber}`);
60
62
  await showPrivateBalances(pxe);
@@ -70,7 +72,7 @@ async function showPublicBalances(pxe) {
70
72
 
71
73
  for (const account of accounts) {
72
74
  // highlight-next-line:showPublicBalances
73
- const balance = await token.methods.balance_of_public(account.address).simulate();
75
+ const balance = await token.methods.balance_of_public(account.address).simulate({ from: account.address });
74
76
  console.log(`Balance of ${account.address}: ${balance}`);
75
77
  }
76
78
  }
@@ -84,7 +86,7 @@ async function mintPublicFunds(pxe) {
84
86
  await showPublicBalances(pxe);
85
87
 
86
88
  console.log(`Sending transaction, awaiting transaction to be mined`);
87
- const receipt = await token.methods.mint_to_public(owner.getAddress(), 100).send().wait();
89
+ const receipt = await token.methods.mint_to_public(owner.getAddress(), 100).send({ from: owner.getAddress() }).wait();
88
90
  console.log(`Transaction ${receipt.txHash} has been mined on block ${receipt.blockNumber}`);
89
91
 
90
92
  await showPublicBalances(pxe);
@@ -93,7 +95,9 @@ async function mintPublicFunds(pxe) {
93
95
  const blockNumber = await pxe.getBlockNumber();
94
96
  const logs = (await pxe.getPublicLogs({ fromBlock: blockNumber - 1 })).logs;
95
97
  const textLogs = logs.map(extendedLog => extendedLog.toHumanReadable().slice(0, 200));
96
- for (const log of textLogs) console.log(`Log emitted: ${log}`);
98
+ for (const log of textLogs) {
99
+ console.log(`Log emitted: ${log}`);
100
+ }
97
101
  // docs:end:showLogs
98
102
  }
99
103
  // docs:end:mintPublicFunds
@@ -116,7 +120,6 @@ async function main() {
116
120
 
117
121
  // Execute main only if run directly
118
122
  if (process.argv[1].replace(/\/index\.m?js$/, '') === fileURLToPath(import.meta.url).replace(/\/index\.m?js$/, '')) {
119
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
120
123
  main()
121
124
  .then(() => process.exit(0))
122
125
  .catch(err => {