@aztec/txe 0.0.1-commit.2f68f620 → 0.0.1-commit.321f6a9

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 (136) hide show
  1. package/dest/AuthRegistry-QVGDDH5X.js +3 -0
  2. package/dest/AuthRegistry-QVGDDH5X.js.map +7 -0
  3. package/dest/ContractClassRegistry-VWR3F42P.js +3 -0
  4. package/dest/ContractClassRegistry-VWR3F42P.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-FHIWE33X.js +3 -0
  6. package/dest/ContractInstanceRegistry-FHIWE33X.js.map +7 -0
  7. package/dest/FeeJuice-SAOWVGG7.js +3 -0
  8. package/dest/FeeJuice-SAOWVGG7.js.map +7 -0
  9. package/dest/HandshakeRegistry-GY5CPEPS.js +3 -0
  10. package/dest/HandshakeRegistry-GY5CPEPS.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-QG5H33ZZ.js +3 -0
  12. package/dest/MultiCallEntrypoint-QG5H33ZZ.js.map +7 -0
  13. package/dest/SchnorrAccount-NME3E45O.js +3 -0
  14. package/dest/SchnorrAccount-NME3E45O.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-WTGXU6SW.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-WTGXU6SW.js.map +7 -0
  17. package/dest/bin/check_txe_oracle_version.js +7 -15
  18. package/dest/bin/index.js +1 -1
  19. package/dest/bin/oracle_test_server.js +2 -2
  20. package/dest/chunk-32UHX7YY.js +3 -0
  21. package/dest/chunk-SZPMCTJK.js +260 -0
  22. package/dest/chunk-SZPMCTJK.js.map +7 -0
  23. package/dest/{chunk-W2NSX64C.js → chunk-YS3UIBVR.js} +2 -2
  24. package/dest/{chunk-W2NSX64C.js.map → chunk-YS3UIBVR.js.map} +3 -3
  25. package/dest/constants.d.ts +1 -1
  26. package/dest/constants.d.ts.map +1 -1
  27. package/dest/constants.js +1 -1
  28. package/dest/dispatcher_pool.d.ts +2 -2
  29. package/dest/dispatcher_pool.d.ts.map +1 -1
  30. package/dest/dispatcher_pool.js +5 -3
  31. package/dest/index.d.ts +2 -136
  32. package/dest/index.d.ts.map +1 -1
  33. package/dest/index.js +5 -3
  34. package/dest/metafile.json +9632 -7418
  35. package/dest/oracle/interfaces.d.ts +24 -11
  36. package/dest/oracle/interfaces.d.ts.map +1 -1
  37. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  38. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  39. package/dest/oracle/tagging_secret_strategy.js +12 -0
  40. package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
  41. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  42. package/dest/oracle/test-resolver/default_fixtures.js +200 -0
  43. package/dest/oracle/test-resolver/index.d.ts +1 -1
  44. package/dest/oracle/test-resolver/index.d.ts.map +1 -1
  45. package/dest/oracle/test-resolver/index.js +1 -2
  46. package/dest/oracle/test-resolver/resolver.d.ts +21 -7
  47. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -1
  48. package/dest/oracle/test-resolver/resolver.js +100 -33
  49. package/dest/oracle/txe_oracle_public_context.d.ts +9 -9
  50. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  51. package/dest/oracle/txe_oracle_public_context.js +15 -9
  52. package/dest/oracle/txe_oracle_registry.d.ts +51 -26
  53. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -1
  54. package/dest/oracle/txe_oracle_registry.js +258 -53
  55. package/dest/oracle/txe_oracle_top_level_context.d.ts +30 -9
  56. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  57. package/dest/oracle/txe_oracle_top_level_context.js +454 -288
  58. package/dest/oracle/txe_oracle_version.d.ts +4 -4
  59. package/dest/oracle/txe_oracle_version.js +4 -4
  60. package/dest/rpc_translator.d.ts +23 -4
  61. package/dest/rpc_translator.d.ts.map +1 -1
  62. package/dest/rpc_translator.js +167 -81
  63. package/dest/server.bundle.js +1 -1
  64. package/dest/state_machine/archiver.d.ts +1 -1
  65. package/dest/state_machine/archiver.d.ts.map +1 -1
  66. package/dest/state_machine/archiver.js +1 -2
  67. package/dest/state_machine/dummy_p2p_client.d.ts +5 -2
  68. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  69. package/dest/state_machine/dummy_p2p_client.js +9 -0
  70. package/dest/state_machine/global_variable_builder.d.ts +3 -4
  71. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  72. package/dest/state_machine/global_variable_builder.js +0 -3
  73. package/dest/state_machine/index.d.ts +8 -6
  74. package/dest/state_machine/index.d.ts.map +1 -1
  75. package/dest/state_machine/index.js +41 -19
  76. package/dest/state_machine/synchronizer.d.ts +10 -2
  77. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  78. package/dest/state_machine/synchronizer.js +18 -5
  79. package/dest/txe_session.d.ts +29 -20
  80. package/dest/txe_session.d.ts.map +1 -1
  81. package/dest/txe_session.js +165 -41
  82. package/dest/utils/block_creation.d.ts +2 -2
  83. package/dest/utils/block_creation.d.ts.map +1 -1
  84. package/dest/utils/block_creation.js +2 -2
  85. package/dest/utils/encoding.d.ts +4 -3
  86. package/dest/utils/encoding.d.ts.map +1 -1
  87. package/dest/utils/tx_effect_creation.d.ts +1 -1
  88. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  89. package/dest/utils/tx_effect_creation.js +0 -1
  90. package/dest/utils/txe_public_contract_data_source.d.ts +1 -1
  91. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -1
  92. package/dest/utils/txe_public_contract_data_source.js +7 -4
  93. package/dest/worker.bundle.js +1 -1
  94. package/package.json +17 -17
  95. package/src/bin/check_txe_oracle_version.ts +9 -12
  96. package/src/bin/oracle_test_server.ts +2 -2
  97. package/src/constants.ts +1 -1
  98. package/src/dispatcher_pool.ts +4 -3
  99. package/src/index.ts +6 -4
  100. package/src/oracle/interfaces.ts +26 -9
  101. package/src/oracle/tagging_secret_strategy.ts +25 -0
  102. package/src/oracle/test-resolver/default_fixtures.ts +271 -0
  103. package/src/oracle/test-resolver/index.ts +1 -2
  104. package/src/oracle/test-resolver/resolver.ts +121 -41
  105. package/src/oracle/txe_oracle_public_context.ts +16 -14
  106. package/src/oracle/txe_oracle_registry.ts +197 -42
  107. package/src/oracle/txe_oracle_top_level_context.ts +201 -66
  108. package/src/oracle/txe_oracle_version.ts +4 -4
  109. package/src/rpc_translator.ts +224 -108
  110. package/src/state_machine/archiver.ts +0 -1
  111. package/src/state_machine/dummy_p2p_client.ts +13 -0
  112. package/src/state_machine/global_variable_builder.ts +2 -16
  113. package/src/state_machine/index.ts +50 -34
  114. package/src/state_machine/synchronizer.ts +26 -5
  115. package/src/txe_session.ts +284 -45
  116. package/src/utils/block_creation.ts +2 -1
  117. package/src/utils/tx_effect_creation.ts +0 -2
  118. package/src/utils/txe_public_contract_data_source.ts +6 -4
  119. package/dest/ContractClassRegistry-PII7Q556.js +0 -3
  120. package/dest/ContractClassRegistry-PII7Q556.js.map +0 -7
  121. package/dest/ContractInstanceRegistry-3MHLGFNZ.js +0 -3
  122. package/dest/ContractInstanceRegistry-3MHLGFNZ.js.map +0 -7
  123. package/dest/FeeJuice-TQV5AQK7.js +0 -3
  124. package/dest/FeeJuice-TQV5AQK7.js.map +0 -7
  125. package/dest/MultiCallEntrypoint-SBJUIJY7.js +0 -3
  126. package/dest/MultiCallEntrypoint-SBJUIJY7.js.map +0 -7
  127. package/dest/SchnorrAccount-MQXPIZ44.js +0 -3
  128. package/dest/SchnorrAccount-MQXPIZ44.js.map +0 -7
  129. package/dest/chunk-BJVAAXNA.js +0 -3
  130. package/dest/chunk-CDITIZHX.js +0 -257
  131. package/dest/chunk-CDITIZHX.js.map +0 -7
  132. package/dest/oracle/test-resolver/fixtures.d.ts +0 -43
  133. package/dest/oracle/test-resolver/fixtures.d.ts.map +0 -1
  134. package/dest/oracle/test-resolver/fixtures.js +0 -39
  135. package/src/oracle/test-resolver/fixtures.ts +0 -84
  136. /package/dest/{chunk-BJVAAXNA.js.map → chunk-32UHX7YY.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "0.0.1-commit.2f68f620",
3
+ "version": "0.0.1-commit.321f6a9",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": {
@@ -69,22 +69,22 @@
69
69
  ]
70
70
  },
71
71
  "dependencies": {
72
- "@aztec/accounts": "0.0.1-commit.2f68f620",
73
- "@aztec/archiver": "0.0.1-commit.2f68f620",
74
- "@aztec/aztec-node": "0.0.1-commit.2f68f620",
75
- "@aztec/aztec.js": "0.0.1-commit.2f68f620",
76
- "@aztec/bb-prover": "0.0.1-commit.2f68f620",
77
- "@aztec/bb.js": "0.0.1-commit.2f68f620",
78
- "@aztec/constants": "0.0.1-commit.2f68f620",
79
- "@aztec/foundation": "0.0.1-commit.2f68f620",
80
- "@aztec/key-store": "0.0.1-commit.2f68f620",
81
- "@aztec/kv-store": "0.0.1-commit.2f68f620",
82
- "@aztec/protocol-contracts": "0.0.1-commit.2f68f620",
83
- "@aztec/pxe": "0.0.1-commit.2f68f620",
84
- "@aztec/simulator": "0.0.1-commit.2f68f620",
85
- "@aztec/standard-contracts": "0.0.1-commit.2f68f620",
86
- "@aztec/stdlib": "0.0.1-commit.2f68f620",
87
- "@aztec/world-state": "0.0.1-commit.2f68f620",
72
+ "@aztec/accounts": "0.0.1-commit.321f6a9",
73
+ "@aztec/archiver": "0.0.1-commit.321f6a9",
74
+ "@aztec/aztec-node": "0.0.1-commit.321f6a9",
75
+ "@aztec/aztec.js": "0.0.1-commit.321f6a9",
76
+ "@aztec/bb-prover": "0.0.1-commit.321f6a9",
77
+ "@aztec/bb.js": "0.0.1-commit.321f6a9",
78
+ "@aztec/constants": "0.0.1-commit.321f6a9",
79
+ "@aztec/foundation": "0.0.1-commit.321f6a9",
80
+ "@aztec/key-store": "0.0.1-commit.321f6a9",
81
+ "@aztec/kv-store": "0.0.1-commit.321f6a9",
82
+ "@aztec/protocol-contracts": "0.0.1-commit.321f6a9",
83
+ "@aztec/pxe": "0.0.1-commit.321f6a9",
84
+ "@aztec/simulator": "0.0.1-commit.321f6a9",
85
+ "@aztec/standard-contracts": "0.0.1-commit.321f6a9",
86
+ "@aztec/stdlib": "0.0.1-commit.321f6a9",
87
+ "@aztec/world-state": "0.0.1-commit.321f6a9",
88
88
  "msgpackr": "^1.11.2",
89
89
  "zod": "^4"
90
90
  },
@@ -1,32 +1,29 @@
1
1
  import { keccak256String } from '@aztec/foundation/crypto/keccak';
2
- import { getOracleInterfaceSignature, readNumericGlobal } from '@aztec/pxe/bin';
2
+ import { getOracleRegistrySignature, readNumericGlobal } from '@aztec/pxe/bin';
3
+ import { ORACLE_REGISTRY, type OracleRegistryEntry } from '@aztec/pxe/simulator';
3
4
 
4
5
  import { dirname, join } from 'path';
5
6
  import { fileURLToPath } from 'url';
6
7
 
8
+ import { TXE_ORACLE_REGISTRY } from '../oracle/txe_oracle_registry.js';
7
9
  import { TXE_ORACLE_INTERFACE_HASH, TXE_ORACLE_VERSION_MAJOR } from '../oracle/txe_oracle_version.js';
8
10
 
9
11
  /**
10
12
  * Verifies that the TXE oracle interfaces match the expected interface hash.
11
13
  *
12
14
  * The TXE oracle interfaces need to be versioned to ensure compatibility between Aztec.nr tests and TXE. This function
13
- * computes a hash of the TXE oracle interfaces and compares it against a known hash. If they don't match, it means an
15
+ * computes a hash of the TXE-specific entries in `TXE_ORACLE_REGISTRY` (the shared PXE entries are covered by the PXE
16
+ * oracle version check) and compares it against a known hash. If they don't match, it means an
14
17
  * interface has changed and the TXE oracle version needs to be bumped:
15
18
  * - If the change is backward-breaking (e.g. removing/renaming an oracle), bump TXE_ORACLE_VERSION_MAJOR.
16
19
  * - If the change is an oracle addition (non-breaking), bump TXE_ORACLE_VERSION_MINOR.
17
20
  */
18
21
  function assertTxeOracleInterfaceMatches(): void {
19
- const currentDir = dirname(fileURLToPath(import.meta.url));
20
- const packageRoot = dirname(dirname(currentDir));
21
- const interfacesSourcePath = join(packageRoot, 'src/oracle/interfaces.ts');
22
-
23
- const targets = ['IAvmExecutionOracle', 'ITxeExecutionOracle'];
24
- // Not an oracle foreign call handler (see TODO(F-335) in interfaces.ts).
25
- const excludedMembers = ['syncContractNonOracleMethod'];
26
-
27
- const txeOracleInterfaceSignature = getOracleInterfaceSignature(interfacesSourcePath, targets, excludedMembers);
22
+ const txeOnlyEntries: Record<string, OracleRegistryEntry> = Object.fromEntries(
23
+ Object.entries(TXE_ORACLE_REGISTRY).filter(([name]) => !(name in ORACLE_REGISTRY)),
24
+ );
28
25
 
29
- const txeOracleInterfaceHash = keccak256String(txeOracleInterfaceSignature);
26
+ const txeOracleInterfaceHash = keccak256String(getOracleRegistrySignature(txeOnlyEntries));
30
27
  if (txeOracleInterfaceHash !== TXE_ORACLE_INTERFACE_HASH) {
31
28
  throw new Error(
32
29
  `The TXE oracle interface has changed. Update TXE_ORACLE_INTERFACE_HASH to ${txeOracleInterfaceHash} in txe/src/oracle/txe_oracle_version.ts and bump the TXE oracle version (TXE_ORACLE_VERSION_MAJOR for breaking changes, TXE_ORACLE_VERSION_MINOR for oracle additions).`,
@@ -5,8 +5,8 @@ import { startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
5
5
  import { createOracleTestRpcServer } from '../oracle/test-resolver/index.js';
6
6
 
7
7
  /**
8
- * Starts an HTTP RPC server that resolves oracle foreign calls using hardcoded fixture scenarios.
9
- * Used by `nargo test --oracle-resolver` to run `#[oracle_test]` roundtrip tests with a dedicated oracle resolver.
8
+ * Starts an HTTP RPC server that resolves oracle foreign calls using auto-synthesized fixture scenarios. Used by
9
+ * `nargo test --oracle-resolver` to run `#[generate_oracle_tests]` serialization tests against a dedicated resolver.
10
10
  * Logs fixture coverage on shutdown.
11
11
  */
12
12
  async function main() {
package/src/constants.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { PRIVATE_LOG_CIPHERTEXT_LEN } from '@aztec/constants';
2
2
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
3
3
 
4
- export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
4
+ export const DEFAULT_ADDRESS = AztecAddress.fromNumberUnsafe(42);
5
5
 
6
6
  // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN
7
7
  export const MAX_PRIVATE_EVENT_LEN = 10;
@@ -4,7 +4,8 @@ import type { Logger } from '@aztec/foundation/log';
4
4
  import { openEphemeralStore } from '@aztec/kv-store/lmdb-v2';
5
5
  import { LazyProtocolContractsProvider } from '@aztec/protocol-contracts/providers/lazy';
6
6
  import { ContractStore } from '@aztec/pxe/client/lazy';
7
- import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry';
7
+ import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry/lazy';
8
+ import { getStandardHandshakeRegistry } from '@aztec/standard-contracts/handshake-registry/lazy';
8
9
  import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
9
10
 
10
11
  import { existsSync } from 'node:fs';
@@ -21,7 +22,7 @@ void BarretenbergSync.initSingleton({ backend: BackendType.Wasm });
21
22
 
22
23
  /**
23
24
  * Opens a fresh LMDB in a tmp dir and writes the protocol contracts in
24
- * {@link TXE_REQUIRED_PROTOCOL_CONTRACTS} plus the standard AuthRegistry and the SchnorrAccount artifact,
25
+ * {@link TXE_REQUIRED_PROTOCOL_CONTRACTS} plus the standard AuthRegistry, HandshakeRegistry, and the SchnorrAccount artifact,
25
26
  * returning the directory path and the SchnorrAccount class id (hex). The store handle is intentionally kept
26
27
  * alive: closing it would trigger the ephemeral-store cleanup hook and remove the tmp
27
28
  * directory, so any worker that has not yet cloned would find it missing.
@@ -33,7 +34,7 @@ export async function buildSharedContractStore(): Promise<{ dataDir: string; sch
33
34
  const provider = new LazyProtocolContractsProvider();
34
35
  const [protocolContracts, standardContracts, schnorrArtifact] = await Promise.all([
35
36
  Promise.all(TXE_REQUIRED_PROTOCOL_CONTRACTS.map(name => provider.getProtocolContractArtifact(name))),
36
- Promise.all([getStandardAuthRegistry()]),
37
+ Promise.all([getStandardAuthRegistry(), getStandardHandshakeRegistry()]),
37
38
  getSchnorrAccountContractArtifact(),
38
39
  ]);
39
40
  const schnorrClass = await getContractClassFromArtifact(schnorrArtifact);
package/src/index.ts CHANGED
@@ -21,9 +21,11 @@ import {
21
21
  } from './utils/encoding.js';
22
22
  import { TXEArtifactResolver } from './utils/txe_artifact_resolver.js';
23
23
 
24
- // Protocol contracts TXE registers in its contract store. Only AuthRegistry is needed for the
25
- // current test suites; add a contract here if a lookup against a `0x000…00X` address fails.
26
- export const TXE_REQUIRED_PROTOCOL_CONTRACTS: ProtocolContractName[] = [];
24
+ export const TXE_REQUIRED_PROTOCOL_CONTRACTS: ProtocolContractName[] = [
25
+ 'ContractClassRegistry',
26
+ 'ContractInstanceRegistry',
27
+ 'FeeJuice',
28
+ ];
27
29
 
28
30
  const sessions = new Map<number, TXESession>();
29
31
 
@@ -35,7 +37,7 @@ export type TXEForeignCallInput = {
35
37
  inputs: ForeignCallArgs;
36
38
  };
37
39
 
38
- export const TXEForeignCallInputSchema = zodFor<TXEForeignCallInput>()(
40
+ export const TXEForeignCallInputSchema: z.ZodType<TXEForeignCallInput> = zodFor<TXEForeignCallInput>()(
39
41
  z.object({
40
42
  // Nargo generates session_id as a u64, which may exceed Number.MAX_SAFE_INTEGER.
41
43
  // Zod 4's `.int()` enforces the safe-integer bound, so we drop it here and only require
@@ -2,6 +2,9 @@ import { CompleteAddress } from '@aztec/aztec.js/addresses';
2
2
  import { TxHash } from '@aztec/aztec.js/tx';
3
3
  import { BlockNumber } from '@aztec/foundation/branded-types';
4
4
  import type { Fr } from '@aztec/foundation/curves/bn254';
5
+ import type { EthAddress } from '@aztec/foundation/eth-address';
6
+ import type { TaggingSecretStrategy } from '@aztec/pxe/server';
7
+ import type { Option } from '@aztec/pxe/simulator';
5
8
  import type { EventSelector, FunctionSelector } from '@aztec/stdlib/abi';
6
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
10
  import type { GasSettings } from '@aztec/stdlib/gas';
@@ -36,15 +39,15 @@ export interface IAvmExecutionOracle {
36
39
  nullifierExists(siloedNullifier: Fr): Promise<boolean>;
37
40
  storageWrite(slot: Fr, value: Fr): Promise<void>;
38
41
  storageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr>;
39
- getContractInstanceDeployer(address: AztecAddress): Promise<{ member: Fr; exists: boolean }>;
40
- getContractInstanceClassId(address: AztecAddress): Promise<{ member: Fr; exists: boolean }>;
41
- getContractInstanceInitializationHash(address: AztecAddress): Promise<{ member: Fr; exists: boolean }>;
42
- getContractInstanceImmutablesHash(address: AztecAddress): Promise<{ member: Fr; exists: boolean }>;
43
- returndataSize(): Promise<Fr>;
42
+ getContractInstanceDeployer(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]>;
43
+ getContractInstanceClassId(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]>;
44
+ getContractInstanceInitializationHash(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]>;
45
+ getContractInstanceImmutablesHash(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]>;
46
+ returndataSize(): Promise<number>;
44
47
  returndataCopy(rdOffset: number, copySize: number): Promise<Fr[]>;
45
- call(l2Gas: number, daGas: number, address: AztecAddress, argsLength: number, args: Fr[]): Promise<Fr[]>;
46
- staticCall(l2Gas: number, daGas: number, address: AztecAddress, argsLength: number, args: Fr[]): Promise<Fr[]>;
47
- successCopy(): Promise<Fr>;
48
+ call(l2Gas: number, daGas: number, address: AztecAddress, argsLength: number, args: Fr[]): Promise<void>;
49
+ staticCall(l2Gas: number, daGas: number, address: AztecAddress, argsLength: number, args: Fr[]): Promise<void>;
50
+ successCopy(): Promise<boolean>;
48
51
  }
49
52
 
50
53
  /**
@@ -66,9 +69,22 @@ export interface ITxeExecutionOracle {
66
69
  salt: Fr,
67
70
  deployer: AztecAddress,
68
71
  ): Promise<Fr[]>;
69
- createAccount(secret: Fr): Promise<CompleteAddress>;
72
+ createAccount(secret: Fr, partialAddress: Fr): Promise<CompleteAddress>;
70
73
  addAccount(secret: Fr): Promise<CompleteAddress>;
71
74
  addAuthWitness(address: AztecAddress, messageHash: Fr): Promise<void>;
75
+ sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr>;
76
+ /**
77
+ * Configures the tagging secret strategy the test's simulated wallet resolves for each delivery mode. A `none`
78
+ * clears that mode, so it falls back to the default strategy (or, when both modes end up unset, to no hook at all).
79
+ */
80
+ setTaggingSecretStrategies(
81
+ unconstrainedStrategy: Option<TaggingSecretStrategy>,
82
+ constrainedStrategy: Option<TaggingSecretStrategy>,
83
+ ): void;
84
+ /**
85
+ * Configures whether the test's simulated wallet authorizes every cross-contract utility call target.
86
+ */
87
+ setAuthorizeAllUtilityCallTargets(authorizeAll: boolean): void;
72
88
  getLastBlockTimestamp(): Promise<bigint>;
73
89
  getLastTxEffects(): Promise<{
74
90
  txHash: TxHash;
@@ -90,6 +106,7 @@ export interface ITxeExecutionOracle {
90
106
  gasSettings: GasSettings,
91
107
  ): Promise<{ returnValues: Fr[]; offchainEffects: Fr[][] }>;
92
108
  executeUtilityFunction(
109
+ from: AztecAddress | undefined,
93
110
  targetContractAddress: AztecAddress,
94
111
  functionSelector: FunctionSelector,
95
112
  args: Fr[],
@@ -0,0 +1,25 @@
1
+ import {
2
+ DEFAULT_TAGGING_SECRET_STRATEGY,
3
+ type ResolveTaggingSecretStrategy,
4
+ type TaggingSecretStrategy,
5
+ } from '@aztec/pxe/server';
6
+ import type { AppTaggingSecretKind } from '@aztec/stdlib/logs';
7
+
8
+ /** The tagging secret strategies a TXE test has configured, keyed by delivery mode. Absence means "not configured". */
9
+ export type TXETaggingSecretStrategies = Map<AppTaggingSecretKind, TaggingSecretStrategy>;
10
+
11
+ /**
12
+ * Builds the `resolveTaggingSecretStrategy` hook backing the `aztec_txe_setTaggingSecretStrategies` oracle. Returns
13
+ * `undefined` when no strategy is configured, so PXE's own no-hook default path is exercised. When at least one mode
14
+ * is configured, modes without an entry resolve to {@link DEFAULT_TAGGING_SECRET_STRATEGY}, matching what PXE would
15
+ * apply without a hook.
16
+ */
17
+ export function makeResolveTaggingSecretStrategyHook(
18
+ strategies: TXETaggingSecretStrategies,
19
+ ): ResolveTaggingSecretStrategy | undefined {
20
+ if (strategies.size === 0) {
21
+ return undefined;
22
+ }
23
+
24
+ return ({ deliveryMode }) => Promise.resolve(strategies.get(deliveryMode) ?? DEFAULT_TAGGING_SECRET_STRATEGY);
25
+ }
@@ -0,0 +1,271 @@
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
+ import { EthAddress } from '@aztec/foundation/eth-address';
5
+ import {
6
+ AZTEC_ADDRESS,
7
+ BIGINT,
8
+ BLOCK_HASH,
9
+ BLOCK_NUMBER,
10
+ BOOL,
11
+ BoundedVec,
12
+ type CompositeMapping,
13
+ DELIVERY_MODE,
14
+ ETH_ADDRESS,
15
+ FIELD,
16
+ FUNCTION_SELECTOR,
17
+ LEAF_INDEX,
18
+ NOTE_SELECTOR,
19
+ Option,
20
+ type OracleRegistryEntry,
21
+ SLOT_NUMBER,
22
+ type StructMapping,
23
+ type TypeMapping,
24
+ U8,
25
+ U32,
26
+ U64,
27
+ U128,
28
+ isArrayMapping,
29
+ isBoundedVecMapping,
30
+ isFixedArrayMapping,
31
+ isFixedBoundedVecMapping,
32
+ isOptionMapping,
33
+ isStructMapping,
34
+ tryFieldWidth,
35
+ } from '@aztec/pxe/simulator';
36
+ import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
37
+ import { BlockHash } from '@aztec/stdlib/block';
38
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
39
+
40
+ import type { OracleTestScenario } from './resolver.js';
41
+
42
+ /**
43
+ * Synthesizes fixture scenarios for every oracle in the registry whose parameters and return are built from scalars,
44
+ * arrays/bounded vecs of them, `Option`s of them, or `STRUCT`s over them. The matching Noir serialization tests are
45
+ * auto-generated by `#[generate_oracle_tests]` from the same seed/scenario convention.
46
+ */
47
+ export function synthesizeDefaultFixtures(
48
+ registry: Record<string, OracleRegistryEntry>,
49
+ ): Record<string, OracleTestScenario[]> {
50
+ const synthesized: Record<string, OracleTestScenario[]> = {};
51
+
52
+ for (const [name, entry] of Object.entries(registry)) {
53
+ const scenarios = synthesizeScenarios(entry);
54
+ if (scenarios !== undefined) {
55
+ synthesized[name] = scenarios;
56
+ }
57
+ }
58
+
59
+ return synthesized;
60
+ }
61
+
62
+ /**
63
+ * The scalar test-value implementations, mirroring the Noir synthesizer's `scalars` table in
64
+ * `noir-projects/aztec-nr/.../macros/oracle_testing.nr` exactly.
65
+ */
66
+ const SCALAR_IMPLS: ScalarImpl[] = [
67
+ scalar(FIELD, seed => new Fr(seed)),
68
+ scalar(U32, seed => seed),
69
+ scalar(BLOCK_NUMBER, seed => BlockNumber(seed)),
70
+ scalar(BIGINT, seed => BigInt(seed)),
71
+ scalar(U64, seed => BigInt(seed)),
72
+ scalar(U128, seed => BigInt(seed)),
73
+ scalar(LEAF_INDEX, seed => seed),
74
+ scalar(U8, seed => seed),
75
+ scalar(BOOL, seed => seed % 2 !== 0),
76
+ scalar(AZTEC_ADDRESS, seed => AztecAddress.fromNumberUnsafe(seed)),
77
+ scalar(ETH_ADDRESS, seed => EthAddress.fromField(new Fr(seed))),
78
+ scalar(FUNCTION_SELECTOR, seed => FunctionSelector.fromField(new Fr(seed))),
79
+ scalar(NOTE_SELECTOR, seed => NoteSelector.fromField(new Fr(seed))),
80
+ scalar(BLOCK_HASH, seed => new BlockHash(new Fr(seed))),
81
+ scalar(SLOT_NUMBER, seed => SlotNumber(seed)),
82
+ // Only two delivery modes are valid for tagging, so the seed alternates between them, matching the Noir impl.
83
+ scalar(DELIVERY_MODE, seed =>
84
+ seed % 2 === 0 ? AppTaggingSecretKind.UNCONSTRAINED : AppTaggingSecretKind.CONSTRAINED,
85
+ ),
86
+ ];
87
+
88
+ /**
89
+ * The composite test-value implementations, one per combinator, mirroring the Noir synthesizer's `synthesizers` table.
90
+ */
91
+ const COMPOSITE_IMPLS: CompositeImpl[] = [
92
+ composite(isOptionMapping, (type, seed) => [
93
+ named(Option.some(testValueFor(type.inner, seed)), 'some'),
94
+ named(Option.none(testValueFor(type.inner, seed)), 'none'),
95
+ ]),
96
+ composite(isArrayMapping, (type, seed) => [unnamed(collectionData(type.inner, seed, DEFAULT_ARRAY_LENGTH))]),
97
+ composite(isBoundedVecMapping, (type, seed) => [
98
+ unnamed(
99
+ BoundedVec.from({
100
+ data: collectionData(type.inner, seed, DEFAULT_ARRAY_LENGTH),
101
+ maxLength: BOUNDED_VEC_MAX_LENGTH,
102
+ }),
103
+ ),
104
+ ]),
105
+ composite(isStructMapping, (type, seed) => [unnamed(structValue(type, seed))]),
106
+ // A fixed-length array uses its real (signature) length, unlike the generic-length ARRAY which is pinned to
107
+ // DEFAULT_ARRAY_LENGTH.
108
+ composite(isFixedArrayMapping, (type, seed) => [unnamed(collectionData(type.inner, seed, type.length))]),
109
+ // Same for a fixed-capacity bounded vec: real capacity, DEFAULT_ARRAY_LENGTH elements (its value type is a plain
110
+ // element array, unlike the two-slot BOUNDED_VEC), clamped to the capacity so small vecs stay valid.
111
+ composite(isFixedBoundedVecMapping, (type, seed) => [
112
+ unnamed(collectionData(type.inner, seed, Math.min(DEFAULT_ARRAY_LENGTH, type.maxLength))),
113
+ ]),
114
+ ];
115
+
116
+ /** The scalar mappings with a registered test-value impl. */
117
+ export const SCALAR_MAPPINGS: TypeMapping<any>[] = SCALAR_IMPLS.map(impl => impl.mapping);
118
+
119
+ /**
120
+ * The base every seed is offset by, applied once where a parameter's position becomes its seed, so generated values
121
+ * stay clear of 0. Must match `SEED_BASE` in the Noir `oracle_testing.nr`.
122
+ */
123
+ const SEED_BASE = 10;
124
+
125
+ /** Elements per synthesized array and bounded vec. Must match `TEST_COLLECTION_LEN` in the Noir `oracle_testing.nr`. */
126
+ const DEFAULT_ARRAY_LENGTH = 3;
127
+
128
+ /**
129
+ * Capacity of synthesized bounded vecs, deliberately larger than the data length so padding is exercised. Must match
130
+ * `TEST_BOUNDED_VEC_CAP` in the Noir `oracle_testing.nr`.
131
+ */
132
+ const BOUNDED_VEC_MAX_LENGTH = 5;
133
+
134
+ /**
135
+ * One canonical test case for a type: the `value` to put on the wire (or expect back), and the `name` of the
136
+ * serialization shape it exercises (unset for single-scenario types). Mirrors the Noir `Scenario<T>`.
137
+ */
138
+ interface Scenario {
139
+ value: unknown;
140
+ name?: string;
141
+ }
142
+
143
+ function unnamed(value: unknown): Scenario {
144
+ return { value };
145
+ }
146
+ function named(value: unknown, name: string): Scenario {
147
+ return { value, name };
148
+ }
149
+
150
+ /** An impl for the single scalar `mapping` it synthesizes for. */
151
+ type ScalarImpl = {
152
+ mapping: TypeMapping<any>;
153
+ scenarios: (type: TypeMapping<any>, seed: number) => Scenario[];
154
+ };
155
+
156
+ /** An impl for a whole family of composite mappings, selected by its `kind` type guard. */
157
+ type CompositeImpl = {
158
+ match: (type: TypeMapping<any>) => boolean;
159
+ scenarios: (type: TypeMapping<any>, seed: number) => Scenario[];
160
+ };
161
+
162
+ /** A scalar impl yielding a single unnamed scenario. */
163
+ function scalar(mapping: TypeMapping<any>, value: (seed: number) => unknown): ScalarImpl {
164
+ return { mapping, scenarios: (_type, seed) => [unnamed(value(seed))] };
165
+ }
166
+
167
+ /** A composite impl, recursing through the matched mapping's element/inner mapping. */
168
+ function composite<K extends CompositeMapping>(
169
+ guard: (type: TypeMapping<any>) => type is K,
170
+ scenarios: (type: K, seed: number) => Scenario[],
171
+ ): CompositeImpl {
172
+ return { match: guard, scenarios: (type, seed) => scenarios(type as K, seed) };
173
+ }
174
+
175
+ /** Synthesized element values for a collection. */
176
+ function collectionData(element: TypeMapping<any>, seed: number, length: number): unknown[] {
177
+ return Array.from({ length }, (_, i) => testValueFor(element, seed + i));
178
+ }
179
+
180
+ /**
181
+ * The synthesized prop bag for a struct: each field's first scenario, seeded at the field's flat wire offset so the
182
+ * values depend on the wire layout rather than on how each side groups its fields. Mirrors the Noir reflected impls.
183
+ */
184
+ function structValue(type: StructMapping, seed: number): Record<string, unknown> {
185
+ const value: Record<string, unknown> = {};
186
+ let offset = 0;
187
+ for (const field of type.fields) {
188
+ value[field.name] = testValueFor(field.type, seed + offset);
189
+ const width = tryFieldWidth(field.type.shape);
190
+ if (width === undefined) {
191
+ // A variable-width field has no flat offset to seed the next field at, so only this oracle is unsynthesizable.
192
+ throw new UnsynthesizableTypeError(field.type, `struct field '${field.name}' has a variable-width shape`);
193
+ }
194
+ offset += width;
195
+ }
196
+ return value;
197
+ }
198
+
199
+ /**
200
+ * The [`Scenario`]s for `type` at `seed`, one per serialization *shape*, mirroring the Noir `scenarios_for`
201
+ * dispatcher. Throws if the type has no matching impl.
202
+ */
203
+ function scenariosForType(type: TypeMapping<any>, seed: number): Scenario[] {
204
+ const impl = SCALAR_IMPLS.find(i => i.mapping === type) ?? COMPOSITE_IMPLS.find(i => i.match(type));
205
+ if (!impl) {
206
+ throw new UnsynthesizableTypeError(type);
207
+ }
208
+ return impl.scenarios(type, seed);
209
+ }
210
+
211
+ /**
212
+ * The test value of `type` at `seed`, matching what the Noir synthesizer produces for the same type and seed. Throws
213
+ * for types without a test-value impl.
214
+ */
215
+ export function testValueFor(type: TypeMapping<any>, seed: number): unknown {
216
+ return scenariosForType(type, seed)[0].value;
217
+ }
218
+
219
+ class UnsynthesizableTypeError extends Error {
220
+ constructor(type: TypeMapping<any>, detail?: string) {
221
+ super(detail ?? `No test-value impl for type: ${JSON.stringify(Object.keys(type))}`);
222
+ this.name = 'UnsynthesizableTypeError';
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Synthesizes the scenarios for one oracle by zipping every position's [`Scenario`] list to one case per test (a
228
+ * shorter list wraps around via mod), mirroring the Noir macro. Returns `undefined` if any param or return type is
229
+ * unsynthesizable (ephemeral arrays, structs with a variable-width field).
230
+ */
231
+ function synthesizeScenarios(entry: OracleRegistryEntry): OracleTestScenario[] | undefined {
232
+ try {
233
+ return synthesizeScenariosOrThrow(entry);
234
+ } catch (e) {
235
+ if (e instanceof UnsynthesizableTypeError) {
236
+ return undefined;
237
+ }
238
+ throw e;
239
+ }
240
+ }
241
+
242
+ function synthesizeScenariosOrThrow(entry: OracleRegistryEntry): OracleTestScenario[] {
243
+ const params = entry.params.map((param, index) => ({
244
+ name: param.name,
245
+ scenarios: scenariosForType(param.type, SEED_BASE + index),
246
+ }));
247
+ // The return's seed is the slot right after the last parameter, so its value is distinct from every parameter.
248
+ const returnScenarios =
249
+ entry.returnType === undefined ? undefined : scenariosForType(entry.returnType, SEED_BASE + entry.params.length);
250
+
251
+ // Positions with more than one scenario drive the test count; their names are zipped together (joined with `+`) per
252
+ // test, matching the announcements the Noir tests emit and the resolver joins.
253
+ const positions = [...params.map(p => p.scenarios), ...(returnScenarios !== undefined ? [returnScenarios] : [])];
254
+ const namedPositions = positions.filter(s => s.length > 1);
255
+ const testCount = Math.max(1, ...positions.map(s => s.length));
256
+
257
+ const scenarios: OracleTestScenario[] = [];
258
+ for (let index = 0; index < testCount; index++) {
259
+ const inputs: Record<string, unknown> = {};
260
+ for (const { name, scenarios: cases } of params) {
261
+ inputs[name] = cases[index % cases.length].value;
262
+ }
263
+ const output = returnScenarios === undefined ? undefined : returnScenarios[index % returnScenarios.length].value;
264
+ const scenario =
265
+ namedPositions.length === 0
266
+ ? undefined
267
+ : namedPositions.map(cases => cases[index % cases.length].name!).join('+');
268
+ scenarios.push({ scenario, inputs, output });
269
+ }
270
+ return scenarios;
271
+ }
@@ -8,7 +8,6 @@ import { z } from 'zod';
8
8
 
9
9
  import { ForeignCallArgsSchema, type ForeignCallResult, ForeignCallResultSchema } from '../../utils/encoding.js';
10
10
  import { TXE_ORACLE_REGISTRY } from '../txe_oracle_registry.js';
11
- import { ORACLE_TEST_FIXTURES } from './fixtures.js';
12
11
  import { type OracleTestCallInput, OracleTestResolver } from './resolver.js';
13
12
 
14
13
  const OracleTestCallInputSchema = zodFor<OracleTestCallInput>()(
@@ -35,7 +34,7 @@ const OracleTestRpcHandlerSchema: ApiSchemaFor<OracleTestRpcHandler> = {
35
34
 
36
35
  /** Creates an RPC server backed by the oracle test resolver. */
37
36
  export function createOracleTestRpcServer(logger: Logger) {
38
- const resolver = new OracleTestResolver(TXE_ORACLE_REGISTRY, ORACLE_TEST_FIXTURES, logger);
37
+ const resolver = OracleTestResolver.fromRegistry(TXE_ORACLE_REGISTRY, logger);
39
38
  const server = createSafeJsonRpcServer<OracleTestRpcHandler>(resolver, OracleTestRpcHandlerSchema, {
40
39
  http200OnError: true,
41
40
  });