@aztec/txe 0.0.1-commit.72dcdcda8 → 0.0.1-commit.7689c7f

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 (126) hide show
  1. package/dest/ContractClassRegistry-KKNT527R.js +3 -0
  2. package/dest/ContractClassRegistry-KKNT527R.js.map +7 -0
  3. package/dest/ContractInstanceRegistry-GSKBNL3Q.js +3 -0
  4. package/dest/ContractInstanceRegistry-GSKBNL3Q.js.map +7 -0
  5. package/dest/FeeJuice-GUJ5O6GB.js +3 -0
  6. package/dest/FeeJuice-GUJ5O6GB.js.map +7 -0
  7. package/dest/MultiCallEntrypoint-ZQPCKVKL.js +3 -0
  8. package/dest/MultiCallEntrypoint-ZQPCKVKL.js.map +7 -0
  9. package/dest/SchnorrAccount-QIXE5DXA.js +3 -0
  10. package/dest/SchnorrAccount-QIXE5DXA.js.map +7 -0
  11. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  12. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  13. package/dest/bin/check_txe_oracle_version.js +32 -0
  14. package/dest/bin/index.js +3 -30
  15. package/dest/bin/index.js.map +7 -0
  16. package/dest/chunk-BJVAAXNA.js +3 -0
  17. package/dest/chunk-BJVAAXNA.js.map +7 -0
  18. package/dest/chunk-DF6RMOC6.js +304 -0
  19. package/dest/chunk-DF6RMOC6.js.map +7 -0
  20. package/dest/chunk-PPJTNNUG.js +265 -0
  21. package/dest/chunk-PPJTNNUG.js.map +7 -0
  22. package/dest/constants.d.ts +3 -1
  23. package/dest/constants.d.ts.map +1 -1
  24. package/dest/constants.js +5 -0
  25. package/dest/dispatcher_pool.d.ts +67 -0
  26. package/dest/dispatcher_pool.d.ts.map +1 -0
  27. package/dest/dispatcher_pool.js +284 -0
  28. package/dest/index.d.ts +188 -7
  29. package/dest/index.d.ts.map +1 -1
  30. package/dest/index.js +160 -119
  31. package/dest/metafile.json +38147 -0
  32. package/dest/msgpackr_fr_extension.d.ts +2 -0
  33. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  34. package/dest/msgpackr_fr_extension.js +21 -0
  35. package/dest/oracle/interfaces.d.ts +39 -28
  36. package/dest/oracle/interfaces.d.ts.map +1 -1
  37. package/dest/oracle/txe_oracle_public_context.d.ts +18 -13
  38. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  39. package/dest/oracle/txe_oracle_public_context.js +27 -12
  40. package/dest/oracle/txe_oracle_top_level_context.d.ts +36 -20
  41. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  42. package/dest/oracle/txe_oracle_top_level_context.js +125 -66
  43. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  44. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  45. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  46. package/dest/rpc_server.d.ts +14 -0
  47. package/dest/rpc_server.d.ts.map +1 -0
  48. package/dest/rpc_server.js +78 -0
  49. package/dest/rpc_translator.d.ts +139 -83
  50. package/dest/rpc_translator.d.ts.map +1 -1
  51. package/dest/rpc_translator.js +567 -243
  52. package/dest/server.bundle.js +3 -0
  53. package/dest/server.bundle.js.map +7 -0
  54. package/dest/state_machine/archiver.d.ts +4 -4
  55. package/dest/state_machine/archiver.d.ts.map +1 -1
  56. package/dest/state_machine/archiver.js +22 -20
  57. package/dest/state_machine/dummy_p2p_client.d.ts +13 -7
  58. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  59. package/dest/state_machine/dummy_p2p_client.js +16 -4
  60. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  61. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  62. package/dest/state_machine/global_variable_builder.js +9 -3
  63. package/dest/state_machine/index.d.ts +7 -3
  64. package/dest/state_machine/index.d.ts.map +1 -1
  65. package/dest/state_machine/index.js +23 -5
  66. package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
  67. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  68. package/dest/state_machine/mock_epoch_cache.js +35 -2
  69. package/dest/state_machine/synchronizer.d.ts +5 -5
  70. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  71. package/dest/state_machine/synchronizer.js +4 -4
  72. package/dest/txe_oracle_version.d.ts +17 -0
  73. package/dest/txe_oracle_version.d.ts.map +1 -0
  74. package/dest/txe_oracle_version.js +14 -0
  75. package/dest/txe_session.d.ts +64 -6
  76. package/dest/txe_session.d.ts.map +1 -1
  77. package/dest/txe_session.js +159 -31
  78. package/dest/utils/encoding.d.ts +191 -0
  79. package/dest/utils/encoding.d.ts.map +1 -0
  80. package/dest/{util → utils}/encoding.js +7 -2
  81. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  82. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  83. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  84. package/dest/utils/txe_account_store.d.ts.map +1 -0
  85. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  86. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  87. package/dest/{util → utils}/txe_public_contract_data_source.js +1 -3
  88. package/dest/worker.bundle.js +3 -0
  89. package/dest/worker.bundle.js.map +7 -0
  90. package/dest/worker.d.ts +2 -0
  91. package/dest/worker.d.ts.map +1 -0
  92. package/dest/worker.js +92 -0
  93. package/package.json +37 -21
  94. package/src/bin/check_txe_oracle_version.ts +37 -0
  95. package/src/bin/index.ts +11 -2
  96. package/src/constants.ts +6 -0
  97. package/src/dispatcher_pool.ts +316 -0
  98. package/src/index.ts +178 -126
  99. package/src/msgpackr_fr_extension.ts +23 -0
  100. package/src/oracle/interfaces.ts +43 -34
  101. package/src/oracle/txe_oracle_public_context.ts +42 -12
  102. package/src/oracle/txe_oracle_top_level_context.ts +146 -77
  103. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  104. package/src/rpc_server.ts +87 -0
  105. package/src/rpc_translator.ts +646 -326
  106. package/src/state_machine/archiver.ts +33 -18
  107. package/src/state_machine/dummy_p2p_client.ts +31 -11
  108. package/src/state_machine/global_variable_builder.ts +18 -3
  109. package/src/state_machine/index.ts +25 -6
  110. package/src/state_machine/mock_epoch_cache.ts +46 -3
  111. package/src/state_machine/synchronizer.ts +5 -5
  112. package/src/txe_oracle_version.ts +17 -0
  113. package/src/txe_session.ts +253 -33
  114. package/src/{util → utils}/encoding.ts +8 -2
  115. package/src/{util → utils}/txe_public_contract_data_source.ts +0 -2
  116. package/src/worker.ts +98 -0
  117. package/dest/util/encoding.d.ts +0 -720
  118. package/dest/util/encoding.d.ts.map +0 -1
  119. package/dest/util/expected_failure_error.d.ts.map +0 -1
  120. package/dest/util/txe_account_store.d.ts.map +0 -1
  121. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  122. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  123. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  124. /package/dest/{util → utils}/txe_account_store.js +0 -0
  125. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  126. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,17 +1,27 @@
1
1
  import type { ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
2
- import { Fr, Point } from '@aztec/aztec.js/fields';
3
- import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
2
+ import { Fr } from '@aztec/aztec.js/fields';
3
+ import {
4
+ ARCHIVE_HEIGHT,
5
+ MAX_NOTE_HASHES_PER_TX,
6
+ MAX_NULLIFIERS_PER_TX,
7
+ MAX_PRIVATE_LOGS_PER_TX,
8
+ PRIVATE_LOG_SIZE_IN_FIELDS,
9
+ } from '@aztec/constants';
4
10
  import { BlockNumber } from '@aztec/foundation/branded-types';
11
+ import { MembershipWitness } from '@aztec/foundation/trees';
5
12
  import {
13
+ BoundedVec,
6
14
  type IMiscOracle,
7
15
  type IPrivateExecutionOracle,
8
16
  type IUtilityExecutionOracle,
17
+ Option,
9
18
  packAsHintedNote,
10
19
  } from '@aztec/pxe/simulator';
11
20
  import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
12
21
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
13
- import { BlockHash } from '@aztec/stdlib/block';
22
+ import { GasSettings } from '@aztec/stdlib/gas';
14
23
 
24
+ import { MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY, MAX_OFFCHAIN_EFFECT_LEN } from './constants.js';
15
25
  import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
16
26
  import type { TXESessionStateHandler } from './txe_session.js';
17
27
  import {
@@ -20,6 +30,7 @@ import {
20
30
  addressFromSingle,
21
31
  arrayOfArraysToBoundedVecOfArrays,
22
32
  arrayToBoundedVec,
33
+ blockHashFromSingle,
23
34
  bufferToU8Array,
24
35
  fromArray,
25
36
  fromSingle,
@@ -28,7 +39,7 @@ import {
28
39
  toArray,
29
40
  toForeignCallResult,
30
41
  toSingle,
31
- } from './util/encoding.js';
42
+ } from './utils/encoding.js';
32
43
 
33
44
  const MAX_EVENT_LEN = 10; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN
34
45
  const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
@@ -102,19 +113,32 @@ export class RPCTranslator {
102
113
  return this.oracleHandler;
103
114
  }
104
115
 
116
+ // eslint-disable-next-line camelcase
117
+ aztec_txe_assertCompatibleOracleVersion(foreignMajor: ForeignCallSingle, foreignMinor: ForeignCallSingle) {
118
+ const major = fromSingle(foreignMajor).toNumber();
119
+ const minor = fromSingle(foreignMinor).toNumber();
120
+
121
+ this.stateHandler.setTxeOracleVersion(major, minor);
122
+
123
+ return toForeignCallResult([]);
124
+ }
125
+
105
126
  // TXE session state transition functions - these get handled by the state handler
106
127
 
107
- async txeSetTopLevelTXEContext() {
128
+ // eslint-disable-next-line camelcase
129
+ async aztec_txe_setTopLevelTXEContext() {
108
130
  await this.stateHandler.enterTopLevelState();
109
131
 
110
132
  return toForeignCallResult([]);
111
133
  }
112
134
 
113
- async txeSetPrivateTXEContext(
135
+ // eslint-disable-next-line camelcase
136
+ async aztec_txe_setPrivateTXEContext(
114
137
  foreignContractAddressIsSome: ForeignCallSingle,
115
138
  foreignContractAddressValue: ForeignCallSingle,
116
139
  foreignAnchorBlockNumberIsSome: ForeignCallSingle,
117
140
  foreignAnchorBlockNumberValue: ForeignCallSingle,
141
+ foreignGasSettings: ForeignCallArray,
118
142
  ) {
119
143
  const contractAddress = fromSingle(foreignContractAddressIsSome).toBool()
120
144
  ? AztecAddress.fromField(fromSingle(foreignContractAddressValue))
@@ -124,12 +148,19 @@ export class RPCTranslator {
124
148
  ? BlockNumber(fromSingle(foreignAnchorBlockNumberValue).toNumber())
125
149
  : undefined;
126
150
 
127
- const privateContextInputs = await this.stateHandler.enterPrivateState(contractAddress, anchorBlockNumber);
151
+ const gasSettings = GasSettings.fromFields(fromArray(foreignGasSettings));
152
+
153
+ const privateContextInputs = await this.stateHandler.enterPrivateState(
154
+ contractAddress,
155
+ anchorBlockNumber,
156
+ gasSettings,
157
+ );
128
158
 
129
159
  return toForeignCallResult(privateContextInputs.toFields().map(toSingle));
130
160
  }
131
161
 
132
- async txeSetPublicTXEContext(
162
+ // eslint-disable-next-line camelcase
163
+ async aztec_txe_setPublicTXEContext(
133
164
  foreignContractAddressIsSome: ForeignCallSingle,
134
165
  foreignContractAddressValue: ForeignCallSingle,
135
166
  ) {
@@ -142,7 +173,8 @@ export class RPCTranslator {
142
173
  return toForeignCallResult([]);
143
174
  }
144
175
 
145
- async txeSetUtilityTXEContext(
176
+ // eslint-disable-next-line camelcase
177
+ async aztec_txe_setUtilityTXEContext(
146
178
  foreignContractAddressIsSome: ForeignCallSingle,
147
179
  foreignContractAddressValue: ForeignCallSingle,
148
180
  ) {
@@ -159,44 +191,54 @@ export class RPCTranslator {
159
191
 
160
192
  // TXE-specific oracles
161
193
 
162
- txeGetDefaultAddress() {
163
- const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
194
+ // eslint-disable-next-line camelcase
195
+ aztec_txe_getDefaultAddress() {
196
+ const defaultAddress = this.handlerAsTxe().getDefaultAddress();
164
197
 
165
198
  return toForeignCallResult([toSingle(defaultAddress)]);
166
199
  }
167
200
 
168
- async txeGetNextBlockNumber() {
169
- const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
201
+ // eslint-disable-next-line camelcase
202
+ async aztec_txe_getNextBlockNumber() {
203
+ const nextBlockNumber = await this.handlerAsTxe().getNextBlockNumber();
170
204
 
171
205
  return toForeignCallResult([toSingle(nextBlockNumber)]);
172
206
  }
173
207
 
174
- async txeGetNextBlockTimestamp() {
175
- const nextBlockTimestamp = await this.handlerAsTxe().txeGetNextBlockTimestamp();
208
+ // eslint-disable-next-line camelcase
209
+ async aztec_txe_getNextBlockTimestamp() {
210
+ const nextBlockTimestamp = await this.handlerAsTxe().getNextBlockTimestamp();
176
211
 
177
212
  return toForeignCallResult([toSingle(nextBlockTimestamp)]);
178
213
  }
179
214
 
180
- async txeAdvanceBlocksBy(foreignBlocks: ForeignCallSingle) {
215
+ // eslint-disable-next-line camelcase
216
+ async aztec_txe_advanceBlocksBy(foreignBlocks: ForeignCallSingle) {
181
217
  const blocks = fromSingle(foreignBlocks).toNumber();
182
218
 
183
- await this.handlerAsTxe().txeAdvanceBlocksBy(blocks);
219
+ await this.handlerAsTxe().advanceBlocksBy(blocks);
184
220
 
185
221
  return toForeignCallResult([]);
186
222
  }
187
223
 
188
- txeAdvanceTimestampBy(foreignDuration: ForeignCallSingle) {
224
+ // eslint-disable-next-line camelcase
225
+ aztec_txe_advanceTimestampBy(foreignDuration: ForeignCallSingle) {
189
226
  const duration = fromSingle(foreignDuration).toBigInt();
190
227
 
191
- this.handlerAsTxe().txeAdvanceTimestampBy(duration);
228
+ this.handlerAsTxe().advanceTimestampBy(duration);
192
229
 
193
230
  return toForeignCallResult([]);
194
231
  }
195
232
 
196
- async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, foreignSecret: ForeignCallSingle) {
233
+ // eslint-disable-next-line camelcase
234
+ async aztec_txe_deploy(
235
+ artifact: ContractArtifact,
236
+ instance: ContractInstanceWithAddress,
237
+ foreignSecret: ForeignCallSingle,
238
+ ) {
197
239
  const secret = fromSingle(foreignSecret);
198
240
 
199
- await this.handlerAsTxe().txeDeploy(artifact, instance, secret);
241
+ await this.handlerAsTxe().deploy(artifact, instance, secret);
200
242
 
201
243
  return toForeignCallResult([
202
244
  toArray([
@@ -204,15 +246,17 @@ export class RPCTranslator {
204
246
  instance.deployer.toField(),
205
247
  instance.currentContractClassId,
206
248
  instance.initializationHash,
249
+ instance.immutablesHash,
207
250
  ...instance.publicKeys.toFields(),
208
251
  ]),
209
252
  ]);
210
253
  }
211
254
 
212
- async txeCreateAccount(foreignSecret: ForeignCallSingle) {
255
+ // eslint-disable-next-line camelcase
256
+ async aztec_txe_createAccount(foreignSecret: ForeignCallSingle) {
213
257
  const secret = fromSingle(foreignSecret);
214
258
 
215
- const completeAddress = await this.handlerAsTxe().txeCreateAccount(secret);
259
+ const completeAddress = await this.handlerAsTxe().createAccount(secret);
216
260
 
217
261
  return toForeignCallResult([
218
262
  toSingle(completeAddress.address),
@@ -220,14 +264,15 @@ export class RPCTranslator {
220
264
  ]);
221
265
  }
222
266
 
223
- async txeAddAccount(
267
+ // eslint-disable-next-line camelcase
268
+ async aztec_txe_addAccount(
224
269
  artifact: ContractArtifact,
225
270
  instance: ContractInstanceWithAddress,
226
271
  foreignSecret: ForeignCallSingle,
227
272
  ) {
228
273
  const secret = fromSingle(foreignSecret);
229
274
 
230
- const completeAddress = await this.handlerAsTxe().txeAddAccount(artifact, instance, secret);
275
+ const completeAddress = await this.handlerAsTxe().addAccount(artifact, instance, secret);
231
276
 
232
277
  return toForeignCallResult([
233
278
  toSingle(completeAddress.address),
@@ -235,48 +280,104 @@ export class RPCTranslator {
235
280
  ]);
236
281
  }
237
282
 
238
- async txeAddAuthWitness(foreignAddress: ForeignCallSingle, foreignMessageHash: ForeignCallSingle) {
283
+ // eslint-disable-next-line camelcase
284
+ async aztec_txe_addAuthWitness(foreignAddress: ForeignCallSingle, foreignMessageHash: ForeignCallSingle) {
239
285
  const address = addressFromSingle(foreignAddress);
240
286
  const messageHash = fromSingle(foreignMessageHash);
241
287
 
242
- await this.handlerAsTxe().txeAddAuthWitness(address, messageHash);
288
+ await this.handlerAsTxe().addAuthWitness(address, messageHash);
243
289
 
244
290
  return toForeignCallResult([]);
245
291
  }
246
292
 
247
293
  // PXE oracles
248
294
 
249
- utilityAssertCompatibleOracleVersion(foreignVersion: ForeignCallSingle) {
250
- const version = fromSingle(foreignVersion).toNumber();
295
+ // eslint-disable-next-line camelcase
296
+ aztec_utl_assertCompatibleOracleVersion(foreignMajor: ForeignCallSingle, foreignMinor: ForeignCallSingle) {
297
+ const major = fromSingle(foreignMajor).toNumber();
298
+ const minor = fromSingle(foreignMinor).toNumber();
251
299
 
252
- this.handlerAsMisc().utilityAssertCompatibleOracleVersion(version);
300
+ this.handlerAsMisc().assertCompatibleOracleVersion(major, minor);
253
301
 
254
302
  return toForeignCallResult([]);
255
303
  }
256
304
 
257
- utilityGetRandomField() {
258
- const randomField = this.handlerAsMisc().utilityGetRandomField();
305
+ // eslint-disable-next-line camelcase
306
+ aztec_utl_getRandomField() {
307
+ const randomField = this.handlerAsMisc().getRandomField();
259
308
 
260
309
  return toForeignCallResult([toSingle(randomField)]);
261
310
  }
262
311
 
263
- async txeGetLastBlockTimestamp() {
264
- const timestamp = await this.handlerAsTxe().txeGetLastBlockTimestamp();
312
+ // eslint-disable-next-line camelcase
313
+ async aztec_txe_getLastBlockTimestamp() {
314
+ const timestamp = await this.handlerAsTxe().getLastBlockTimestamp();
265
315
 
266
316
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
267
317
  }
268
318
 
269
- async txeGetLastTxEffects() {
270
- const { txHash, noteHashes, nullifiers } = await this.handlerAsTxe().txeGetLastTxEffects();
319
+ // eslint-disable-next-line camelcase
320
+ async aztec_txe_getLastTxEffects() {
321
+ const { txHash, noteHashes, nullifiers, privateLogs } = await this.handlerAsTxe().getLastTxEffects();
322
+
323
+ // Same workaround as `aztec_txe_getPrivateEvents`: Noir cannot yet return nested structs with arrays, so we return
324
+ // a flat multidimensional array plus per-log lengths and the total count, and reassemble into a
325
+ // `BoundedVec<BoundedVec<T>>` on the Noir side. Each log contributes only its emitted fields. The rest
326
+ // is zero-padded to `PRIVATE_LOG_SIZE_IN_FIELDS`.
327
+ const emittedLogs = privateLogs.map(log => log.getEmittedFields());
328
+
329
+ const rawLogStorage = emittedLogs
330
+ .map(fields => fields.concat(Array(PRIVATE_LOG_SIZE_IN_FIELDS - fields.length).fill(new Fr(0))))
331
+ .concat(
332
+ Array(MAX_PRIVATE_LOGS_PER_TX - emittedLogs.length).fill(Array(PRIVATE_LOG_SIZE_IN_FIELDS).fill(new Fr(0))),
333
+ )
334
+ .flat();
335
+
336
+ const logLengths = emittedLogs
337
+ .map(fields => new Fr(fields.length))
338
+ .concat(Array(MAX_PRIVATE_LOGS_PER_TX - emittedLogs.length).fill(new Fr(0)));
339
+
340
+ const logCount = new Fr(emittedLogs.length);
271
341
 
272
342
  return toForeignCallResult([
273
343
  toSingle(txHash.hash),
274
344
  ...arrayToBoundedVec(toArray(noteHashes), MAX_NOTE_HASHES_PER_TX),
275
345
  ...arrayToBoundedVec(toArray(nullifiers), MAX_NULLIFIERS_PER_TX),
346
+ toArray(rawLogStorage),
347
+ toArray(logLengths),
348
+ toSingle(logCount),
276
349
  ]);
277
350
  }
278
351
 
279
- async txeGetPrivateEvents(
352
+ // eslint-disable-next-line camelcase
353
+ aztec_txe_getLastCallOffchainEffects() {
354
+ const { effects } = this.stateHandler.getLastCallOffchainEffects();
355
+
356
+ const rawArrayStorage = effects
357
+ .map(e => e.concat(Array(MAX_OFFCHAIN_EFFECT_LEN - e.length).fill(new Fr(0))))
358
+ .concat(
359
+ Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(Array(MAX_OFFCHAIN_EFFECT_LEN).fill(new Fr(0))),
360
+ )
361
+ .flat();
362
+
363
+ const effectLengths = effects
364
+ .map(e => new Fr(e.length))
365
+ .concat(Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(new Fr(0)));
366
+
367
+ const count = new Fr(effects.length);
368
+
369
+ return toForeignCallResult([toArray(rawArrayStorage), toArray(effectLengths), toSingle(count)]);
370
+ }
371
+
372
+ // eslint-disable-next-line camelcase
373
+ aztec_txe_getLastCallContext() {
374
+ const { txHash, anchorBlockTimestamp } = this.stateHandler.getLastCallContext();
375
+ const isSome = txHash.isZero() ? 0 : 1;
376
+ return toForeignCallResult([toSingle(isSome), toSingle(txHash), toSingle(new Fr(anchorBlockTimestamp))]);
377
+ }
378
+
379
+ // eslint-disable-next-line camelcase
380
+ async aztec_txe_getPrivateEvents(
280
381
  foreignSelector: ForeignCallSingle,
281
382
  foreignContractAddress: ForeignCallSingle,
282
383
  foreignScope: ForeignCallSingle,
@@ -292,7 +393,7 @@ export class RPCTranslator {
292
393
  await this.stateHandler.cycleJob();
293
394
  }
294
395
 
295
- const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
396
+ const events = await this.handlerAsTxe().getPrivateEvents(selector, contractAddress, scope);
296
397
 
297
398
  if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
298
399
  throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
@@ -316,26 +417,29 @@ export class RPCTranslator {
316
417
  return toForeignCallResult([toArray(rawArrayStorage), toArray(eventLengths), toSingle(queryLength)]);
317
418
  }
318
419
 
319
- privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
420
+ // eslint-disable-next-line camelcase
421
+ aztec_prv_setHashPreimage(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
320
422
  const values = fromArray(foreignValues);
321
423
  const hash = fromSingle(foreignHash);
322
424
 
323
- this.handlerAsPrivate().privateStoreInExecutionCache(values, hash);
425
+ this.handlerAsPrivate().setHashPreimage(values, hash);
324
426
 
325
427
  return toForeignCallResult([]);
326
428
  }
327
429
 
328
- async privateLoadFromExecutionCache(foreignHash: ForeignCallSingle) {
430
+ // eslint-disable-next-line camelcase
431
+ async aztec_prv_getHashPreimage(foreignHash: ForeignCallSingle) {
329
432
  const hash = fromSingle(foreignHash);
330
433
 
331
- const returns = await this.handlerAsPrivate().privateLoadFromExecutionCache(hash);
434
+ const returns = await this.handlerAsPrivate().getHashPreimage(hash);
332
435
 
333
436
  return toForeignCallResult([toArray(returns)]);
334
437
  }
335
438
 
336
439
  // When the argument is a slice, noir automatically adds a length field to oracle call.
337
440
  // When the argument is an array, we add the field length manually to the signature.
338
- async utilityLog(
441
+ // eslint-disable-next-line camelcase
442
+ async aztec_utl_log(
339
443
  foreignLevel: ForeignCallSingle,
340
444
  foreignMessage: ForeignCallArray,
341
445
  _foreignLength: ForeignCallSingle,
@@ -347,23 +451,24 @@ export class RPCTranslator {
347
451
  .join('');
348
452
  const fields = fromArray(foreignFields);
349
453
 
350
- await this.handlerAsMisc().utilityLog(level, message, fields);
454
+ await this.handlerAsMisc().log(level, message, fields);
351
455
 
352
456
  return toForeignCallResult([]);
353
457
  }
354
458
 
355
- async utilityStorageRead(
459
+ // eslint-disable-next-line camelcase
460
+ async aztec_utl_getFromPublicStorage(
356
461
  foreignBlockHash: ForeignCallSingle,
357
462
  foreignContractAddress: ForeignCallSingle,
358
463
  foreignStartStorageSlot: ForeignCallSingle,
359
464
  foreignNumberOfElements: ForeignCallSingle,
360
465
  ) {
361
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
466
+ const blockHash = blockHashFromSingle(foreignBlockHash);
362
467
  const contractAddress = addressFromSingle(foreignContractAddress);
363
468
  const startStorageSlot = fromSingle(foreignStartStorageSlot);
364
469
  const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
365
470
 
366
- const values = await this.handlerAsUtility().utilityStorageRead(
471
+ const values = await this.handlerAsUtility().getFromPublicStorage(
367
472
  blockHash,
368
473
  contractAddress,
369
474
  startStorageSlot,
@@ -373,19 +478,17 @@ export class RPCTranslator {
373
478
  return toForeignCallResult([toArray(values)]);
374
479
  }
375
480
 
376
- async utilityGetPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
377
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
481
+ // eslint-disable-next-line camelcase
482
+ async aztec_utl_getPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
483
+ const blockHash = blockHashFromSingle(foreignBlockHash);
378
484
  const leafSlot = fromSingle(foreignLeafSlot);
379
485
 
380
- const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockHash, leafSlot);
381
-
382
- if (!witness) {
383
- throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockHash.toString()}.`);
384
- }
486
+ const witness = await this.handlerAsUtility().getPublicDataWitness(blockHash, leafSlot);
385
487
  return toForeignCallResult(witness.toNoirRepresentation());
386
488
  }
387
489
 
388
- async utilityGetNotes(
490
+ // eslint-disable-next-line camelcase
491
+ async aztec_utl_getNotes(
389
492
  foreignOwnerIsSome: ForeignCallSingle,
390
493
  foreignOwnerValue: ForeignCallSingle,
391
494
  foreignStorageSlot: ForeignCallSingle,
@@ -407,8 +510,8 @@ export class RPCTranslator {
407
510
  ) {
408
511
  // Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
409
512
  const owner = fromSingle(foreignOwnerIsSome).toBool()
410
- ? AztecAddress.fromField(fromSingle(foreignOwnerValue))
411
- : undefined;
513
+ ? Option.some(AztecAddress.fromField(fromSingle(foreignOwnerValue)))
514
+ : Option.none(AztecAddress.ZERO);
412
515
  const storageSlot = fromSingle(foreignStorageSlot);
413
516
  const numSelects = fromSingle(foreignNumSelects).toNumber();
414
517
  const selectByIndexes = fromArray(foreignSelectByIndexes).map(fr => fr.toNumber());
@@ -426,7 +529,7 @@ export class RPCTranslator {
426
529
  const maxNotes = fromSingle(foreignMaxNotes).toNumber();
427
530
  const packedHintedNoteLength = fromSingle(foreignPackedHintedNoteLength).toNumber();
428
531
 
429
- const noteDatas = await this.handlerAsUtility().utilityGetNotes(
532
+ const noteVec = await this.handlerAsUtility().getNotes(
430
533
  owner,
431
534
  storageSlot,
432
535
  numSelects,
@@ -442,9 +545,11 @@ export class RPCTranslator {
442
545
  limit,
443
546
  offset,
444
547
  status,
548
+ maxNotes,
549
+ packedHintedNoteLength,
445
550
  );
446
551
 
447
- const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
552
+ const returnDataAsArrayOfArrays = Array.from(noteVec.data).map(noteData =>
448
553
  packAsHintedNote({
449
554
  contractAddress: noteData.contractAddress,
450
555
  owner: noteData.owner,
@@ -456,18 +561,17 @@ export class RPCTranslator {
456
561
  }),
457
562
  );
458
563
 
459
- // Now we convert each sub-array to an array of ForeignCallSingles
460
564
  const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray =>
461
565
  subArray.map(toSingle),
462
566
  );
463
567
 
464
- // At last we convert the array of arrays to a bounded vec of arrays
465
568
  return toForeignCallResult(
466
569
  arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength),
467
570
  );
468
571
  }
469
572
 
470
- privateNotifyCreatedNote(
573
+ // eslint-disable-next-line camelcase
574
+ aztec_prv_notifyCreatedNote(
471
575
  foreignOwner: ForeignCallSingle,
472
576
  foreignStorageSlot: ForeignCallSingle,
473
577
  foreignRandomness: ForeignCallSingle,
@@ -484,20 +588,13 @@ export class RPCTranslator {
484
588
  const noteHash = fromSingle(foreignNoteHash);
485
589
  const counter = fromSingle(foreignCounter).toNumber();
486
590
 
487
- this.handlerAsPrivate().privateNotifyCreatedNote(
488
- owner,
489
- storageSlot,
490
- randomness,
491
- noteTypeId,
492
- note,
493
- noteHash,
494
- counter,
495
- );
591
+ this.handlerAsPrivate().notifyCreatedNote(owner, storageSlot, randomness, noteTypeId, note, noteHash, counter);
496
592
 
497
593
  return toForeignCallResult([]);
498
594
  }
499
595
 
500
- async privateNotifyNullifiedNote(
596
+ // eslint-disable-next-line camelcase
597
+ async aztec_prv_notifyNullifiedNote(
501
598
  foreignInnerNullifier: ForeignCallSingle,
502
599
  foreignNoteHash: ForeignCallSingle,
503
600
  foreignCounter: ForeignCallSingle,
@@ -506,40 +603,47 @@ export class RPCTranslator {
506
603
  const noteHash = fromSingle(foreignNoteHash);
507
604
  const counter = fromSingle(foreignCounter).toNumber();
508
605
 
509
- await this.handlerAsPrivate().privateNotifyNullifiedNote(innerNullifier, noteHash, counter);
606
+ await this.handlerAsPrivate().notifyNullifiedNote(innerNullifier, noteHash, counter);
510
607
 
511
608
  return toForeignCallResult([]);
512
609
  }
513
610
 
514
- async privateNotifyCreatedNullifier(foreignInnerNullifier: ForeignCallSingle) {
611
+ // eslint-disable-next-line camelcase
612
+ async aztec_prv_notifyCreatedNullifier(foreignInnerNullifier: ForeignCallSingle) {
515
613
  const innerNullifier = fromSingle(foreignInnerNullifier);
516
614
 
517
- await this.handlerAsPrivate().privateNotifyCreatedNullifier(innerNullifier);
615
+ await this.handlerAsPrivate().notifyCreatedNullifier(innerNullifier);
518
616
 
519
617
  return toForeignCallResult([]);
520
618
  }
521
619
 
522
- async privateIsNullifierPending(foreignInnerNullifier: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
620
+ // eslint-disable-next-line camelcase
621
+ async aztec_prv_isNullifierPending(
622
+ foreignInnerNullifier: ForeignCallSingle,
623
+ foreignContractAddress: ForeignCallSingle,
624
+ ) {
523
625
  const innerNullifier = fromSingle(foreignInnerNullifier);
524
626
  const contractAddress = addressFromSingle(foreignContractAddress);
525
627
 
526
- const isPending = await this.handlerAsPrivate().privateIsNullifierPending(innerNullifier, contractAddress);
628
+ const isPending = await this.handlerAsPrivate().isNullifierPending(innerNullifier, contractAddress);
527
629
 
528
630
  return toForeignCallResult([toSingle(new Fr(isPending))]);
529
631
  }
530
632
 
531
- async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
633
+ // eslint-disable-next-line camelcase
634
+ async aztec_utl_doesNullifierExist(foreignInnerNullifier: ForeignCallSingle) {
532
635
  const innerNullifier = fromSingle(foreignInnerNullifier);
533
636
 
534
- const exists = await this.handlerAsUtility().utilityCheckNullifierExists(innerNullifier);
637
+ const exists = await this.handlerAsUtility().doesNullifierExist(innerNullifier);
535
638
 
536
639
  return toForeignCallResult([toSingle(new Fr(exists))]);
537
640
  }
538
641
 
539
- async utilityGetContractInstance(foreignAddress: ForeignCallSingle) {
642
+ // eslint-disable-next-line camelcase
643
+ async aztec_utl_getContractInstance(foreignAddress: ForeignCallSingle) {
540
644
  const address = addressFromSingle(foreignAddress);
541
645
 
542
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
646
+ const instance = await this.handlerAsUtility().getContractInstance(address);
543
647
 
544
648
  return toForeignCallResult(
545
649
  [
@@ -547,267 +651,343 @@ export class RPCTranslator {
547
651
  instance.deployer.toField(),
548
652
  instance.currentContractClassId,
549
653
  instance.initializationHash,
654
+ instance.immutablesHash,
550
655
  ...instance.publicKeys.toFields(),
551
656
  ].map(toSingle),
552
657
  );
553
658
  }
554
659
 
555
- async utilityTryGetPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
660
+ // eslint-disable-next-line camelcase
661
+ async aztec_utl_getPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
556
662
  const address = addressFromSingle(foreignAddress);
557
663
 
558
- const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(address);
664
+ const result = await this.handlerAsUtility().getPublicKeysAndPartialAddress(address);
559
665
 
560
666
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
561
667
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
562
- if (result === undefined) {
668
+ if (!result.isSome()) {
563
669
  // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
564
- return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(13).fill(new Fr(0)))]);
670
+ // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, mspk_m_hash, fbpk_m_hash, partial_address] = 8 fields.
671
+ return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(8).fill(new Fr(0)))]);
565
672
  } else {
566
- // Data was found so we set `some` to 1 and return it along with `value`.
673
+ // The Noir side hand-decodes a `[Field; 8]` here (see aztec-nr/aztec/src/oracle/keys.nr), so we
674
+ // emit the 7-field PublicKeys shape + partial_address explicitly
675
+ // rather than going through `publicKeys.toFields()` (which is the struct-flattened 8-field
676
+ // wire for oracle returns that decode via struct shape).
677
+ const { publicKeys, partialAddress } = result.value;
567
678
  return toForeignCallResult([
568
679
  toSingle(new Fr(1)),
569
- toArray([...result.publicKeys.toFields(), result.partialAddress]),
680
+ toArray([
681
+ publicKeys.npkMHash,
682
+ publicKeys.ivpkM.x,
683
+ publicKeys.ivpkM.y,
684
+ publicKeys.ovpkMHash,
685
+ publicKeys.tpkMHash,
686
+ publicKeys.mspkMHash,
687
+ publicKeys.fbpkMHash,
688
+ partialAddress,
689
+ ]),
570
690
  ]);
571
691
  }
572
692
  }
573
693
 
574
- async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
694
+ // eslint-disable-next-line camelcase
695
+ async aztec_utl_getKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
575
696
  const pkMHash = fromSingle(foreignPkMHash);
576
697
 
577
- const keyValidationRequest = await this.handlerAsUtility().utilityGetKeyValidationRequest(pkMHash);
698
+ const keyValidationRequest = await this.handlerAsUtility().getKeyValidationRequest(pkMHash);
578
699
 
579
700
  return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
580
701
  }
581
702
 
582
- privateCallPrivateFunction(
583
- _foreignTargetContractAddress: ForeignCallSingle,
584
- _foreignFunctionSelector: ForeignCallSingle,
585
- _foreignArgsHash: ForeignCallSingle,
586
- _foreignSideEffectCounter: ForeignCallSingle,
587
- _foreignIsStaticCall: ForeignCallSingle,
703
+ // eslint-disable-next-line camelcase
704
+ async aztec_prv_callPrivateFunction(
705
+ foreignTargetContractAddress: ForeignCallSingle,
706
+ foreignFunctionSelector: ForeignCallSingle,
707
+ foreignArgsHash: ForeignCallSingle,
708
+ foreignSideEffectCounter: ForeignCallSingle,
709
+ foreignIsStaticCall: ForeignCallSingle,
588
710
  ) {
589
- throw new Error(
590
- 'Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead',
711
+ const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
712
+ const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
713
+ const argsHash = fromSingle(foreignArgsHash);
714
+ const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
715
+ const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
716
+
717
+ const { endSideEffectCounter, returnsHash } = await this.handlerAsPrivate().callPrivateFunction(
718
+ targetContractAddress,
719
+ functionSelector,
720
+ argsHash,
721
+ sideEffectCounter,
722
+ isStaticCall,
591
723
  );
724
+ return toForeignCallResult([[endSideEffectCounter, returnsHash].map(toSingle)]);
592
725
  }
593
726
 
594
- async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
595
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
727
+ // eslint-disable-next-line camelcase
728
+ async aztec_utl_getNullifierMembershipWitness(
729
+ foreignBlockHash: ForeignCallSingle,
730
+ foreignNullifier: ForeignCallSingle,
731
+ ) {
732
+ const blockHash = blockHashFromSingle(foreignBlockHash);
596
733
  const nullifier = fromSingle(foreignNullifier);
597
734
 
598
- const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
599
-
600
- if (!witness) {
601
- throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
602
- }
735
+ const witness = await this.handlerAsUtility().getNullifierMembershipWitness(blockHash, nullifier);
603
736
  return toForeignCallResult(witness.toNoirRepresentation());
604
737
  }
605
738
 
606
- async utilityGetAuthWitness(foreignMessageHash: ForeignCallSingle) {
739
+ // eslint-disable-next-line camelcase
740
+ async aztec_utl_getAuthWitness(foreignMessageHash: ForeignCallSingle) {
607
741
  const messageHash = fromSingle(foreignMessageHash);
608
742
 
609
- const authWitness = await this.handlerAsUtility().utilityGetAuthWitness(messageHash);
610
-
611
- if (!authWitness) {
612
- throw new Error(`Auth witness not found for message hash ${messageHash}.`);
613
- }
743
+ const authWitness = await this.handlerAsUtility().getAuthWitness(messageHash);
614
744
  return toForeignCallResult([toArray(authWitness)]);
615
745
  }
616
746
 
617
- public privateNotifyEnqueuedPublicFunctionCall(
618
- _foreignTargetContractAddress: ForeignCallSingle,
619
- _foreignCalldataHash: ForeignCallSingle,
620
- _foreignSideEffectCounter: ForeignCallSingle,
621
- _foreignIsStaticCall: ForeignCallSingle,
622
- ) {
623
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
624
- }
625
-
626
- public privateNotifySetPublicTeardownFunctionCall(
627
- _foreignTargetContractAddress: ForeignCallSingle,
628
- _foreignCalldataHash: ForeignCallSingle,
629
- _foreignSideEffectCounter: ForeignCallSingle,
630
- _foreignIsStaticCall: ForeignCallSingle,
631
- ) {
632
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
747
+ // eslint-disable-next-line camelcase
748
+ public async aztec_prv_assertValidPublicCalldata(foreignCalldataHash: ForeignCallSingle) {
749
+ const calldataHash = fromSingle(foreignCalldataHash);
750
+ await this.handlerAsPrivate().assertValidPublicCalldata(calldataHash);
751
+ return toForeignCallResult([]);
633
752
  }
634
753
 
635
- public privateNotifySetMinRevertibleSideEffectCounter(_foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
636
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
754
+ // eslint-disable-next-line camelcase
755
+ public async aztec_prv_notifyRevertiblePhaseStart(foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
756
+ const minRevertibleSideEffectCounter = fromSingle(foreignMinRevertibleSideEffectCounter).toNumber();
757
+ await this.handlerAsPrivate().notifyRevertiblePhaseStart(minRevertibleSideEffectCounter);
758
+ return toForeignCallResult([]);
637
759
  }
638
760
 
639
- public async privateIsSideEffectCounterRevertible(foreignSideEffectCounter: ForeignCallSingle) {
761
+ // eslint-disable-next-line camelcase
762
+ public async aztec_prv_isExecutionInRevertiblePhase(foreignSideEffectCounter: ForeignCallSingle) {
640
763
  const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
641
- const isRevertible = await this.handlerAsPrivate().privateIsSideEffectCounterRevertible(sideEffectCounter);
764
+ const isRevertible = await this.handlerAsPrivate().isExecutionInRevertiblePhase(sideEffectCounter);
642
765
  return toForeignCallResult([toSingle(new Fr(isRevertible))]);
643
766
  }
644
767
 
645
- utilityGetUtilityContext() {
646
- const context = this.handlerAsUtility().utilityGetUtilityContext();
768
+ // eslint-disable-next-line camelcase
769
+ aztec_utl_getUtilityContext() {
770
+ const context = this.handlerAsUtility().getUtilityContext();
647
771
 
648
772
  return toForeignCallResult(context.toNoirRepresentation());
649
773
  }
650
774
 
651
- async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
775
+ // eslint-disable-next-line camelcase
776
+ async aztec_utl_getBlockHeader(foreignBlockNumber: ForeignCallSingle) {
652
777
  const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
653
778
 
654
- const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
655
-
656
- if (!header) {
657
- throw new Error(`Block header not found for block ${blockNumber}.`);
658
- }
779
+ const header = await this.handlerAsUtility().getBlockHeader(blockNumber);
659
780
  return toForeignCallResult(header.toFields().map(toSingle));
660
781
  }
661
782
 
662
- async utilityGetNoteHashMembershipWitness(
783
+ // eslint-disable-next-line camelcase
784
+ async aztec_utl_getNoteHashMembershipWitness(
663
785
  foreignAnchorBlockHash: ForeignCallSingle,
664
786
  foreignNoteHash: ForeignCallSingle,
665
787
  ) {
666
- const blockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
788
+ const blockHash = blockHashFromSingle(foreignAnchorBlockHash);
667
789
  const noteHash = fromSingle(foreignNoteHash);
668
790
 
669
- const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, noteHash);
670
-
671
- if (!witness) {
672
- throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
673
- }
791
+ const witness = await this.handlerAsUtility().getNoteHashMembershipWitness(blockHash, noteHash);
674
792
  return toForeignCallResult(witness.toNoirRepresentation());
675
793
  }
676
794
 
677
- async utilityGetBlockHashMembershipWitness(
795
+ // eslint-disable-next-line camelcase
796
+ async aztec_utl_getBlockHashMembershipWitness(
678
797
  foreignAnchorBlockHash: ForeignCallSingle,
679
798
  foreignBlockHash: ForeignCallSingle,
680
799
  ) {
681
- const anchorBlockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
682
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
800
+ const anchorBlockHash = blockHashFromSingle(foreignAnchorBlockHash);
801
+ const blockHash = blockHashFromSingle(foreignBlockHash);
683
802
 
684
- const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(anchorBlockHash, blockHash);
685
-
686
- if (!witness) {
687
- throw new Error(
688
- `Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`,
689
- );
690
- }
691
- return toForeignCallResult(witness.toNoirRepresentation());
803
+ const witnessOpt = await this.handlerAsUtility().getBlockHashMembershipWitness(anchorBlockHash, blockHash);
804
+ const effective = witnessOpt.value ?? MembershipWitness.empty(ARCHIVE_HEIGHT);
805
+ return toForeignCallResult([toSingle(new Fr(witnessOpt.isSome() ? 1 : 0)), ...effective.toNoirRepresentation()]);
692
806
  }
693
807
 
694
- async utilityGetLowNullifierMembershipWitness(
808
+ // eslint-disable-next-line camelcase
809
+ async aztec_utl_getLowNullifierMembershipWitness(
695
810
  foreignBlockHash: ForeignCallSingle,
696
811
  foreignNullifier: ForeignCallSingle,
697
812
  ) {
698
- const blockHash = new BlockHash(fromSingle(foreignBlockHash));
813
+ const blockHash = blockHashFromSingle(foreignBlockHash);
699
814
  const nullifier = fromSingle(foreignNullifier);
700
815
 
701
- const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
702
-
703
- if (!witness) {
704
- throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
705
- }
816
+ const witness = await this.handlerAsUtility().getLowNullifierMembershipWitness(blockHash, nullifier);
706
817
  return toForeignCallResult(witness.toNoirRepresentation());
707
818
  }
708
819
 
709
- async utilityFetchTaggedLogs(foreignPendingTaggedLogArrayBaseSlot: ForeignCallSingle) {
710
- const pendingTaggedLogArrayBaseSlot = fromSingle(foreignPendingTaggedLogArrayBaseSlot);
711
-
712
- await this.handlerAsUtility().utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
713
-
714
- return toForeignCallResult([]);
820
+ // eslint-disable-next-line camelcase
821
+ async aztec_utl_getPendingTaggedLogs(foreignScope: ForeignCallSingle) {
822
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
823
+ const slot = await this.handlerAsUtility().getPendingTaggedLogs(scope);
824
+ return toForeignCallResult([toSingle(slot)]);
715
825
  }
716
826
 
717
- public async utilityValidateAndStoreEnqueuedNotesAndEvents(
718
- foreignContractAddress: ForeignCallSingle,
827
+ // eslint-disable-next-line camelcase
828
+ public async aztec_utl_validateAndStoreEnqueuedNotesAndEvents(
719
829
  foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
720
830
  foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
831
+ foreignScope: ForeignCallSingle,
721
832
  ) {
722
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
723
833
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
724
834
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
835
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
725
836
 
726
- await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
727
- contractAddress,
837
+ await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEvents(
728
838
  noteValidationRequestsArrayBaseSlot,
729
839
  eventValidationRequestsArrayBaseSlot,
840
+ scope,
730
841
  );
731
842
 
732
843
  return toForeignCallResult([]);
733
844
  }
734
845
 
735
- public async utilityBulkRetrieveLogs(
736
- foreignContractAddress: ForeignCallSingle,
737
- foreignLogRetrievalRequestsArrayBaseSlot: ForeignCallSingle,
738
- foreignLogRetrievalResponsesArrayBaseSlot: ForeignCallSingle,
739
- ) {
740
- const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
741
- const logRetrievalRequestsArrayBaseSlot = fromSingle(foreignLogRetrievalRequestsArrayBaseSlot);
742
- const logRetrievalResponsesArrayBaseSlot = fromSingle(foreignLogRetrievalResponsesArrayBaseSlot);
743
-
744
- await this.handlerAsUtility().utilityBulkRetrieveLogs(
745
- contractAddress,
746
- logRetrievalRequestsArrayBaseSlot,
747
- logRetrievalResponsesArrayBaseSlot,
748
- );
846
+ // eslint-disable-next-line camelcase
847
+ async aztec_utl_getLogsByTag(foreignRequestArrayBaseSlot: ForeignCallSingle) {
848
+ const requestArrayBaseSlot = fromSingle(foreignRequestArrayBaseSlot);
849
+ const responseSlot = await this.handlerAsUtility().getLogsByTag(requestArrayBaseSlot);
850
+ return toForeignCallResult([toSingle(responseSlot)]);
851
+ }
749
852
 
750
- return toForeignCallResult([]);
853
+ // eslint-disable-next-line camelcase
854
+ async aztec_utl_getMessageContextsByTxHash(foreignRequestArrayBaseSlot: ForeignCallSingle) {
855
+ const requestArrayBaseSlot = fromSingle(foreignRequestArrayBaseSlot);
856
+ const responseSlot = await this.handlerAsUtility().getMessageContextsByTxHash(requestArrayBaseSlot);
857
+ return toForeignCallResult([toSingle(responseSlot)]);
751
858
  }
752
859
 
753
- async utilityStoreCapsule(
860
+ // eslint-disable-next-line camelcase
861
+ aztec_utl_setCapsule(
754
862
  foreignContractAddress: ForeignCallSingle,
755
863
  foreignSlot: ForeignCallSingle,
756
864
  foreignCapsule: ForeignCallArray,
865
+ foreignScope: ForeignCallSingle,
757
866
  ) {
758
867
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
759
868
  const slot = fromSingle(foreignSlot);
760
869
  const capsule = fromArray(foreignCapsule);
870
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
761
871
 
762
- await this.handlerAsUtility().utilityStoreCapsule(contractAddress, slot, capsule);
872
+ this.handlerAsUtility().setCapsule(contractAddress, slot, capsule, scope);
763
873
 
764
874
  return toForeignCallResult([]);
765
875
  }
766
876
 
767
- async utilityLoadCapsule(
877
+ // eslint-disable-next-line camelcase
878
+ async aztec_utl_getCapsule(
768
879
  foreignContractAddress: ForeignCallSingle,
769
880
  foreignSlot: ForeignCallSingle,
770
881
  foreignTSize: ForeignCallSingle,
882
+ foreignScope: ForeignCallSingle,
771
883
  ) {
772
884
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
773
885
  const slot = fromSingle(foreignSlot);
774
886
  const tSize = fromSingle(foreignTSize).toNumber();
887
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
775
888
 
776
- const values = await this.handlerAsUtility().utilityLoadCapsule(contractAddress, slot);
889
+ const opt = await this.handlerAsUtility().getCapsule(contractAddress, slot, tSize, scope);
777
890
 
778
891
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
779
892
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
780
- if (values === null) {
893
+ if (opt.isSome()) {
894
+ // Data was found so we set `some` to 1 and return it along with `value`.
895
+ return toForeignCallResult([toSingle(new Fr(1)), toArray(Array.from(opt.value))]);
896
+ } else {
781
897
  // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
782
898
  return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(tSize).fill(new Fr(0)))]);
783
- } else {
784
- // Data was found so we set `some` to 1 and return it along with `value`.
785
- return toForeignCallResult([toSingle(new Fr(1)), toArray(values)]);
786
899
  }
787
900
  }
788
901
 
789
- async utilityDeleteCapsule(foreignContractAddress: ForeignCallSingle, foreignSlot: ForeignCallSingle) {
902
+ // eslint-disable-next-line camelcase
903
+ aztec_utl_deleteCapsule(
904
+ foreignContractAddress: ForeignCallSingle,
905
+ foreignSlot: ForeignCallSingle,
906
+ foreignScope: ForeignCallSingle,
907
+ ) {
790
908
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
791
909
  const slot = fromSingle(foreignSlot);
910
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
792
911
 
793
- await this.handlerAsUtility().utilityDeleteCapsule(contractAddress, slot);
912
+ this.handlerAsUtility().deleteCapsule(contractAddress, slot, scope);
794
913
 
795
914
  return toForeignCallResult([]);
796
915
  }
797
916
 
798
- async utilityCopyCapsule(
917
+ // eslint-disable-next-line camelcase
918
+ async aztec_utl_copyCapsule(
799
919
  foreignContractAddress: ForeignCallSingle,
800
920
  foreignSrcSlot: ForeignCallSingle,
801
921
  foreignDstSlot: ForeignCallSingle,
802
922
  foreignNumEntries: ForeignCallSingle,
923
+ foreignScope: ForeignCallSingle,
803
924
  ) {
804
925
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
805
926
  const srcSlot = fromSingle(foreignSrcSlot);
806
927
  const dstSlot = fromSingle(foreignDstSlot);
807
928
  const numEntries = fromSingle(foreignNumEntries).toNumber();
929
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
808
930
 
809
- await this.handlerAsUtility().utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
931
+ await this.handlerAsUtility().copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, scope);
932
+
933
+ return toForeignCallResult([]);
934
+ }
935
+
936
+ // eslint-disable-next-line camelcase
937
+ aztec_utl_pushEphemeral(foreignSlot: ForeignCallSingle, foreignElements: ForeignCallArray) {
938
+ const slot = fromSingle(foreignSlot);
939
+ const elements = fromArray(foreignElements);
940
+ const newLen = this.handlerAsUtility().pushEphemeral(slot, elements);
941
+ return toForeignCallResult([toSingle(new Fr(newLen))]);
942
+ }
943
+
944
+ // eslint-disable-next-line camelcase
945
+ aztec_utl_popEphemeral(foreignSlot: ForeignCallSingle) {
946
+ const slot = fromSingle(foreignSlot);
947
+ const element = this.handlerAsUtility().popEphemeral(slot);
948
+ return toForeignCallResult([toArray(element)]);
949
+ }
950
+
951
+ // eslint-disable-next-line camelcase
952
+ aztec_utl_getEphemeral(foreignSlot: ForeignCallSingle, foreignIndex: ForeignCallSingle) {
953
+ const slot = fromSingle(foreignSlot);
954
+ const index = fromSingle(foreignIndex).toNumber();
955
+ const element = this.handlerAsUtility().getEphemeral(slot, index);
956
+ return toForeignCallResult([toArray(element)]);
957
+ }
958
+
959
+ // eslint-disable-next-line camelcase
960
+ aztec_utl_setEphemeral(
961
+ foreignSlot: ForeignCallSingle,
962
+ foreignIndex: ForeignCallSingle,
963
+ foreignElements: ForeignCallArray,
964
+ ) {
965
+ const slot = fromSingle(foreignSlot);
966
+ const index = fromSingle(foreignIndex).toNumber();
967
+ const elements = fromArray(foreignElements);
968
+ this.handlerAsUtility().setEphemeral(slot, index, elements);
969
+ return toForeignCallResult([]);
970
+ }
971
+
972
+ // eslint-disable-next-line camelcase
973
+ aztec_utl_getEphemeralLen(foreignSlot: ForeignCallSingle) {
974
+ const slot = fromSingle(foreignSlot);
975
+ const len = this.handlerAsUtility().getEphemeralLen(slot);
976
+ return toForeignCallResult([toSingle(new Fr(len))]);
977
+ }
978
+
979
+ // eslint-disable-next-line camelcase
980
+ aztec_utl_removeEphemeral(foreignSlot: ForeignCallSingle, foreignIndex: ForeignCallSingle) {
981
+ const slot = fromSingle(foreignSlot);
982
+ const index = fromSingle(foreignIndex).toNumber();
983
+ this.handlerAsUtility().removeEphemeral(slot, index);
984
+ return toForeignCallResult([]);
985
+ }
810
986
 
987
+ // eslint-disable-next-line camelcase
988
+ aztec_utl_clearEphemeral(foreignSlot: ForeignCallSingle) {
989
+ const slot = fromSingle(foreignSlot);
990
+ this.handlerAsUtility().clearEphemeral(slot);
811
991
  return toForeignCallResult([]);
812
992
  }
813
993
 
@@ -815,74 +995,107 @@ export class RPCTranslator {
815
995
  // The compiler didn't throw an error, so it took me a while to learn of the existence of this file, and that I need
816
996
  // to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
817
997
  // existence of a txe_oracle method?
818
- async utilityAes128Decrypt(
998
+ // eslint-disable-next-line camelcase
999
+ async aztec_utl_decryptAes128(
819
1000
  foreignCiphertextBVecStorage: ForeignCallArray,
820
1001
  foreignCiphertextLength: ForeignCallSingle,
821
1002
  foreignIv: ForeignCallArray,
822
1003
  foreignSymKey: ForeignCallArray,
823
1004
  ) {
824
- const ciphertext = fromUintBoundedVec(foreignCiphertextBVecStorage, foreignCiphertextLength, 8);
1005
+ const capacity = foreignCiphertextBVecStorage.length;
1006
+ const ciphertextBuf = fromUintBoundedVec(foreignCiphertextBVecStorage, foreignCiphertextLength, 8);
1007
+ const ciphertext = BoundedVec.from<number>({ data: [...ciphertextBuf], maxLength: capacity });
825
1008
  const iv = fromUintArray(foreignIv, 8);
826
1009
  const symKey = fromUintArray(foreignSymKey, 8);
827
1010
 
828
- const plaintextBuffer = await this.handlerAsUtility().utilityAes128Decrypt(ciphertext, iv, symKey);
829
-
830
- return toForeignCallResult(
831
- arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length),
832
- );
1011
+ // Noir Option<BoundedVec> is encoded as [is_some: Field, storage: Field[], length: Field].
1012
+ const plaintextOpt = await this.handlerAsUtility().decryptAes128(ciphertext, iv, symKey);
1013
+ if (plaintextOpt.isSome()) {
1014
+ const [storage, length] = arrayToBoundedVec(bufferToU8Array(Buffer.from(plaintextOpt.value.data)), capacity);
1015
+ return toForeignCallResult([toSingle(new Fr(1)), storage, length]);
1016
+ } else {
1017
+ const zeroStorage = toArray(Array(capacity).fill(new Fr(0)));
1018
+ return toForeignCallResult([toSingle(new Fr(0)), zeroStorage, toSingle(new Fr(0))]);
1019
+ }
833
1020
  }
834
1021
 
835
- async utilityGetSharedSecret(
1022
+ // eslint-disable-next-line camelcase
1023
+ async aztec_utl_getSharedSecrets(
836
1024
  foreignAddress: ForeignCallSingle,
837
- foreignEphPKField0: ForeignCallSingle,
838
- foreignEphPKField1: ForeignCallSingle,
839
- foreignEphPKField2: ForeignCallSingle,
1025
+ foreignEphPksSlot: ForeignCallSingle,
1026
+ foreignContractAddress: ForeignCallSingle,
840
1027
  ) {
841
1028
  const address = AztecAddress.fromField(fromSingle(foreignAddress));
842
- const ephPK = Point.fromFields([
843
- fromSingle(foreignEphPKField0),
844
- fromSingle(foreignEphPKField1),
845
- fromSingle(foreignEphPKField2),
846
- ]);
1029
+ const ephPksSlot = fromSingle(foreignEphPksSlot);
1030
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
847
1031
 
848
- const secret = await this.handlerAsUtility().utilityGetSharedSecret(address, ephPK);
1032
+ const responseSlot = await this.handlerAsUtility().getSharedSecrets(address, ephPksSlot, contractAddress);
849
1033
 
850
- return toForeignCallResult(secret.toFields().map(toSingle));
1034
+ return toForeignCallResult([toSingle(responseSlot)]);
851
1035
  }
852
1036
 
853
- emitOffchainEffect(_foreignData: ForeignCallArray) {
854
- throw new Error('Offchain effects are not yet supported in the TestEnvironment');
1037
+ // eslint-disable-next-line camelcase
1038
+ aztec_utl_setContractSyncCacheInvalid(
1039
+ foreignContractAddress: ForeignCallSingle,
1040
+ foreignScopes: ForeignCallArray,
1041
+ foreignScopeCount: ForeignCallSingle,
1042
+ ) {
1043
+ const contractAddress = addressFromSingle(foreignContractAddress);
1044
+ const allFields = fromArray(foreignScopes);
1045
+ const count = fromSingle(foreignScopeCount).toNumber();
1046
+ const scopes = BoundedVec.from({
1047
+ data: allFields.slice(0, count).map(f => new AztecAddress(f)),
1048
+ maxLength: allFields.length,
1049
+ });
1050
+
1051
+ this.handlerAsUtility().setContractSyncCacheInvalid(contractAddress, scopes);
1052
+
1053
+ return Promise.resolve(toForeignCallResult([]));
1054
+ }
1055
+
1056
+ // eslint-disable-next-line camelcase
1057
+ aztec_utl_emitOffchainEffect(foreignData: ForeignCallArray) {
1058
+ // Record the raw payload against the currently-executing top-level call. The Noir side
1059
+ // (via `env.offchain_messages()`) is responsible for decoding the protocol-reserved prefix
1060
+ // (`OFFCHAIN_MESSAGE_IDENTIFIER`, recipient) and turning each payload into an `OffchainMessage` struct suitable
1061
+ // for `offchain_receive`.
1062
+ this.stateHandler.recordOffchainEffect(fromArray(foreignData));
1063
+ return Promise.resolve(toForeignCallResult([]));
855
1064
  }
856
1065
 
857
1066
  // AVM opcodes
858
1067
 
859
- avmOpcodeEmitPublicLog(_foreignMessage: ForeignCallArray) {
1068
+ // eslint-disable-next-line camelcase
1069
+ aztec_avm_emitPublicLog(_foreignMessage: ForeignCallArray) {
860
1070
  // TODO(#8811): Implement
861
1071
  return toForeignCallResult([]);
862
1072
  }
863
1073
 
864
- async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
1074
+ // eslint-disable-next-line camelcase
1075
+ async aztec_avm_storageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
865
1076
  const slot = fromSingle(foreignSlot);
866
1077
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
867
1078
 
868
- const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
1079
+ const value = (await this.handlerAsAvm().storageRead(slot, contractAddress)).value;
869
1080
 
870
1081
  return toForeignCallResult([toSingle(new Fr(value))]);
871
1082
  }
872
1083
 
873
- async avmOpcodeStorageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
1084
+ // eslint-disable-next-line camelcase
1085
+ async aztec_avm_storageWrite(foreignSlot: ForeignCallSingle, foreignValue: ForeignCallSingle) {
874
1086
  const slot = fromSingle(foreignSlot);
875
1087
  const value = fromSingle(foreignValue);
876
1088
 
877
- await this.handlerAsAvm().avmOpcodeStorageWrite(slot, value);
1089
+ await this.handlerAsAvm().storageWrite(slot, value);
878
1090
 
879
1091
  return toForeignCallResult([]);
880
1092
  }
881
1093
 
882
- async avmOpcodeGetContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
1094
+ // eslint-disable-next-line camelcase
1095
+ async aztec_avm_getContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
883
1096
  const address = addressFromSingle(foreignAddress);
884
1097
 
885
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1098
+ const instance = await this.handlerAsUtility().getContractInstance(address);
886
1099
 
887
1100
  return toForeignCallResult([
888
1101
  toSingle(instance.deployer),
@@ -891,10 +1104,11 @@ export class RPCTranslator {
891
1104
  ]);
892
1105
  }
893
1106
 
894
- async avmOpcodeGetContractInstanceClassId(foreignAddress: ForeignCallSingle) {
1107
+ // eslint-disable-next-line camelcase
1108
+ async aztec_avm_getContractInstanceClassId(foreignAddress: ForeignCallSingle) {
895
1109
  const address = addressFromSingle(foreignAddress);
896
1110
 
897
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1111
+ const instance = await this.handlerAsUtility().getContractInstance(address);
898
1112
 
899
1113
  return toForeignCallResult([
900
1114
  toSingle(instance.currentContractClassId),
@@ -903,10 +1117,11 @@ export class RPCTranslator {
903
1117
  ]);
904
1118
  }
905
1119
 
906
- async avmOpcodeGetContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
1120
+ // eslint-disable-next-line camelcase
1121
+ async aztec_avm_getContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
907
1122
  const address = addressFromSingle(foreignAddress);
908
1123
 
909
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
1124
+ const instance = await this.handlerAsUtility().getContractInstance(address);
910
1125
 
911
1126
  return toForeignCallResult([
912
1127
  toSingle(instance.initializationHash),
@@ -915,210 +1130,315 @@ export class RPCTranslator {
915
1130
  ]);
916
1131
  }
917
1132
 
918
- async avmOpcodeSender() {
919
- const sender = await this.handlerAsAvm().avmOpcodeSender();
1133
+ // eslint-disable-next-line camelcase
1134
+ async aztec_avm_getContractInstanceImmutablesHash(foreignAddress: ForeignCallSingle) {
1135
+ const address = addressFromSingle(foreignAddress);
1136
+
1137
+ const instance = await this.handlerAsUtility().getContractInstance(address);
1138
+
1139
+ return toForeignCallResult([
1140
+ toSingle(instance.immutablesHash),
1141
+ // AVM requires an extra boolean indicating the instance was found
1142
+ toSingle(new Fr(1)),
1143
+ ]);
1144
+ }
1145
+
1146
+ // eslint-disable-next-line camelcase
1147
+ async aztec_avm_sender() {
1148
+ const sender = await this.handlerAsAvm().sender();
920
1149
 
921
1150
  return toForeignCallResult([toSingle(sender)]);
922
1151
  }
923
1152
 
924
- async avmOpcodeEmitNullifier(foreignNullifier: ForeignCallSingle) {
1153
+ // eslint-disable-next-line camelcase
1154
+ async aztec_avm_emitNullifier(foreignNullifier: ForeignCallSingle) {
925
1155
  const nullifier = fromSingle(foreignNullifier);
926
1156
 
927
- await this.handlerAsAvm().avmOpcodeEmitNullifier(nullifier);
1157
+ await this.handlerAsAvm().emitNullifier(nullifier);
928
1158
 
929
1159
  return toForeignCallResult([]);
930
1160
  }
931
1161
 
932
- async avmOpcodeEmitNoteHash(foreignNoteHash: ForeignCallSingle) {
1162
+ // eslint-disable-next-line camelcase
1163
+ async aztec_avm_emitNoteHash(foreignNoteHash: ForeignCallSingle) {
933
1164
  const noteHash = fromSingle(foreignNoteHash);
934
1165
 
935
- await this.handlerAsAvm().avmOpcodeEmitNoteHash(noteHash);
1166
+ await this.handlerAsAvm().emitNoteHash(noteHash);
936
1167
 
937
1168
  return toForeignCallResult([]);
938
1169
  }
939
1170
 
940
- async avmOpcodeNullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
1171
+ // eslint-disable-next-line camelcase
1172
+ async aztec_avm_nullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
941
1173
  const siloedNullifier = fromSingle(foreignSiloedNullifier);
942
1174
 
943
- const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
1175
+ const exists = await this.handlerAsAvm().nullifierExists(siloedNullifier);
944
1176
 
945
1177
  return toForeignCallResult([toSingle(new Fr(exists))]);
946
1178
  }
947
1179
 
948
- async avmOpcodeAddress() {
949
- const contractAddress = await this.handlerAsAvm().avmOpcodeAddress();
1180
+ // eslint-disable-next-line camelcase
1181
+ async aztec_avm_address() {
1182
+ const contractAddress = await this.handlerAsAvm().address();
950
1183
 
951
1184
  return toForeignCallResult([toSingle(contractAddress.toField())]);
952
1185
  }
953
1186
 
954
- async avmOpcodeBlockNumber() {
955
- const blockNumber = await this.handlerAsAvm().avmOpcodeBlockNumber();
1187
+ // eslint-disable-next-line camelcase
1188
+ async aztec_avm_blockNumber() {
1189
+ const blockNumber = await this.handlerAsAvm().blockNumber();
956
1190
 
957
1191
  return toForeignCallResult([toSingle(new Fr(blockNumber))]);
958
1192
  }
959
1193
 
960
- async avmOpcodeTimestamp() {
961
- const timestamp = await this.handlerAsAvm().avmOpcodeTimestamp();
1194
+ // eslint-disable-next-line camelcase
1195
+ async aztec_avm_timestamp() {
1196
+ const timestamp = await this.handlerAsAvm().timestamp();
962
1197
 
963
1198
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
964
1199
  }
965
1200
 
966
- async avmOpcodeIsStaticCall() {
967
- const isStaticCall = await this.handlerAsAvm().avmOpcodeIsStaticCall();
1201
+ // eslint-disable-next-line camelcase
1202
+ async aztec_avm_isStaticCall() {
1203
+ const isStaticCall = await this.handlerAsAvm().isStaticCall();
968
1204
 
969
1205
  return toForeignCallResult([toSingle(new Fr(isStaticCall ? 1 : 0))]);
970
1206
  }
971
1207
 
972
- async avmOpcodeChainId() {
973
- const chainId = await this.handlerAsAvm().avmOpcodeChainId();
1208
+ // eslint-disable-next-line camelcase
1209
+ async aztec_avm_chainId() {
1210
+ const chainId = await this.handlerAsAvm().chainId();
974
1211
 
975
1212
  return toForeignCallResult([toSingle(chainId)]);
976
1213
  }
977
1214
 
978
- async avmOpcodeVersion() {
979
- const version = await this.handlerAsAvm().avmOpcodeVersion();
1215
+ // eslint-disable-next-line camelcase
1216
+ async aztec_avm_version() {
1217
+ const version = await this.handlerAsAvm().version();
980
1218
 
981
1219
  return toForeignCallResult([toSingle(version)]);
982
1220
  }
983
1221
 
984
- avmOpcodeReturndataSize() {
985
- throw new Error(
986
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
987
- );
1222
+ // eslint-disable-next-line camelcase
1223
+ async aztec_avm_returndataSize() {
1224
+ const result = await this.handlerAsAvm().returndataSize();
1225
+ return toForeignCallResult([toSingle(result)]);
988
1226
  }
989
1227
 
990
- avmOpcodeReturndataCopy(_foreignRdOffset: ForeignCallSingle, _foreignCopySize: ForeignCallSingle) {
991
- throw new Error(
992
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
993
- );
1228
+ // eslint-disable-next-line camelcase
1229
+ async aztec_avm_returndataCopy(foreignRdOffset: ForeignCallSingle, foreignCopySize: ForeignCallSingle) {
1230
+ const rdOffset = fromSingle(foreignRdOffset).toNumber();
1231
+ const copySize = fromSingle(foreignCopySize).toNumber();
1232
+ const result = await this.handlerAsAvm().returndataCopy(rdOffset, copySize);
1233
+ return toForeignCallResult([toArray(result)]);
994
1234
  }
995
1235
 
996
- avmOpcodeCall(
997
- _foreignL2Gas: ForeignCallSingle,
998
- _foreignDaGas: ForeignCallSingle,
999
- _foreignAddress: ForeignCallSingle,
1000
- _foreignLength: ForeignCallSingle,
1001
- _foreignArgs: ForeignCallArray,
1236
+ // eslint-disable-next-line camelcase
1237
+ async aztec_avm_call(
1238
+ foreignL2Gas: ForeignCallSingle,
1239
+ foreignDaGas: ForeignCallSingle,
1240
+ foreignAddress: ForeignCallSingle,
1241
+ foreignLength: ForeignCallSingle,
1242
+ foreignArgs: ForeignCallArray,
1002
1243
  ) {
1003
- throw new Error(
1004
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
1005
- );
1244
+ const l2Gas = fromSingle(foreignL2Gas).toNumber();
1245
+ const daGas = fromSingle(foreignDaGas).toNumber();
1246
+ const address = addressFromSingle(foreignAddress);
1247
+ const argsLength = fromSingle(foreignLength).toNumber();
1248
+ const args = fromArray(foreignArgs);
1249
+ const result = await this.handlerAsAvm().call(l2Gas, daGas, address, argsLength, args);
1250
+ return toForeignCallResult([toArray(result)]);
1006
1251
  }
1007
1252
 
1008
- avmOpcodeStaticCall(
1009
- _foreignL2Gas: ForeignCallSingle,
1010
- _foreignDaGas: ForeignCallSingle,
1011
- _foreignAddress: ForeignCallSingle,
1012
- _foreignLength: ForeignCallSingle,
1013
- _foreignArgs: ForeignCallArray,
1253
+ // eslint-disable-next-line camelcase
1254
+ async aztec_avm_staticCall(
1255
+ foreignL2Gas: ForeignCallSingle,
1256
+ foreignDaGas: ForeignCallSingle,
1257
+ foreignAddress: ForeignCallSingle,
1258
+ foreignLength: ForeignCallSingle,
1259
+ foreignArgs: ForeignCallArray,
1014
1260
  ) {
1015
- throw new Error(
1016
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
1017
- );
1261
+ const l2Gas = fromSingle(foreignL2Gas).toNumber();
1262
+ const daGas = fromSingle(foreignDaGas).toNumber();
1263
+ const address = addressFromSingle(foreignAddress);
1264
+ const argsLength = fromSingle(foreignLength).toNumber();
1265
+ const args = fromArray(foreignArgs);
1266
+ const result = await this.handlerAsAvm().staticCall(l2Gas, daGas, address, argsLength, args);
1267
+ return toForeignCallResult([toArray(result)]);
1018
1268
  }
1019
1269
 
1020
- avmOpcodeSuccessCopy() {
1021
- throw new Error(
1022
- 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
1023
- );
1270
+ // eslint-disable-next-line camelcase
1271
+ async aztec_avm_successCopy() {
1272
+ const result = await this.handlerAsAvm().successCopy();
1273
+ return toForeignCallResult([toSingle(result)]);
1024
1274
  }
1025
1275
 
1026
- async txePrivateCallNewFlow(
1027
- foreignFrom: ForeignCallSingle,
1276
+ // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize.
1277
+ // eslint-disable-next-line camelcase
1278
+ async aztec_txe_privateCallNewFlow(
1279
+ foreignFromIsSome: ForeignCallSingle,
1280
+ foreignFromValue: ForeignCallSingle,
1028
1281
  foreignTargetContractAddress: ForeignCallSingle,
1029
1282
  foreignFunctionSelector: ForeignCallSingle,
1030
1283
  foreignArgs: ForeignCallArray,
1031
1284
  foreignArgsHash: ForeignCallSingle,
1032
1285
  foreignIsStaticCall: ForeignCallSingle,
1286
+ foreignAdditionalScopes: ForeignCallArray,
1287
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1288
+ foreignGasSettings: ForeignCallArray,
1033
1289
  ) {
1034
- const from = addressFromSingle(foreignFrom);
1290
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1035
1291
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1036
1292
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1037
1293
  const args = fromArray(foreignArgs);
1038
1294
  const argsHash = fromSingle(foreignArgsHash);
1039
1295
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1040
-
1041
- const returnValues = await this.handlerAsTxe().txePrivateCallNewFlow(
1042
- from,
1043
- targetContractAddress,
1044
- functionSelector,
1045
- args,
1046
- argsHash,
1047
- isStaticCall,
1048
- this.stateHandler.getCurrentJob(),
1296
+ const additionalScopes = fromArray(foreignAdditionalScopes).map(field => AztecAddress.fromField(field));
1297
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1298
+ AztecAddress.fromField(field),
1049
1299
  );
1300
+ const gasSettings = GasSettings.fromFields(fromArray(foreignGasSettings));
1301
+
1302
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1303
+ const { returnValues, offchainEffects } = await this.handlerAsTxe().privateCallNewFlow(
1304
+ from,
1305
+ targetContractAddress,
1306
+ functionSelector,
1307
+ args,
1308
+ argsHash,
1309
+ isStaticCall,
1310
+ additionalScopes,
1311
+ this.stateHandler.getCurrentJob(),
1312
+ authorizedUtilityCallTargets,
1313
+ gasSettings,
1314
+ );
1315
+
1316
+ // Private execution collects offchain effects inside PXE's PrivateExecutionOracle rather than
1317
+ // round-tripping them through `aztec_utl_emitOffchainEffect`, so the session buffer is empty
1318
+ // at this point. Drain the effects from the execution tree into the session buffer so the
1319
+ // next `env.offchain_messages()` call in the test sees them.
1320
+ for (const data of offchainEffects) {
1321
+ this.stateHandler.recordOffchainEffect(data);
1322
+ }
1323
+
1324
+ // TODO(F-335): Avoid doing the following call here.
1325
+ await this.stateHandler.cycleJob();
1326
+
1327
+ if (isStaticCall) {
1328
+ // Static calls revert their checkpoint and mine no block, so there is no tx hash to tag
1329
+ // offchain effects with. Querying `getLastTxEffects()` here would return an unrelated
1330
+ // predecessor tx.
1331
+ return { result: returnValues };
1332
+ }
1333
+ const { txHash } = await this.handlerAsTxe().getLastTxEffects();
1334
+ return { result: returnValues, txHash: txHash.hash };
1335
+ });
1050
1336
 
1051
- // TODO(F-335): Avoid doing the following call here.
1052
- await this.stateHandler.cycleJob();
1053
1337
  return toForeignCallResult([toArray(returnValues)]);
1054
1338
  }
1055
1339
 
1056
- async txeExecuteUtilityFunction(
1340
+ // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize.
1341
+ // eslint-disable-next-line camelcase
1342
+ async aztec_txe_executeUtilityFunction(
1057
1343
  foreignTargetContractAddress: ForeignCallSingle,
1058
1344
  foreignFunctionSelector: ForeignCallSingle,
1059
1345
  foreignArgs: ForeignCallArray,
1346
+ foreignAuthorizedUtilityCallTargets: ForeignCallArray,
1060
1347
  ) {
1061
1348
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
1062
1349
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1063
1350
  const args = fromArray(foreignArgs);
1064
-
1065
- const returnValues = await this.handlerAsTxe().txeExecuteUtilityFunction(
1066
- targetContractAddress,
1067
- functionSelector,
1068
- args,
1069
- this.stateHandler.getCurrentJob(),
1351
+ const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field =>
1352
+ AztecAddress.fromField(field),
1070
1353
  );
1071
1354
 
1072
- // TODO(F-335): Avoid doing the following call here.
1073
- await this.stateHandler.cycleJob();
1355
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1356
+ const returnValues = await this.handlerAsTxe().executeUtilityFunction(
1357
+ targetContractAddress,
1358
+ functionSelector,
1359
+ args,
1360
+ this.stateHandler.getCurrentJob(),
1361
+ authorizedUtilityCallTargets,
1362
+ );
1363
+
1364
+ // TODO(F-335): Avoid doing the following call here.
1365
+ await this.stateHandler.cycleJob();
1366
+
1367
+ return { result: returnValues };
1368
+ });
1369
+
1074
1370
  return toForeignCallResult([toArray(returnValues)]);
1075
1371
  }
1076
1372
 
1077
- async txePublicCallNewFlow(
1078
- foreignFrom: ForeignCallSingle,
1373
+ // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize.
1374
+ // eslint-disable-next-line camelcase
1375
+ async aztec_txe_publicCallNewFlow(
1376
+ foreignFromIsSome: ForeignCallSingle,
1377
+ foreignFromValue: ForeignCallSingle,
1079
1378
  foreignAddress: ForeignCallSingle,
1080
1379
  foreignCalldata: ForeignCallArray,
1081
1380
  foreignIsStaticCall: ForeignCallSingle,
1381
+ foreignGasSettings: ForeignCallArray,
1082
1382
  ) {
1083
- const from = addressFromSingle(foreignFrom);
1383
+ const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined;
1084
1384
  const address = addressFromSingle(foreignAddress);
1085
1385
  const calldata = fromArray(foreignCalldata);
1086
1386
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1387
+ const gasSettings = GasSettings.fromFields(fromArray(foreignGasSettings));
1388
+
1389
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1390
+ const returnValues = await this.handlerAsTxe().publicCallNewFlow(
1391
+ from,
1392
+ address,
1393
+ calldata,
1394
+ isStaticCall,
1395
+ gasSettings,
1396
+ );
1397
+
1398
+ // TODO(F-335): Avoid doing the following call here.
1399
+ await this.stateHandler.cycleJob();
1087
1400
 
1088
- const returnValues = await this.handlerAsTxe().txePublicCallNewFlow(from, address, calldata, isStaticCall);
1401
+ if (isStaticCall) {
1402
+ // See equivalent branch in `aztec_txe_privateCallNewFlow`.
1403
+ return { result: returnValues };
1404
+ }
1405
+ const { txHash } = await this.handlerAsTxe().getLastTxEffects();
1406
+ return { result: returnValues, txHash: txHash.hash };
1407
+ });
1089
1408
 
1090
- // TODO(F-335): Avoid doing the following call here.
1091
- await this.stateHandler.cycleJob();
1092
1409
  return toForeignCallResult([toArray(returnValues)]);
1093
1410
  }
1094
1411
 
1095
- async privateGetSenderForTags() {
1096
- const sender = await this.handlerAsPrivate().privateGetSenderForTags();
1412
+ // eslint-disable-next-line camelcase
1413
+ async aztec_prv_getSenderForTags() {
1414
+ const senderOpt = await this.handlerAsPrivate().getSenderForTags();
1097
1415
 
1098
1416
  // Return a Noir Option struct with `some` and `value` fields
1099
- if (sender === undefined) {
1417
+ if (senderOpt.isSome()) {
1418
+ // Sender found, return Option with some=1 and value=sender address
1419
+ return toForeignCallResult([toSingle(1), toSingle(senderOpt.value)]);
1420
+ } else {
1100
1421
  // No sender found, return Option with some=0 and value=0
1101
1422
  return toForeignCallResult([toSingle(0), toSingle(0)]);
1102
- } else {
1103
- // Sender found, return Option with some=1 and value=sender address
1104
- return toForeignCallResult([toSingle(1), toSingle(sender)]);
1105
1423
  }
1106
1424
  }
1107
1425
 
1108
- async privateSetSenderForTags(foreignSenderForTags: ForeignCallSingle) {
1109
- const senderForTags = AztecAddress.fromField(fromSingle(foreignSenderForTags));
1426
+ // eslint-disable-next-line camelcase
1427
+ async aztec_prv_getNextAppTagAsSender(foreignSender: ForeignCallSingle, foreignRecipient: ForeignCallSingle) {
1428
+ const sender = AztecAddress.fromField(fromSingle(foreignSender));
1429
+ const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
1110
1430
 
1111
- await this.handlerAsPrivate().privateSetSenderForTags(senderForTags);
1431
+ const nextAppTag = await this.handlerAsPrivate().getNextAppTagAsSender(sender, recipient);
1112
1432
 
1113
- return toForeignCallResult([]);
1433
+ return toForeignCallResult([toSingle(nextAppTag.value)]);
1114
1434
  }
1115
1435
 
1116
- async privateGetNextAppTagAsSender(foreignSender: ForeignCallSingle, foreignRecipient: ForeignCallSingle) {
1117
- const sender = AztecAddress.fromField(fromSingle(foreignSender));
1118
- const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
1436
+ // eslint-disable-next-line camelcase
1437
+ async aztec_prv_getNextConstrainedTaggingIndex(foreignAppSiloedSecret: ForeignCallSingle) {
1438
+ const appSiloedSecret = fromSingle(foreignAppSiloedSecret);
1119
1439
 
1120
- const nextAppTag = await this.handlerAsPrivate().privateGetNextAppTagAsSender(sender, recipient);
1440
+ const index = await this.handlerAsPrivate().getNextConstrainedTaggingIndex(appSiloedSecret);
1121
1441
 
1122
- return toForeignCallResult([toSingle(nextAppTag.value)]);
1442
+ return toForeignCallResult([toSingle(new Fr(index))]);
1123
1443
  }
1124
1444
  }