@aztec/end-to-end 0.0.1-commit.2ed92850 → 0.0.1-commit.2f68f620

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 (234) 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 +3 -3
  6. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  7. package/dest/bench/client_flows/client_flows_benchmark.js +36 -39
  8. package/dest/bench/client_flows/config.d.ts +2 -2
  9. package/dest/bench/client_flows/config.d.ts.map +1 -1
  10. package/dest/bench/client_flows/config.js +18 -0
  11. package/dest/bench/utils.d.ts +1 -1
  12. package/dest/bench/utils.d.ts.map +1 -1
  13. package/dest/bench/utils.js +8 -3
  14. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +8 -5
  15. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  16. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +36 -17
  17. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +16 -5
  18. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  19. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +42 -9
  20. package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -4
  21. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  22. package/dest/e2e_deploy_contract/deploy_test.js +2 -1
  23. package/dest/e2e_epochs/epochs_test.d.ts +39 -8
  24. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  25. package/dest/e2e_epochs/epochs_test.js +170 -52
  26. package/dest/e2e_fees/fees_test.d.ts +6 -3
  27. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  28. package/dest/e2e_fees/fees_test.js +50 -17
  29. package/dest/e2e_l1_publisher/write_json.d.ts +3 -2
  30. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
  31. package/dest/e2e_l1_publisher/write_json.js +1 -7
  32. package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
  33. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  34. package/dest/e2e_nested_contract/nested_contract_test.js +6 -7
  35. package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
  36. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  37. package/dest/e2e_p2p/inactivity_slash_test.js +4 -3
  38. package/dest/e2e_p2p/p2p_network.d.ts +14 -12
  39. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  40. package/dest/e2e_p2p/p2p_network.js +70 -34
  41. package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
  42. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
  43. package/dest/e2e_p2p/reqresp/utils.js +206 -0
  44. package/dest/e2e_p2p/shared.d.ts +37 -8
  45. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  46. package/dest/e2e_p2p/shared.js +93 -53
  47. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  48. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  49. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  50. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  51. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  52. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  53. package/dest/e2e_token_contract/token_contract_test.d.ts +6 -4
  54. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  55. package/dest/e2e_token_contract/token_contract_test.js +23 -11
  56. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  57. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  58. package/dest/fixtures/authwit_proxy.js +34 -0
  59. package/dest/fixtures/e2e_prover_test.d.ts +9 -8
  60. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  61. package/dest/fixtures/e2e_prover_test.js +40 -51
  62. package/dest/fixtures/elu_monitor.d.ts +21 -0
  63. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  64. package/dest/fixtures/elu_monitor.js +102 -0
  65. package/dest/fixtures/fixtures.d.ts +74 -1
  66. package/dest/fixtures/fixtures.d.ts.map +1 -1
  67. package/dest/fixtures/fixtures.js +71 -0
  68. package/dest/fixtures/get_bb_config.d.ts +1 -1
  69. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  70. package/dest/fixtures/get_bb_config.js +5 -5
  71. package/dest/fixtures/ha_setup.d.ts +71 -0
  72. package/dest/fixtures/ha_setup.d.ts.map +1 -0
  73. package/dest/fixtures/ha_setup.js +116 -0
  74. package/dest/fixtures/index.d.ts +2 -1
  75. package/dest/fixtures/index.d.ts.map +1 -1
  76. package/dest/fixtures/index.js +1 -0
  77. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  78. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  79. package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
  80. package/dest/fixtures/setup.d.ts +88 -34
  81. package/dest/fixtures/setup.d.ts.map +1 -1
  82. package/dest/fixtures/setup.js +225 -180
  83. package/dest/fixtures/setup_p2p_test.d.ts +22 -11
  84. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  85. package/dest/fixtures/setup_p2p_test.js +43 -32
  86. package/dest/fixtures/token_utils.d.ts +2 -2
  87. package/dest/fixtures/token_utils.d.ts.map +1 -1
  88. package/dest/fixtures/token_utils.js +5 -7
  89. package/dest/fixtures/utils.d.ts +2 -2
  90. package/dest/fixtures/utils.d.ts.map +1 -1
  91. package/dest/fixtures/utils.js +1 -1
  92. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  93. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  94. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  95. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  96. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  97. package/dest/forward-compatibility/wallet_service.js +109 -0
  98. package/dest/install_legacy_contracts.d.cts +10 -0
  99. package/dest/install_legacy_contracts.d.cts.map +1 -0
  100. package/dest/legacy-jest-resolver.d.cts +3 -0
  101. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  102. package/dest/shared/cross_chain_test_harness.d.ts +4 -2
  103. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  104. package/dest/shared/cross_chain_test_harness.js +22 -18
  105. package/dest/shared/gas_portal_test_harness.d.ts +8 -5
  106. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  107. package/dest/shared/gas_portal_test_harness.js +19 -10
  108. package/dest/shared/index.d.ts +2 -1
  109. package/dest/shared/index.d.ts.map +1 -1
  110. package/dest/shared/index.js +1 -0
  111. package/dest/shared/jest_setup.js +41 -1
  112. package/dest/shared/mock_state_view.d.ts +86 -0
  113. package/dest/shared/mock_state_view.d.ts.map +1 -0
  114. package/dest/shared/mock_state_view.js +186 -0
  115. package/dest/shared/submit-transactions.d.ts +2 -2
  116. package/dest/shared/submit-transactions.d.ts.map +1 -1
  117. package/dest/shared/submit-transactions.js +1 -1
  118. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  119. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  120. package/dest/shared/uniswap_l1_l2.js +57 -40
  121. package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
  122. package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
  123. package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
  124. package/dest/simulators/lending_simulator.d.ts +10 -3
  125. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  126. package/dest/simulators/lending_simulator.js +26 -14
  127. package/dest/simulators/token_simulator.d.ts +1 -1
  128. package/dest/simulators/token_simulator.d.ts.map +1 -1
  129. package/dest/simulators/token_simulator.js +3 -24
  130. package/dest/spartan/setup_test_wallets.d.ts +12 -3
  131. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  132. package/dest/spartan/setup_test_wallets.js +108 -41
  133. package/dest/spartan/tx_metrics.d.ts +52 -4
  134. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  135. package/dest/spartan/tx_metrics.js +224 -21
  136. package/dest/spartan/utils/bot.d.ts +3 -2
  137. package/dest/spartan/utils/bot.d.ts.map +1 -1
  138. package/dest/spartan/utils/bot.js +2 -1
  139. package/dest/spartan/utils/config.d.ts +11 -28
  140. package/dest/spartan/utils/config.d.ts.map +1 -1
  141. package/dest/spartan/utils/config.js +4 -1
  142. package/dest/spartan/utils/index.d.ts +6 -4
  143. package/dest/spartan/utils/index.d.ts.map +1 -1
  144. package/dest/spartan/utils/index.js +6 -2
  145. package/dest/spartan/utils/k8s.d.ts +31 -1
  146. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  147. package/dest/spartan/utils/k8s.js +124 -0
  148. package/dest/spartan/utils/nodes.d.ts +14 -5
  149. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  150. package/dest/spartan/utils/nodes.js +204 -33
  151. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  152. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  153. package/dest/spartan/utils/pod_logs.js +74 -0
  154. package/dest/spartan/utils/scripts.d.ts +18 -4
  155. package/dest/spartan/utils/scripts.d.ts.map +1 -1
  156. package/dest/spartan/utils/scripts.js +19 -4
  157. package/dest/test-wallet/test_wallet.d.ts +85 -0
  158. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  159. package/dest/test-wallet/test_wallet.js +273 -0
  160. package/dest/test-wallet/utils.d.ts +41 -0
  161. package/dest/test-wallet/utils.d.ts.map +1 -0
  162. package/dest/test-wallet/utils.js +66 -0
  163. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  164. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  165. package/dest/test-wallet/wallet_worker_script.js +53 -0
  166. package/dest/test-wallet/worker_wallet.d.ts +53 -0
  167. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  168. package/dest/test-wallet/worker_wallet.js +155 -0
  169. package/dest/test-wallet/worker_wallet_schema.d.ts +160 -0
  170. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  171. package/dest/test-wallet/worker_wallet_schema.js +22 -0
  172. package/package.json +52 -45
  173. package/src/bench/client_flows/benchmark.ts +19 -0
  174. package/src/bench/client_flows/client_flows_benchmark.ts +64 -49
  175. package/src/bench/client_flows/config.ts +9 -1
  176. package/src/bench/utils.ts +10 -4
  177. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +52 -25
  178. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +56 -19
  179. package/src/e2e_deploy_contract/deploy_test.ts +6 -5
  180. package/src/e2e_epochs/epochs_test.ts +196 -77
  181. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  182. package/src/e2e_fees/fees_test.ts +57 -32
  183. package/src/e2e_l1_publisher/write_json.ts +1 -6
  184. package/src/e2e_nested_contract/nested_contract_test.ts +10 -6
  185. package/src/e2e_p2p/inactivity_slash_test.ts +8 -7
  186. package/src/e2e_p2p/p2p_network.ts +93 -49
  187. package/src/e2e_p2p/reqresp/utils.ts +274 -0
  188. package/src/e2e_p2p/shared.ts +117 -65
  189. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  190. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  191. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  192. package/src/e2e_token_contract/token_contract_test.ts +38 -11
  193. package/src/fixtures/authwit_proxy.ts +54 -0
  194. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  195. package/src/fixtures/e2e_prover_test.ts +50 -57
  196. package/src/fixtures/elu_monitor.ts +126 -0
  197. package/src/fixtures/fixtures.ts +93 -0
  198. package/src/fixtures/get_bb_config.ts +7 -6
  199. package/src/fixtures/ha_setup.ts +188 -0
  200. package/src/fixtures/index.ts +1 -0
  201. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  202. package/src/fixtures/setup.ts +282 -243
  203. package/src/fixtures/setup_p2p_test.ts +52 -52
  204. package/src/fixtures/token_utils.ts +3 -3
  205. package/src/fixtures/utils.ts +2 -0
  206. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  207. package/src/forward-compatibility/wallet_service.ts +104 -0
  208. package/src/guides/up_quick_start.sh +3 -5
  209. package/src/install_legacy_contracts.cjs +75 -0
  210. package/src/legacy-jest-resolver.cjs +112 -0
  211. package/src/shared/cross_chain_test_harness.ts +27 -13
  212. package/src/shared/gas_portal_test_harness.ts +21 -11
  213. package/src/shared/index.ts +1 -0
  214. package/src/shared/jest_setup.ts +51 -1
  215. package/src/shared/mock_state_view.ts +188 -0
  216. package/src/shared/submit-transactions.ts +3 -2
  217. package/src/shared/uniswap_l1_l2.ts +103 -54
  218. package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
  219. package/src/simulators/lending_simulator.ts +32 -14
  220. package/src/simulators/token_simulator.ts +6 -30
  221. package/src/spartan/setup_test_wallets.ts +146 -35
  222. package/src/spartan/tx_metrics.ts +208 -24
  223. package/src/spartan/utils/bot.ts +4 -1
  224. package/src/spartan/utils/config.ts +3 -0
  225. package/src/spartan/utils/index.ts +10 -1
  226. package/src/spartan/utils/k8s.ts +160 -0
  227. package/src/spartan/utils/nodes.ts +251 -31
  228. package/src/spartan/utils/pod_logs.ts +99 -0
  229. package/src/spartan/utils/scripts.ts +43 -7
  230. package/src/test-wallet/test_wallet.ts +376 -0
  231. package/src/test-wallet/utils.ts +108 -0
  232. package/src/test-wallet/wallet_worker_script.ts +63 -0
  233. package/src/test-wallet/worker_wallet.ts +218 -0
  234. package/src/test-wallet/worker_wallet_schema.ts +13 -0
@@ -4,14 +4,12 @@
4
4
  import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
5
5
  import { range } from '@aztec/foundation/array';
6
6
  import { SecretValue } from '@aztec/foundation/config';
7
- import { addLogNameHandler, removeLogNameHandler } from '@aztec/foundation/log';
7
+ import { withLoggerBindings } from '@aztec/foundation/log/server';
8
8
  import { bufferToHex } from '@aztec/foundation/string';
9
9
  import type { DateProvider } from '@aztec/foundation/timer';
10
- import type { ProverNodeConfig, ProverNodeDeps } from '@aztec/prover-node';
11
- import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
10
+ import type { GenesisData } from '@aztec/stdlib/world-state';
12
11
 
13
12
  import getPort from 'get-port';
14
- import { AsyncLocalStorage } from 'node:async_hooks';
15
13
 
16
14
  import { TEST_PEER_CHECK_INTERVAL_MS } from './fixtures.js';
17
15
  import { createAndSyncProverNode, getPrivateKeyFromIndex } from './utils.js';
@@ -22,6 +20,11 @@ import { getEndToEndTestTelemetryClient } from './with_telemetry_utils.js';
22
20
  // to avoid running validators with the same key
23
21
  export const ATTESTER_PRIVATE_KEYS_START_INDEX = 3;
24
22
 
23
+ // Global counters for actor naming (start at 1)
24
+ let validatorCounter = 1;
25
+ let nodeCounter = 1;
26
+ let proverCounter = 1;
27
+
25
28
  export function generatePrivateKeys(startIndex: number, numberOfKeys: number): `0x${string}`[] {
26
29
  const privateKeys: `0x${string}`[] = [];
27
30
  // Do not start from 0 as it is used during setup
@@ -37,17 +40,13 @@ export async function createNodes(
37
40
  bootstrapNodeEnr: string,
38
41
  numNodes: number,
39
42
  bootNodePort: number,
40
- prefilledPublicData?: PublicDataTreeLeaf[],
43
+ genesis?: GenesisData,
41
44
  dataDirectory?: string,
42
45
  metricsPort?: number,
43
46
  indexOffset = 0,
44
47
  validatorsPerNode = 1,
45
48
  ): Promise<AztecNodeService[]> {
46
49
  const nodePromises: Promise<AztecNodeService>[] = [];
47
- const loggerIdStorage = new AsyncLocalStorage<string>();
48
- const logNameHandler = (module: string) =>
49
- loggerIdStorage.getStore() ? `${module}:${loggerIdStorage.getStore()}` : module;
50
- addLogNameHandler(logNameHandler);
51
50
 
52
51
  for (let i = 0; i < numNodes; i++) {
53
52
  const index = indexOffset + i;
@@ -66,10 +65,9 @@ export async function createNodes(
66
65
  port,
67
66
  bootstrapNodeEnr,
68
67
  validatorIndices,
69
- prefilledPublicData,
68
+ genesis,
70
69
  dataDir,
71
70
  metricsPort,
72
- loggerIdStorage,
73
71
  );
74
72
  nodePromises.push(nodePromise);
75
73
  }
@@ -81,32 +79,42 @@ export async function createNodes(
81
79
  throw new Error('Sequencer not found');
82
80
  }
83
81
 
84
- removeLogNameHandler(logNameHandler);
85
82
  return nodes;
86
83
  }
87
84
 
88
- /** Creates a P2P enabled instance of Aztec Node Service with a validator */
85
+ /** Extended config type for createNode with test-specific overrides. */
86
+ export type CreateNodeConfig = AztecNodeConfig & {
87
+ /** Whether to skip starting the sequencer. */
88
+ dontStartSequencer?: boolean;
89
+ /** Override the private key (instead of deriving from addressIndex). */
90
+ validatorPrivateKey?: `0x${string}`;
91
+ /** Corrupt only the block proposal at this indexWithinCheckpoint (testing only). */
92
+ invalidBlockProposalIndexWithinCheckpoint?: number;
93
+ /** Accept proposal gossip regardless of slot timing (testing only). */
94
+ skipProposalSlotValidation?: boolean;
95
+ };
96
+
97
+ /** Creates a P2P enabled instance of Aztec Node Service with a validator. */
89
98
  export async function createNode(
90
- config: AztecNodeConfig & { dontStartSequencer?: boolean },
99
+ config: CreateNodeConfig,
91
100
  dateProvider: DateProvider,
92
101
  tcpPort: number,
93
102
  bootstrapNode: string | undefined,
94
103
  addressIndex: number | number[],
95
- prefilledPublicData?: PublicDataTreeLeaf[],
104
+ genesis?: GenesisData,
96
105
  dataDirectory?: string,
97
106
  metricsPort?: number,
98
- loggerIdStorage?: AsyncLocalStorage<string>,
99
107
  ) {
100
- const createNode = async () => {
108
+ const actorIndex = validatorCounter++;
109
+ return await withLoggerBindings({ actor: `validator-${actorIndex}` }, async () => {
101
110
  const validatorConfig = await createValidatorConfig(config, bootstrapNode, tcpPort, addressIndex, dataDirectory);
102
111
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
103
112
  return await AztecNodeService.createAndSync(
104
113
  validatorConfig,
105
114
  { telemetry, dateProvider },
106
- { prefilledPublicData, dontStartSequencer: config.dontStartSequencer },
115
+ { genesis, dontStartSequencer: config.dontStartSequencer },
107
116
  );
108
- };
109
- return loggerIdStorage ? await loggerIdStorage.run(tcpPort.toString(), createNode) : createNode();
117
+ });
110
118
  }
111
119
 
112
120
  /** Creates a P2P enabled instance of Aztec Node Service without a validator */
@@ -115,23 +123,22 @@ export async function createNonValidatorNode(
115
123
  dateProvider: DateProvider,
116
124
  tcpPort: number,
117
125
  bootstrapNode: string | undefined,
118
- prefilledPublicData?: PublicDataTreeLeaf[],
126
+ genesis?: GenesisData,
119
127
  dataDirectory?: string,
120
128
  metricsPort?: number,
121
- loggerIdStorage?: AsyncLocalStorage<string>,
122
129
  ) {
123
- const createNode = async () => {
130
+ const actorIndex = nodeCounter++;
131
+ return await withLoggerBindings({ actor: `node-${actorIndex}` }, async () => {
124
132
  const p2pConfig = await createP2PConfig(baseConfig, bootstrapNode, tcpPort, dataDirectory);
125
133
  const config: AztecNodeConfig = {
126
134
  ...p2pConfig,
127
135
  disableValidator: true,
128
136
  validatorPrivateKeys: undefined,
129
- publisherPrivateKeys: [],
137
+ sequencerPublisherPrivateKeys: [],
130
138
  };
131
139
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
132
- return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, { prefilledPublicData });
133
- };
134
- return loggerIdStorage ? await loggerIdStorage.run(tcpPort.toString(), createNode) : createNode();
140
+ return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, { genesis });
141
+ });
135
142
  }
136
143
 
137
144
  export async function createProverNode(
@@ -139,34 +146,26 @@ export async function createProverNode(
139
146
  tcpPort: number,
140
147
  bootstrapNode: string | undefined,
141
148
  addressIndex: number,
142
- proverNodeDeps: ProverNodeDeps & Required<Pick<ProverNodeDeps, 'dateProvider'>>,
143
- prefilledPublicData?: PublicDataTreeLeaf[],
149
+ deps: { dateProvider: DateProvider },
150
+ genesis?: GenesisData,
144
151
  dataDirectory?: string,
145
152
  metricsPort?: number,
146
- loggerIdStorage?: AsyncLocalStorage<string>,
147
- ) {
148
- const createProverNode = async () => {
153
+ ): Promise<{ proverNode: AztecNodeService }> {
154
+ const actorIndex = proverCounter++;
155
+ return await withLoggerBindings({ actor: `prover-${actorIndex}` }, async () => {
149
156
  const proverNodePrivateKey = getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + addressIndex)!;
150
157
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
151
158
 
152
- const proverConfig: Partial<ProverNodeConfig> = await createP2PConfig(
153
- config,
154
- bootstrapNode,
155
- tcpPort,
156
- dataDirectory,
157
- );
159
+ const p2pConfig = await createP2PConfig(config, bootstrapNode, tcpPort, dataDirectory);
158
160
 
159
- const aztecNodeRpcTxProvider = undefined;
160
161
  return await createAndSyncProverNode(
161
162
  bufferToHex(proverNodePrivateKey),
162
- config,
163
- { ...proverConfig, dataDirectory },
164
- aztecNodeRpcTxProvider,
165
- prefilledPublicData,
166
- { ...proverNodeDeps, telemetry },
163
+ { ...config, ...p2pConfig },
164
+ { dataDirectory },
165
+ { ...deps, telemetry },
166
+ { genesis },
167
167
  );
168
- };
169
- return loggerIdStorage ? await loggerIdStorage.run(tcpPort.toString(), createProverNode) : createProverNode();
168
+ });
170
169
  }
171
170
 
172
171
  export async function createP2PConfig(
@@ -192,26 +191,27 @@ export async function createP2PConfig(
192
191
  }
193
192
 
194
193
  export async function createValidatorConfig(
195
- config: AztecNodeConfig,
194
+ config: CreateNodeConfig,
196
195
  bootstrapNodeEnr?: string,
197
196
  port?: number,
198
197
  addressIndex: number | number[] = 1,
199
198
  dataDirectory?: string,
200
199
  ) {
201
200
  const addressIndices = Array.isArray(addressIndex) ? addressIndex : [addressIndex];
202
- if (addressIndices.length === 0) {
201
+ if (addressIndices.length === 0 && !config.validatorPrivateKey) {
203
202
  throw new Error('At least one address index must be provided to create a validator config');
204
203
  }
205
204
 
206
- const attesterPrivateKeys = addressIndices.map(index =>
207
- bufferToHex(getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + index)!),
208
- );
205
+ // Use override private key if provided, otherwise derive from address indices
206
+ const attesterPrivateKeys = config.validatorPrivateKey
207
+ ? [config.validatorPrivateKey]
208
+ : addressIndices.map(index => bufferToHex(getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + index)!));
209
209
  const p2pConfig = await createP2PConfig(config, bootstrapNodeEnr, port, dataDirectory);
210
210
  const nodeConfig: AztecNodeConfig = {
211
211
  ...config,
212
212
  ...p2pConfig,
213
213
  validatorPrivateKeys: new SecretValue(attesterPrivateKeys),
214
- publisherPrivateKeys: [new SecretValue(attesterPrivateKeys[0])],
214
+ sequencerPublisherPrivateKeys: [new SecretValue(attesterPrivateKeys[0])],
215
215
  };
216
216
 
217
217
  return nodeConfig;
@@ -8,7 +8,6 @@ export async function deployToken(wallet: Wallet, admin: AztecAddress, initialAd
8
8
  logger.info(`Deploying Token contract...`);
9
9
  const { contract, instance } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
10
10
  from: admin,
11
- wait: { returnReceipt: true },
12
11
  });
13
12
 
14
13
  if (initialAdminBalance > 0n) {
@@ -25,8 +24,9 @@ export async function mintTokensToPrivate(
25
24
  minter: AztecAddress,
26
25
  recipient: AztecAddress,
27
26
  amount: bigint,
27
+ additionalScopes?: AztecAddress[],
28
28
  ) {
29
- await token.methods.mint_to_private(recipient, amount).send({ from: minter });
29
+ await token.methods.mint_to_private(recipient, amount).send({ from: minter, additionalScopes });
30
30
  }
31
31
 
32
32
  export async function expectTokenBalance(
@@ -38,7 +38,7 @@ export async function expectTokenBalance(
38
38
  ) {
39
39
  // Then check the balance
40
40
  const contractWithWallet = TokenContract.at(token.address, wallet);
41
- const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
41
+ const { result: balance } = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
42
42
  logger.info(`Account ${owner} balance: ${balance}`);
43
43
  expect(balance).toBe(expectedBalance);
44
44
  }
@@ -9,6 +9,8 @@ export {
9
9
  createAndSyncProverNode,
10
10
  deployAccounts,
11
11
  ensureAccountContractsPublished,
12
+ ensureAuthRegistryPublished,
13
+ ensurePublicChecksPublished,
12
14
  expectMapping,
13
15
  expectMappingDelta,
14
16
  getBalancesFn,
@@ -0,0 +1,14 @@
1
+ import type { Wallet } from '@aztec/aztec.js/wallet';
2
+ import { WalletSchema } from '@aztec/aztec.js/wallet';
3
+ import { createSafeJsonRpcClient, makeFetch } from '@aztec/foundation/json-rpc/client';
4
+
5
+ /**
6
+ * Creates a JSON-RPC client that connects to a remote wallet service.
7
+ * The returned object implements the {@link Wallet} interface, proxying all calls over HTTP to the specified URL.
8
+ */
9
+ export function createWalletClient(url: string): Wallet {
10
+ return createSafeJsonRpcClient<Wallet>(url, WalletSchema, {
11
+ namespaceMethods: 'wallet',
12
+ fetch: makeFetch([1, 2, 3], false),
13
+ });
14
+ }
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env -S node --no-warnings
2
+ /**
3
+ * Standalone entrypoint that spins up a local Aztec network (L1 + node) and exposes a {@link NodeEmbeddedWallet} over
4
+ * JSON-RPC.
5
+ *
6
+ * Intended for forward-compatibility testing: an **old** release image runs this script so that **new** tests can send
7
+ * new artifacts to old runtime code (loadContractArtifact, ACIR simulator, class-ID computation, entrypoint encoding,
8
+ * etc.).
9
+ */
10
+ import { getSchnorrAccountContractAddress } from '@aztec/accounts/schnorr';
11
+ import { getInitialTestAccountsData } from '@aztec/accounts/testing';
12
+ import { createLocalNetwork } from '@aztec/aztec';
13
+ import { Fr } from '@aztec/aztec.js/fields';
14
+ import { WalletSchema } from '@aztec/aztec.js/wallet';
15
+ import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin';
16
+ import { createNamespacedSafeJsonRpcServer, startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
17
+ import { createLogger } from '@aztec/foundation/log';
18
+ import { AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
19
+ import { EmbeddedWallet } from '@aztec/wallets/embedded';
20
+
21
+ const logger = createLogger('wallet-service');
22
+
23
+ const { ETHEREUM_HOSTS = 'http://localhost:8545', NODE_PORT = '8080', WALLET_PORT = '8081' } = process.env;
24
+
25
+ async function main() {
26
+ const l1RpcUrls = ETHEREUM_HOSTS.split(',').map(url => url.trim());
27
+
28
+ // Some tests (e.g. AMM) need 4 accounts but only 3 are funded via genesis. Generate deterministic keys for a 4th
29
+ // account so we can compute its address before network startup and include it in genesis funding. We cannot do this
30
+ // in the test because Wallet interface does not expose account creation functionality (only TestWallet exposes that
31
+ // but that's not used in forward compatibility testing).
32
+ const extraAccountSecret = Fr.fromHexString('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef');
33
+ const extraAccountSalt = Fr.ZERO;
34
+ const extraAccountSigningKey = GrumpkinScalar.random();
35
+ const extraAccountAddress = await getSchnorrAccountContractAddress(
36
+ extraAccountSecret,
37
+ extraAccountSalt,
38
+ extraAccountSigningKey,
39
+ );
40
+
41
+ logger.info('Starting wallet service...', { l1RpcUrls });
42
+
43
+ // createLocalNetwork deploys L1 contracts, starts the node, and optionally deploys funded test accounts (when
44
+ // TEST_ACCOUNTS=true via env). We are not proving anything just like is done when local network is started by
45
+ // the `aztecStart` function. The extra account address is passed via prefundAddresses so it gets fee juice at genesis.
46
+ const { node, stop: stopNetwork } = await createLocalNetwork(
47
+ { l1RpcUrls, realProofs: false, prefundAddresses: [extraAccountAddress.toString()] },
48
+ logger.info,
49
+ );
50
+
51
+ // Create an ephemeral embedded wallet backed by the local node.
52
+ const wallet = await EmbeddedWallet.create(node, { ephemeral: true });
53
+
54
+ // Re-register the initial test accounts so they are available via wallet.getAccounts(). createLocalNetwork deploys
55
+ // them onchain but uses a temporary wallet that is then stopped.
56
+ //
57
+ // We use the non-lazy import path (@aztec/accounts/testing, not /lazy) to avoid the dynamic JSON import that is
58
+ // incompatible with Node.js import attribute enforcement.
59
+ const testAccountsData = await getInitialTestAccountsData();
60
+ const accounts = await Promise.all(
61
+ testAccountsData.map(({ secret, salt, signingKey }) => wallet.createSchnorrAccount(secret, salt, signingKey)),
62
+ );
63
+
64
+ // Register and deploy the 4th account.
65
+ const extraAccount = await wallet.createSchnorrAccount(extraAccountSecret, extraAccountSalt, extraAccountSigningKey);
66
+ const deployMethod = await extraAccount.getDeployMethod();
67
+ await deployMethod.send({ from: accounts[0].address });
68
+
69
+ logger.info('Embedded wallet created', {
70
+ accounts: [...accounts, extraAccount].map(a => a.address.toString()),
71
+ });
72
+
73
+ // Contract artifacts are large, so allow generous body sizes for RPC requests.
74
+ const rpcOptions = { maxBodySizeBytes: '50mb' };
75
+
76
+ // Serve node RPC
77
+ const nodeRpcServer = createNamespacedSafeJsonRpcServer({ node: [node, AztecNodeApiSchema] }, rpcOptions);
78
+ const nodeHttpServer = await startHttpRpcServer(nodeRpcServer, { port: NODE_PORT });
79
+ logger.info(`Node JSON-RPC server listening on port ${nodeHttpServer.port}`);
80
+
81
+ // Serve wallet RPC
82
+ const walletRpcServer = createNamespacedSafeJsonRpcServer({ wallet: [wallet, WalletSchema] }, rpcOptions);
83
+ const walletHttpServer = await startHttpRpcServer(walletRpcServer, { port: WALLET_PORT });
84
+ logger.info(`Wallet JSON-RPC server listening on port ${walletHttpServer.port}`);
85
+
86
+ const shutdown = async () => {
87
+ logger.info('Shutting down...');
88
+ nodeHttpServer.close();
89
+ walletHttpServer.close();
90
+ await wallet.stop();
91
+ await stopNetwork();
92
+ process.exit(0);
93
+ };
94
+
95
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
96
+ process.once('SIGINT', shutdown);
97
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
98
+ process.once('SIGTERM', shutdown);
99
+ }
100
+
101
+ main().catch(err => {
102
+ logger.error('Wallet service failed to start', err);
103
+ process.exit(1);
104
+ });
@@ -18,10 +18,10 @@ aztec-wallet() {
18
18
 
19
19
  aztec-wallet import-test-accounts
20
20
 
21
- # docs:start:declare-accounts
22
21
  aztec-wallet create-account -a alice -f test0
23
22
  aztec-wallet create-account -a bob -f test0
24
- # docs:end:declare-accounts
23
+
24
+ aztec-wallet bridge-fee-juice 1000000000000000000000 accounts:alice --mint --no-wait
25
25
 
26
26
  DEPLOY_OUTPUT=$(aztec-wallet deploy ../noir-contracts.js/artifacts/token_contract-Token.json --args accounts:test0 Test TST 18 -f test0)
27
27
  TOKEN_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE 'Contract deployed at 0x[0-9a-fA-F]+' | cut -d ' ' -f4)
@@ -38,9 +38,7 @@ fi
38
38
 
39
39
  TRANSFER_AMOUNT=42
40
40
 
41
- aztec-wallet create-authwit transfer_in_private accounts:test0 -ca last --args accounts:alice accounts:bob $TRANSFER_AMOUNT 1 -f alice
42
-
43
- aztec-wallet send transfer_in_private -ca last --args accounts:alice accounts:bob $TRANSFER_AMOUNT 1 -aw authwits:last -f test0
41
+ aztec-wallet send transfer_in_private -ca last --args accounts:alice accounts:bob $TRANSFER_AMOUNT 0 -f alice --payment method=fee_juice,claim
44
42
 
45
43
  # Test end result
46
44
  ALICE_BALANCE=$(aztec-wallet simulate balance_of_private -ca last --args accounts:alice -f alice)
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ // Installs pinned legacy @aztec/* contract-artifact packages into .legacy-contracts/<version>/.
3
+ //
4
+ // Called from two places:
5
+ // - bootstrap.sh ci-compat-e2e: pre-populates the cache on the host before hermetic test
6
+ // containers launch. The containers run with --net=none (see ci3/docker_isolate), so on-demand
7
+ // installs from inside them fail with EAI_AGAIN.
8
+ // - legacy-jest-resolver.cjs: on-demand install for local dev, where jest runs with network.
9
+ //
10
+ // Idempotent: no-op when all packages are already present.
11
+ /* eslint-disable @typescript-eslint/no-require-imports */
12
+
13
+ const path = require('path');
14
+ const fs = require('fs');
15
+ const { execFileSync } = require('child_process');
16
+
17
+ const REDIRECTED = ['@aztec/noir-contracts.js', '@aztec/noir-test-contracts.js', '@aztec/accounts'];
18
+
19
+ const e2eRoot = path.resolve(__dirname, '..');
20
+
21
+ function cacheRoot(version) {
22
+ return path.join(e2eRoot, '.legacy-contracts', version);
23
+ }
24
+
25
+ function pkgJsonPath(version, pkg) {
26
+ return path.join(cacheRoot(version), 'node_modules', pkg, 'package.json');
27
+ }
28
+
29
+ function installLegacyContracts(version) {
30
+ if (!version) {
31
+ throw new Error('installLegacyContracts: version is required');
32
+ }
33
+ if (REDIRECTED.every(pkg => fs.existsSync(pkgJsonPath(version, pkg)))) {
34
+ return;
35
+ }
36
+
37
+ const cacheDir = cacheRoot(version);
38
+ fs.mkdirSync(cacheDir, { recursive: true });
39
+
40
+ // Seed a standalone package.json so `npm install --prefix` treats cacheRoot as its own project. Without this, npm
41
+ // walks up and finds the yarn-project workspace root, which breaks on `workspace:` protocol deps and risks
42
+ // clobbering the monorepo's node_modules.
43
+ const seed = path.join(cacheDir, 'package.json');
44
+ if (!fs.existsSync(seed)) {
45
+ fs.writeFileSync(seed, JSON.stringify({ name: 'legacy-contracts-cache', private: true }));
46
+ }
47
+
48
+ const specs = REDIRECTED.map(pkg => `${pkg}@${version}`);
49
+ process.stderr.write(`[legacy-contracts] installing ${specs.join(' ')} into ${cacheDir}\n`);
50
+ // --prefix: install into cacheRoot instead of cwd, so the cache is isolated from the monorepo.
51
+ // --no-save: don't write the installed packages back to the seeded package.json.
52
+ // --ignore-scripts: skip lifecycle scripts (preinstall/postinstall) of the legacy packages and their transitive
53
+ // deps; we only want the files on disk, not to run any build steps.
54
+ // --legacy-peer-deps: tolerate peer-dependency mismatches between the pinned legacy @aztec/* graph and whatever
55
+ // current versions npm would otherwise try to reconcile.
56
+ execFileSync(
57
+ 'npm',
58
+ ['install', '--prefix', cacheDir, '--no-save', '--ignore-scripts', '--legacy-peer-deps', ...specs],
59
+ { stdio: 'inherit' },
60
+ );
61
+
62
+ // Verify versions on disk match the requested version.
63
+ for (const pkg of REDIRECTED) {
64
+ const onDisk = JSON.parse(fs.readFileSync(pkgJsonPath(version, pkg), 'utf8')).version;
65
+ if (onDisk !== version) {
66
+ throw new Error(`[legacy-contracts] ${pkg} on disk is ${onDisk}, expected ${version}`);
67
+ }
68
+ }
69
+ }
70
+
71
+ module.exports = { installLegacyContracts, REDIRECTED, cacheRoot };
72
+
73
+ if (require.main === module) {
74
+ installLegacyContracts(process.argv[2]);
75
+ }
@@ -0,0 +1,112 @@
1
+ // Custom Jest resolver. When CONTRACT_ARTIFACTS_VERSION is set, redirects *only* JSON artifact files under
2
+ // @aztec/noir-contracts.js/artifacts/, @aztec/noir-test-contracts.js/artifacts/, and @aztec/accounts/artifacts/ to a local cache of the pinned
3
+ // legacy versions. TypeScript wrapper classes (e.g. Token.ts) continue to load from the current workspace and use the
4
+ // current @aztec/aztec.js — only the artifact JSON (the deployed-contract ABI / bytecode / notes surface) is swapped.
5
+ //
6
+ // Why JSON-only: the JSON artifact is the actual interchange surface a "deployed contract" exposes. The TS wrapper is
7
+ // generated client-side ergonomics that's tightly coupled to the current @aztec/aztec.js API. Redirecting the wrapper
8
+ // would couple this test to a moving aztec.js surface and break at import time on unrelated breaking changes; we want
9
+ // to fail only on actual artifact-compat regressions.
10
+ //
11
+ // Cache population lives in install_legacy_contracts.cjs — invoked lazily here for local dev, and eagerly
12
+ // by bootstrap.sh ci-compat-e2e before hermetic test containers (which run with --net=none) launch.
13
+ //
14
+ // Missing artifacts: legacy version directories are immutable, so an artifact missing from the cache means the
15
+ // contract was added after the pinned release — there's nothing to compat-test. Rather than failing or silently
16
+ // falling back to the workspace artifact (which would turn the compat run into a regular e2e run that always
17
+ // passes), we log the miss and exit the process cleanly with code 0. The test never runs, but the per-test CI
18
+ // log captures the explanatory line so the reason is auditable. This keeps the change scoped to this resolver,
19
+ // avoiding a new exit-code contract in the shared ci3 test runner.
20
+ //
21
+ // Activated by env var; passthrough otherwise.
22
+ /* eslint-disable @typescript-eslint/no-require-imports */
23
+
24
+ const path = require('path');
25
+ const fs = require('fs');
26
+ const { installLegacyContracts, REDIRECTED, cacheRoot } = require('./install_legacy_contracts.cjs');
27
+
28
+ const version = process.env.CONTRACT_ARTIFACTS_VERSION;
29
+ const cacheDir = version ? cacheRoot(version) : null;
30
+
31
+ function pkgJsonPath(name) {
32
+ return path.join(cacheDir, 'node_modules', name, 'package.json');
33
+ }
34
+
35
+ // Kept in a separate module (not inlined) because bootstrap.sh ci-compat-e2e also calls it directly
36
+ // via `node .../install_legacy_contracts.cjs <version>` to pre-populate the cache on the host before
37
+ // hermetic --net=none test containers launch. Inlining here would force us to duplicate the logic
38
+ // in bash or re-run jest just to trigger the install.
39
+ if (version) {
40
+ installLegacyContracts(version);
41
+ }
42
+
43
+ let bannerPrinted = false;
44
+ const seen = new Set();
45
+
46
+ function printBannerOnce() {
47
+ if (bannerPrinted || !version) {
48
+ return;
49
+ }
50
+ bannerPrinted = true;
51
+ const lines = ['='.repeat(60), `[legacy-contracts][jest] CONTRACT_ARTIFACTS_VERSION=${version}`];
52
+ for (const p of REDIRECTED) {
53
+ const v = JSON.parse(fs.readFileSync(pkgJsonPath(p), 'utf8')).version;
54
+ if (v !== version) {
55
+ throw new Error(`[legacy-contracts] ${p} on disk is ${v}, expected ${version}`);
56
+ }
57
+ lines.push(`[legacy-contracts][jest] redirecting ${p}/artifacts/*.json -> .legacy-contracts/${version}/...`);
58
+ }
59
+ lines.push('='.repeat(60));
60
+ process.stderr.write(lines.join('\n') + '\n');
61
+ }
62
+
63
+ // Match a resolved absolute path against the workspace artifacts dirs and return the legacy cache equivalent, or null
64
+ // if it's not an artifact path we should redirect.
65
+ function legacyArtifactPath(resolved) {
66
+ if (!resolved.endsWith('.json')) {
67
+ return null;
68
+ }
69
+ for (const pkg of REDIRECTED) {
70
+ // pkg = '@aztec/noir-contracts.js' -> match '/noir-contracts.js/artifacts/'
71
+ const dirName = pkg.split('/')[1];
72
+ const marker = `/${dirName}/artifacts/`;
73
+ const idx = resolved.indexOf(marker);
74
+ if (idx === -1) {
75
+ continue;
76
+ }
77
+ const basename = resolved.slice(idx + marker.length);
78
+ return path.join(cacheDir, 'node_modules', pkg, 'artifacts', basename);
79
+ }
80
+ return null;
81
+ }
82
+
83
+ module.exports = function legacyResolver(request, options) {
84
+ // Always run the default resolver first. We only inspect (and possibly rewrite) the *result*; this catches both
85
+ // bare-specifier imports of `@aztec/noir-contracts.js/artifacts/foo.json` and the relative `../artifacts/foo.json`
86
+ // imports inside the workspace TS wrapper classes — both resolve to the same workspace artifact path that we then
87
+ // redirect.
88
+ const resolved = options.defaultResolver(request, options);
89
+ if (!version) {
90
+ return resolved;
91
+ }
92
+ printBannerOnce();
93
+ const legacy = legacyArtifactPath(resolved);
94
+ if (!legacy) {
95
+ return resolved;
96
+ }
97
+ if (!fs.existsSync(legacy)) {
98
+ // Contract was added after this historical release, there is nothing to compat-test for it. Exit the process
99
+ // cleanly with code 0 so the test runner reports the run as passed.
100
+ fs.writeSync(
101
+ 2,
102
+ `[legacy-contracts][jest] artifact ${path.basename(legacy)} not in legacy cache @${version}; ` +
103
+ `assumed added after this release. No compat coverage applicable for this version, treating as passed.\n`,
104
+ );
105
+ process.exit(0);
106
+ }
107
+ if (!seen.has(resolved)) {
108
+ seen.add(resolved);
109
+ process.stderr.write(`[legacy-contracts][jest] redirected ${path.basename(legacy)} -> ${legacy}\n`);
110
+ }
111
+ return legacy;
112
+ };