@aztec/end-to-end 0.0.1-commit.fffb133c → 0.0.1-dev

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 (201) hide show
  1. package/README.md +27 -0
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
  3. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  4. package/dest/bench/client_flows/client_flows_benchmark.js +21 -14
  5. package/dest/bench/client_flows/config.d.ts +2 -2
  6. package/dest/bench/client_flows/config.d.ts.map +1 -1
  7. package/dest/bench/client_flows/config.js +18 -0
  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 +6 -3
  11. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +6 -3
  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 +23 -13
  14. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +2 -2
  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 +3 -2
  17. package/dest/e2e_deploy_contract/deploy_test.d.ts +2 -2
  18. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  19. package/dest/e2e_epochs/epochs_test.d.ts +17 -7
  20. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  21. package/dest/e2e_epochs/epochs_test.js +89 -42
  22. package/dest/e2e_fees/fees_test.d.ts +2 -2
  23. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  24. package/dest/e2e_fees/fees_test.js +19 -12
  25. package/dest/e2e_l1_publisher/write_json.d.ts +3 -2
  26. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
  27. package/dest/e2e_l1_publisher/write_json.js +1 -7
  28. package/dest/e2e_nested_contract/nested_contract_test.d.ts +1 -1
  29. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  30. package/dest/e2e_nested_contract/nested_contract_test.js +4 -6
  31. package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
  32. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  33. package/dest/e2e_p2p/inactivity_slash_test.js +1 -0
  34. package/dest/e2e_p2p/p2p_network.d.ts +4 -3
  35. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  36. package/dest/e2e_p2p/p2p_network.js +23 -6
  37. package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
  38. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
  39. package/dest/e2e_p2p/reqresp/utils.js +177 -0
  40. package/dest/e2e_p2p/shared.d.ts +34 -2
  41. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  42. package/dest/e2e_p2p/shared.js +63 -5
  43. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  44. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  45. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  46. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  47. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  48. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  49. package/dest/e2e_token_contract/token_contract_test.d.ts +4 -2
  50. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  51. package/dest/e2e_token_contract/token_contract_test.js +19 -9
  52. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  53. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  54. package/dest/fixtures/authwit_proxy.js +34 -0
  55. package/dest/fixtures/e2e_prover_test.d.ts +4 -4
  56. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  57. package/dest/fixtures/e2e_prover_test.js +34 -41
  58. package/dest/fixtures/fixtures.d.ts +5 -1
  59. package/dest/fixtures/fixtures.d.ts.map +1 -1
  60. package/dest/fixtures/fixtures.js +6 -0
  61. package/dest/fixtures/ha_setup.d.ts +71 -0
  62. package/dest/fixtures/ha_setup.d.ts.map +1 -0
  63. package/dest/fixtures/ha_setup.js +116 -0
  64. package/dest/fixtures/index.d.ts +2 -1
  65. package/dest/fixtures/index.d.ts.map +1 -1
  66. package/dest/fixtures/index.js +1 -0
  67. package/dest/fixtures/setup.d.ts +53 -31
  68. package/dest/fixtures/setup.d.ts.map +1 -1
  69. package/dest/fixtures/setup.js +117 -168
  70. package/dest/fixtures/setup_p2p_test.d.ts +16 -9
  71. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  72. package/dest/fixtures/setup_p2p_test.js +40 -29
  73. package/dest/fixtures/token_utils.d.ts +2 -2
  74. package/dest/fixtures/token_utils.d.ts.map +1 -1
  75. package/dest/fixtures/token_utils.js +5 -4
  76. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  77. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  78. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  79. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  80. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  81. package/dest/forward-compatibility/wallet_service.js +109 -0
  82. package/dest/install_legacy_contracts.d.cts +10 -0
  83. package/dest/install_legacy_contracts.d.cts.map +1 -0
  84. package/dest/legacy-jest-resolver.d.cts +3 -0
  85. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  86. package/dest/shared/cross_chain_test_harness.d.ts +1 -1
  87. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  88. package/dest/shared/cross_chain_test_harness.js +13 -13
  89. package/dest/shared/gas_portal_test_harness.js +3 -3
  90. package/dest/shared/index.d.ts +2 -1
  91. package/dest/shared/index.d.ts.map +1 -1
  92. package/dest/shared/index.js +1 -0
  93. package/dest/shared/mock_state_view.d.ts +86 -0
  94. package/dest/shared/mock_state_view.d.ts.map +1 -0
  95. package/dest/shared/mock_state_view.js +186 -0
  96. package/dest/shared/submit-transactions.d.ts +2 -2
  97. package/dest/shared/submit-transactions.d.ts.map +1 -1
  98. package/dest/shared/submit-transactions.js +1 -1
  99. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  100. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  101. package/dest/shared/uniswap_l1_l2.js +16 -21
  102. package/dest/simulators/lending_simulator.d.ts +1 -1
  103. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  104. package/dest/simulators/lending_simulator.js +4 -4
  105. package/dest/simulators/token_simulator.d.ts +1 -1
  106. package/dest/simulators/token_simulator.d.ts.map +1 -1
  107. package/dest/simulators/token_simulator.js +3 -24
  108. package/dest/spartan/setup_test_wallets.d.ts +12 -3
  109. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  110. package/dest/spartan/setup_test_wallets.js +59 -16
  111. package/dest/spartan/tx_metrics.d.ts +35 -1
  112. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  113. package/dest/spartan/tx_metrics.js +150 -0
  114. package/dest/spartan/utils/bot.d.ts +3 -2
  115. package/dest/spartan/utils/bot.d.ts.map +1 -1
  116. package/dest/spartan/utils/bot.js +2 -1
  117. package/dest/spartan/utils/config.d.ts +4 -1
  118. package/dest/spartan/utils/config.d.ts.map +1 -1
  119. package/dest/spartan/utils/config.js +2 -1
  120. package/dest/spartan/utils/index.d.ts +5 -4
  121. package/dest/spartan/utils/index.d.ts.map +1 -1
  122. package/dest/spartan/utils/index.js +4 -2
  123. package/dest/spartan/utils/k8s.d.ts +31 -1
  124. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  125. package/dest/spartan/utils/k8s.js +124 -0
  126. package/dest/spartan/utils/nodes.d.ts +11 -1
  127. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  128. package/dest/spartan/utils/nodes.js +198 -27
  129. package/dest/spartan/utils/scripts.d.ts +18 -4
  130. package/dest/spartan/utils/scripts.d.ts.map +1 -1
  131. package/dest/spartan/utils/scripts.js +19 -4
  132. package/dest/test-wallet/test_wallet.d.ts +84 -0
  133. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  134. package/dest/test-wallet/test_wallet.js +253 -0
  135. package/dest/test-wallet/utils.d.ts +41 -0
  136. package/dest/test-wallet/utils.d.ts.map +1 -0
  137. package/dest/test-wallet/utils.js +66 -0
  138. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  139. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  140. package/dest/test-wallet/wallet_worker_script.js +48 -0
  141. package/dest/test-wallet/worker_wallet.d.ts +52 -0
  142. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  143. package/dest/test-wallet/worker_wallet.js +151 -0
  144. package/dest/test-wallet/worker_wallet_schema.d.ts +277 -0
  145. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  146. package/dest/test-wallet/worker_wallet_schema.js +10 -0
  147. package/package.json +48 -40
  148. package/src/bench/client_flows/client_flows_benchmark.ts +44 -40
  149. package/src/bench/client_flows/config.ts +9 -1
  150. package/src/bench/utils.ts +8 -3
  151. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +31 -21
  152. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +7 -8
  153. package/src/e2e_deploy_contract/deploy_test.ts +3 -3
  154. package/src/e2e_epochs/epochs_test.ts +113 -70
  155. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  156. package/src/e2e_fees/fees_test.ts +21 -29
  157. package/src/e2e_l1_publisher/write_json.ts +1 -6
  158. package/src/e2e_nested_contract/nested_contract_test.ts +7 -5
  159. package/src/e2e_p2p/inactivity_slash_test.ts +5 -4
  160. package/src/e2e_p2p/p2p_network.ts +35 -9
  161. package/src/e2e_p2p/reqresp/utils.ts +235 -0
  162. package/src/e2e_p2p/shared.ts +110 -5
  163. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  164. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  165. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  166. package/src/e2e_token_contract/token_contract_test.ts +26 -9
  167. package/src/fixtures/authwit_proxy.ts +54 -0
  168. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  169. package/src/fixtures/e2e_prover_test.ts +40 -44
  170. package/src/fixtures/fixtures.ts +10 -0
  171. package/src/fixtures/ha_setup.ts +186 -0
  172. package/src/fixtures/index.ts +1 -0
  173. package/src/fixtures/setup.ts +161 -228
  174. package/src/fixtures/setup_p2p_test.ts +40 -44
  175. package/src/fixtures/token_utils.ts +6 -3
  176. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  177. package/src/forward-compatibility/wallet_service.ts +104 -0
  178. package/src/guides/up_quick_start.sh +3 -5
  179. package/src/install_legacy_contracts.cjs +75 -0
  180. package/src/legacy-jest-resolver.cjs +112 -0
  181. package/src/shared/cross_chain_test_harness.ts +13 -9
  182. package/src/shared/gas_portal_test_harness.ts +1 -2
  183. package/src/shared/index.ts +1 -0
  184. package/src/shared/mock_state_view.ts +188 -0
  185. package/src/shared/submit-transactions.ts +6 -2
  186. package/src/shared/uniswap_l1_l2.ts +38 -37
  187. package/src/simulators/lending_simulator.ts +8 -4
  188. package/src/simulators/token_simulator.ts +6 -30
  189. package/src/spartan/setup_test_wallets.ts +104 -18
  190. package/src/spartan/tx_metrics.ts +126 -0
  191. package/src/spartan/utils/bot.ts +4 -1
  192. package/src/spartan/utils/config.ts +1 -0
  193. package/src/spartan/utils/index.ts +7 -1
  194. package/src/spartan/utils/k8s.ts +160 -0
  195. package/src/spartan/utils/nodes.ts +239 -24
  196. package/src/spartan/utils/scripts.ts +43 -7
  197. package/src/test-wallet/test_wallet.ts +355 -0
  198. package/src/test-wallet/utils.ts +107 -0
  199. package/src/test-wallet/wallet_worker_script.ts +60 -0
  200. package/src/test-wallet/worker_wallet.ts +214 -0
  201. 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
10
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
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
@@ -44,10 +47,6 @@ export async function createNodes(
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;
@@ -69,7 +68,6 @@ export async function createNodes(
69
68
  prefilledPublicData,
70
69
  dataDir,
71
70
  metricsPort,
72
- loggerIdStorage,
73
71
  );
74
72
  nodePromises.push(nodePromise);
75
73
  }
@@ -81,13 +79,20 @@ 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
+ };
92
+
93
+ /** Creates a P2P enabled instance of Aztec Node Service with a validator. */
89
94
  export async function createNode(
90
- config: AztecNodeConfig & { dontStartSequencer?: boolean },
95
+ config: CreateNodeConfig,
91
96
  dateProvider: DateProvider,
92
97
  tcpPort: number,
93
98
  bootstrapNode: string | undefined,
@@ -95,9 +100,9 @@ export async function createNode(
95
100
  prefilledPublicData?: PublicDataTreeLeaf[],
96
101
  dataDirectory?: string,
97
102
  metricsPort?: number,
98
- loggerIdStorage?: AsyncLocalStorage<string>,
99
103
  ) {
100
- const createNode = async () => {
104
+ const actorIndex = validatorCounter++;
105
+ return await withLoggerBindings({ actor: `validator-${actorIndex}` }, async () => {
101
106
  const validatorConfig = await createValidatorConfig(config, bootstrapNode, tcpPort, addressIndex, dataDirectory);
102
107
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
103
108
  return await AztecNodeService.createAndSync(
@@ -105,8 +110,7 @@ export async function createNode(
105
110
  { telemetry, dateProvider },
106
111
  { prefilledPublicData, dontStartSequencer: config.dontStartSequencer },
107
112
  );
108
- };
109
- return loggerIdStorage ? await loggerIdStorage.run(tcpPort.toString(), createNode) : createNode();
113
+ });
110
114
  }
111
115
 
112
116
  /** Creates a P2P enabled instance of Aztec Node Service without a validator */
@@ -118,20 +122,19 @@ export async function createNonValidatorNode(
118
122
  prefilledPublicData?: PublicDataTreeLeaf[],
119
123
  dataDirectory?: string,
120
124
  metricsPort?: number,
121
- loggerIdStorage?: AsyncLocalStorage<string>,
122
125
  ) {
123
- const createNode = async () => {
126
+ const actorIndex = nodeCounter++;
127
+ return await withLoggerBindings({ actor: `node-${actorIndex}` }, async () => {
124
128
  const p2pConfig = await createP2PConfig(baseConfig, bootstrapNode, tcpPort, dataDirectory);
125
129
  const config: AztecNodeConfig = {
126
130
  ...p2pConfig,
127
131
  disableValidator: true,
128
132
  validatorPrivateKeys: undefined,
129
- publisherPrivateKeys: [],
133
+ sequencerPublisherPrivateKeys: [],
130
134
  };
131
135
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
132
136
  return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, { prefilledPublicData });
133
- };
134
- return loggerIdStorage ? await loggerIdStorage.run(tcpPort.toString(), createNode) : createNode();
137
+ });
135
138
  }
136
139
 
137
140
  export async function createProverNode(
@@ -139,34 +142,26 @@ export async function createProverNode(
139
142
  tcpPort: number,
140
143
  bootstrapNode: string | undefined,
141
144
  addressIndex: number,
142
- proverNodeDeps: ProverNodeDeps & Required<Pick<ProverNodeDeps, 'dateProvider'>>,
145
+ deps: { dateProvider: DateProvider },
143
146
  prefilledPublicData?: PublicDataTreeLeaf[],
144
147
  dataDirectory?: string,
145
148
  metricsPort?: number,
146
- loggerIdStorage?: AsyncLocalStorage<string>,
147
- ) {
148
- const createProverNode = async () => {
149
+ ): Promise<{ proverNode: AztecNodeService }> {
150
+ const actorIndex = proverCounter++;
151
+ return await withLoggerBindings({ actor: `prover-${actorIndex}` }, async () => {
149
152
  const proverNodePrivateKey = getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + addressIndex)!;
150
153
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
151
154
 
152
- const proverConfig: Partial<ProverNodeConfig> = await createP2PConfig(
153
- config,
154
- bootstrapNode,
155
- tcpPort,
156
- dataDirectory,
157
- );
155
+ const p2pConfig = await createP2PConfig(config, bootstrapNode, tcpPort, dataDirectory);
158
156
 
159
- const aztecNodeRpcTxProvider = undefined;
160
157
  return await createAndSyncProverNode(
161
158
  bufferToHex(proverNodePrivateKey),
162
- config,
163
- { ...proverConfig, dataDirectory },
164
- aztecNodeRpcTxProvider,
165
- prefilledPublicData,
166
- { ...proverNodeDeps, telemetry },
159
+ { ...config, ...p2pConfig },
160
+ { dataDirectory },
161
+ { ...deps, telemetry },
162
+ { prefilledPublicData: prefilledPublicData ?? [] },
167
163
  );
168
- };
169
- return loggerIdStorage ? await loggerIdStorage.run(tcpPort.toString(), createProverNode) : createProverNode();
164
+ });
170
165
  }
171
166
 
172
167
  export async function createP2PConfig(
@@ -192,26 +187,27 @@ export async function createP2PConfig(
192
187
  }
193
188
 
194
189
  export async function createValidatorConfig(
195
- config: AztecNodeConfig,
190
+ config: CreateNodeConfig,
196
191
  bootstrapNodeEnr?: string,
197
192
  port?: number,
198
193
  addressIndex: number | number[] = 1,
199
194
  dataDirectory?: string,
200
195
  ) {
201
196
  const addressIndices = Array.isArray(addressIndex) ? addressIndex : [addressIndex];
202
- if (addressIndices.length === 0) {
197
+ if (addressIndices.length === 0 && !config.validatorPrivateKey) {
203
198
  throw new Error('At least one address index must be provided to create a validator config');
204
199
  }
205
200
 
206
- const attesterPrivateKeys = addressIndices.map(index =>
207
- bufferToHex(getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + index)!),
208
- );
201
+ // Use override private key if provided, otherwise derive from address indices
202
+ const attesterPrivateKeys = config.validatorPrivateKey
203
+ ? [config.validatorPrivateKey]
204
+ : addressIndices.map(index => bufferToHex(getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + index)!));
209
205
  const p2pConfig = await createP2PConfig(config, bootstrapNodeEnr, port, dataDirectory);
210
206
  const nodeConfig: AztecNodeConfig = {
211
207
  ...config,
212
208
  ...p2pConfig,
213
209
  validatorPrivateKeys: new SecretValue(attesterPrivateKeys),
214
- publisherPrivateKeys: [new SecretValue(attesterPrivateKeys[0])],
210
+ sequencerPublisherPrivateKeys: [new SecretValue(attesterPrivateKeys[0])],
215
211
  };
216
212
 
217
213
  return nodeConfig;
@@ -6,7 +6,9 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token';
6
6
 
7
7
  export async function deployToken(wallet: Wallet, admin: AztecAddress, initialAdminBalance: bigint, logger: Logger) {
8
8
  logger.info(`Deploying Token contract...`);
9
- const { contract, instance } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
9
+ const {
10
+ receipt: { contract, instance },
11
+ } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
10
12
  from: admin,
11
13
  wait: { returnReceipt: true },
12
14
  });
@@ -25,8 +27,9 @@ export async function mintTokensToPrivate(
25
27
  minter: AztecAddress,
26
28
  recipient: AztecAddress,
27
29
  amount: bigint,
30
+ additionalScopes?: AztecAddress[],
28
31
  ) {
29
- await token.methods.mint_to_private(recipient, amount).send({ from: minter });
32
+ await token.methods.mint_to_private(recipient, amount).send({ from: minter, additionalScopes });
30
33
  }
31
34
 
32
35
  export async function expectTokenBalance(
@@ -38,7 +41,7 @@ export async function expectTokenBalance(
38
41
  ) {
39
42
  // Then check the balance
40
43
  const contractWithWallet = TokenContract.at(token.address, wallet);
41
- const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
44
+ const { result: balance } = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
42
45
  logger.info(`Account ${owner} balance: ${balance}`);
43
46
  expect(balance).toBe(expectedBalance);
44
47
  }
@@ -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
+ };
@@ -73,22 +73,26 @@ export async function deployAndInitializeTokenAndBridgeContracts(
73
73
  });
74
74
 
75
75
  // deploy l2 token
76
- const token = await TokenContract.deploy(wallet, owner, 'TokenName', 'TokenSymbol', 18).send({ from: owner });
76
+ const { contract: token } = await TokenContract.deploy(wallet, owner, 'TokenName', 'TokenSymbol', 18).send({
77
+ from: owner,
78
+ });
77
79
 
78
80
  // deploy l2 token bridge and attach to the portal
79
- const bridge = await TokenBridgeContract.deploy(wallet, token.address, tokenPortalAddress).send({ from: owner });
81
+ const { contract: bridge } = await TokenBridgeContract.deploy(wallet, token.address, tokenPortalAddress).send({
82
+ from: owner,
83
+ });
80
84
 
81
- if ((await token.methods.get_admin().simulate({ from: owner })) !== owner.toBigInt()) {
85
+ if ((await token.methods.get_admin().simulate({ from: owner })).result !== owner.toBigInt()) {
82
86
  throw new Error(`Token admin is not ${owner}`);
83
87
  }
84
88
 
85
- if (!(await bridge.methods.get_config().simulate({ from: owner })).token.equals(token.address)) {
89
+ if (!(await bridge.methods.get_config().simulate({ from: owner })).result.token.equals(token.address)) {
86
90
  throw new Error(`Bridge token is not ${token.address}`);
87
91
  }
88
92
 
89
93
  // make the bridge a minter on the token:
90
94
  await token.methods.set_minter(bridge.address, true).send({ from: owner });
91
- if ((await token.methods.is_minter(bridge.address).simulate({ from: owner })) === 1n) {
95
+ if ((await token.methods.is_minter(bridge.address).simulate({ from: owner })).result === 1n) {
92
96
  throw new Error(`Bridge is not a minter`);
93
97
  }
94
98
 
@@ -269,7 +273,7 @@ export class CrossChainTestHarness {
269
273
  authwitNonce: Fr = Fr.ZERO,
270
274
  authWitness: AuthWitness,
271
275
  ): Promise<TxReceipt> {
272
- const withdrawReceipt = await this.l2Bridge.methods
276
+ const { receipt: withdrawReceipt } = await this.l2Bridge.methods
273
277
  .exit_to_l1_private(this.l2Token.address, this.ethAccount, withdrawAmount, EthAddress.ZERO, authwitNonce)
274
278
  .send({ authWitnesses: [authWitness], from: this.ownerAddress });
275
279
 
@@ -277,7 +281,7 @@ export class CrossChainTestHarness {
277
281
  }
278
282
 
279
283
  async withdrawPublicFromAztecToL1(withdrawAmount: bigint, authwitNonce: Fr = Fr.ZERO): Promise<TxReceipt> {
280
- const withdrawReceipt = await this.l2Bridge.methods
284
+ const { receipt: withdrawReceipt } = await this.l2Bridge.methods
281
285
  .exit_to_l1_public(this.ethAccount, withdrawAmount, EthAddress.ZERO, authwitNonce)
282
286
  .send({ from: this.ownerAddress });
283
287
 
@@ -285,7 +289,7 @@ export class CrossChainTestHarness {
285
289
  }
286
290
 
287
291
  async getL2PrivateBalanceOf(owner: AztecAddress) {
288
- return await this.l2Token.methods.balance_of_private(owner).simulate({ from: owner });
292
+ return (await this.l2Token.methods.balance_of_private(owner).simulate({ from: owner })).result;
289
293
  }
290
294
 
291
295
  async expectPrivateBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) {
@@ -295,7 +299,7 @@ export class CrossChainTestHarness {
295
299
  }
296
300
 
297
301
  async getL2PublicBalanceOf(owner: AztecAddress) {
298
- return await this.l2Token.methods.balance_of_public(owner).simulate({ from: this.ownerAddress });
302
+ return (await this.l2Token.methods.balance_of_public(owner).simulate({ from: this.ownerAddress })).result;
299
303
  }
300
304
 
301
305
  async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) {
@@ -131,7 +131,7 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
131
131
  }
132
132
 
133
133
  async getL2PublicBalanceOf(owner: AztecAddress) {
134
- return await this.feeJuice.methods.balance_of_public(owner).simulate({ from: owner });
134
+ return (await this.feeJuice.methods.balance_of_public(owner).simulate({ from: owner })).result;
135
135
  }
136
136
 
137
137
  async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) {
@@ -178,4 +178,3 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
178
178
  }
179
179
  }
180
180
  }
181
- // docs:end:cross_chain_test_harness
@@ -1 +1,2 @@
1
1
  export { uniswapL1L2TestSuite } from './uniswap_l1_l2.js';
2
+ export { MockStateView, diffInBps } from './mock_state_view.js';