@aztec/txe 0.0.1-commit.9b94fc1 → 0.0.1-commit.9badcec54

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 (78) hide show
  1. package/dest/constants.d.ts +3 -0
  2. package/dest/constants.d.ts.map +1 -0
  3. package/dest/constants.js +2 -0
  4. package/dest/index.d.ts +1 -1
  5. package/dest/index.d.ts.map +1 -1
  6. package/dest/index.js +91 -56
  7. package/dest/oracle/interfaces.d.ts +33 -29
  8. package/dest/oracle/interfaces.d.ts.map +1 -1
  9. package/dest/oracle/txe_oracle_public_context.d.ts +16 -16
  10. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  11. package/dest/oracle/txe_oracle_public_context.js +20 -22
  12. package/dest/oracle/txe_oracle_top_level_context.d.ts +42 -27
  13. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  14. package/dest/oracle/txe_oracle_top_level_context.js +232 -107
  15. package/dest/rpc_translator.d.ts +129 -79
  16. package/dest/rpc_translator.d.ts.map +1 -1
  17. package/dest/rpc_translator.js +465 -176
  18. package/dest/state_machine/archiver.d.ts +21 -52
  19. package/dest/state_machine/archiver.d.ts.map +1 -1
  20. package/dest/state_machine/archiver.js +67 -99
  21. package/dest/state_machine/dummy_p2p_client.d.ts +21 -15
  22. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  23. package/dest/state_machine/dummy_p2p_client.js +45 -25
  24. package/dest/state_machine/global_variable_builder.d.ts +11 -5
  25. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  26. package/dest/state_machine/global_variable_builder.js +21 -3
  27. package/dest/state_machine/index.d.ts +9 -7
  28. package/dest/state_machine/index.d.ts.map +1 -1
  29. package/dest/state_machine/index.js +45 -24
  30. package/dest/state_machine/mock_epoch_cache.d.ts +26 -8
  31. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  32. package/dest/state_machine/mock_epoch_cache.js +49 -9
  33. package/dest/state_machine/synchronizer.d.ts +6 -5
  34. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  35. package/dest/state_machine/synchronizer.js +8 -7
  36. package/dest/txe_session.d.ts +27 -15
  37. package/dest/txe_session.d.ts.map +1 -1
  38. package/dest/txe_session.js +173 -55
  39. package/dest/util/encoding.d.ts +688 -19
  40. package/dest/util/encoding.d.ts.map +1 -1
  41. package/dest/util/encoding.js +5 -1
  42. package/dest/util/txe_account_store.d.ts +10 -0
  43. package/dest/util/txe_account_store.d.ts.map +1 -0
  44. package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
  45. package/dest/util/txe_public_contract_data_source.d.ts +8 -8
  46. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  47. package/dest/util/txe_public_contract_data_source.js +13 -32
  48. package/dest/utils/block_creation.d.ts +21 -6
  49. package/dest/utils/block_creation.d.ts.map +1 -1
  50. package/dest/utils/block_creation.js +38 -4
  51. package/dest/utils/tx_effect_creation.d.ts +3 -3
  52. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  53. package/dest/utils/tx_effect_creation.js +4 -7
  54. package/package.json +18 -18
  55. package/src/constants.ts +3 -0
  56. package/src/index.ts +103 -63
  57. package/src/oracle/interfaces.ts +36 -32
  58. package/src/oracle/txe_oracle_public_context.ts +21 -28
  59. package/src/oracle/txe_oracle_top_level_context.ts +285 -149
  60. package/src/rpc_translator.ts +552 -193
  61. package/src/state_machine/archiver.ts +63 -117
  62. package/src/state_machine/dummy_p2p_client.ts +62 -33
  63. package/src/state_machine/global_variable_builder.ts +38 -6
  64. package/src/state_machine/index.ts +67 -22
  65. package/src/state_machine/mock_epoch_cache.ts +61 -14
  66. package/src/state_machine/synchronizer.ts +9 -8
  67. package/src/txe_session.ts +239 -104
  68. package/src/util/encoding.ts +6 -1
  69. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  70. package/src/util/txe_public_contract_data_source.ts +20 -47
  71. package/src/utils/block_creation.ts +49 -15
  72. package/src/utils/tx_effect_creation.ts +5 -12
  73. package/dest/util/txe_account_data_provider.d.ts +0 -10
  74. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  75. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  76. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
  77. package/dest/util/txe_contract_data_provider.js +0 -22
  78. package/src/util/txe_contract_data_provider.ts +0 -36
@@ -1,10 +1,12 @@
1
1
  import { Fr, Point } from '@aztec/aztec.js/fields';
2
2
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
3
- import { packAsRetrievedNote } from '@aztec/pxe/simulator';
4
- import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
3
+ import { BlockNumber } from '@aztec/foundation/branded-types';
4
+ import { packAsHintedNote } from '@aztec/pxe/simulator';
5
+ import { EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
5
6
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import { MerkleTreeId } from '@aztec/stdlib/trees';
7
- import { addressFromSingle, arrayOfArraysToBoundedVecOfArrays, arrayToBoundedVec, bufferToU8Array, fromArray, fromSingle, fromUintArray, fromUintBoundedVec, toArray, toForeignCallResult, toSingle } from './util/encoding.js';
7
+ import { addressFromSingle, arrayOfArraysToBoundedVecOfArrays, arrayToBoundedVec, blockHashFromSingle, bufferToU8Array, fromArray, fromSingle, fromUintArray, fromUintBoundedVec, toArray, toForeignCallResult, toSingle } from './util/encoding.js';
8
+ const MAX_EVENT_LEN = 10; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN
9
+ const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
8
10
  export class UnavailableOracleError extends Error {
9
11
  constructor(oracleName){
10
12
  super(`${oracleName} oracles not available with the current handler`);
@@ -58,53 +60,69 @@ export class RPCTranslator {
58
60
  return this.oracleHandler;
59
61
  }
60
62
  // TXE session state transition functions - these get handled by the state handler
61
- async txeSetTopLevelTXEContext() {
63
+ // eslint-disable-next-line camelcase
64
+ async aztec_txe_setTopLevelTXEContext() {
62
65
  await this.stateHandler.enterTopLevelState();
63
66
  return toForeignCallResult([]);
64
67
  }
65
- async txeSetPrivateTXEContext(foreignContractAddressIsSome, foreignContractAddressValue, foreignAnchorBlockNumberIsSome, foreignAnchorBlockNumberValue) {
68
+ // eslint-disable-next-line camelcase
69
+ async aztec_txe_setPrivateTXEContext(foreignContractAddressIsSome, foreignContractAddressValue, foreignAnchorBlockNumberIsSome, foreignAnchorBlockNumberValue) {
66
70
  const contractAddress = fromSingle(foreignContractAddressIsSome).toBool() ? AztecAddress.fromField(fromSingle(foreignContractAddressValue)) : undefined;
67
- const anchorBlockNumber = fromSingle(foreignAnchorBlockNumberIsSome).toBool() ? fromSingle(foreignAnchorBlockNumberValue).toNumber() : undefined;
71
+ const anchorBlockNumber = fromSingle(foreignAnchorBlockNumberIsSome).toBool() ? BlockNumber(fromSingle(foreignAnchorBlockNumberValue).toNumber()) : undefined;
68
72
  const privateContextInputs = await this.stateHandler.enterPrivateState(contractAddress, anchorBlockNumber);
69
73
  return toForeignCallResult(privateContextInputs.toFields().map(toSingle));
70
74
  }
71
- async txeSetPublicTXEContext(foreignContractAddressIsSome, foreignContractAddressValue) {
75
+ // eslint-disable-next-line camelcase
76
+ async aztec_txe_setPublicTXEContext(foreignContractAddressIsSome, foreignContractAddressValue) {
72
77
  const contractAddress = fromSingle(foreignContractAddressIsSome).toBool() ? AztecAddress.fromField(fromSingle(foreignContractAddressValue)) : undefined;
73
78
  await this.stateHandler.enterPublicState(contractAddress);
74
79
  return toForeignCallResult([]);
75
80
  }
76
- async txeSetUtilityTXEContext(foreignContractAddressIsSome, foreignContractAddressValue) {
81
+ // eslint-disable-next-line camelcase
82
+ async aztec_txe_setUtilityTXEContext(foreignContractAddressIsSome, foreignContractAddressValue) {
77
83
  const contractAddress = fromSingle(foreignContractAddressIsSome).toBool() ? AztecAddress.fromField(fromSingle(foreignContractAddressValue)) : undefined;
78
84
  await this.stateHandler.enterUtilityState(contractAddress);
79
85
  return toForeignCallResult([]);
80
86
  }
81
87
  // Other oracles - these get handled by the oracle handler
82
88
  // TXE-specific oracles
83
- async txeGetNextBlockNumber() {
84
- const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
89
+ // eslint-disable-next-line camelcase
90
+ aztec_txe_getDefaultAddress() {
91
+ const defaultAddress = this.handlerAsTxe().getDefaultAddress();
92
+ return toForeignCallResult([
93
+ toSingle(defaultAddress)
94
+ ]);
95
+ }
96
+ // eslint-disable-next-line camelcase
97
+ async aztec_txe_getNextBlockNumber() {
98
+ const nextBlockNumber = await this.handlerAsTxe().getNextBlockNumber();
85
99
  return toForeignCallResult([
86
100
  toSingle(nextBlockNumber)
87
101
  ]);
88
102
  }
89
- async txeGetNextBlockTimestamp() {
90
- const nextBlockTimestamp = await this.handlerAsTxe().txeGetNextBlockTimestamp();
103
+ // eslint-disable-next-line camelcase
104
+ async aztec_txe_getNextBlockTimestamp() {
105
+ const nextBlockTimestamp = await this.handlerAsTxe().getNextBlockTimestamp();
91
106
  return toForeignCallResult([
92
107
  toSingle(nextBlockTimestamp)
93
108
  ]);
94
109
  }
95
- async txeAdvanceBlocksBy(foreignBlocks) {
110
+ // eslint-disable-next-line camelcase
111
+ async aztec_txe_advanceBlocksBy(foreignBlocks) {
96
112
  const blocks = fromSingle(foreignBlocks).toNumber();
97
- await this.handlerAsTxe().txeAdvanceBlocksBy(blocks);
113
+ await this.handlerAsTxe().advanceBlocksBy(blocks);
98
114
  return toForeignCallResult([]);
99
115
  }
100
- txeAdvanceTimestampBy(foreignDuration) {
116
+ // eslint-disable-next-line camelcase
117
+ aztec_txe_advanceTimestampBy(foreignDuration) {
101
118
  const duration = fromSingle(foreignDuration).toBigInt();
102
- this.handlerAsTxe().txeAdvanceTimestampBy(duration);
119
+ this.handlerAsTxe().advanceTimestampBy(duration);
103
120
  return toForeignCallResult([]);
104
121
  }
105
- async txeDeploy(artifact, instance, foreignSecret) {
122
+ // eslint-disable-next-line camelcase
123
+ async aztec_txe_deploy(artifact, instance, foreignSecret) {
106
124
  const secret = fromSingle(foreignSecret);
107
- await this.handlerAsTxe().txeDeploy(artifact, instance, secret);
125
+ await this.handlerAsTxe().deploy(artifact, instance, secret);
108
126
  return toForeignCallResult([
109
127
  toArray([
110
128
  instance.salt,
@@ -115,96 +133,141 @@ export class RPCTranslator {
115
133
  ])
116
134
  ]);
117
135
  }
118
- async txeCreateAccount(foreignSecret) {
136
+ // eslint-disable-next-line camelcase
137
+ async aztec_txe_createAccount(foreignSecret) {
119
138
  const secret = fromSingle(foreignSecret);
120
- const completeAddress = await this.handlerAsTxe().txeCreateAccount(secret);
139
+ const completeAddress = await this.handlerAsTxe().createAccount(secret);
121
140
  return toForeignCallResult([
122
141
  toSingle(completeAddress.address),
123
142
  ...completeAddress.publicKeys.toFields().map(toSingle)
124
143
  ]);
125
144
  }
126
- async txeAddAccount(artifact, instance, foreignSecret) {
145
+ // eslint-disable-next-line camelcase
146
+ async aztec_txe_addAccount(artifact, instance, foreignSecret) {
127
147
  const secret = fromSingle(foreignSecret);
128
- const completeAddress = await this.handlerAsTxe().txeAddAccount(artifact, instance, secret);
148
+ const completeAddress = await this.handlerAsTxe().addAccount(artifact, instance, secret);
129
149
  return toForeignCallResult([
130
150
  toSingle(completeAddress.address),
131
151
  ...completeAddress.publicKeys.toFields().map(toSingle)
132
152
  ]);
133
153
  }
134
- async txeAddAuthWitness(foreignAddress, foreignMessageHash) {
154
+ // eslint-disable-next-line camelcase
155
+ async aztec_txe_addAuthWitness(foreignAddress, foreignMessageHash) {
135
156
  const address = addressFromSingle(foreignAddress);
136
157
  const messageHash = fromSingle(foreignMessageHash);
137
- await this.handlerAsTxe().txeAddAuthWitness(address, messageHash);
158
+ await this.handlerAsTxe().addAuthWitness(address, messageHash);
138
159
  return toForeignCallResult([]);
139
160
  }
140
161
  // PXE oracles
141
- utilityAssertCompatibleOracleVersion(foreignVersion) {
142
- const version = fromSingle(foreignVersion).toNumber();
143
- this.handlerAsMisc().utilityAssertCompatibleOracleVersion(version);
162
+ // eslint-disable-next-line camelcase
163
+ aztec_utl_assertCompatibleOracleVersionV2(foreignMajor, foreignMinor) {
164
+ const major = fromSingle(foreignMajor).toNumber();
165
+ const minor = fromSingle(foreignMinor).toNumber();
166
+ this.handlerAsMisc().assertCompatibleOracleVersion(major, minor);
144
167
  return toForeignCallResult([]);
145
168
  }
146
- utilityGetRandomField() {
147
- const randomField = this.handlerAsMisc().utilityGetRandomField();
169
+ // eslint-disable-next-line camelcase
170
+ aztec_utl_getRandomField() {
171
+ const randomField = this.handlerAsMisc().getRandomField();
148
172
  return toForeignCallResult([
149
173
  toSingle(randomField)
150
174
  ]);
151
175
  }
152
- async txeGetLastBlockTimestamp() {
153
- const timestamp = await this.handlerAsTxe().txeGetLastBlockTimestamp();
176
+ // eslint-disable-next-line camelcase
177
+ async aztec_txe_getLastBlockTimestamp() {
178
+ const timestamp = await this.handlerAsTxe().getLastBlockTimestamp();
154
179
  return toForeignCallResult([
155
180
  toSingle(new Fr(timestamp))
156
181
  ]);
157
182
  }
158
- async txeGetLastTxEffects() {
159
- const { txHash, noteHashes, nullifiers } = await this.handlerAsTxe().txeGetLastTxEffects();
183
+ // eslint-disable-next-line camelcase
184
+ async aztec_txe_getLastTxEffects() {
185
+ const { txHash, noteHashes, nullifiers } = await this.handlerAsTxe().getLastTxEffects();
160
186
  return toForeignCallResult([
161
187
  toSingle(txHash.hash),
162
188
  ...arrayToBoundedVec(toArray(noteHashes), MAX_NOTE_HASHES_PER_TX),
163
189
  ...arrayToBoundedVec(toArray(nullifiers), MAX_NULLIFIERS_PER_TX)
164
190
  ]);
165
191
  }
166
- privateStoreInExecutionCache(foreignValues, foreignHash) {
192
+ // eslint-disable-next-line camelcase
193
+ async aztec_txe_getPrivateEvents(foreignSelector, foreignContractAddress, foreignScope) {
194
+ const selector = EventSelector.fromField(fromSingle(foreignSelector));
195
+ const contractAddress = addressFromSingle(foreignContractAddress);
196
+ const scope = addressFromSingle(foreignScope);
197
+ // TODO(F-335): Avoid doing the following 2 calls here.
198
+ {
199
+ await this.handlerAsTxe().syncContractNonOracleMethod(contractAddress, scope, this.stateHandler.getCurrentJob());
200
+ // We cycle job to commit the stores after the contract sync.
201
+ await this.stateHandler.cycleJob();
202
+ }
203
+ const events = await this.handlerAsTxe().getPrivateEvents(selector, contractAddress, scope);
204
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
205
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
206
+ }
207
+ if (events.some((e)=>e.length > MAX_EVENT_LEN)) {
208
+ throw new Error(`Some private event has length larger than maxLen ${MAX_EVENT_LEN}`);
209
+ }
210
+ // This is a workaround as Noir does not currently let us return nested structs with arrays. We instead return a raw
211
+ // multidimensional array in get_private_events_oracle and create the BoundedVecs here.
212
+ const rawArrayStorage = events.map((e)=>e.concat(Array(MAX_EVENT_LEN - e.length).fill(new Fr(0)))).concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_EVENT_LEN).fill(new Fr(0)))).flat();
213
+ const eventLengths = events.map((e)=>new Fr(e.length)).concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(new Fr(0)));
214
+ const queryLength = new Fr(events.length);
215
+ return toForeignCallResult([
216
+ toArray(rawArrayStorage),
217
+ toArray(eventLengths),
218
+ toSingle(queryLength)
219
+ ]);
220
+ }
221
+ // eslint-disable-next-line camelcase
222
+ aztec_prv_setHashPreimage(foreignValues, foreignHash) {
167
223
  const values = fromArray(foreignValues);
168
224
  const hash = fromSingle(foreignHash);
169
- this.handlerAsPrivate().privateStoreInExecutionCache(values, hash);
225
+ this.handlerAsPrivate().setHashPreimage(values, hash);
170
226
  return toForeignCallResult([]);
171
227
  }
172
- async privateLoadFromExecutionCache(foreignHash) {
228
+ // eslint-disable-next-line camelcase
229
+ async aztec_prv_getHashPreimage(foreignHash) {
173
230
  const hash = fromSingle(foreignHash);
174
- const returns = await this.handlerAsPrivate().privateLoadFromExecutionCache(hash);
231
+ const returns = await this.handlerAsPrivate().getHashPreimage(hash);
175
232
  return toForeignCallResult([
176
233
  toArray(returns)
177
234
  ]);
178
235
  }
179
236
  // When the argument is a slice, noir automatically adds a length field to oracle call.
180
237
  // When the argument is an array, we add the field length manually to the signature.
181
- utilityDebugLog(foreignLevel, foreignMessage, _foreignLength, foreignFields) {
238
+ // eslint-disable-next-line camelcase
239
+ async aztec_utl_log(foreignLevel, foreignMessage, _foreignLength, foreignFields) {
182
240
  const level = fromSingle(foreignLevel).toNumber();
183
241
  const message = fromArray(foreignMessage).map((field)=>String.fromCharCode(field.toNumber())).join('');
184
242
  const fields = fromArray(foreignFields);
185
- this.handlerAsMisc().utilityDebugLog(level, message, fields);
243
+ await this.handlerAsMisc().log(level, message, fields);
186
244
  return toForeignCallResult([]);
187
245
  }
188
- async utilityStorageRead(foreignContractAddress, foreignStartStorageSlot, foreignBlockNumber, foreignNumberOfElements) {
246
+ // eslint-disable-next-line camelcase
247
+ async aztec_utl_getFromPublicStorage(foreignBlockHash, foreignContractAddress, foreignStartStorageSlot, foreignNumberOfElements) {
248
+ const blockHash = blockHashFromSingle(foreignBlockHash);
189
249
  const contractAddress = addressFromSingle(foreignContractAddress);
190
250
  const startStorageSlot = fromSingle(foreignStartStorageSlot);
191
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
192
251
  const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
193
- const values = await this.handlerAsUtility().utilityStorageRead(contractAddress, startStorageSlot, blockNumber, numberOfElements);
252
+ const values = await this.handlerAsUtility().getFromPublicStorage(blockHash, contractAddress, startStorageSlot, numberOfElements);
194
253
  return toForeignCallResult([
195
254
  toArray(values)
196
255
  ]);
197
256
  }
198
- async utilityGetPublicDataWitness(foreignBlockNumber, foreignLeafSlot) {
199
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
257
+ // eslint-disable-next-line camelcase
258
+ async aztec_utl_getPublicDataWitness(foreignBlockHash, foreignLeafSlot) {
259
+ const blockHash = blockHashFromSingle(foreignBlockHash);
200
260
  const leafSlot = fromSingle(foreignLeafSlot);
201
- const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockNumber, leafSlot);
261
+ const witness = await this.handlerAsUtility().getPublicDataWitness(blockHash, leafSlot);
202
262
  if (!witness) {
203
- throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockNumber}.`);
263
+ throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockHash.toString()}.`);
204
264
  }
205
265
  return toForeignCallResult(witness.toNoirRepresentation());
206
266
  }
207
- async utilityGetNotes(foreignStorageSlot, foreignNumSelects, foreignSelectByIndexes, foreignSelectByOffsets, foreignSelectByLengths, foreignSelectValues, foreignSelectComparators, foreignSortByIndexes, foreignSortByOffsets, foreignSortByLengths, foreignSortOrder, foreignLimit, foreignOffset, foreignStatus, foreignMaxNotes, foreignPackedRetrievedNoteLength) {
267
+ // eslint-disable-next-line camelcase
268
+ async aztec_utl_getNotes(foreignOwnerIsSome, foreignOwnerValue, foreignStorageSlot, foreignNumSelects, foreignSelectByIndexes, foreignSelectByOffsets, foreignSelectByLengths, foreignSelectValues, foreignSelectComparators, foreignSortByIndexes, foreignSortByOffsets, foreignSortByLengths, foreignSortOrder, foreignLimit, foreignOffset, foreignStatus, foreignMaxNotes, foreignPackedHintedNoteLength) {
269
+ // Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
270
+ const owner = fromSingle(foreignOwnerIsSome).toBool() ? AztecAddress.fromField(fromSingle(foreignOwnerValue)) : undefined;
208
271
  const storageSlot = fromSingle(foreignStorageSlot);
209
272
  const numSelects = fromSingle(foreignNumSelects).toNumber();
210
273
  const selectByIndexes = fromArray(foreignSelectByIndexes).map((fr)=>fr.toNumber());
@@ -220,46 +283,69 @@ export class RPCTranslator {
220
283
  const offset = fromSingle(foreignOffset).toNumber();
221
284
  const status = fromSingle(foreignStatus).toNumber();
222
285
  const maxNotes = fromSingle(foreignMaxNotes).toNumber();
223
- const packedRetrievedNoteLength = fromSingle(foreignPackedRetrievedNoteLength).toNumber();
224
- const noteDatas = await this.handlerAsUtility().utilityGetNotes(storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, status);
225
- const returnDataAsArrayOfArrays = noteDatas.map(packAsRetrievedNote);
286
+ const packedHintedNoteLength = fromSingle(foreignPackedHintedNoteLength).toNumber();
287
+ const noteDatas = await this.handlerAsUtility().getNotes(owner, storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, status);
288
+ const returnDataAsArrayOfArrays = noteDatas.map((noteData)=>packAsHintedNote({
289
+ contractAddress: noteData.contractAddress,
290
+ owner: noteData.owner,
291
+ randomness: noteData.randomness,
292
+ storageSlot: noteData.storageSlot,
293
+ noteNonce: noteData.noteNonce,
294
+ isPending: noteData.isPending,
295
+ note: noteData.note
296
+ }));
226
297
  // Now we convert each sub-array to an array of ForeignCallSingles
227
298
  const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map((subArray)=>subArray.map(toSingle));
228
299
  // At last we convert the array of arrays to a bounded vec of arrays
229
- return toForeignCallResult(arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedRetrievedNoteLength));
300
+ return toForeignCallResult(arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength));
230
301
  }
231
- privateNotifyCreatedNote(foreignStorageSlot, foreignRandomness, foreignNoteTypeId, foreignNote, foreignNoteHash, foreignCounter) {
302
+ // eslint-disable-next-line camelcase
303
+ aztec_prv_notifyCreatedNote(foreignOwner, foreignStorageSlot, foreignRandomness, foreignNoteTypeId, foreignNote, foreignNoteHash, foreignCounter) {
304
+ const owner = addressFromSingle(foreignOwner);
232
305
  const storageSlot = fromSingle(foreignStorageSlot);
233
306
  const randomness = fromSingle(foreignRandomness);
234
307
  const noteTypeId = NoteSelector.fromField(fromSingle(foreignNoteTypeId));
235
308
  const note = fromArray(foreignNote);
236
309
  const noteHash = fromSingle(foreignNoteHash);
237
310
  const counter = fromSingle(foreignCounter).toNumber();
238
- this.handlerAsPrivate().privateNotifyCreatedNote(storageSlot, randomness, noteTypeId, note, noteHash, counter);
311
+ this.handlerAsPrivate().notifyCreatedNote(owner, storageSlot, randomness, noteTypeId, note, noteHash, counter);
239
312
  return toForeignCallResult([]);
240
313
  }
241
- async privateNotifyNullifiedNote(foreignInnerNullifier, foreignNoteHash, foreignCounter) {
314
+ // eslint-disable-next-line camelcase
315
+ async aztec_prv_notifyNullifiedNote(foreignInnerNullifier, foreignNoteHash, foreignCounter) {
242
316
  const innerNullifier = fromSingle(foreignInnerNullifier);
243
317
  const noteHash = fromSingle(foreignNoteHash);
244
318
  const counter = fromSingle(foreignCounter).toNumber();
245
- await this.handlerAsPrivate().privateNotifyNullifiedNote(innerNullifier, noteHash, counter);
319
+ await this.handlerAsPrivate().notifyNullifiedNote(innerNullifier, noteHash, counter);
246
320
  return toForeignCallResult([]);
247
321
  }
248
- async privateNotifyCreatedNullifier(foreignInnerNullifier) {
322
+ // eslint-disable-next-line camelcase
323
+ async aztec_prv_notifyCreatedNullifier(foreignInnerNullifier) {
249
324
  const innerNullifier = fromSingle(foreignInnerNullifier);
250
- await this.handlerAsPrivate().privateNotifyCreatedNullifier(innerNullifier);
325
+ await this.handlerAsPrivate().notifyCreatedNullifier(innerNullifier);
251
326
  return toForeignCallResult([]);
252
327
  }
253
- async utilityCheckNullifierExists(foreignInnerNullifier) {
328
+ // eslint-disable-next-line camelcase
329
+ async aztec_prv_isNullifierPending(foreignInnerNullifier, foreignContractAddress) {
330
+ const innerNullifier = fromSingle(foreignInnerNullifier);
331
+ const contractAddress = addressFromSingle(foreignContractAddress);
332
+ const isPending = await this.handlerAsPrivate().isNullifierPending(innerNullifier, contractAddress);
333
+ return toForeignCallResult([
334
+ toSingle(new Fr(isPending))
335
+ ]);
336
+ }
337
+ // eslint-disable-next-line camelcase
338
+ async aztec_utl_doesNullifierExist(foreignInnerNullifier) {
254
339
  const innerNullifier = fromSingle(foreignInnerNullifier);
255
- const exists = await this.handlerAsUtility().utilityCheckNullifierExists(innerNullifier);
340
+ const exists = await this.handlerAsUtility().doesNullifierExist(innerNullifier);
256
341
  return toForeignCallResult([
257
342
  toSingle(new Fr(exists))
258
343
  ]);
259
344
  }
260
- async utilityGetContractInstance(foreignAddress) {
345
+ // eslint-disable-next-line camelcase
346
+ async aztec_utl_getContractInstance(foreignAddress) {
261
347
  const address = addressFromSingle(foreignAddress);
262
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
348
+ const instance = await this.handlerAsUtility().getContractInstance(address);
263
349
  return toForeignCallResult([
264
350
  instance.salt,
265
351
  instance.deployer.toField(),
@@ -268,36 +354,53 @@ export class RPCTranslator {
268
354
  ...instance.publicKeys.toFields()
269
355
  ].map(toSingle));
270
356
  }
271
- async utilityGetPublicKeysAndPartialAddress(foreignAddress) {
357
+ // eslint-disable-next-line camelcase
358
+ async aztec_utl_getPublicKeysAndPartialAddress(foreignAddress) {
272
359
  const address = addressFromSingle(foreignAddress);
273
- const { publicKeys, partialAddress } = await this.handlerAsUtility().utilityGetPublicKeysAndPartialAddress(address);
274
- return toForeignCallResult([
275
- toArray([
276
- ...publicKeys.toFields(),
277
- partialAddress
278
- ])
279
- ]);
360
+ const result = await this.handlerAsUtility().getPublicKeysAndPartialAddress(address);
361
+ // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
362
+ // with two fields: `some` (a boolean) and `value` (a field array in this case).
363
+ if (result === undefined) {
364
+ // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
365
+ return toForeignCallResult([
366
+ toSingle(new Fr(0)),
367
+ toArray(Array(13).fill(new Fr(0)))
368
+ ]);
369
+ } else {
370
+ // Data was found so we set `some` to 1 and return it along with `value`.
371
+ return toForeignCallResult([
372
+ toSingle(new Fr(1)),
373
+ toArray([
374
+ ...result.publicKeys.toFields(),
375
+ result.partialAddress
376
+ ])
377
+ ]);
378
+ }
280
379
  }
281
- async utilityGetKeyValidationRequest(foreignPkMHash) {
380
+ // eslint-disable-next-line camelcase
381
+ async aztec_utl_getKeyValidationRequest(foreignPkMHash) {
282
382
  const pkMHash = fromSingle(foreignPkMHash);
283
- const keyValidationRequest = await this.handlerAsUtility().utilityGetKeyValidationRequest(pkMHash);
383
+ const keyValidationRequest = await this.handlerAsUtility().getKeyValidationRequest(pkMHash);
284
384
  return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
285
385
  }
286
- privateCallPrivateFunction(_foreignTargetContractAddress, _foreignFunctionSelector, _foreignArgsHash, _foreignSideEffectCounter, _foreignIsStaticCall) {
386
+ // eslint-disable-next-line camelcase
387
+ aztec_prv_callPrivateFunction(_foreignTargetContractAddress, _foreignFunctionSelector, _foreignArgsHash, _foreignSideEffectCounter, _foreignIsStaticCall) {
287
388
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead');
288
389
  }
289
- async utilityGetNullifierMembershipWitness(foreignBlockNumber, foreignNullifier) {
290
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
390
+ // eslint-disable-next-line camelcase
391
+ async aztec_utl_getNullifierMembershipWitness(foreignBlockHash, foreignNullifier) {
392
+ const blockHash = blockHashFromSingle(foreignBlockHash);
291
393
  const nullifier = fromSingle(foreignNullifier);
292
- const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockNumber, nullifier);
394
+ const witness = await this.handlerAsUtility().getNullifierMembershipWitness(blockHash, nullifier);
293
395
  if (!witness) {
294
- throw new Error(`Nullifier membership witness not found at block ${blockNumber}.`);
396
+ throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
295
397
  }
296
398
  return toForeignCallResult(witness.toNoirRepresentation());
297
399
  }
298
- async utilityGetAuthWitness(foreignMessageHash) {
400
+ // eslint-disable-next-line camelcase
401
+ async aztec_utl_getAuthWitness(foreignMessageHash) {
299
402
  const messageHash = fromSingle(foreignMessageHash);
300
- const authWitness = await this.handlerAsUtility().utilityGetAuthWitness(messageHash);
403
+ const authWitness = await this.handlerAsUtility().getAuthWitness(messageHash);
301
404
  if (!authWitness) {
302
405
  throw new Error(`Auth witness not found for message hash ${messageHash}.`);
303
406
  }
@@ -305,87 +408,152 @@ export class RPCTranslator {
305
408
  toArray(authWitness)
306
409
  ]);
307
410
  }
308
- privateNotifyEnqueuedPublicFunctionCall(_foreignTargetContractAddress, _foreignCalldataHash, _foreignSideEffectCounter, _foreignIsStaticCall) {
309
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
310
- }
311
- privateNotifySetPublicTeardownFunctionCall(_foreignTargetContractAddress, _foreignCalldataHash, _foreignSideEffectCounter, _foreignIsStaticCall) {
411
+ // eslint-disable-next-line camelcase
412
+ aztec_prv_assertValidPublicCalldata(_foreignCalldataHash) {
312
413
  throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
313
414
  }
314
- privateNotifySetMinRevertibleSideEffectCounter(_foreignMinRevertibleSideEffectCounter) {
415
+ // eslint-disable-next-line camelcase
416
+ aztec_prv_notifyRevertiblePhaseStart(_foreignMinRevertibleSideEffectCounter) {
315
417
  throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
316
418
  }
317
- async privateIsSideEffectCounterRevertible(foreignSideEffectCounter) {
419
+ // eslint-disable-next-line camelcase
420
+ async aztec_prv_isExecutionInRevertiblePhase(foreignSideEffectCounter) {
318
421
  const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
319
- const isRevertible = await this.handlerAsPrivate().privateIsSideEffectCounterRevertible(sideEffectCounter);
422
+ const isRevertible = await this.handlerAsPrivate().isExecutionInRevertiblePhase(sideEffectCounter);
320
423
  return toForeignCallResult([
321
424
  toSingle(new Fr(isRevertible))
322
425
  ]);
323
426
  }
324
- async utilityGetUtilityContext() {
325
- const context = await this.handlerAsUtility().utilityGetUtilityContext();
427
+ // eslint-disable-next-line camelcase
428
+ aztec_utl_getUtilityContext() {
429
+ const context = this.handlerAsUtility().getUtilityContext();
326
430
  return toForeignCallResult(context.toNoirRepresentation());
327
431
  }
328
- async utilityGetBlockHeader(foreignBlockNumber) {
329
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
330
- const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
432
+ // eslint-disable-next-line camelcase
433
+ async aztec_utl_getBlockHeader(foreignBlockNumber) {
434
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
435
+ const header = await this.handlerAsUtility().getBlockHeader(blockNumber);
331
436
  if (!header) {
332
437
  throw new Error(`Block header not found for block ${blockNumber}.`);
333
438
  }
334
439
  return toForeignCallResult(header.toFields().map(toSingle));
335
440
  }
336
- async utilityGetMembershipWitness(foreignBlockNumber, foreignTreeId, foreignLeafValue) {
337
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
338
- const treeId = fromSingle(foreignTreeId).toNumber();
339
- const leafValue = fromSingle(foreignLeafValue);
340
- const witness = await this.handlerAsUtility().utilityGetMembershipWitness(blockNumber, treeId, leafValue);
441
+ // eslint-disable-next-line camelcase
442
+ async aztec_utl_getNoteHashMembershipWitness(foreignAnchorBlockHash, foreignNoteHash) {
443
+ const blockHash = blockHashFromSingle(foreignAnchorBlockHash);
444
+ const noteHash = fromSingle(foreignNoteHash);
445
+ const witness = await this.handlerAsUtility().getNoteHashMembershipWitness(blockHash, noteHash);
341
446
  if (!witness) {
342
- throw new Error(`Membership witness in tree ${MerkleTreeId[treeId]} not found for value ${leafValue} at block ${blockNumber}.`);
447
+ throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
343
448
  }
344
- return toForeignCallResult([
345
- toSingle(witness[0]),
346
- toArray(witness.slice(1))
347
- ]);
449
+ return toForeignCallResult(witness.toNoirRepresentation());
450
+ }
451
+ // eslint-disable-next-line camelcase
452
+ async aztec_utl_getBlockHashMembershipWitness(foreignAnchorBlockHash, foreignBlockHash) {
453
+ const anchorBlockHash = blockHashFromSingle(foreignAnchorBlockHash);
454
+ const blockHash = blockHashFromSingle(foreignBlockHash);
455
+ const witness = await this.handlerAsUtility().getBlockHashMembershipWitness(anchorBlockHash, blockHash);
456
+ if (!witness) {
457
+ throw new Error(`Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`);
458
+ }
459
+ return toForeignCallResult(witness.toNoirRepresentation());
348
460
  }
349
- async utilityGetLowNullifierMembershipWitness(foreignBlockNumber, foreignNullifier) {
350
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
461
+ // eslint-disable-next-line camelcase
462
+ async aztec_utl_getLowNullifierMembershipWitness(foreignBlockHash, foreignNullifier) {
463
+ const blockHash = blockHashFromSingle(foreignBlockHash);
351
464
  const nullifier = fromSingle(foreignNullifier);
352
- const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);
465
+ const witness = await this.handlerAsUtility().getLowNullifierMembershipWitness(blockHash, nullifier);
353
466
  if (!witness) {
354
- throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockNumber}.`);
467
+ throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
355
468
  }
356
469
  return toForeignCallResult(witness.toNoirRepresentation());
357
470
  }
358
- async utilityFetchTaggedLogs(foreignPendingTaggedLogArrayBaseSlot) {
471
+ // eslint-disable-next-line camelcase
472
+ async aztec_utl_getPendingTaggedLogs(foreignPendingTaggedLogArrayBaseSlot, foreignScope) {
359
473
  const pendingTaggedLogArrayBaseSlot = fromSingle(foreignPendingTaggedLogArrayBaseSlot);
360
- await this.handlerAsUtility().utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
474
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
475
+ await this.handlerAsUtility().getPendingTaggedLogs(pendingTaggedLogArrayBaseSlot, scope);
361
476
  return toForeignCallResult([]);
362
477
  }
363
- async utilityValidateEnqueuedNotesAndEvents(foreignContractAddress, foreignNoteValidationRequestsArrayBaseSlot, foreignEventValidationRequestsArrayBaseSlot) {
478
+ // eslint-disable-next-line camelcase
479
+ async aztec_utl_getPendingTaggedLogs_v2(foreignScope) {
480
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
481
+ const slot = await this.handlerAsUtility().getPendingTaggedLogsV2(scope);
482
+ return toForeignCallResult([
483
+ toSingle(slot)
484
+ ]);
485
+ }
486
+ // eslint-disable-next-line camelcase
487
+ async aztec_utl_validateAndStoreEnqueuedNotesAndEvents(foreignContractAddress, foreignNoteValidationRequestsArrayBaseSlot, foreignEventValidationRequestsArrayBaseSlot, foreignMaxNotePackedLen, foreignMaxEventSerializedLen, foreignScope) {
364
488
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
365
489
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
366
490
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
367
- await this.handlerAsUtility().utilityValidateEnqueuedNotesAndEvents(contractAddress, noteValidationRequestsArrayBaseSlot, eventValidationRequestsArrayBaseSlot);
491
+ const maxNotePackedLen = fromSingle(foreignMaxNotePackedLen).toNumber();
492
+ const maxEventSerializedLen = fromSingle(foreignMaxEventSerializedLen).toNumber();
493
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
494
+ await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEvents(contractAddress, noteValidationRequestsArrayBaseSlot, eventValidationRequestsArrayBaseSlot, maxNotePackedLen, maxEventSerializedLen, scope);
495
+ return toForeignCallResult([]);
496
+ }
497
+ // eslint-disable-next-line camelcase
498
+ async aztec_utl_validateAndStoreEnqueuedNotesAndEvents_v2(foreignNoteValidationRequestsArrayBaseSlot, foreignEventValidationRequestsArrayBaseSlot, foreignMaxNotePackedLen, foreignMaxEventSerializedLen, foreignScope) {
499
+ const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
500
+ const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
501
+ const maxNotePackedLen = fromSingle(foreignMaxNotePackedLen).toNumber();
502
+ const maxEventSerializedLen = fromSingle(foreignMaxEventSerializedLen).toNumber();
503
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
504
+ await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEventsV2(noteValidationRequestsArrayBaseSlot, eventValidationRequestsArrayBaseSlot, maxNotePackedLen, maxEventSerializedLen, scope);
368
505
  return toForeignCallResult([]);
369
506
  }
370
- async utilityBulkRetrieveLogs(foreignContractAddress, foreignLogRetrievalRequestsArrayBaseSlot, foreignLogRetrievalResponsesArrayBaseSlot) {
507
+ // eslint-disable-next-line camelcase
508
+ async aztec_utl_getLogsByTag(foreignContractAddress, foreignLogRetrievalRequestsArrayBaseSlot, foreignLogRetrievalResponsesArrayBaseSlot, foreignScope) {
371
509
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
372
510
  const logRetrievalRequestsArrayBaseSlot = fromSingle(foreignLogRetrievalRequestsArrayBaseSlot);
373
511
  const logRetrievalResponsesArrayBaseSlot = fromSingle(foreignLogRetrievalResponsesArrayBaseSlot);
374
- await this.handlerAsUtility().utilityBulkRetrieveLogs(contractAddress, logRetrievalRequestsArrayBaseSlot, logRetrievalResponsesArrayBaseSlot);
512
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
513
+ await this.handlerAsUtility().getLogsByTag(contractAddress, logRetrievalRequestsArrayBaseSlot, logRetrievalResponsesArrayBaseSlot, scope);
375
514
  return toForeignCallResult([]);
376
515
  }
377
- async utilityStoreCapsule(foreignContractAddress, foreignSlot, foreignCapsule) {
516
+ // eslint-disable-next-line camelcase
517
+ async aztec_utl_getMessageContextsByTxHash(foreignContractAddress, foreignMessageContextRequestsArrayBaseSlot, foreignMessageContextResponsesArrayBaseSlot, foreignScope) {
518
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
519
+ const messageContextRequestsArrayBaseSlot = fromSingle(foreignMessageContextRequestsArrayBaseSlot);
520
+ const messageContextResponsesArrayBaseSlot = fromSingle(foreignMessageContextResponsesArrayBaseSlot);
521
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
522
+ await this.handlerAsUtility().getMessageContextsByTxHash(contractAddress, messageContextRequestsArrayBaseSlot, messageContextResponsesArrayBaseSlot, scope);
523
+ return toForeignCallResult([]);
524
+ }
525
+ // eslint-disable-next-line camelcase
526
+ async aztec_utl_getLogsByTag_v2(foreignRequestArrayBaseSlot) {
527
+ const requestArrayBaseSlot = fromSingle(foreignRequestArrayBaseSlot);
528
+ const responseSlot = await this.handlerAsUtility().getLogsByTagV2(requestArrayBaseSlot);
529
+ return toForeignCallResult([
530
+ toSingle(responseSlot)
531
+ ]);
532
+ }
533
+ // eslint-disable-next-line camelcase
534
+ async aztec_utl_getMessageContextsByTxHash_v2(foreignRequestArrayBaseSlot) {
535
+ const requestArrayBaseSlot = fromSingle(foreignRequestArrayBaseSlot);
536
+ const responseSlot = await this.handlerAsUtility().getMessageContextsByTxHashV2(requestArrayBaseSlot);
537
+ return toForeignCallResult([
538
+ toSingle(responseSlot)
539
+ ]);
540
+ }
541
+ // eslint-disable-next-line camelcase
542
+ aztec_utl_setCapsule(foreignContractAddress, foreignSlot, foreignCapsule, foreignScope) {
378
543
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
379
544
  const slot = fromSingle(foreignSlot);
380
545
  const capsule = fromArray(foreignCapsule);
381
- await this.handlerAsUtility().utilityStoreCapsule(contractAddress, slot, capsule);
546
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
547
+ this.handlerAsUtility().setCapsule(contractAddress, slot, capsule, scope);
382
548
  return toForeignCallResult([]);
383
549
  }
384
- async utilityLoadCapsule(foreignContractAddress, foreignSlot, foreignTSize) {
550
+ // eslint-disable-next-line camelcase
551
+ async aztec_utl_getCapsule(foreignContractAddress, foreignSlot, foreignTSize, foreignScope) {
385
552
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
386
553
  const slot = fromSingle(foreignSlot);
387
554
  const tSize = fromSingle(foreignTSize).toNumber();
388
- const values = await this.handlerAsUtility().utilityLoadCapsule(contractAddress, slot);
555
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
556
+ const values = await this.handlerAsUtility().getCapsule(contractAddress, slot, scope);
389
557
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
390
558
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
391
559
  if (values === null) {
@@ -402,197 +570,316 @@ export class RPCTranslator {
402
570
  ]);
403
571
  }
404
572
  }
405
- async utilityDeleteCapsule(foreignContractAddress, foreignSlot) {
573
+ // eslint-disable-next-line camelcase
574
+ aztec_utl_deleteCapsule(foreignContractAddress, foreignSlot, foreignScope) {
406
575
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
407
576
  const slot = fromSingle(foreignSlot);
408
- await this.handlerAsUtility().utilityDeleteCapsule(contractAddress, slot);
577
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
578
+ this.handlerAsUtility().deleteCapsule(contractAddress, slot, scope);
409
579
  return toForeignCallResult([]);
410
580
  }
411
- async utilityCopyCapsule(foreignContractAddress, foreignSrcSlot, foreignDstSlot, foreignNumEntries) {
581
+ // eslint-disable-next-line camelcase
582
+ async aztec_utl_copyCapsule(foreignContractAddress, foreignSrcSlot, foreignDstSlot, foreignNumEntries, foreignScope) {
412
583
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
413
584
  const srcSlot = fromSingle(foreignSrcSlot);
414
585
  const dstSlot = fromSingle(foreignDstSlot);
415
586
  const numEntries = fromSingle(foreignNumEntries).toNumber();
416
- await this.handlerAsUtility().utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
587
+ const scope = AztecAddress.fromField(fromSingle(foreignScope));
588
+ await this.handlerAsUtility().copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, scope);
589
+ return toForeignCallResult([]);
590
+ }
591
+ // eslint-disable-next-line camelcase
592
+ aztec_utl_pushEphemeral(foreignSlot, foreignElements) {
593
+ const slot = fromSingle(foreignSlot);
594
+ const elements = fromArray(foreignElements);
595
+ const newLen = this.handlerAsUtility().pushEphemeral(slot, elements);
596
+ return toForeignCallResult([
597
+ toSingle(new Fr(newLen))
598
+ ]);
599
+ }
600
+ // eslint-disable-next-line camelcase
601
+ aztec_utl_popEphemeral(foreignSlot) {
602
+ const slot = fromSingle(foreignSlot);
603
+ const element = this.handlerAsUtility().popEphemeral(slot);
604
+ return toForeignCallResult([
605
+ toArray(element)
606
+ ]);
607
+ }
608
+ // eslint-disable-next-line camelcase
609
+ aztec_utl_getEphemeral(foreignSlot, foreignIndex) {
610
+ const slot = fromSingle(foreignSlot);
611
+ const index = fromSingle(foreignIndex).toNumber();
612
+ const element = this.handlerAsUtility().getEphemeral(slot, index);
613
+ return toForeignCallResult([
614
+ toArray(element)
615
+ ]);
616
+ }
617
+ // eslint-disable-next-line camelcase
618
+ aztec_utl_setEphemeral(foreignSlot, foreignIndex, foreignElements) {
619
+ const slot = fromSingle(foreignSlot);
620
+ const index = fromSingle(foreignIndex).toNumber();
621
+ const elements = fromArray(foreignElements);
622
+ this.handlerAsUtility().setEphemeral(slot, index, elements);
623
+ return toForeignCallResult([]);
624
+ }
625
+ // eslint-disable-next-line camelcase
626
+ aztec_utl_getEphemeralLen(foreignSlot) {
627
+ const slot = fromSingle(foreignSlot);
628
+ const len = this.handlerAsUtility().getEphemeralLen(slot);
629
+ return toForeignCallResult([
630
+ toSingle(new Fr(len))
631
+ ]);
632
+ }
633
+ // eslint-disable-next-line camelcase
634
+ aztec_utl_removeEphemeral(foreignSlot, foreignIndex) {
635
+ const slot = fromSingle(foreignSlot);
636
+ const index = fromSingle(foreignIndex).toNumber();
637
+ this.handlerAsUtility().removeEphemeral(slot, index);
638
+ return toForeignCallResult([]);
639
+ }
640
+ // eslint-disable-next-line camelcase
641
+ aztec_utl_clearEphemeral(foreignSlot) {
642
+ const slot = fromSingle(foreignSlot);
643
+ this.handlerAsUtility().clearEphemeral(slot);
417
644
  return toForeignCallResult([]);
418
645
  }
419
646
  // TODO: I forgot to add a corresponding function here, when I introduced an oracle method to txe_oracle.ts.
420
647
  // 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
421
648
  // to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
422
649
  // existence of a txe_oracle method?
423
- async utilityAes128Decrypt(foreignCiphertextBVecStorage, foreignCiphertextLength, foreignIv, foreignSymKey) {
650
+ // eslint-disable-next-line camelcase
651
+ async aztec_utl_decryptAes128(foreignCiphertextBVecStorage, foreignCiphertextLength, foreignIv, foreignSymKey) {
424
652
  const ciphertext = fromUintBoundedVec(foreignCiphertextBVecStorage, foreignCiphertextLength, 8);
425
653
  const iv = fromUintArray(foreignIv, 8);
426
654
  const symKey = fromUintArray(foreignSymKey, 8);
427
- const plaintextBuffer = await this.handlerAsUtility().utilityAes128Decrypt(ciphertext, iv, symKey);
428
- return toForeignCallResult(arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length));
655
+ // Noir Option<BoundedVec> is encoded as [is_some: Field, storage: Field[], length: Field].
656
+ try {
657
+ const plaintextBuffer = await this.handlerAsUtility().decryptAes128(ciphertext, iv, symKey);
658
+ const [storage, length] = arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length);
659
+ return toForeignCallResult([
660
+ toSingle(new Fr(1)),
661
+ storage,
662
+ length
663
+ ]);
664
+ } catch {
665
+ const zeroStorage = toArray(Array(foreignCiphertextBVecStorage.length).fill(new Fr(0)));
666
+ return toForeignCallResult([
667
+ toSingle(new Fr(0)),
668
+ zeroStorage,
669
+ toSingle(new Fr(0))
670
+ ]);
671
+ }
429
672
  }
430
- async utilityGetSharedSecret(foreignAddress, foreignEphPKField0, foreignEphPKField1, foreignEphPKField2) {
673
+ // eslint-disable-next-line camelcase
674
+ async aztec_utl_getSharedSecret(foreignAddress, foreignEphPKField0, foreignEphPKField1, foreignEphPKField2, foreignContractAddress) {
431
675
  const address = AztecAddress.fromField(fromSingle(foreignAddress));
432
676
  const ephPK = Point.fromFields([
433
677
  fromSingle(foreignEphPKField0),
434
678
  fromSingle(foreignEphPKField1),
435
679
  fromSingle(foreignEphPKField2)
436
680
  ]);
437
- const secret = await this.handlerAsUtility().utilityGetSharedSecret(address, ephPK);
438
- return toForeignCallResult(secret.toFields().map(toSingle));
681
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
682
+ const secret = await this.handlerAsUtility().getSharedSecret(address, ephPK, contractAddress);
683
+ return toForeignCallResult([
684
+ toSingle(secret)
685
+ ]);
686
+ }
687
+ // eslint-disable-next-line camelcase
688
+ aztec_utl_setContractSyncCacheInvalid(foreignContractAddress, foreignScopes, foreignScopeCount) {
689
+ const contractAddress = addressFromSingle(foreignContractAddress);
690
+ const count = fromSingle(foreignScopeCount).toNumber();
691
+ const scopes = fromArray(foreignScopes).slice(0, count).map((f)=>new AztecAddress(f));
692
+ this.handlerAsUtility().setContractSyncCacheInvalid(contractAddress, scopes);
693
+ return Promise.resolve(toForeignCallResult([]));
439
694
  }
440
- emitOffchainEffect(_foreignData) {
695
+ // eslint-disable-next-line camelcase
696
+ aztec_utl_emitOffchainEffect(_foreignData) {
441
697
  throw new Error('Offchain effects are not yet supported in the TestEnvironment');
442
698
  }
443
699
  // AVM opcodes
444
- avmOpcodeEmitUnencryptedLog(_foreignMessage) {
700
+ // eslint-disable-next-line camelcase
701
+ aztec_avm_emitPublicLog(_foreignMessage) {
445
702
  // TODO(#8811): Implement
446
703
  return toForeignCallResult([]);
447
704
  }
448
- async avmOpcodeStorageRead(foreignSlot) {
705
+ // eslint-disable-next-line camelcase
706
+ async aztec_avm_storageRead(foreignSlot, foreignContractAddress) {
449
707
  const slot = fromSingle(foreignSlot);
450
- const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
708
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
709
+ const value = (await this.handlerAsAvm().storageRead(slot, contractAddress)).value;
451
710
  return toForeignCallResult([
452
711
  toSingle(new Fr(value))
453
712
  ]);
454
713
  }
455
- async avmOpcodeStorageWrite(foreignSlot, foreignValue) {
714
+ // eslint-disable-next-line camelcase
715
+ async aztec_avm_storageWrite(foreignSlot, foreignValue) {
456
716
  const slot = fromSingle(foreignSlot);
457
717
  const value = fromSingle(foreignValue);
458
- await this.handlerAsAvm().avmOpcodeStorageWrite(slot, value);
718
+ await this.handlerAsAvm().storageWrite(slot, value);
459
719
  return toForeignCallResult([]);
460
720
  }
461
- async avmOpcodeGetContractInstanceDeployer(foreignAddress) {
721
+ // eslint-disable-next-line camelcase
722
+ async aztec_avm_getContractInstanceDeployer(foreignAddress) {
462
723
  const address = addressFromSingle(foreignAddress);
463
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
724
+ const instance = await this.handlerAsUtility().getContractInstance(address);
464
725
  return toForeignCallResult([
465
726
  toSingle(instance.deployer),
466
727
  // AVM requires an extra boolean indicating the instance was found
467
728
  toSingle(new Fr(1))
468
729
  ]);
469
730
  }
470
- async avmOpcodeGetContractInstanceClassId(foreignAddress) {
731
+ // eslint-disable-next-line camelcase
732
+ async aztec_avm_getContractInstanceClassId(foreignAddress) {
471
733
  const address = addressFromSingle(foreignAddress);
472
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
734
+ const instance = await this.handlerAsUtility().getContractInstance(address);
473
735
  return toForeignCallResult([
474
736
  toSingle(instance.currentContractClassId),
475
737
  // AVM requires an extra boolean indicating the instance was found
476
738
  toSingle(new Fr(1))
477
739
  ]);
478
740
  }
479
- async avmOpcodeGetContractInstanceInitializationHash(foreignAddress) {
741
+ // eslint-disable-next-line camelcase
742
+ async aztec_avm_getContractInstanceInitializationHash(foreignAddress) {
480
743
  const address = addressFromSingle(foreignAddress);
481
- const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
744
+ const instance = await this.handlerAsUtility().getContractInstance(address);
482
745
  return toForeignCallResult([
483
746
  toSingle(instance.initializationHash),
484
747
  // AVM requires an extra boolean indicating the instance was found
485
748
  toSingle(new Fr(1))
486
749
  ]);
487
750
  }
488
- async avmOpcodeSender() {
489
- const sender = await this.handlerAsAvm().avmOpcodeSender();
751
+ // eslint-disable-next-line camelcase
752
+ async aztec_avm_sender() {
753
+ const sender = await this.handlerAsAvm().sender();
490
754
  return toForeignCallResult([
491
755
  toSingle(sender)
492
756
  ]);
493
757
  }
494
- async avmOpcodeEmitNullifier(foreignNullifier) {
758
+ // eslint-disable-next-line camelcase
759
+ async aztec_avm_emitNullifier(foreignNullifier) {
495
760
  const nullifier = fromSingle(foreignNullifier);
496
- await this.handlerAsAvm().avmOpcodeEmitNullifier(nullifier);
761
+ await this.handlerAsAvm().emitNullifier(nullifier);
497
762
  return toForeignCallResult([]);
498
763
  }
499
- async avmOpcodeEmitNoteHash(foreignNoteHash) {
764
+ // eslint-disable-next-line camelcase
765
+ async aztec_avm_emitNoteHash(foreignNoteHash) {
500
766
  const noteHash = fromSingle(foreignNoteHash);
501
- await this.handlerAsAvm().avmOpcodeEmitNoteHash(noteHash);
767
+ await this.handlerAsAvm().emitNoteHash(noteHash);
502
768
  return toForeignCallResult([]);
503
769
  }
504
- async avmOpcodeNullifierExists(foreignInnerNullifier, foreignTargetAddress) {
505
- const innerNullifier = fromSingle(foreignInnerNullifier);
506
- const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
507
- const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(innerNullifier, targetAddress);
770
+ // eslint-disable-next-line camelcase
771
+ async aztec_avm_nullifierExists(foreignSiloedNullifier) {
772
+ const siloedNullifier = fromSingle(foreignSiloedNullifier);
773
+ const exists = await this.handlerAsAvm().nullifierExists(siloedNullifier);
508
774
  return toForeignCallResult([
509
775
  toSingle(new Fr(exists))
510
776
  ]);
511
777
  }
512
- async avmOpcodeAddress() {
513
- const contractAddress = await this.handlerAsAvm().avmOpcodeAddress();
778
+ // eslint-disable-next-line camelcase
779
+ async aztec_avm_address() {
780
+ const contractAddress = await this.handlerAsAvm().address();
514
781
  return toForeignCallResult([
515
782
  toSingle(contractAddress.toField())
516
783
  ]);
517
784
  }
518
- async avmOpcodeBlockNumber() {
519
- const blockNumber = await this.handlerAsAvm().avmOpcodeBlockNumber();
785
+ // eslint-disable-next-line camelcase
786
+ async aztec_avm_blockNumber() {
787
+ const blockNumber = await this.handlerAsAvm().blockNumber();
520
788
  return toForeignCallResult([
521
789
  toSingle(new Fr(blockNumber))
522
790
  ]);
523
791
  }
524
- async avmOpcodeTimestamp() {
525
- const timestamp = await this.handlerAsAvm().avmOpcodeTimestamp();
792
+ // eslint-disable-next-line camelcase
793
+ async aztec_avm_timestamp() {
794
+ const timestamp = await this.handlerAsAvm().timestamp();
526
795
  return toForeignCallResult([
527
796
  toSingle(new Fr(timestamp))
528
797
  ]);
529
798
  }
530
- async avmOpcodeIsStaticCall() {
531
- const isStaticCall = await this.handlerAsAvm().avmOpcodeIsStaticCall();
799
+ // eslint-disable-next-line camelcase
800
+ async aztec_avm_isStaticCall() {
801
+ const isStaticCall = await this.handlerAsAvm().isStaticCall();
532
802
  return toForeignCallResult([
533
803
  toSingle(new Fr(isStaticCall ? 1 : 0))
534
804
  ]);
535
805
  }
536
- async avmOpcodeChainId() {
537
- const chainId = await this.handlerAsAvm().avmOpcodeChainId();
806
+ // eslint-disable-next-line camelcase
807
+ async aztec_avm_chainId() {
808
+ const chainId = await this.handlerAsAvm().chainId();
538
809
  return toForeignCallResult([
539
810
  toSingle(chainId)
540
811
  ]);
541
812
  }
542
- async avmOpcodeVersion() {
543
- const version = await this.handlerAsAvm().avmOpcodeVersion();
813
+ // eslint-disable-next-line camelcase
814
+ async aztec_avm_version() {
815
+ const version = await this.handlerAsAvm().version();
544
816
  return toForeignCallResult([
545
817
  toSingle(version)
546
818
  ]);
547
819
  }
548
- avmOpcodeReturndataSize() {
820
+ // eslint-disable-next-line camelcase
821
+ aztec_avm_returndataSize() {
549
822
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
550
823
  }
551
- avmOpcodeReturndataCopy(_foreignRdOffset, _foreignCopySize) {
824
+ // eslint-disable-next-line camelcase
825
+ aztec_avm_returndataCopy(_foreignRdOffset, _foreignCopySize) {
552
826
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
553
827
  }
554
- avmOpcodeCall(_foreignL2Gas, _foreignDaGas, _foreignAddress, _foreignLength, _foreignArgs) {
828
+ // eslint-disable-next-line camelcase
829
+ aztec_avm_call(_foreignL2Gas, _foreignDaGas, _foreignAddress, _foreignLength, _foreignArgs) {
555
830
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
556
831
  }
557
- avmOpcodeStaticCall(_foreignL2Gas, _foreignDaGas, _foreignAddress, _foreignLength, _foreignArgs) {
832
+ // eslint-disable-next-line camelcase
833
+ aztec_avm_staticCall(_foreignL2Gas, _foreignDaGas, _foreignAddress, _foreignLength, _foreignArgs) {
558
834
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
559
835
  }
560
- avmOpcodeSuccessCopy() {
836
+ // eslint-disable-next-line camelcase
837
+ aztec_avm_successCopy() {
561
838
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
562
839
  }
563
- async txePrivateCallNewFlow(foreignFrom, foreignTargetContractAddress, foreignFunctionSelector, foreignArgs, foreignArgsHash, foreignIsStaticCall) {
840
+ // eslint-disable-next-line camelcase
841
+ async aztec_txe_privateCallNewFlow(foreignFrom, foreignTargetContractAddress, foreignFunctionSelector, foreignArgs, foreignArgsHash, foreignIsStaticCall) {
564
842
  const from = addressFromSingle(foreignFrom);
565
843
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
566
844
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
567
845
  const args = fromArray(foreignArgs);
568
846
  const argsHash = fromSingle(foreignArgsHash);
569
847
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
570
- const returnValues = await this.handlerAsTxe().txePrivateCallNewFlow(from, targetContractAddress, functionSelector, args, argsHash, isStaticCall);
848
+ const returnValues = await this.handlerAsTxe().privateCallNewFlow(from, targetContractAddress, functionSelector, args, argsHash, isStaticCall, this.stateHandler.getCurrentJob());
849
+ // TODO(F-335): Avoid doing the following call here.
850
+ await this.stateHandler.cycleJob();
571
851
  return toForeignCallResult([
572
852
  toArray(returnValues)
573
853
  ]);
574
854
  }
575
- async txeSimulateUtilityFunction(foreignTargetContractAddress, foreignFunctionSelector, foreignArgs) {
855
+ // eslint-disable-next-line camelcase
856
+ async aztec_txe_executeUtilityFunction(foreignTargetContractAddress, foreignFunctionSelector, foreignArgs) {
576
857
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
577
858
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
578
859
  const args = fromArray(foreignArgs);
579
- const returnValues = await this.handlerAsTxe().txeSimulateUtilityFunction(targetContractAddress, functionSelector, args);
860
+ const returnValues = await this.handlerAsTxe().executeUtilityFunction(targetContractAddress, functionSelector, args, this.stateHandler.getCurrentJob());
861
+ // TODO(F-335): Avoid doing the following call here.
862
+ await this.stateHandler.cycleJob();
580
863
  return toForeignCallResult([
581
864
  toArray(returnValues)
582
865
  ]);
583
866
  }
584
- async txePublicCallNewFlow(foreignFrom, foreignAddress, foreignCalldata, foreignIsStaticCall) {
867
+ // eslint-disable-next-line camelcase
868
+ async aztec_txe_publicCallNewFlow(foreignFrom, foreignAddress, foreignCalldata, foreignIsStaticCall) {
585
869
  const from = addressFromSingle(foreignFrom);
586
870
  const address = addressFromSingle(foreignAddress);
587
871
  const calldata = fromArray(foreignCalldata);
588
872
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
589
- const returnValues = await this.handlerAsTxe().txePublicCallNewFlow(from, address, calldata, isStaticCall);
873
+ const returnValues = await this.handlerAsTxe().publicCallNewFlow(from, address, calldata, isStaticCall);
874
+ // TODO(F-335): Avoid doing the following call here.
875
+ await this.stateHandler.cycleJob();
590
876
  return toForeignCallResult([
591
877
  toArray(returnValues)
592
878
  ]);
593
879
  }
594
- async privateGetSenderForTags() {
595
- const sender = await this.handlerAsPrivate().privateGetSenderForTags();
880
+ // eslint-disable-next-line camelcase
881
+ async aztec_prv_getSenderForTags() {
882
+ const sender = await this.handlerAsPrivate().getSenderForTags();
596
883
  // Return a Noir Option struct with `some` and `value` fields
597
884
  if (sender === undefined) {
598
885
  // No sender found, return Option with some=0 and value=0
@@ -608,15 +895,17 @@ export class RPCTranslator {
608
895
  ]);
609
896
  }
610
897
  }
611
- async privateSetSenderForTags(foreignSenderForTags) {
898
+ // eslint-disable-next-line camelcase
899
+ async aztec_prv_setSenderForTags(foreignSenderForTags) {
612
900
  const senderForTags = AztecAddress.fromField(fromSingle(foreignSenderForTags));
613
- await this.handlerAsPrivate().privateSetSenderForTags(senderForTags);
901
+ await this.handlerAsPrivate().setSenderForTags(senderForTags);
614
902
  return toForeignCallResult([]);
615
903
  }
616
- async privateGetNextAppTagAsSender(foreignSender, foreignRecipient) {
904
+ // eslint-disable-next-line camelcase
905
+ async aztec_prv_getNextAppTagAsSender(foreignSender, foreignRecipient) {
617
906
  const sender = AztecAddress.fromField(fromSingle(foreignSender));
618
907
  const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
619
- const nextAppTag = await this.handlerAsPrivate().privateGetNextAppTagAsSender(sender, recipient);
908
+ const nextAppTag = await this.handlerAsPrivate().getNextAppTagAsSender(sender, recipient);
620
909
  return toForeignCallResult([
621
910
  toSingle(nextAppTag.value)
622
911
  ]);