@aztec/txe 3.0.0-nightly.20250925 → 3.0.0-nightly.20250926

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.
@@ -1,11 +1,16 @@
1
1
  import { type ContractInstanceWithAddress, Fr, Point } from '@aztec/aztec.js';
2
2
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
3
- import { packAsRetrievedNote } from '@aztec/pxe/simulator';
3
+ import {
4
+ type IMiscOracle,
5
+ type IPrivateExecutionOracle,
6
+ type IUtilityExecutionOracle,
7
+ packAsRetrievedNote,
8
+ } from '@aztec/pxe/simulator';
4
9
  import { type ContractArtifact, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
5
10
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
11
  import { MerkleTreeId } from '@aztec/stdlib/trees';
7
12
 
8
- import type { TXETypedOracle } from './oracle/txe_typed_oracle.js';
13
+ import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
9
14
  import type { TXESessionStateHandler } from './txe_session.js';
10
15
  import {
11
16
  type ForeignCallArray,
@@ -23,6 +28,12 @@ import {
23
28
  toSingle,
24
29
  } from './util/encoding.js';
25
30
 
31
+ export class UnavailableOracleError extends Error {
32
+ constructor(oracleName: string) {
33
+ super(`${oracleName} oracles not available with the current handler`);
34
+ }
35
+ }
36
+
26
37
  export class RPCTranslator {
27
38
  /**
28
39
  * Create a new instance of `RPCTranslator` that will translate all TXE RPC calls to and from the foreign
@@ -35,9 +46,54 @@ export class RPCTranslator {
35
46
  */
36
47
  constructor(
37
48
  private stateHandler: TXESessionStateHandler,
38
- private oracleHandler: TXETypedOracle,
49
+ private oracleHandler:
50
+ | IMiscOracle
51
+ | IUtilityExecutionOracle
52
+ | IPrivateExecutionOracle
53
+ | IAvmExecutionOracle
54
+ | ITxeExecutionOracle,
39
55
  ) {}
40
56
 
57
+ private handlerAsMisc(): IMiscOracle {
58
+ if (!('isMisc' in this.oracleHandler)) {
59
+ throw new UnavailableOracleError('Misc');
60
+ }
61
+
62
+ return this.oracleHandler;
63
+ }
64
+
65
+ private handlerAsUtility(): IUtilityExecutionOracle {
66
+ if (!('isUtility' in this.oracleHandler)) {
67
+ throw new UnavailableOracleError('Utility');
68
+ }
69
+
70
+ return this.oracleHandler;
71
+ }
72
+
73
+ private handlerAsPrivate(): IPrivateExecutionOracle {
74
+ if (!('isPrivate' in this.oracleHandler)) {
75
+ throw new UnavailableOracleError('Private');
76
+ }
77
+
78
+ return this.oracleHandler;
79
+ }
80
+
81
+ private handlerAsAvm(): IAvmExecutionOracle {
82
+ if (!('isAvm' in this.oracleHandler)) {
83
+ throw new UnavailableOracleError('Avm');
84
+ }
85
+
86
+ return this.oracleHandler;
87
+ }
88
+
89
+ private handlerAsTxe(): ITxeExecutionOracle {
90
+ if (!('isTxe' in this.oracleHandler)) {
91
+ throw new UnavailableOracleError('Txe');
92
+ }
93
+
94
+ return this.oracleHandler;
95
+ }
96
+
41
97
  // TXE session state transition functions - these get handled by the state handler
42
98
 
43
99
  async txeSetTopLevelTXEContext() {
@@ -96,13 +152,13 @@ export class RPCTranslator {
96
152
  // TXE-specific oracles
97
153
 
98
154
  async txeGetNextBlockNumber() {
99
- const nextBlockNumber = await this.oracleHandler.txeGetNextBlockNumber();
155
+ const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
100
156
 
101
157
  return toForeignCallResult([toSingle(nextBlockNumber)]);
102
158
  }
103
159
 
104
160
  async txeGetNextBlockTimestamp() {
105
- const nextBlockTimestamp = await this.oracleHandler.txeGetNextBlockTimestamp();
161
+ const nextBlockTimestamp = await this.handlerAsTxe().txeGetNextBlockTimestamp();
106
162
 
107
163
  return toForeignCallResult([toSingle(nextBlockTimestamp)]);
108
164
  }
@@ -110,7 +166,7 @@ export class RPCTranslator {
110
166
  async txeAdvanceBlocksBy(foreignBlocks: ForeignCallSingle) {
111
167
  const blocks = fromSingle(foreignBlocks).toNumber();
112
168
 
113
- await this.oracleHandler.txeAdvanceBlocksBy(blocks);
169
+ await this.handlerAsTxe().txeAdvanceBlocksBy(blocks);
114
170
 
115
171
  return toForeignCallResult([]);
116
172
  }
@@ -118,7 +174,7 @@ export class RPCTranslator {
118
174
  txeAdvanceTimestampBy(foreignDuration: ForeignCallSingle) {
119
175
  const duration = fromSingle(foreignDuration).toBigInt();
120
176
 
121
- this.oracleHandler.txeAdvanceTimestampBy(duration);
177
+ this.handlerAsTxe().txeAdvanceTimestampBy(duration);
122
178
 
123
179
  return toForeignCallResult([]);
124
180
  }
@@ -126,7 +182,7 @@ export class RPCTranslator {
126
182
  async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, foreignSecret: ForeignCallSingle) {
127
183
  const secret = fromSingle(foreignSecret);
128
184
 
129
- await this.oracleHandler.txeDeploy(artifact, instance, secret);
185
+ await this.handlerAsTxe().txeDeploy(artifact, instance, secret);
130
186
 
131
187
  return toForeignCallResult([
132
188
  toArray([
@@ -142,7 +198,7 @@ export class RPCTranslator {
142
198
  async txeCreateAccount(foreignSecret: ForeignCallSingle) {
143
199
  const secret = fromSingle(foreignSecret);
144
200
 
145
- const completeAddress = await this.oracleHandler.txeCreateAccount(secret);
201
+ const completeAddress = await this.handlerAsTxe().txeCreateAccount(secret);
146
202
 
147
203
  return toForeignCallResult([
148
204
  toSingle(completeAddress.address),
@@ -157,7 +213,7 @@ export class RPCTranslator {
157
213
  ) {
158
214
  const secret = fromSingle(foreignSecret);
159
215
 
160
- const completeAddress = await this.oracleHandler.txeAddAccount(artifact, instance, secret);
216
+ const completeAddress = await this.handlerAsTxe().txeAddAccount(artifact, instance, secret);
161
217
 
162
218
  return toForeignCallResult([
163
219
  toSingle(completeAddress.address),
@@ -169,7 +225,7 @@ export class RPCTranslator {
169
225
  const address = addressFromSingle(foreignAddress);
170
226
  const messageHash = fromSingle(foreignMessageHash);
171
227
 
172
- await this.oracleHandler.txeAddAuthWitness(address, messageHash);
228
+ await this.handlerAsTxe().txeAddAuthWitness(address, messageHash);
173
229
 
174
230
  return toForeignCallResult([]);
175
231
  }
@@ -179,25 +235,25 @@ export class RPCTranslator {
179
235
  utilityAssertCompatibleOracleVersion(foreignVersion: ForeignCallSingle) {
180
236
  const version = fromSingle(foreignVersion).toNumber();
181
237
 
182
- this.oracleHandler.utilityAssertCompatibleOracleVersion(version);
238
+ this.handlerAsMisc().utilityAssertCompatibleOracleVersion(version);
183
239
 
184
240
  return toForeignCallResult([]);
185
241
  }
186
242
 
187
243
  utilityGetRandomField() {
188
- const randomField = this.oracleHandler.utilityGetRandomField();
244
+ const randomField = this.handlerAsMisc().utilityGetRandomField();
189
245
 
190
246
  return toForeignCallResult([toSingle(randomField)]);
191
247
  }
192
248
 
193
249
  async txeGetLastBlockTimestamp() {
194
- const timestamp = await this.oracleHandler.txeGetLastBlockTimestamp();
250
+ const timestamp = await this.handlerAsTxe().txeGetLastBlockTimestamp();
195
251
 
196
252
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
197
253
  }
198
254
 
199
255
  async txeGetLastTxEffects() {
200
- const { txHash, noteHashes, nullifiers } = await this.oracleHandler.txeGetLastTxEffects();
256
+ const { txHash, noteHashes, nullifiers } = await this.handlerAsTxe().txeGetLastTxEffects();
201
257
 
202
258
  return toForeignCallResult([
203
259
  toSingle(txHash.hash),
@@ -215,7 +271,7 @@ export class RPCTranslator {
215
271
  const values = fromArray(foreignValues);
216
272
  const hash = fromSingle(foreignHash);
217
273
 
218
- this.oracleHandler.privateStoreInExecutionCache(values, hash);
274
+ this.handlerAsPrivate().privateStoreInExecutionCache(values, hash);
219
275
 
220
276
  return toForeignCallResult([]);
221
277
  }
@@ -223,7 +279,7 @@ export class RPCTranslator {
223
279
  async privateLoadFromExecutionCache(foreignHash: ForeignCallSingle) {
224
280
  const hash = fromSingle(foreignHash);
225
281
 
226
- const returns = await this.oracleHandler.privateLoadFromExecutionCache(hash);
282
+ const returns = await this.handlerAsPrivate().privateLoadFromExecutionCache(hash);
227
283
 
228
284
  return toForeignCallResult([toArray(returns)]);
229
285
  }
@@ -239,7 +295,7 @@ export class RPCTranslator {
239
295
  .join('');
240
296
  const fields = fromArray(foreignFields);
241
297
 
242
- this.oracleHandler.utilityDebugLog(message, fields);
298
+ this.handlerAsMisc().utilityDebugLog(message, fields);
243
299
 
244
300
  return toForeignCallResult([]);
245
301
  }
@@ -255,7 +311,7 @@ export class RPCTranslator {
255
311
  const blockNumber = fromSingle(foreignBlockNumber).toNumber();
256
312
  const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
257
313
 
258
- const values = await this.oracleHandler.utilityStorageRead(
314
+ const values = await this.handlerAsUtility().utilityStorageRead(
259
315
  contractAddress,
260
316
  startStorageSlot,
261
317
  blockNumber,
@@ -269,7 +325,7 @@ export class RPCTranslator {
269
325
  const blockNumber = fromSingle(foreignBlockNumber).toNumber();
270
326
  const leafSlot = fromSingle(foreignLeafSlot);
271
327
 
272
- const witness = await this.oracleHandler.utilityGetPublicDataWitness(blockNumber, leafSlot);
328
+ const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockNumber, leafSlot);
273
329
 
274
330
  if (!witness) {
275
331
  throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockNumber}.`);
@@ -312,7 +368,7 @@ export class RPCTranslator {
312
368
  const maxNotes = fromSingle(foreignMaxNotes).toNumber();
313
369
  const packedRetrievedNoteLength = fromSingle(foreignPackedRetrievedNoteLength).toNumber();
314
370
 
315
- const noteDatas = await this.oracleHandler.utilityGetNotes(
371
+ const noteDatas = await this.handlerAsUtility().utilityGetNotes(
316
372
  storageSlot,
317
373
  numSelects,
318
374
  selectByIndexes,
@@ -359,7 +415,7 @@ export class RPCTranslator {
359
415
  const noteHash = fromSingle(foreignNoteHash);
360
416
  const counter = fromSingle(foreignCounter).toNumber();
361
417
 
362
- this.oracleHandler.privateNotifyCreatedNote(storageSlot, noteTypeId, note, noteHash, counter);
418
+ this.handlerAsPrivate().privateNotifyCreatedNote(storageSlot, noteTypeId, note, noteHash, counter);
363
419
 
364
420
  return toForeignCallResult([]);
365
421
  }
@@ -373,7 +429,7 @@ export class RPCTranslator {
373
429
  const noteHash = fromSingle(foreignNoteHash);
374
430
  const counter = fromSingle(foreignCounter).toNumber();
375
431
 
376
- await this.oracleHandler.privateNotifyNullifiedNote(innerNullifier, noteHash, counter);
432
+ await this.handlerAsPrivate().privateNotifyNullifiedNote(innerNullifier, noteHash, counter);
377
433
 
378
434
  return toForeignCallResult([]);
379
435
  }
@@ -381,7 +437,7 @@ export class RPCTranslator {
381
437
  async privateNotifyCreatedNullifier(foreignInnerNullifier: ForeignCallSingle) {
382
438
  const innerNullifier = fromSingle(foreignInnerNullifier);
383
439
 
384
- await this.oracleHandler.privateNotifyCreatedNullifier(innerNullifier);
440
+ await this.handlerAsPrivate().privateNotifyCreatedNullifier(innerNullifier);
385
441
 
386
442
  return toForeignCallResult([]);
387
443
  }
@@ -389,7 +445,7 @@ export class RPCTranslator {
389
445
  async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
390
446
  const innerNullifier = fromSingle(foreignInnerNullifier);
391
447
 
392
- const exists = await this.oracleHandler.utilityCheckNullifierExists(innerNullifier);
448
+ const exists = await this.handlerAsUtility().utilityCheckNullifierExists(innerNullifier);
393
449
 
394
450
  return toForeignCallResult([toSingle(new Fr(exists))]);
395
451
  }
@@ -397,7 +453,7 @@ export class RPCTranslator {
397
453
  async utilityGetContractInstance(foreignAddress: ForeignCallSingle) {
398
454
  const address = addressFromSingle(foreignAddress);
399
455
 
400
- const instance = await this.oracleHandler.utilityGetContractInstance(address);
456
+ const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
401
457
 
402
458
  return toForeignCallResult(
403
459
  [
@@ -413,7 +469,7 @@ export class RPCTranslator {
413
469
  async utilityGetPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
414
470
  const address = addressFromSingle(foreignAddress);
415
471
 
416
- const { publicKeys, partialAddress } = await this.oracleHandler.utilityGetPublicKeysAndPartialAddress(address);
472
+ const { publicKeys, partialAddress } = await this.handlerAsUtility().utilityGetPublicKeysAndPartialAddress(address);
417
473
 
418
474
  return toForeignCallResult([toArray([...publicKeys.toFields(), partialAddress])]);
419
475
  }
@@ -421,7 +477,7 @@ export class RPCTranslator {
421
477
  async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
422
478
  const pkMHash = fromSingle(foreignPkMHash);
423
479
 
424
- const keyValidationRequest = await this.oracleHandler.utilityGetKeyValidationRequest(pkMHash);
480
+ const keyValidationRequest = await this.handlerAsUtility().utilityGetKeyValidationRequest(pkMHash);
425
481
 
426
482
  return toForeignCallResult(keyValidationRequest.toFields().map(toSingle));
427
483
  }
@@ -445,7 +501,7 @@ export class RPCTranslator {
445
501
  const blockNumber = fromSingle(foreignBlockNumber).toNumber();
446
502
  const nullifier = fromSingle(foreignNullifier);
447
503
 
448
- const witness = await this.oracleHandler.utilityGetNullifierMembershipWitness(blockNumber, nullifier);
504
+ const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockNumber, nullifier);
449
505
 
450
506
  if (!witness) {
451
507
  throw new Error(`Nullifier membership witness not found at block ${blockNumber}.`);
@@ -456,7 +512,7 @@ export class RPCTranslator {
456
512
  async utilityGetAuthWitness(foreignMessageHash: ForeignCallSingle) {
457
513
  const messageHash = fromSingle(foreignMessageHash);
458
514
 
459
- const authWitness = await this.oracleHandler.utilityGetAuthWitness(messageHash);
515
+ const authWitness = await this.handlerAsUtility().utilityGetAuthWitness(messageHash);
460
516
 
461
517
  if (!authWitness) {
462
518
  throw new Error(`Auth witness not found for message hash ${messageHash}.`);
@@ -487,7 +543,7 @@ export class RPCTranslator {
487
543
  }
488
544
 
489
545
  async utilityGetUtilityContext() {
490
- const context = await this.oracleHandler.utilityGetUtilityContext();
546
+ const context = await this.handlerAsUtility().utilityGetUtilityContext();
491
547
 
492
548
  return toForeignCallResult(context.toNoirRepresentation());
493
549
  }
@@ -495,7 +551,7 @@ export class RPCTranslator {
495
551
  async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
496
552
  const blockNumber = fromSingle(foreignBlockNumber).toNumber();
497
553
 
498
- const header = await this.oracleHandler.utilityGetBlockHeader(blockNumber);
554
+ const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
499
555
 
500
556
  if (!header) {
501
557
  throw new Error(`Block header not found for block ${blockNumber}.`);
@@ -512,7 +568,7 @@ export class RPCTranslator {
512
568
  const treeId = fromSingle(foreignTreeId).toNumber();
513
569
  const leafValue = fromSingle(foreignLeafValue);
514
570
 
515
- const witness = await this.oracleHandler.utilityGetMembershipWitness(blockNumber, treeId, leafValue);
571
+ const witness = await this.handlerAsUtility().utilityGetMembershipWitness(blockNumber, treeId, leafValue);
516
572
 
517
573
  if (!witness) {
518
574
  throw new Error(
@@ -529,7 +585,7 @@ export class RPCTranslator {
529
585
  const blockNumber = fromSingle(foreignBlockNumber).toNumber();
530
586
  const nullifier = fromSingle(foreignNullifier);
531
587
 
532
- const witness = await this.oracleHandler.utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);
588
+ const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);
533
589
 
534
590
  if (!witness) {
535
591
  throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockNumber}.`);
@@ -541,7 +597,7 @@ export class RPCTranslator {
541
597
  const sender = AztecAddress.fromField(fromSingle(foreignSender));
542
598
  const recipient = AztecAddress.fromField(fromSingle(foreignRecipient));
543
599
 
544
- const secret = await this.oracleHandler.utilityGetIndexedTaggingSecretAsSender(sender, recipient);
600
+ const secret = await this.handlerAsUtility().utilityGetIndexedTaggingSecretAsSender(sender, recipient);
545
601
 
546
602
  return toForeignCallResult(secret.toFields().map(toSingle));
547
603
  }
@@ -549,7 +605,7 @@ export class RPCTranslator {
549
605
  async utilityFetchTaggedLogs(foreignPendingTaggedLogArrayBaseSlot: ForeignCallSingle) {
550
606
  const pendingTaggedLogArrayBaseSlot = fromSingle(foreignPendingTaggedLogArrayBaseSlot);
551
607
 
552
- await this.oracleHandler.utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
608
+ await this.handlerAsUtility().utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
553
609
 
554
610
  return toForeignCallResult([]);
555
611
  }
@@ -563,7 +619,7 @@ export class RPCTranslator {
563
619
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
564
620
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
565
621
 
566
- await this.oracleHandler.utilityValidateEnqueuedNotesAndEvents(
622
+ await this.handlerAsUtility().utilityValidateEnqueuedNotesAndEvents(
567
623
  contractAddress,
568
624
  noteValidationRequestsArrayBaseSlot,
569
625
  eventValidationRequestsArrayBaseSlot,
@@ -581,7 +637,7 @@ export class RPCTranslator {
581
637
  const logRetrievalRequestsArrayBaseSlot = fromSingle(foreignLogRetrievalRequestsArrayBaseSlot);
582
638
  const logRetrievalResponsesArrayBaseSlot = fromSingle(foreignLogRetrievalResponsesArrayBaseSlot);
583
639
 
584
- await this.oracleHandler.utilityBulkRetrieveLogs(
640
+ await this.handlerAsUtility().utilityBulkRetrieveLogs(
585
641
  contractAddress,
586
642
  logRetrievalRequestsArrayBaseSlot,
587
643
  logRetrievalResponsesArrayBaseSlot,
@@ -599,7 +655,7 @@ export class RPCTranslator {
599
655
  const slot = fromSingle(foreignSlot);
600
656
  const capsule = fromArray(foreignCapsule);
601
657
 
602
- await this.oracleHandler.utilityStoreCapsule(contractAddress, slot, capsule);
658
+ await this.handlerAsUtility().utilityStoreCapsule(contractAddress, slot, capsule);
603
659
 
604
660
  return toForeignCallResult([]);
605
661
  }
@@ -613,7 +669,7 @@ export class RPCTranslator {
613
669
  const slot = fromSingle(foreignSlot);
614
670
  const tSize = fromSingle(foreignTSize).toNumber();
615
671
 
616
- const values = await this.oracleHandler.utilityLoadCapsule(contractAddress, slot);
672
+ const values = await this.handlerAsUtility().utilityLoadCapsule(contractAddress, slot);
617
673
 
618
674
  // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
619
675
  // with two fields: `some` (a boolean) and `value` (a field array in this case).
@@ -630,7 +686,7 @@ export class RPCTranslator {
630
686
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
631
687
  const slot = fromSingle(foreignSlot);
632
688
 
633
- await this.oracleHandler.utilityDeleteCapsule(contractAddress, slot);
689
+ await this.handlerAsUtility().utilityDeleteCapsule(contractAddress, slot);
634
690
 
635
691
  return toForeignCallResult([]);
636
692
  }
@@ -646,7 +702,7 @@ export class RPCTranslator {
646
702
  const dstSlot = fromSingle(foreignDstSlot);
647
703
  const numEntries = fromSingle(foreignNumEntries).toNumber();
648
704
 
649
- await this.oracleHandler.utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
705
+ await this.handlerAsUtility().utilityCopyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
650
706
 
651
707
  return toForeignCallResult([]);
652
708
  }
@@ -665,7 +721,7 @@ export class RPCTranslator {
665
721
  const iv = fromUintArray(foreignIv, 8);
666
722
  const symKey = fromUintArray(foreignSymKey, 8);
667
723
 
668
- const plaintextBuffer = await this.oracleHandler.utilityAes128Decrypt(ciphertext, iv, symKey);
724
+ const plaintextBuffer = await this.handlerAsUtility().utilityAes128Decrypt(ciphertext, iv, symKey);
669
725
 
670
726
  return toForeignCallResult(
671
727
  arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length),
@@ -685,7 +741,7 @@ export class RPCTranslator {
685
741
  fromSingle(foreignEphPKField2),
686
742
  ]);
687
743
 
688
- const secret = await this.oracleHandler.utilityGetSharedSecret(address, ephPK);
744
+ const secret = await this.handlerAsUtility().utilityGetSharedSecret(address, ephPK);
689
745
 
690
746
  return toForeignCallResult(secret.toFields().map(toSingle));
691
747
  }
@@ -704,7 +760,7 @@ export class RPCTranslator {
704
760
  async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle) {
705
761
  const slot = fromSingle(foreignSlot);
706
762
 
707
- const value = (await this.oracleHandler.avmOpcodeStorageRead(slot)).value;
763
+ const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
708
764
 
709
765
  return toForeignCallResult([toSingle(new Fr(value))]);
710
766
  }
@@ -713,7 +769,7 @@ export class RPCTranslator {
713
769
  const slot = fromSingle(foreignSlot);
714
770
  const value = fromSingle(foreignValue);
715
771
 
716
- await this.oracleHandler.avmOpcodeStorageWrite(slot, value);
772
+ await this.handlerAsAvm().avmOpcodeStorageWrite(slot, value);
717
773
 
718
774
  return toForeignCallResult([]);
719
775
  }
@@ -721,7 +777,7 @@ export class RPCTranslator {
721
777
  async avmOpcodeGetContractInstanceDeployer(foreignAddress: ForeignCallSingle) {
722
778
  const address = addressFromSingle(foreignAddress);
723
779
 
724
- const instance = await this.oracleHandler.utilityGetContractInstance(address);
780
+ const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
725
781
 
726
782
  return toForeignCallResult([
727
783
  toSingle(instance.deployer),
@@ -733,7 +789,7 @@ export class RPCTranslator {
733
789
  async avmOpcodeGetContractInstanceClassId(foreignAddress: ForeignCallSingle) {
734
790
  const address = addressFromSingle(foreignAddress);
735
791
 
736
- const instance = await this.oracleHandler.utilityGetContractInstance(address);
792
+ const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
737
793
 
738
794
  return toForeignCallResult([
739
795
  toSingle(instance.currentContractClassId),
@@ -745,7 +801,7 @@ export class RPCTranslator {
745
801
  async avmOpcodeGetContractInstanceInitializationHash(foreignAddress: ForeignCallSingle) {
746
802
  const address = addressFromSingle(foreignAddress);
747
803
 
748
- const instance = await this.oracleHandler.utilityGetContractInstance(address);
804
+ const instance = await this.handlerAsUtility().utilityGetContractInstance(address);
749
805
 
750
806
  return toForeignCallResult([
751
807
  toSingle(instance.initializationHash),
@@ -754,8 +810,8 @@ export class RPCTranslator {
754
810
  ]);
755
811
  }
756
812
 
757
- avmOpcodeSender() {
758
- const sender = this.oracleHandler.getMsgSender();
813
+ async avmOpcodeSender() {
814
+ const sender = await this.handlerAsAvm().avmOpcodeSender();
759
815
 
760
816
  return toForeignCallResult([toSingle(sender)]);
761
817
  }
@@ -763,7 +819,7 @@ export class RPCTranslator {
763
819
  async avmOpcodeEmitNullifier(foreignNullifier: ForeignCallSingle) {
764
820
  const nullifier = fromSingle(foreignNullifier);
765
821
 
766
- await this.oracleHandler.avmOpcodeEmitNullifier(nullifier);
822
+ await this.handlerAsAvm().avmOpcodeEmitNullifier(nullifier);
767
823
 
768
824
  return toForeignCallResult([]);
769
825
  }
@@ -771,7 +827,7 @@ export class RPCTranslator {
771
827
  async avmOpcodeEmitNoteHash(foreignNoteHash: ForeignCallSingle) {
772
828
  const noteHash = fromSingle(foreignNoteHash);
773
829
 
774
- await this.oracleHandler.avmOpcodeEmitNoteHash(noteHash);
830
+ await this.handlerAsAvm().avmOpcodeEmitNoteHash(noteHash);
775
831
 
776
832
  return toForeignCallResult([]);
777
833
  }
@@ -780,43 +836,43 @@ export class RPCTranslator {
780
836
  const innerNullifier = fromSingle(foreignInnerNullifier);
781
837
  const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
782
838
 
783
- const exists = await this.oracleHandler.avmOpcodeNullifierExists(innerNullifier, targetAddress);
839
+ const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(innerNullifier, targetAddress);
784
840
 
785
841
  return toForeignCallResult([toSingle(new Fr(exists))]);
786
842
  }
787
843
 
788
844
  async avmOpcodeAddress() {
789
- const contractAddress = await this.oracleHandler.avmOpcodeAddress();
845
+ const contractAddress = await this.handlerAsAvm().avmOpcodeAddress();
790
846
 
791
847
  return toForeignCallResult([toSingle(contractAddress.toField())]);
792
848
  }
793
849
 
794
850
  async avmOpcodeBlockNumber() {
795
- const blockNumber = await this.oracleHandler.avmOpcodeBlockNumber();
851
+ const blockNumber = await this.handlerAsAvm().avmOpcodeBlockNumber();
796
852
 
797
853
  return toForeignCallResult([toSingle(new Fr(blockNumber))]);
798
854
  }
799
855
 
800
856
  async avmOpcodeTimestamp() {
801
- const timestamp = await this.oracleHandler.avmOpcodeTimestamp();
857
+ const timestamp = await this.handlerAsAvm().avmOpcodeTimestamp();
802
858
 
803
859
  return toForeignCallResult([toSingle(new Fr(timestamp))]);
804
860
  }
805
861
 
806
862
  async avmOpcodeIsStaticCall() {
807
- const isStaticCall = await this.oracleHandler.avmOpcodeIsStaticCall();
863
+ const isStaticCall = await this.handlerAsAvm().avmOpcodeIsStaticCall();
808
864
 
809
865
  return toForeignCallResult([toSingle(new Fr(isStaticCall ? 1 : 0))]);
810
866
  }
811
867
 
812
868
  async avmOpcodeChainId() {
813
- const chainId = await this.oracleHandler.avmOpcodeChainId();
869
+ const chainId = await this.handlerAsAvm().avmOpcodeChainId();
814
870
 
815
871
  return toForeignCallResult([toSingle(chainId)]);
816
872
  }
817
873
 
818
874
  async avmOpcodeVersion() {
819
- const version = await this.oracleHandler.avmOpcodeVersion();
875
+ const version = await this.handlerAsAvm().avmOpcodeVersion();
820
876
 
821
877
  return toForeignCallResult([toSingle(version)]);
822
878
  }
@@ -879,7 +935,7 @@ export class RPCTranslator {
879
935
  const argsHash = fromSingle(foreignArgsHash);
880
936
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
881
937
 
882
- const returnValues = await this.oracleHandler.txePrivateCallNewFlow(
938
+ const returnValues = await this.handlerAsTxe().txePrivateCallNewFlow(
883
939
  from,
884
940
  targetContractAddress,
885
941
  functionSelector,
@@ -901,7 +957,7 @@ export class RPCTranslator {
901
957
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
902
958
  const args = fromArray(foreignArgs);
903
959
 
904
- const returnValues = await this.oracleHandler.txeSimulateUtilityFunction(
960
+ const returnValues = await this.handlerAsTxe().txeSimulateUtilityFunction(
905
961
  targetContractAddress,
906
962
  functionSelector,
907
963
  args,
@@ -922,13 +978,13 @@ export class RPCTranslator {
922
978
  const calldata = fromArray(foreignCalldata);
923
979
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
924
980
 
925
- const returnValues = await this.oracleHandler.txePublicCallNewFlow(from, address, calldata, isStaticCall);
981
+ const returnValues = await this.handlerAsTxe().txePublicCallNewFlow(from, address, calldata, isStaticCall);
926
982
 
927
983
  return toForeignCallResult([toArray(returnValues)]);
928
984
  }
929
985
 
930
986
  async privateGetSenderForTags() {
931
- const sender = await this.oracleHandler.privateGetSenderForTags();
987
+ const sender = await this.handlerAsPrivate().privateGetSenderForTags();
932
988
 
933
989
  // Return a Noir Option struct with `some` and `value` fields
934
990
  if (sender === undefined) {
@@ -943,7 +999,7 @@ export class RPCTranslator {
943
999
  async privateSetSenderForTags(foreignSenderForTags: ForeignCallSingle) {
944
1000
  const senderForTags = AztecAddress.fromField(fromSingle(foreignSenderForTags));
945
1001
 
946
- await this.oracleHandler.privateSetSenderForTags(senderForTags);
1002
+ await this.handlerAsPrivate().privateSetSenderForTags(senderForTags);
947
1003
 
948
1004
  return toForeignCallResult([]);
949
1005
  }
@@ -11,7 +11,9 @@ import {
11
11
  PrivateEventDataProvider,
12
12
  TaggingDataProvider,
13
13
  } from '@aztec/pxe/server';
14
+ import type { IPrivateExecutionOracle, IUtilityExecutionOracle } from '@aztec/pxe/simulator';
14
15
  import { FunctionSelector } from '@aztec/stdlib/abi';
16
+ import type { AuthWitness } from '@aztec/stdlib/auth-witness';
15
17
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
16
18
  import { GasSettings } from '@aztec/stdlib/gas';
17
19
  import { PrivateContextInputs } from '@aztec/stdlib/kernel';
@@ -19,10 +21,10 @@ import { makeGlobalVariables } from '@aztec/stdlib/testing';
19
21
  import { CallContext, GlobalVariables, TxContext } from '@aztec/stdlib/tx';
20
22
  import type { UInt32 } from '@aztec/stdlib/types';
21
23
 
24
+ import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
22
25
  import { TXE } from './oracle/txe_oracle.js';
23
26
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
24
27
  import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
25
- import type { TXETypedOracle } from './oracle/txe_typed_oracle.js';
26
28
  import { RPCTranslator } from './rpc_translator.js';
27
29
  import { TXEStateMachine } from './state_machine/index.js';
28
30
  import type { ForeignCallArgs, ForeignCallResult } from './util/encoding.js';
@@ -82,11 +84,16 @@ const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
82
84
  */
83
85
  export class TXESession implements TXESessionStateHandler {
84
86
  private state = SessionState.TOP_LEVEL;
87
+ private authwits: Map<string, AuthWitness> = new Map();
85
88
 
86
89
  constructor(
87
90
  private logger: Logger,
88
91
  private stateMachine: TXEStateMachine,
89
- private oracleHandler: TXETypedOracle,
92
+ private oracleHandler:
93
+ | IUtilityExecutionOracle
94
+ | IPrivateExecutionOracle
95
+ | IAvmExecutionOracle
96
+ | ITxeExecutionOracle,
90
97
  private contractDataProvider: TXEContractDataProvider,
91
98
  private keyStore: KeyStore,
92
99
  private addressDataProvider: AddressDataProvider,
@@ -143,6 +150,7 @@ export class TXESession implements TXESessionStateHandler {
143
150
  nextBlockTimestamp,
144
151
  version,
145
152
  chainId,
153
+ new Map(),
146
154
  );
147
155
  await topLevelOracleHandler.txeAdvanceBlocksBy(1);
148
156
 
@@ -168,7 +176,19 @@ export class TXESession implements TXESessionStateHandler {
168
176
  * @returns The oracle return values.
169
177
  */
170
178
  processFunction(functionName: TXEOracleFunctionName, inputs: ForeignCallArgs): Promise<ForeignCallResult> {
171
- return (new RPCTranslator(this, this.oracleHandler) as any)[functionName](...inputs);
179
+ try {
180
+ return (new RPCTranslator(this, this.oracleHandler) as any)[functionName](...inputs);
181
+ } catch (error) {
182
+ if (error instanceof Error) {
183
+ throw new Error(
184
+ `Execution error while processing function ${functionName} in state ${SessionState[this.state]}: ${error.message}`,
185
+ );
186
+ } else {
187
+ throw new Error(
188
+ `Unknown execution error while processing function ${functionName} in state ${SessionState[this.state]}`,
189
+ );
190
+ }
191
+ }
172
192
  }
173
193
 
174
194
  async setTopLevelContext() {
@@ -194,6 +214,7 @@ export class TXESession implements TXESessionStateHandler {
194
214
  this.nextBlockTimestamp,
195
215
  this.version,
196
216
  this.chainId,
217
+ this.authwits,
197
218
  );
198
219
 
199
220
  this.state = SessionState.TOP_LEVEL;
@@ -295,7 +316,11 @@ export class TXESession implements TXESessionStateHandler {
295
316
  // others, it will create empty blocks (via `txeAdvanceBlocksBy` and `deploy`), create blocks with transactions via
296
317
  // `txePrivateCallNewFlow` and `txePublicCallNewFlow`, add accounts to PXE via `txeAddAccount`, etc. This is a
297
318
  // slight inconsistency in the working model of this class, but is not too bad.
298
- this.nextBlockTimestamp = (this.oracleHandler as TXEOracleTopLevelContext).close();
319
+ // TODO: it's quite unfortunate that we need to capture the authwits created to later pass them again when the top
320
+ // level context is re-created. This is because authwits create a temporary utility context that'd otherwise reset
321
+ // the authwits if not persisted, so we'd not be able to pass more than one per execution.
322
+ // Ideally authwits would be passed alongside a contract call instead of pre-seeded.
323
+ [this.nextBlockTimestamp, this.authwits] = (this.oracleHandler as TXEOracleTopLevelContext).close();
299
324
  }
300
325
 
301
326
  private async exitPublicContext() {