@aztec/pxe 5.0.0-rc.1 → 5.0.0-rc.2
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.
- package/dest/block_synchronizer/block_stream_source.d.ts +5 -5
- package/dest/block_synchronizer/block_stream_source.d.ts.map +1 -1
- package/dest/block_synchronizer/block_stream_source.js +4 -29
- package/dest/block_synchronizer/block_synchronizer.d.ts +13 -11
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +43 -15
- package/dest/config/index.d.ts +2 -1
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +1 -0
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +11 -16
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +22 -18
- package/dest/contract_function_simulator/index.d.ts +15 -9
- package/dest/contract_function_simulator/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.js +3 -7
- package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts +8 -27
- package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/bounded_vec.js +8 -23
- package/dest/contract_function_simulator/noir-structs/contract_class_log_data.d.ts +9 -0
- package/dest/contract_function_simulator/noir-structs/contract_class_log_data.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/contract_class_log_data.js +1 -0
- package/dest/contract_function_simulator/noir-structs/embedded_curve_point.d.ts +7 -0
- package/dest/contract_function_simulator/noir-structs/embedded_curve_point.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/embedded_curve_point.js +1 -0
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/fact.d.ts +16 -0
- package/dest/contract_function_simulator/noir-structs/fact.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/fact.js +6 -0
- package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts +27 -0
- package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/fact_collection.js +29 -0
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +11 -12
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +6 -49
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +4 -8
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -60
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +2 -2
- package/dest/contract_function_simulator/noir-structs/option.d.ts +9 -11
- package/dest/contract_function_simulator/noir-structs/option.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/option.js +18 -13
- package/dest/contract_function_simulator/noir-structs/origin_block.d.ts +11 -0
- package/dest/contract_function_simulator/noir-structs/origin_block.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/origin_block.js +5 -0
- package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts +5 -8
- package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/provided_secret.js +1 -14
- package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts +21 -0
- package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.js +33 -0
- package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts +21 -0
- package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/resolved_tx.js +50 -0
- package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts +14 -0
- package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/tx_effect_data.js +5 -0
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +6 -11
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/utility_context.js +1 -20
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +3 -14
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.js +1 -24
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +81 -6
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle_registry.js +128 -9
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +80 -36
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +926 -264
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +13 -8
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +80 -11
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +46 -20
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +119 -55
- package/dest/contract_sync/helpers.d.ts +7 -6
- package/dest/contract_sync/helpers.d.ts.map +1 -1
- package/dest/contract_sync/helpers.js +11 -16
- package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +1 -0
- package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +1 -0
- package/dest/entrypoints/pxe_creation_options.d.ts +8 -2
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/server/index.d.ts +1 -2
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +0 -1
- package/dest/entrypoints/server/utils.d.ts +1 -1
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +3 -1
- package/dest/error_enriching.js +1 -1
- package/dest/hooks/execution_hooks.d.ts +16 -7
- package/dest/hooks/execution_hooks.d.ts.map +1 -1
- package/dest/hooks/execution_hooks.js +3 -3
- package/dest/hooks/index.d.ts +3 -3
- package/dest/hooks/index.d.ts.map +1 -1
- package/dest/hooks/resolve_tagging_secret_strategy.d.ts +41 -0
- package/dest/hooks/resolve_tagging_secret_strategy.d.ts.map +1 -0
- package/dest/hooks/resolve_tagging_secret_strategy.js +3 -0
- package/dest/logs/log_service.d.ts +6 -6
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +62 -28
- package/dest/messages/tx_resolver_service.d.ts +17 -0
- package/dest/messages/tx_resolver_service.d.ts.map +1 -0
- package/dest/messages/{message_context_service.js → tx_resolver_service.js} +8 -8
- package/dest/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +2 -2
- package/dest/private_kernel/hints/test_utils.js +1 -1
- package/dest/pxe.d.ts +46 -19
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +104 -52
- package/dest/storage/allowed_scopes.d.ts +6 -0
- package/dest/storage/allowed_scopes.d.ts.map +1 -0
- package/dest/storage/allowed_scopes.js +7 -0
- package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +1 -1
- package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -1
- package/dest/storage/backwards_compatibility_tests/schema_tests.js +86 -33
- package/dest/storage/capsule_store/capsule_service.d.ts +1 -1
- package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -1
- package/dest/storage/capsule_store/capsule_service.js +6 -9
- package/dest/storage/contract_store/contract_store.js +2 -2
- package/dest/storage/fact_store/fact_service.d.ts +20 -0
- package/dest/storage/fact_store/fact_service.d.ts.map +1 -0
- package/dest/storage/fact_store/fact_service.js +30 -0
- package/dest/storage/fact_store/fact_store.d.ts +95 -0
- package/dest/storage/fact_store/fact_store.d.ts.map +1 -0
- package/dest/storage/fact_store/fact_store.js +408 -0
- package/dest/storage/fact_store/fact_store_keys.d.ts +34 -0
- package/dest/storage/fact_store/fact_store_keys.d.ts.map +1 -0
- package/dest/storage/fact_store/fact_store_keys.js +50 -0
- package/dest/storage/fact_store/index.d.ts +5 -0
- package/dest/storage/fact_store/index.d.ts.map +1 -0
- package/dest/storage/fact_store/index.js +3 -0
- package/dest/storage/fact_store/stored_fact.d.ts +32 -0
- package/dest/storage/fact_store/stored_fact.d.ts.map +1 -0
- package/dest/storage/fact_store/stored_fact.js +64 -0
- package/dest/storage/index.d.ts +2 -1
- package/dest/storage/index.d.ts.map +1 -1
- package/dest/storage/index.js +1 -0
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/open_pxe_stores.d.ts +5 -3
- package/dest/storage/open_pxe_stores.d.ts.map +1 -1
- package/dest/storage/open_pxe_stores.js +5 -3
- package/dest/storage/tagging_store/index.d.ts +2 -2
- package/dest/storage/tagging_store/index.d.ts.map +1 -1
- package/dest/storage/tagging_store/index.js +1 -1
- package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts +40 -0
- package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts.map +1 -0
- package/dest/storage/tagging_store/tagging_secret_sources_store.js +92 -0
- package/package.json +17 -17
- package/src/block_synchronizer/block_stream_source.ts +6 -45
- package/src/block_synchronizer/block_synchronizer.ts +56 -23
- package/src/config/index.ts +1 -0
- package/src/contract_function_simulator/contract_function_simulator.ts +32 -31
- package/src/contract_function_simulator/index.ts +17 -8
- package/src/contract_function_simulator/noir-structs/bounded_vec.ts +12 -24
- package/src/contract_function_simulator/noir-structs/contract_class_log_data.ts +9 -0
- package/src/contract_function_simulator/noir-structs/embedded_curve_point.ts +4 -0
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/fact.ts +13 -0
- package/src/contract_function_simulator/noir-structs/fact_collection.ts +59 -0
- package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +20 -46
- package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +7 -60
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +2 -2
- package/src/contract_function_simulator/noir-structs/option.ts +17 -11
- package/src/contract_function_simulator/noir-structs/origin_block.ts +8 -0
- package/src/contract_function_simulator/noir-structs/provided_secret.ts +3 -14
- package/src/contract_function_simulator/noir-structs/resolved_tagging_strategy.ts +45 -0
- package/src/contract_function_simulator/noir-structs/resolved_tx.ts +53 -0
- package/src/contract_function_simulator/noir-structs/tx_effect_data.ts +15 -0
- package/src/contract_function_simulator/noir-structs/utility_context.ts +5 -17
- package/src/contract_function_simulator/oracle/message_load_oracle_inputs.ts +6 -21
- package/src/contract_function_simulator/oracle/oracle_registry.ts +87 -79
- package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +641 -247
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +94 -14
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +206 -66
- package/src/contract_sync/helpers.ts +11 -18
- package/src/entrypoints/client/bundle/utils.ts +1 -0
- package/src/entrypoints/client/lazy/utils.ts +1 -0
- package/src/entrypoints/pxe_creation_options.ts +7 -1
- package/src/entrypoints/server/index.ts +0 -1
- package/src/entrypoints/server/utils.ts +3 -1
- package/src/error_enriching.ts +1 -1
- package/src/hooks/execution_hooks.ts +17 -8
- package/src/hooks/index.ts +6 -2
- package/src/hooks/resolve_tagging_secret_strategy.ts +46 -0
- package/src/logs/log_service.ts +71 -37
- package/src/messages/{message_context_service.ts → tx_resolver_service.ts} +16 -9
- package/src/oracle_version.ts +2 -2
- package/src/private_kernel/hints/test_utils.ts +1 -1
- package/src/pxe.ts +150 -54
- package/src/storage/allowed_scopes.ts +14 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/FactStore.json +40 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json +1 -1
- package/src/storage/backwards_compatibility_tests/__snapshots__/TaggingSecretSourcesStore.json +30 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +21 -5
- package/src/storage/backwards_compatibility_tests/schema_tests.ts +88 -33
- package/src/storage/capsule_store/capsule_service.ts +8 -13
- package/src/storage/contract_store/contract_store.ts +2 -2
- package/src/storage/fact_store/fact_service.ts +45 -0
- package/src/storage/fact_store/fact_store.ts +487 -0
- package/src/storage/fact_store/fact_store_keys.ts +75 -0
- package/src/storage/fact_store/index.ts +4 -0
- package/src/storage/fact_store/stored_fact.ts +80 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/metadata.ts +1 -1
- package/src/storage/open_pxe_stores.ts +6 -3
- package/src/storage/tagging_store/index.ts +1 -1
- package/src/storage/tagging_store/tagging_secret_sources_store.ts +117 -0
- package/dest/messages/message_context_service.d.ts +0 -17
- package/dest/messages/message_context_service.d.ts.map +0 -1
- package/dest/storage/tagging_store/sender_address_book_store.d.ts +0 -14
- package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +0 -1
- package/dest/storage/tagging_store/sender_address_book_store.js +0 -36
- package/src/storage/backwards_compatibility_tests/__snapshots__/SenderAddressBookStore.json +0 -16
- package/src/storage/tagging_store/sender_address_book_store.ts +0 -48
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
CONTRACT_CLASS_LOG_SIZE_IN_FIELDS,
|
|
3
|
+
FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH,
|
|
4
4
|
L1_TO_L2_MSG_TREE_HEIGHT,
|
|
5
5
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
6
6
|
MAX_L2_TO_L1_MSGS_PER_TX,
|
|
@@ -8,48 +8,93 @@ import {
|
|
|
8
8
|
MAX_NULLIFIERS_PER_TX,
|
|
9
9
|
MAX_PRIVATE_LOGS_PER_TX,
|
|
10
10
|
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
11
|
+
NULLIFIER_TREE_HEIGHT,
|
|
12
|
+
PRIVATE_LOG_CIPHERTEXT_LEN,
|
|
13
|
+
PRIVATE_LOG_SIZE_IN_FIELDS,
|
|
14
|
+
PUBLIC_DATA_TREE_HEIGHT,
|
|
11
15
|
} from '@aztec/constants';
|
|
12
|
-
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
16
|
+
import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
13
17
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
14
18
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
15
|
-
import {
|
|
19
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
16
20
|
import { FieldReader } from '@aztec/foundation/serialize';
|
|
17
|
-
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
21
|
+
import { MembershipWitness, type SiblingPath } from '@aztec/foundation/trees';
|
|
18
22
|
import { type ACVMField, fromUintArray } from '@aztec/simulator/client';
|
|
19
23
|
import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
20
|
-
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
24
|
+
import { PublicDataWrite, RevertCode } from '@aztec/stdlib/avm';
|
|
21
25
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
22
26
|
import { BlockHash } from '@aztec/stdlib/block';
|
|
23
27
|
import type { ContractInstance, PartialAddress } from '@aztec/stdlib/contract';
|
|
28
|
+
import type { GasFees } from '@aztec/stdlib/gas';
|
|
24
29
|
import { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
25
30
|
import type { PublicKeys } from '@aztec/stdlib/keys';
|
|
26
31
|
import {
|
|
27
32
|
type AppTaggingSecretKind,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
MessageContext,
|
|
32
|
-
PendingTaggedLog,
|
|
33
|
+
type FlatPublicLogs,
|
|
34
|
+
type MessageContext,
|
|
35
|
+
type PendingTaggedLog,
|
|
33
36
|
PrivateLog,
|
|
34
37
|
Tag,
|
|
35
38
|
appTaggingSecretKindFromDeliveryMode,
|
|
36
39
|
} from '@aztec/stdlib/logs';
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
import {
|
|
41
|
+
type AppendOnlyTreeSnapshot,
|
|
42
|
+
type NullifierLeaf,
|
|
43
|
+
type NullifierLeafPreimage,
|
|
44
|
+
NullifierMembershipWitness,
|
|
45
|
+
type PublicDataTreeLeaf,
|
|
46
|
+
type PublicDataTreeLeafPreimage,
|
|
47
|
+
PublicDataWitness,
|
|
48
|
+
} from '@aztec/stdlib/trees';
|
|
49
|
+
import {
|
|
50
|
+
BlockHeader,
|
|
51
|
+
type GlobalVariables,
|
|
52
|
+
type PartialStateReference,
|
|
53
|
+
type StateReference,
|
|
54
|
+
TxHash,
|
|
55
|
+
} from '@aztec/stdlib/tx';
|
|
56
|
+
|
|
57
|
+
import type { OriginBlock } from '../../storage/fact_store/index.js';
|
|
40
58
|
import { BoundedVec } from '../noir-structs/bounded_vec.js';
|
|
59
|
+
import type { ContractClassLogData } from '../noir-structs/contract_class_log_data.js';
|
|
60
|
+
import type { EmbeddedCurvePoint } from '../noir-structs/embedded_curve_point.js';
|
|
41
61
|
import { EphemeralArray } from '../noir-structs/ephemeral_array.js';
|
|
42
62
|
import { EventValidationRequest } from '../noir-structs/event_validation_request.js';
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
63
|
+
import type { Fact } from '../noir-structs/fact.js';
|
|
64
|
+
import type { FactCollection } from '../noir-structs/fact_collection.js';
|
|
65
|
+
import { type LogRetrievalRequest, type LogSource, logSourceFromField } from '../noir-structs/log_retrieval_request.js';
|
|
66
|
+
import type { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
|
|
45
67
|
import type { NoteData } from '../noir-structs/note_data.js';
|
|
46
68
|
import { NoteValidationRequest } from '../noir-structs/note_validation_request.js';
|
|
47
69
|
import { Option } from '../noir-structs/option.js';
|
|
48
|
-
import { ProvidedSecret } from '../noir-structs/provided_secret.js';
|
|
49
|
-
import {
|
|
50
|
-
|
|
70
|
+
import type { ProvidedSecret } from '../noir-structs/provided_secret.js';
|
|
71
|
+
import {
|
|
72
|
+
type ResolvedTaggingStrategy,
|
|
73
|
+
resolvedTaggingStrategyFromFields,
|
|
74
|
+
resolvedTaggingStrategyToFields,
|
|
75
|
+
} from '../noir-structs/resolved_tagging_strategy.js';
|
|
76
|
+
import type { ResolvedTx } from '../noir-structs/resolved_tx.js';
|
|
77
|
+
import type { TxEffectData } from '../noir-structs/tx_effect_data.js';
|
|
78
|
+
import type { UtilityContext } from '../noir-structs/utility_context.js';
|
|
79
|
+
import type { MessageLoadOracleInputs } from './message_load_oracle_inputs.js';
|
|
51
80
|
import { packAsHintedNote } from './note_packing_utils.js';
|
|
52
81
|
|
|
82
|
+
// `ORACLE_REGISTRY` infers its entry signatures from these mappings, so its emitted declaration (and the oracle
|
|
83
|
+
// interfaces derived from it) names the protocol types below. Re-exporting them gives tsc a portable path to each
|
|
84
|
+
// type instead of falling back to a deep node_modules path that breaks .d.ts portability (TS2742).
|
|
85
|
+
export type {
|
|
86
|
+
AppTaggingSecretKind,
|
|
87
|
+
BlockHash,
|
|
88
|
+
BlockHeader,
|
|
89
|
+
ContractInstance,
|
|
90
|
+
MembershipWitness,
|
|
91
|
+
MessageContext,
|
|
92
|
+
NullifierMembershipWitness,
|
|
93
|
+
PendingTaggedLog,
|
|
94
|
+
PublicDataWitness,
|
|
95
|
+
TxHash,
|
|
96
|
+
};
|
|
97
|
+
|
|
53
98
|
// ─── Core Types ──────────────────────────────────────────────────────────────
|
|
54
99
|
|
|
55
100
|
/** One ACVM input slot: an array of hex-encoded field strings. */
|
|
@@ -58,6 +103,18 @@ export type InputSlot = ACVMField[];
|
|
|
58
103
|
/** One ACVM output slot: a scalar hex string or an array of hex strings. */
|
|
59
104
|
export type OutputSlot = ACVMField | ACVMField[];
|
|
60
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Wire layout of a single slot:
|
|
108
|
+
* - `'scalar'` — a bare field (one `Fr`); on the ACVM/Noir wire a `Field`.
|
|
109
|
+
* - `{ len }` — an array of exactly `len` fields (`Fr[]`); a `[Field; len]`.
|
|
110
|
+
* - `'variable'` — a slot whose field count is not statically known and cannot be sized on demand (a string, a
|
|
111
|
+
* length-prefixed struct). It contributes to the slot count but can never be zero-filled.
|
|
112
|
+
* - `{ lenFrom: fn }` — like `'variable'`, but its field count can be resolved from a runtime size descriptor. The
|
|
113
|
+
* descriptor's shape is type-specific (e.g. `{ length }`, `{ maxLength }`), so `size` is typed `any`: a single union
|
|
114
|
+
* can't type each mapping's distinct `lenFrom` under parameter contravariance.
|
|
115
|
+
*/
|
|
116
|
+
export type SlotShape = 'scalar' | { len: number } | 'variable' | { lenFrom: (size: any) => number };
|
|
117
|
+
|
|
61
118
|
/**
|
|
62
119
|
* Describes how to serialize and/or deserialize a single typed value to/from ACVM wire format.
|
|
63
120
|
* Either side is optional — output-only types omit `deserialization`, input-only types omit `serialization`.
|
|
@@ -68,18 +125,18 @@ export interface TypeMapping<T = any> {
|
|
|
68
125
|
fn: (value: T) => (Fr | Fr[])[];
|
|
69
126
|
};
|
|
70
127
|
deserialization?: {
|
|
71
|
-
/** Read a typed value from one FieldReader per
|
|
128
|
+
/** Read a typed value from its slots — one {@link FieldReader} per slot, as laid out by {@link shape}. */
|
|
72
129
|
fn: (readers: FieldReader[]) => T;
|
|
73
|
-
/**
|
|
74
|
-
* Number of InputSlots this type reads from. `deserialization.fn` receives one FieldReader per slot in `readers`.
|
|
75
|
-
*
|
|
76
|
-
* Examples:
|
|
77
|
-
* - `FIELD`, `U32`, `AZTEC_ADDRESS` — single slot → `slots: 1`
|
|
78
|
-
* - `OPTION(T)` — discriminant + inner slots → `slots: T.slots + 1`
|
|
79
|
-
* - `CONTRACT_CLASS_LOG_INPUT` — [addr], [fields], [len] → `slots: 3`
|
|
80
|
-
*/
|
|
81
|
-
slots: number;
|
|
82
130
|
};
|
|
131
|
+
/**
|
|
132
|
+
* The type's wire layout, one entry per slot.
|
|
133
|
+
*
|
|
134
|
+
* Examples:
|
|
135
|
+
* - `FIELD` → `['scalar']` // single slot
|
|
136
|
+
* - `OPTION(T)` → `['scalar', ...T.shape]` // [discriminant], [...inner.shape]
|
|
137
|
+
* - `CONTRACT_CLASS_LOG` → `['scalar', { len: N }, 'scalar']` // [addr], [fields], [len]
|
|
138
|
+
*/
|
|
139
|
+
shape: SlotShape[];
|
|
83
140
|
}
|
|
84
141
|
|
|
85
142
|
export type MaybePromise<T> = T | Promise<T>;
|
|
@@ -101,12 +158,14 @@ export function assertReadersConsumed(readers: FieldReader[]): void {
|
|
|
101
158
|
|
|
102
159
|
export const FIELD: TypeMapping<Fr> = {
|
|
103
160
|
serialization: { fn: v => [v] },
|
|
104
|
-
deserialization: { fn: ([reader]) => reader.readField()
|
|
161
|
+
deserialization: { fn: ([reader]) => reader.readField() },
|
|
162
|
+
shape: ['scalar'],
|
|
105
163
|
};
|
|
106
164
|
|
|
107
165
|
export const BOOL: TypeMapping<boolean> = {
|
|
108
166
|
serialization: { fn: v => [new Fr(v ? 1n : 0n)] },
|
|
109
|
-
deserialization: { fn: ([reader]) => !reader.readField().isZero()
|
|
167
|
+
deserialization: { fn: ([reader]) => !reader.readField().isZero() },
|
|
168
|
+
shape: ['scalar'],
|
|
110
169
|
};
|
|
111
170
|
|
|
112
171
|
export const U32: TypeMapping<number> = {
|
|
@@ -119,13 +178,14 @@ export const U32: TypeMapping<number> = {
|
|
|
119
178
|
}
|
|
120
179
|
return Number(value);
|
|
121
180
|
},
|
|
122
|
-
slots: 1,
|
|
123
181
|
},
|
|
182
|
+
shape: ['scalar'],
|
|
124
183
|
};
|
|
125
184
|
|
|
126
185
|
export const BLOCK_NUMBER: TypeMapping<BlockNumber> = {
|
|
127
186
|
serialization: { fn: v => [new Fr(v)] },
|
|
128
|
-
deserialization: { fn: ([reader]) => BlockNumber(reader.readField().toNumber())
|
|
187
|
+
deserialization: { fn: ([reader]) => BlockNumber(reader.readField().toNumber()) },
|
|
188
|
+
shape: ['scalar'],
|
|
129
189
|
};
|
|
130
190
|
|
|
131
191
|
/** A u8 byte: serializes to a single Fr; deserializes from a single Fr to a number in [0, 255]. */
|
|
@@ -139,21 +199,31 @@ export const BYTE: TypeMapping<number> = {
|
|
|
139
199
|
}
|
|
140
200
|
return Number(value);
|
|
141
201
|
},
|
|
142
|
-
slots: 1,
|
|
143
202
|
},
|
|
203
|
+
shape: ['scalar'],
|
|
144
204
|
};
|
|
145
205
|
|
|
146
206
|
// Noir passes `MessageDelivery` onchain variants here.
|
|
147
207
|
export const DELIVERY_MODE: TypeMapping<AppTaggingSecretKind> = {
|
|
148
208
|
deserialization: {
|
|
149
209
|
fn: readers => appTaggingSecretKindFromDeliveryMode(BYTE.deserialization!.fn(readers)),
|
|
150
|
-
slots: BYTE.deserialization!.slots,
|
|
151
210
|
},
|
|
211
|
+
shape: BYTE.shape,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export const RESOLVED_TAGGING_STRATEGY: TypeMapping<ResolvedTaggingStrategy> = {
|
|
215
|
+
serialization: { fn: resolved => resolvedTaggingStrategyToFields(resolved) },
|
|
216
|
+
deserialization: {
|
|
217
|
+
fn: ([kindReader, secretReader]) =>
|
|
218
|
+
resolvedTaggingStrategyFromFields(kindReader.readField().toNumber(), secretReader.readField()),
|
|
219
|
+
},
|
|
220
|
+
shape: ['scalar', 'scalar'],
|
|
152
221
|
};
|
|
153
222
|
|
|
154
223
|
export const BIGINT: TypeMapping<bigint> = {
|
|
155
224
|
serialization: { fn: v => [new Fr(v)] },
|
|
156
|
-
deserialization: { fn: ([reader]) => reader.readField().toBigInt()
|
|
225
|
+
deserialization: { fn: ([reader]) => reader.readField().toBigInt() },
|
|
226
|
+
shape: ['scalar'],
|
|
157
227
|
};
|
|
158
228
|
|
|
159
229
|
/** Reads every field in the slot as a UTF-8 character code. */
|
|
@@ -167,163 +237,241 @@ export const STR: TypeMapping<string> = {
|
|
|
167
237
|
}
|
|
168
238
|
return chars.join('');
|
|
169
239
|
},
|
|
170
|
-
slots: 1,
|
|
171
240
|
},
|
|
241
|
+
shape: ['variable'],
|
|
172
242
|
};
|
|
173
243
|
|
|
174
244
|
export const AZTEC_ADDRESS: TypeMapping<AztecAddress> = {
|
|
175
245
|
serialization: { fn: v => [v.toField()] },
|
|
176
|
-
deserialization: { fn: ([reader]) => AztecAddress.
|
|
246
|
+
deserialization: { fn: ([reader]) => AztecAddress.fromFieldUnsafe(reader.readField()) },
|
|
247
|
+
shape: ['scalar'],
|
|
177
248
|
};
|
|
178
249
|
|
|
179
250
|
export const BLOCK_HASH: TypeMapping<BlockHash> = {
|
|
180
251
|
serialization: { fn: v => [new Fr(v.toBuffer())] },
|
|
181
|
-
deserialization: { fn: ([reader]) => new BlockHash(reader.readField())
|
|
252
|
+
deserialization: { fn: ([reader]) => new BlockHash(reader.readField()) },
|
|
253
|
+
shape: ['scalar'],
|
|
182
254
|
};
|
|
183
255
|
|
|
184
256
|
export const FUNCTION_SELECTOR: TypeMapping<FunctionSelector> = {
|
|
185
257
|
serialization: { fn: v => [v.toField()] },
|
|
186
|
-
deserialization: { fn: ([reader]) => FunctionSelector.fromField(reader.readField())
|
|
258
|
+
deserialization: { fn: ([reader]) => FunctionSelector.fromField(reader.readField()) },
|
|
259
|
+
shape: ['scalar'],
|
|
187
260
|
};
|
|
188
261
|
|
|
189
262
|
export const NOTE_SELECTOR: TypeMapping<NoteSelector> = {
|
|
190
263
|
serialization: { fn: v => [v.toField()] },
|
|
191
|
-
deserialization: { fn: ([reader]) => NoteSelector.fromField(reader.readField())
|
|
264
|
+
deserialization: { fn: ([reader]) => NoteSelector.fromField(reader.readField()) },
|
|
265
|
+
shape: ['scalar'],
|
|
192
266
|
};
|
|
193
267
|
|
|
194
268
|
export const TX_HASH: TypeMapping<TxHash> = {
|
|
195
269
|
serialization: { fn: v => [v.hash] },
|
|
196
|
-
deserialization: { fn: ([reader]) => TxHash.fromField(reader.readField())
|
|
270
|
+
deserialization: { fn: ([reader]) => TxHash.fromField(reader.readField()) },
|
|
271
|
+
shape: ['scalar'],
|
|
197
272
|
};
|
|
198
273
|
|
|
199
|
-
|
|
274
|
+
const TAG: TypeMapping<Tag> = {
|
|
200
275
|
serialization: { fn: v => [v.value] },
|
|
201
|
-
deserialization: { fn: ([reader]) => new Tag(reader.readField())
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
export const POINT: TypeMapping<Point> = {
|
|
205
|
-
serialization: { fn: p => [p.toFields()] },
|
|
206
|
-
deserialization: {
|
|
207
|
-
fn: ([reader]) => Point.fromFields([reader.readField(), reader.readField()]),
|
|
208
|
-
slots: 1,
|
|
209
|
-
},
|
|
276
|
+
deserialization: { fn: ([reader]) => new Tag(reader.readField()) },
|
|
277
|
+
shape: ['scalar'],
|
|
210
278
|
};
|
|
211
279
|
|
|
212
|
-
|
|
280
|
+
export const POINT: TypeMapping<EmbeddedCurvePoint> = STRUCT([
|
|
281
|
+
{ name: 'x', type: FIELD },
|
|
282
|
+
{ name: 'y', type: FIELD },
|
|
283
|
+
]);
|
|
213
284
|
|
|
214
|
-
|
|
215
|
-
serialization: { fn: v => v
|
|
216
|
-
deserialization: { fn: ([reader]) =>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
export const KEY_VALIDATION_REQUEST: TypeMapping<KeyValidationRequest> = {
|
|
220
|
-
serialization: { fn: v => v.toFields() },
|
|
221
|
-
deserialization: {
|
|
222
|
-
fn: ([reader]) => KeyValidationRequest.fromFields(reader.readFieldArray(KEY_VALIDATION_REQUEST_LENGTH)),
|
|
223
|
-
slots: 1,
|
|
224
|
-
},
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
export const CONTRACT_INSTANCE: TypeMapping<ContractInstance> = {
|
|
228
|
-
serialization: {
|
|
229
|
-
fn: v => [
|
|
230
|
-
v.salt,
|
|
231
|
-
v.deployer.toField(),
|
|
232
|
-
v.currentContractClassId,
|
|
233
|
-
v.initializationHash,
|
|
234
|
-
v.immutablesHash,
|
|
235
|
-
...v.publicKeys.toFields(),
|
|
236
|
-
],
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
export const NULLIFIER_MEMBERSHIP_WITNESS: TypeMapping<NullifierMembershipWitness> = {
|
|
241
|
-
serialization: {
|
|
242
|
-
fn: (w: NullifierMembershipWitness) =>
|
|
243
|
-
w
|
|
244
|
-
.toNoirRepresentation()
|
|
245
|
-
.map(slot => (Array.isArray(slot) ? slot.map(s => Fr.fromString(s)) : Fr.fromString(slot as string))),
|
|
246
|
-
},
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
export const PUBLIC_DATA_WITNESS: TypeMapping<PublicDataWitness> = {
|
|
250
|
-
serialization: {
|
|
251
|
-
fn: (w: PublicDataWitness) =>
|
|
252
|
-
w
|
|
253
|
-
.toNoirRepresentation()
|
|
254
|
-
.map(slot => (Array.isArray(slot) ? slot.map(s => Fr.fromString(s)) : Fr.fromString(slot as string))),
|
|
255
|
-
},
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
export const MESSAGE_LOAD_ORACLE_INPUTS: TypeMapping<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>> = {
|
|
259
|
-
serialization: {
|
|
260
|
-
fn: (m: MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>) =>
|
|
261
|
-
m
|
|
262
|
-
.toNoirRepresentation()
|
|
263
|
-
.map(slot => (Array.isArray(slot) ? slot.map(s => Fr.fromString(s)) : Fr.fromString(slot as string))),
|
|
264
|
-
},
|
|
285
|
+
const LOG_SOURCE: TypeMapping<LogSource> = {
|
|
286
|
+
serialization: { fn: v => [new Fr(v)] },
|
|
287
|
+
deserialization: { fn: ([reader]) => logSourceFromField(reader.readField()) },
|
|
288
|
+
shape: ['scalar'],
|
|
265
289
|
};
|
|
266
290
|
|
|
267
|
-
export const
|
|
268
|
-
serialization: {
|
|
269
|
-
|
|
270
|
-
|
|
291
|
+
export const ETH_ADDRESS: TypeMapping<EthAddress> = {
|
|
292
|
+
serialization: { fn: v => [v.toField()] },
|
|
293
|
+
deserialization: { fn: ([reader]) => EthAddress.fromField(reader.readField()) },
|
|
294
|
+
shape: ['scalar'],
|
|
271
295
|
};
|
|
272
296
|
|
|
273
|
-
|
|
274
|
-
serialization: { fn: v => [
|
|
275
|
-
|
|
297
|
+
const SLOT_NUMBER: TypeMapping<SlotNumber> = {
|
|
298
|
+
serialization: { fn: v => [new Fr(v)] },
|
|
299
|
+
shape: ['scalar'],
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const APPEND_ONLY_TREE_SNAPSHOT: TypeMapping<AppendOnlyTreeSnapshot> = STRUCT<AppendOnlyTreeSnapshot>([
|
|
303
|
+
{ name: 'root', type: FIELD },
|
|
304
|
+
{ name: 'nextAvailableLeafIndex', type: U32 },
|
|
305
|
+
]);
|
|
306
|
+
|
|
307
|
+
const PARTIAL_STATE_REFERENCE: TypeMapping<PartialStateReference> = STRUCT<PartialStateReference>([
|
|
308
|
+
{ name: 'noteHashTree', type: APPEND_ONLY_TREE_SNAPSHOT },
|
|
309
|
+
{ name: 'nullifierTree', type: APPEND_ONLY_TREE_SNAPSHOT },
|
|
310
|
+
{ name: 'publicDataTree', type: APPEND_ONLY_TREE_SNAPSHOT },
|
|
311
|
+
]);
|
|
312
|
+
|
|
313
|
+
const STATE_REFERENCE: TypeMapping<StateReference> = STRUCT<StateReference>([
|
|
314
|
+
{ name: 'l1ToL2MessageTree', type: APPEND_ONLY_TREE_SNAPSHOT },
|
|
315
|
+
{ name: 'partial', type: PARTIAL_STATE_REFERENCE },
|
|
316
|
+
]);
|
|
317
|
+
|
|
318
|
+
const GAS_FEES: TypeMapping<GasFees> = STRUCT<GasFees>([
|
|
319
|
+
{ name: 'feePerDaGas', type: BIGINT },
|
|
320
|
+
{ name: 'feePerL2Gas', type: BIGINT },
|
|
321
|
+
]);
|
|
322
|
+
|
|
323
|
+
const GLOBAL_VARIABLES: TypeMapping<GlobalVariables> = STRUCT<GlobalVariables>([
|
|
324
|
+
{ name: 'chainId', type: FIELD },
|
|
325
|
+
{ name: 'version', type: FIELD },
|
|
326
|
+
{ name: 'blockNumber', type: BLOCK_NUMBER },
|
|
327
|
+
{ name: 'slotNumber', type: SLOT_NUMBER },
|
|
328
|
+
{ name: 'timestamp', type: BIGINT },
|
|
329
|
+
{ name: 'coinbase', type: ETH_ADDRESS },
|
|
330
|
+
{ name: 'feeRecipient', type: AZTEC_ADDRESS },
|
|
331
|
+
{ name: 'gasFees', type: GAS_FEES },
|
|
332
|
+
]);
|
|
333
|
+
|
|
334
|
+
export const BLOCK_HEADER: TypeMapping<BlockHeader> = STRUCT<BlockHeader>([
|
|
335
|
+
{ name: 'lastArchive', type: APPEND_ONLY_TREE_SNAPSHOT },
|
|
336
|
+
{ name: 'state', type: STATE_REFERENCE },
|
|
337
|
+
{ name: 'spongeBlobHash', type: FIELD },
|
|
338
|
+
{ name: 'globalVariables', type: GLOBAL_VARIABLES },
|
|
339
|
+
{ name: 'totalFees', type: FIELD },
|
|
340
|
+
{ name: 'totalManaUsed', type: FIELD },
|
|
341
|
+
]);
|
|
342
|
+
|
|
343
|
+
export const KEY_VALIDATION_REQUEST: TypeMapping<KeyValidationRequest> = STRUCT<KeyValidationRequest>([
|
|
344
|
+
{ name: 'pkMHash', type: FIELD },
|
|
345
|
+
{ name: 'skApp', type: FIELD },
|
|
346
|
+
]);
|
|
347
|
+
|
|
348
|
+
const PUBLIC_KEYS: TypeMapping<PublicKeys> = STRUCT<PublicKeys>([
|
|
349
|
+
{ name: 'npkMHash', type: FIELD },
|
|
350
|
+
{ name: 'ivpkM', type: POINT },
|
|
351
|
+
{ name: 'ovpkMHash', type: FIELD },
|
|
352
|
+
{ name: 'tpkMHash', type: FIELD },
|
|
353
|
+
{ name: 'mspkMHash', type: FIELD },
|
|
354
|
+
{ name: 'fbpkMHash', type: FIELD },
|
|
355
|
+
]);
|
|
356
|
+
|
|
357
|
+
export const CONTRACT_INSTANCE: TypeMapping<ContractInstance> = STRUCT<ContractInstance>([
|
|
358
|
+
{ name: 'salt', type: FIELD },
|
|
359
|
+
{ name: 'deployer', type: AZTEC_ADDRESS },
|
|
360
|
+
// Note that the nr side of this struct does not contain the current class, only original
|
|
361
|
+
{ name: 'originalContractClassId', type: FIELD },
|
|
362
|
+
{ name: 'initializationHash', type: FIELD },
|
|
363
|
+
{ name: 'immutablesHash', type: FIELD },
|
|
364
|
+
{ name: 'publicKeys', type: PUBLIC_KEYS },
|
|
365
|
+
]);
|
|
366
|
+
|
|
367
|
+
const NULLIFIER_LEAF: TypeMapping<NullifierLeaf> = STRUCT<NullifierLeaf>([{ name: 'nullifier', type: FIELD }]);
|
|
368
|
+
|
|
369
|
+
const NULLIFIER_LEAF_PREIMAGE: TypeMapping<NullifierLeafPreimage> = STRUCT<NullifierLeafPreimage>([
|
|
370
|
+
{ name: 'leaf', type: NULLIFIER_LEAF },
|
|
371
|
+
{ name: 'nextKey', type: FIELD },
|
|
372
|
+
{ name: 'nextIndex', type: BIGINT },
|
|
373
|
+
]);
|
|
374
|
+
|
|
375
|
+
export const NULLIFIER_MEMBERSHIP_WITNESS: TypeMapping<NullifierMembershipWitness> = STRUCT<NullifierMembershipWitness>(
|
|
376
|
+
[
|
|
377
|
+
{ name: 'leafPreimage', type: NULLIFIER_LEAF_PREIMAGE },
|
|
378
|
+
{ name: 'index', type: BIGINT },
|
|
379
|
+
{ name: 'siblingPath', type: SIBLING_PATH(NULLIFIER_TREE_HEIGHT) },
|
|
380
|
+
],
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const PUBLIC_DATA_LEAF: TypeMapping<PublicDataTreeLeaf> = STRUCT<PublicDataTreeLeaf>([
|
|
384
|
+
{ name: 'slot', type: FIELD },
|
|
385
|
+
{ name: 'value', type: FIELD },
|
|
386
|
+
]);
|
|
387
|
+
|
|
388
|
+
const PUBLIC_DATA_LEAF_PREIMAGE: TypeMapping<PublicDataTreeLeafPreimage> = STRUCT<PublicDataTreeLeafPreimage>([
|
|
389
|
+
{ name: 'leaf', type: PUBLIC_DATA_LEAF },
|
|
390
|
+
{ name: 'nextKey', type: FIELD },
|
|
391
|
+
{ name: 'nextIndex', type: BIGINT },
|
|
392
|
+
]);
|
|
393
|
+
|
|
394
|
+
export const PUBLIC_DATA_WITNESS: TypeMapping<PublicDataWitness> = STRUCT<PublicDataWitness>([
|
|
395
|
+
{ name: 'index', type: BIGINT },
|
|
396
|
+
{ name: 'leafPreimage', type: PUBLIC_DATA_LEAF_PREIMAGE },
|
|
397
|
+
{ name: 'siblingPath', type: SIBLING_PATH(PUBLIC_DATA_TREE_HEIGHT) },
|
|
398
|
+
]);
|
|
399
|
+
|
|
400
|
+
export const MESSAGE_LOAD_ORACLE_INPUTS: TypeMapping<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>> = STRUCT<
|
|
401
|
+
MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>
|
|
402
|
+
>([
|
|
403
|
+
{ name: 'index', type: BIGINT },
|
|
404
|
+
{ name: 'siblingPath', type: SIBLING_PATH(L1_TO_L2_MSG_TREE_HEIGHT) },
|
|
405
|
+
]);
|
|
406
|
+
|
|
407
|
+
export const UTILITY_CONTEXT: TypeMapping<UtilityContext> = STRUCT<UtilityContext>([
|
|
408
|
+
{ name: 'blockHeader', type: BLOCK_HEADER },
|
|
409
|
+
{ name: 'contractAddress', type: AZTEC_ADDRESS },
|
|
410
|
+
{ name: 'msgSender', type: AZTEC_ADDRESS },
|
|
411
|
+
]);
|
|
412
|
+
|
|
413
|
+
export const CALL_PRIVATE_RESULT: TypeMapping<{ endSideEffectCounter: Fr; returnsHash: Fr }> = STRUCT([
|
|
414
|
+
{ name: 'endSideEffectCounter', type: FIELD },
|
|
415
|
+
{ name: 'returnsHash', type: FIELD },
|
|
416
|
+
]);
|
|
276
417
|
|
|
277
418
|
export const PUBLIC_KEYS_AND_PARTIAL_ADDRESS: TypeMapping<{
|
|
278
419
|
publicKeys: PublicKeys;
|
|
279
420
|
partialAddress: PartialAddress;
|
|
280
|
-
}> =
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
},
|
|
326
|
-
}
|
|
421
|
+
}> = STRUCT([
|
|
422
|
+
{ name: 'publicKeys', type: PUBLIC_KEYS },
|
|
423
|
+
{ name: 'partialAddress', type: FIELD },
|
|
424
|
+
]);
|
|
425
|
+
|
|
426
|
+
export const CONTRACT_CLASS_LOG: TypeMapping<ContractClassLogData> = STRUCT([
|
|
427
|
+
{ name: 'contractAddress', type: AZTEC_ADDRESS },
|
|
428
|
+
{ name: 'fields', type: FIXED_ARRAY(FIELD, CONTRACT_CLASS_LOG_SIZE_IN_FIELDS) },
|
|
429
|
+
{ name: 'emittedLength', type: U32 },
|
|
430
|
+
]);
|
|
431
|
+
|
|
432
|
+
const REVERT_CODE: TypeMapping<RevertCode> = {
|
|
433
|
+
serialization: { fn: rc => [rc.toField()] },
|
|
434
|
+
shape: ['scalar'],
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
const PUBLIC_DATA_WRITE: TypeMapping<PublicDataWrite> = STRUCT<PublicDataWrite>([
|
|
438
|
+
{ name: 'leafSlot', type: FIELD },
|
|
439
|
+
{ name: 'value', type: FIELD },
|
|
440
|
+
]);
|
|
441
|
+
|
|
442
|
+
const PRIVATE_LOG: TypeMapping<PrivateLog> = STRUCT<PrivateLog>([
|
|
443
|
+
{ name: 'fields', type: FIXED_ARRAY(FIELD, PRIVATE_LOG_SIZE_IN_FIELDS) },
|
|
444
|
+
{ name: 'emittedLength', type: U32 },
|
|
445
|
+
]);
|
|
446
|
+
|
|
447
|
+
const FLAT_PUBLIC_LOGS: TypeMapping<FlatPublicLogs> = STRUCT<FlatPublicLogs>([
|
|
448
|
+
{ name: 'length', type: U32 },
|
|
449
|
+
{ name: 'payload', type: FIXED_ARRAY(FIELD, FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH) },
|
|
450
|
+
]);
|
|
451
|
+
|
|
452
|
+
const CONTRACT_CLASS_LOG_ENTRY: TypeMapping<ContractClassLogData> = STRUCT<ContractClassLogData>([
|
|
453
|
+
{ name: 'fields', type: FIXED_ARRAY(FIELD, CONTRACT_CLASS_LOG_SIZE_IN_FIELDS) },
|
|
454
|
+
{ name: 'emittedLength', type: U32 },
|
|
455
|
+
{ name: 'contractAddress', type: AZTEC_ADDRESS },
|
|
456
|
+
]);
|
|
457
|
+
|
|
458
|
+
const CONTRACT_CLASS_LOGS: TypeMapping<ContractClassLogData[]> = FIXED_ARRAY(
|
|
459
|
+
CONTRACT_CLASS_LOG_ENTRY,
|
|
460
|
+
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
export const TX_EFFECT: TypeMapping<TxEffectData> = STRUCT<TxEffectData>([
|
|
464
|
+
{ name: 'revertCode', type: REVERT_CODE },
|
|
465
|
+
{ name: 'txHash', type: TX_HASH },
|
|
466
|
+
{ name: 'transactionFee', type: FIELD },
|
|
467
|
+
{ name: 'noteHashes', type: FIXED_ARRAY(FIELD, MAX_NOTE_HASHES_PER_TX) },
|
|
468
|
+
{ name: 'nullifiers', type: FIXED_ARRAY(FIELD, MAX_NULLIFIERS_PER_TX) },
|
|
469
|
+
{ name: 'l2ToL1Msgs', type: FIXED_ARRAY(FIELD, MAX_L2_TO_L1_MSGS_PER_TX) },
|
|
470
|
+
{ name: 'publicDataWrites', type: FIXED_ARRAY(PUBLIC_DATA_WRITE, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) },
|
|
471
|
+
{ name: 'privateLogs', type: FIXED_ARRAY(PRIVATE_LOG, MAX_PRIVATE_LOGS_PER_TX) },
|
|
472
|
+
{ name: 'publicLogs', type: FLAT_PUBLIC_LOGS },
|
|
473
|
+
{ name: 'contractClassLogs', type: CONTRACT_CLASS_LOGS },
|
|
474
|
+
]);
|
|
327
475
|
|
|
328
476
|
export const NOTE: TypeMapping<NoteData> = {
|
|
329
477
|
serialization: {
|
|
@@ -338,77 +486,152 @@ export const NOTE: TypeMapping<NoteData> = {
|
|
|
338
486
|
note: noteData.note,
|
|
339
487
|
}),
|
|
340
488
|
},
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
serialization: { fn: log => [log.toFields()] },
|
|
489
|
+
// A packed note is the note's (variable-count) field items followed by 6 metadata scalars, emitted as one field
|
|
490
|
+
// output per element. Its length depends on the note, so it is described as a single variable-width run.
|
|
491
|
+
shape: ['variable'],
|
|
345
492
|
};
|
|
346
493
|
|
|
347
494
|
export const NOTE_VALIDATION_REQUEST: TypeMapping<NoteValidationRequest> = {
|
|
348
495
|
deserialization: {
|
|
349
496
|
fn: ([reader]) => NoteValidationRequest.fromFields(reader),
|
|
350
|
-
slots: 1,
|
|
351
497
|
},
|
|
498
|
+
shape: ['variable'],
|
|
352
499
|
};
|
|
353
500
|
|
|
354
501
|
export const EVENT_VALIDATION_REQUEST: TypeMapping<EventValidationRequest> = {
|
|
355
502
|
deserialization: {
|
|
356
503
|
fn: ([reader]) => EventValidationRequest.fromFields(reader),
|
|
357
|
-
slots: 1,
|
|
358
504
|
},
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
505
|
+
shape: ['variable'],
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
export const LOG_RETRIEVAL_REQUEST: TypeMapping<LogRetrievalRequest> = STRUCT<LogRetrievalRequest>([
|
|
509
|
+
{ name: 'contractAddress', type: AZTEC_ADDRESS },
|
|
510
|
+
{ name: 'tag', type: TAG },
|
|
511
|
+
{ name: 'source', type: LOG_SOURCE },
|
|
512
|
+
{ name: 'fromBlock', type: OPTION(BLOCK_NUMBER) },
|
|
513
|
+
{ name: 'toBlock', type: OPTION(BLOCK_NUMBER) },
|
|
514
|
+
]);
|
|
515
|
+
|
|
516
|
+
export const LOG_RETRIEVAL_RESPONSE: TypeMapping<LogRetrievalResponse> = STRUCT<LogRetrievalResponse>([
|
|
517
|
+
{ name: 'logPayload', type: FIXED_BOUNDED_VEC(FIELD, PRIVATE_LOG_CIPHERTEXT_LEN) },
|
|
518
|
+
{ name: 'txHash', type: TX_HASH },
|
|
519
|
+
{ name: 'uniqueNoteHashesInTx', type: FIXED_BOUNDED_VEC(FIELD, MAX_NOTE_HASHES_PER_TX) },
|
|
520
|
+
{ name: 'firstNullifierInTx', type: FIELD },
|
|
521
|
+
]);
|
|
522
|
+
|
|
523
|
+
export const MESSAGE_CONTEXT: TypeMapping<MessageContext> = STRUCT<MessageContext>([
|
|
524
|
+
{ name: 'txHash', type: TX_HASH },
|
|
525
|
+
{ name: 'uniqueNoteHashesInTx', type: FIXED_BOUNDED_VEC(FIELD, MAX_NOTE_HASHES_PER_TX) },
|
|
526
|
+
{ name: 'firstNullifierInTx', type: FIELD },
|
|
527
|
+
]);
|
|
528
|
+
|
|
529
|
+
export const PENDING_TAGGED_LOG: TypeMapping<PendingTaggedLog> = STRUCT<PendingTaggedLog>([
|
|
530
|
+
{ name: 'log', type: FIXED_BOUNDED_VEC(FIELD, PRIVATE_LOG_SIZE_IN_FIELDS) },
|
|
531
|
+
{ name: 'context', type: MESSAGE_CONTEXT },
|
|
532
|
+
]);
|
|
533
|
+
|
|
534
|
+
// `ResolvedTx.toFields()` packs the whole struct into a single slot: txHash, the uniqueNoteHashesInTx BoundedVec
|
|
535
|
+
// (MAX_NOTE_HASHES_PER_TX storage fields + length), firstNullifierInTx, blockNumber and blockHash.
|
|
536
|
+
export const RESOLVED_TX: TypeMapping<ResolvedTx> = {
|
|
537
|
+
serialization: { fn: resolved => [resolved.toFields()] },
|
|
538
|
+
shape: [{ len: MAX_NOTE_HASHES_PER_TX + 5 }],
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
export const ORIGIN_BLOCK: TypeMapping<OriginBlock> = {
|
|
542
|
+
serialization: { fn: ob => [new Fr(ob.blockNumber), ob.blockHash] },
|
|
363
543
|
deserialization: {
|
|
364
|
-
fn: ([
|
|
365
|
-
|
|
544
|
+
fn: ([blockNumberReader, blockHashReader]) => ({
|
|
545
|
+
blockNumber: blockNumberReader.readField().toNumber(),
|
|
546
|
+
blockHash: blockHashReader.readField(),
|
|
547
|
+
}),
|
|
366
548
|
},
|
|
549
|
+
shape: ['scalar', 'scalar'],
|
|
367
550
|
};
|
|
368
551
|
|
|
369
|
-
|
|
370
|
-
|
|
552
|
+
// `facts` and `payload` each materialize to a single service-slot id, so a Fact occupies: factTypeId, the payload
|
|
553
|
+
// array slot, and `OPTION(ORIGIN_BLOCK)` (its discriminant plus ORIGIN_BLOCK's two slots).
|
|
554
|
+
export const FACT: TypeMapping<Fact> = {
|
|
555
|
+
serialization: {
|
|
556
|
+
fn: f => [
|
|
557
|
+
f.factTypeId,
|
|
558
|
+
f.payload.materializeSlot(v => FIELD.serialization!.fn(v).flat() as Fr[]),
|
|
559
|
+
...OPTION(ORIGIN_BLOCK).serialization!.fn(f.originBlock),
|
|
560
|
+
],
|
|
561
|
+
},
|
|
562
|
+
shape: ['scalar', 'scalar', 'scalar', 'scalar', 'scalar'],
|
|
371
563
|
};
|
|
372
564
|
|
|
373
|
-
export const
|
|
374
|
-
serialization: {
|
|
565
|
+
export const FACT_COLLECTION: TypeMapping<FactCollection> = {
|
|
566
|
+
serialization: {
|
|
567
|
+
fn: c => [
|
|
568
|
+
c.contractAddress.toField(),
|
|
569
|
+
c.scope.toField(),
|
|
570
|
+
c.factCollectionTypeId,
|
|
571
|
+
c.factCollectionId,
|
|
572
|
+
c.facts.materializeSlot(v => FACT.serialization!.fn(v).flat() as Fr[]),
|
|
573
|
+
],
|
|
574
|
+
},
|
|
575
|
+
shape: ['scalar', 'scalar', 'scalar', 'scalar', 'scalar'],
|
|
375
576
|
};
|
|
376
577
|
|
|
377
578
|
export const PROVIDED_SECRET: TypeMapping<ProvidedSecret> = {
|
|
378
579
|
deserialization: {
|
|
379
|
-
fn: ([reader]) =>
|
|
380
|
-
|
|
580
|
+
fn: ([reader]) => ({
|
|
581
|
+
secret: reader.readField(),
|
|
582
|
+
mode: appTaggingSecretKindFromDeliveryMode(BYTE.deserialization!.fn([reader])),
|
|
583
|
+
}),
|
|
381
584
|
},
|
|
585
|
+
shape: [{ len: 2 }],
|
|
382
586
|
};
|
|
383
587
|
|
|
384
588
|
// ─── Combinator Type Mappings ────────────────────────────────────────────────
|
|
385
589
|
|
|
386
|
-
|
|
387
|
-
export function MEMBERSHIP_WITNESS<N extends number>(_height: N): TypeMapping<MembershipWitness<N>> {
|
|
590
|
+
function SIBLING_PATH<N extends number>(height: N): TypeMapping<SiblingPath<N>> {
|
|
388
591
|
return {
|
|
389
|
-
serialization: {
|
|
390
|
-
|
|
391
|
-
|
|
592
|
+
serialization: { fn: sp => [sp.toFields()] },
|
|
593
|
+
shape: [{ len: height }],
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
export function MEMBERSHIP_WITNESS<N extends number>(height: N): TypeMapping<MembershipWitness<N>> {
|
|
598
|
+
return STRUCT<MembershipWitness<N>>([
|
|
599
|
+
{ name: 'leafIndex', type: BIGINT },
|
|
600
|
+
{ name: 'siblingPath', type: FIXED_ARRAY(FIELD, height) },
|
|
601
|
+
]);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
export function ARRAY<T>(inner: TypeMapping<T>): TypeMapping<T[]> & { kind: 'array'; inner: TypeMapping<T> } {
|
|
605
|
+
return {
|
|
606
|
+
kind: 'array',
|
|
607
|
+
inner,
|
|
608
|
+
serialization: inner.serialization ? { fn: values => [packElements(inner, values)] } : undefined,
|
|
609
|
+
deserialization: inner.deserialization
|
|
610
|
+
? {
|
|
611
|
+
// The whole slot is the array, so read as many elements as its fields hold.
|
|
612
|
+
fn: ([reader]) => unpackElements(inner, reader, reader.remainingFields() / fieldWidth(inner.shape)),
|
|
613
|
+
}
|
|
614
|
+
: undefined,
|
|
615
|
+
// One slot of variable length (all elements flattened into it).
|
|
616
|
+
shape: [{ lenFrom: (size: { length: number }) => size.length * fieldWidth(inner.shape) }],
|
|
392
617
|
};
|
|
393
618
|
}
|
|
394
619
|
|
|
395
|
-
|
|
620
|
+
/**
|
|
621
|
+
* Noir's fixed-length array `[T; maxLength]` in one slot: serializes `values` (each flattened via `element`)
|
|
622
|
+
* zero-padded to exactly `maxLength * elementWidth` fields, and deserializes all `maxLength` elements back. An absent
|
|
623
|
+
* element is the zero encoding, so the padding is derived from the shape.
|
|
624
|
+
*/
|
|
625
|
+
function FIXED_ARRAY<T>(element: TypeMapping<T>, maxLength: number): TypeMapping<T[]> {
|
|
626
|
+
const elementWidth = fieldWidth(element.shape);
|
|
396
627
|
return {
|
|
397
628
|
serialization: element.serialization
|
|
398
|
-
? { fn: values => [values.
|
|
629
|
+
? { fn: values => [padArrayEnd(packElements(element, values), Fr.ZERO, maxLength * elementWidth)] }
|
|
399
630
|
: undefined,
|
|
400
631
|
deserialization: element.deserialization
|
|
401
|
-
? {
|
|
402
|
-
fn: ([reader]) => {
|
|
403
|
-
const result: T[] = [];
|
|
404
|
-
while (!reader.isFinished()) {
|
|
405
|
-
result.push(element.deserialization!.fn([reader]));
|
|
406
|
-
}
|
|
407
|
-
return result;
|
|
408
|
-
},
|
|
409
|
-
slots: 1,
|
|
410
|
-
}
|
|
632
|
+
? { fn: ([reader]) => unpackElements(element, reader, maxLength) }
|
|
411
633
|
: undefined,
|
|
634
|
+
shape: [{ len: maxLength * elementWidth }],
|
|
412
635
|
};
|
|
413
636
|
}
|
|
414
637
|
|
|
@@ -425,129 +648,300 @@ export function ARRAY<T>(element: TypeMapping<T>): TypeMapping<T[]> {
|
|
|
425
648
|
* slot 1: Fr(2) // actual length
|
|
426
649
|
* ```
|
|
427
650
|
*/
|
|
428
|
-
export function BOUNDED_VEC<T>(
|
|
651
|
+
export function BOUNDED_VEC<T>(
|
|
652
|
+
inner: TypeMapping<T>,
|
|
653
|
+
): TypeMapping<BoundedVec<T>> & { kind: 'bounded-vec'; inner: TypeMapping<T> } {
|
|
429
654
|
return {
|
|
430
|
-
|
|
655
|
+
kind: 'bounded-vec',
|
|
656
|
+
inner,
|
|
657
|
+
serialization: inner.serialization
|
|
431
658
|
? {
|
|
432
659
|
fn: bv => {
|
|
433
660
|
if (bv.data.length > bv.maxLength) {
|
|
434
661
|
throw new Error(`Got ${bv.data.length} items, but maxLength is ${bv.maxLength}`);
|
|
435
662
|
}
|
|
436
|
-
|
|
437
|
-
|
|
663
|
+
// Fixed-width elements take their width from the shape (consistent with deserialization); only a
|
|
664
|
+
// variable-width element (e.g. a packed note) falls back to the runtime `elementSize` the value carries.
|
|
665
|
+
const elementWidth = tryFieldWidth(inner.shape) ?? bv.elementSize;
|
|
666
|
+
const flat = padArrayEnd(packElements(inner, bv.data), Fr.ZERO, bv.maxLength * elementWidth);
|
|
667
|
+
return [flat, new Fr(bv.data.length)];
|
|
438
668
|
},
|
|
439
669
|
}
|
|
440
670
|
: undefined,
|
|
441
|
-
deserialization:
|
|
671
|
+
deserialization: inner.deserialization
|
|
442
672
|
? {
|
|
443
673
|
fn: ([storageReader, lengthReader]) => {
|
|
444
|
-
|
|
674
|
+
// slot 0 is the padded storage, slot 1 the actual length. Parse only the first `length` elements out of
|
|
675
|
+
// storage, then drain the trailing zero-padding so the storage reader is fully consumed.
|
|
676
|
+
const maxLength = storageReader.remainingFields() / fieldWidth(inner.shape);
|
|
445
677
|
const length = lengthReader.readField().toNumber();
|
|
446
|
-
const elements
|
|
447
|
-
for (let i = 0; i < length; i++) {
|
|
448
|
-
elements.push(element.deserialization!.fn([storageReader]));
|
|
449
|
-
}
|
|
450
|
-
// Drain the trailing zero-padding (maxLength - length unused element slots) so the storage reader is
|
|
451
|
-
// fully consumed.
|
|
678
|
+
const elements = unpackElements(inner, storageReader, length);
|
|
452
679
|
storageReader.skip(storageReader.remainingFields());
|
|
453
680
|
return BoundedVec.from<T>({ data: elements, maxLength });
|
|
454
681
|
},
|
|
455
|
-
slots: 2,
|
|
456
682
|
}
|
|
457
683
|
: undefined,
|
|
684
|
+
// slot 0: variable-length storage; slot 1: the length scalar.
|
|
685
|
+
shape: [{ lenFrom: (size: { maxLength: number }) => size.maxLength * fieldWidth(inner.shape) }, 'scalar'],
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Noir's `BoundedVec<T, MaxLen>` in its padded form (one fixed-width slot): `maxLength * elementWidth` storage fields
|
|
691
|
+
* (zero-padded) followed by the actual length, with no length prefix, so the width is statically known. Serialize-only.
|
|
692
|
+
* Throws if the input exceeds `maxLength`.
|
|
693
|
+
*/
|
|
694
|
+
function FIXED_BOUNDED_VEC<T>(element: TypeMapping<T>, maxLength: number): TypeMapping<T[]> {
|
|
695
|
+
const width = fieldWidth(element.shape);
|
|
696
|
+
return {
|
|
697
|
+
serialization: element.serialization
|
|
698
|
+
? {
|
|
699
|
+
fn: values => {
|
|
700
|
+
if (values.length > maxLength) {
|
|
701
|
+
throw new Error(`Got ${values.length} items, but maxLength is ${maxLength}`);
|
|
702
|
+
}
|
|
703
|
+
const flat = padArrayEnd(packElements(element, values), Fr.ZERO, maxLength * width);
|
|
704
|
+
return [[...flat, new Fr(values.length)]];
|
|
705
|
+
},
|
|
706
|
+
}
|
|
707
|
+
: undefined,
|
|
708
|
+
shape: [{ len: maxLength * width + 1 }],
|
|
458
709
|
};
|
|
459
710
|
}
|
|
460
711
|
|
|
461
712
|
/**
|
|
462
|
-
* Wraps an inner TypeMapping in Noir-style `Option<T
|
|
463
|
-
* `Option.none(shape)` template to produce a correctly-sized zero-filled output for the None case.
|
|
713
|
+
* Wraps an inner TypeMapping in Noir-style `Option<T>`, adding a leading discriminant slot.
|
|
464
714
|
*
|
|
465
|
-
*
|
|
715
|
+
* For the `None` case, the inner's slots must still be present on the wire as zero-padding (so `Some` and `None` have
|
|
716
|
+
* identical size). That padding is derived entirely from `inner.shape`.
|
|
717
|
+
*
|
|
718
|
+
* @example Serializing `Option.some(AztecAddress.fromFieldUnsafe(Fr(42)))` with `OPTION(AZTEC_ADDRESS)`:
|
|
466
719
|
* ```
|
|
467
720
|
* slot 0: Fr(1) // discriminant: Some
|
|
468
721
|
* slot 1: Fr(42) // inner value
|
|
469
722
|
* ```
|
|
470
723
|
*
|
|
471
|
-
* @example Serializing `Option.
|
|
724
|
+
* @example Serializing `Option.none()` with `OPTION(AZTEC_ADDRESS)`:
|
|
472
725
|
* ```
|
|
473
726
|
* slot 0: Fr(0) // discriminant: None
|
|
474
|
-
* slot 1: Fr(0) // zero-filled
|
|
727
|
+
* slot 1: Fr(0) // zero-filled from AZTEC_ADDRESS.shape
|
|
475
728
|
* ```
|
|
476
729
|
*/
|
|
477
|
-
export function OPTION<T>(inner: TypeMapping<T>): TypeMapping<Option<T>> {
|
|
730
|
+
export function OPTION<T>(inner: TypeMapping<T>): TypeMapping<Option<T>> & { kind: 'option'; inner: TypeMapping<T> } {
|
|
478
731
|
return {
|
|
732
|
+
kind: 'option',
|
|
733
|
+
inner,
|
|
479
734
|
serialization: inner.serialization
|
|
480
735
|
? {
|
|
481
|
-
fn: opt =>
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
if (opt.template === undefined) {
|
|
486
|
-
throw new Error(
|
|
487
|
-
'Cannot serialize Option.empty() without an emptyTemplate — provide one via Option.empty(emptyTemplate)',
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
const zeroSlots = inner
|
|
491
|
-
.serialization!.fn(opt.template)
|
|
492
|
-
.map(s => (Array.isArray(s) ? Array(s.length).fill(Fr.ZERO) : Fr.ZERO));
|
|
493
|
-
return [Fr.ZERO, ...zeroSlots];
|
|
494
|
-
},
|
|
736
|
+
fn: opt =>
|
|
737
|
+
opt.isSome()
|
|
738
|
+
? [Fr.ONE, ...inner.serialization!.fn(opt.value)]
|
|
739
|
+
: [Fr.ZERO, ...zeroSlotsFromShape(inner.shape, opt.size)],
|
|
495
740
|
}
|
|
496
741
|
: undefined,
|
|
497
742
|
deserialization: inner.deserialization
|
|
498
743
|
? {
|
|
499
744
|
fn: ([discriminant, ...innerReaders]) => {
|
|
500
745
|
if (discriminant.readField().isZero()) {
|
|
501
|
-
// None still carries zero-
|
|
502
|
-
//
|
|
746
|
+
// None still carries the inner's zero-padded slots; consume them without parsing, since an inner that
|
|
747
|
+
// validates its fields would reject the zeros.
|
|
503
748
|
innerReaders.forEach(reader => reader.skip(reader.remainingFields()));
|
|
504
|
-
return Option.none<T>(
|
|
749
|
+
return Option.none<T>();
|
|
505
750
|
}
|
|
506
751
|
return Option.some(inner.deserialization!.fn(innerReaders));
|
|
507
752
|
},
|
|
508
|
-
slots: inner.deserialization.slots + 1,
|
|
509
753
|
}
|
|
510
754
|
: undefined,
|
|
755
|
+
// A leading discriminant slot followed by the inner's slots.
|
|
756
|
+
shape: ['scalar', ...inner.shape],
|
|
511
757
|
};
|
|
512
758
|
}
|
|
513
759
|
|
|
514
|
-
/**
|
|
515
|
-
|
|
760
|
+
/**
|
|
761
|
+
* A fixed packed uint buffer (Noir `[u8; length]` at `bitSize` 8): one slot of `length` packed uint values ↔ `Buffer`.
|
|
762
|
+
* `length` is the field count, which equals the byte count at `bitSize` 8.
|
|
763
|
+
*/
|
|
764
|
+
export function BUFFER(bitSize: number, length: number): TypeMapping<Buffer> {
|
|
516
765
|
return {
|
|
517
766
|
serialization: {
|
|
518
767
|
fn: buf => [Array.from(buf).map(b => new Fr(b))],
|
|
519
768
|
},
|
|
520
769
|
deserialization: {
|
|
521
|
-
fn: ([reader]) =>
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
770
|
+
fn: ([reader]) =>
|
|
771
|
+
fromUintArray(
|
|
772
|
+
reader.readFieldArray(length).map(f => f.toString()),
|
|
773
|
+
bitSize,
|
|
774
|
+
),
|
|
526
775
|
},
|
|
776
|
+
shape: [{ len: length }],
|
|
527
777
|
};
|
|
528
778
|
}
|
|
529
779
|
|
|
530
780
|
export function EPHEMERAL_ARRAY<T>(element: TypeMapping<T>): TypeMapping<EphemeralArray<T>> {
|
|
531
|
-
//
|
|
532
|
-
//
|
|
781
|
+
// EphemeralArray.readAll hands each row's flat fields in as a single reader; reconstruct the element's per-slot
|
|
782
|
+
// readers from its shape, deserialize, and assert the row was fully consumed so a row with trailing fields is
|
|
783
|
+
// rejected.
|
|
533
784
|
const rowElement: TypeMapping<T> | undefined = element.deserialization
|
|
534
785
|
? {
|
|
535
786
|
deserialization: {
|
|
536
|
-
fn:
|
|
537
|
-
const value = element.deserialization!.fn(readers);
|
|
538
|
-
assertReadersConsumed(readers);
|
|
539
|
-
return value;
|
|
540
|
-
},
|
|
541
|
-
slots: element.deserialization.slots,
|
|
787
|
+
fn: ([rowReader]) => deserializeElement(element, rowReader.readFieldArray(rowReader.remainingFields())),
|
|
542
788
|
},
|
|
789
|
+
// `fn` reads the whole row from one reader, so this is one variable-width slot, not the element's multi-slot
|
|
790
|
+
// shape.
|
|
791
|
+
shape: ['variable'],
|
|
543
792
|
}
|
|
544
793
|
: undefined;
|
|
545
794
|
return {
|
|
546
795
|
serialization: element.serialization
|
|
547
|
-
? { fn: ea => [ea.materializeSlot(v => element
|
|
796
|
+
? { fn: ea => [ea.materializeSlot(v => serializeElement(element, v))] }
|
|
548
797
|
: undefined,
|
|
549
798
|
deserialization: rowElement
|
|
550
|
-
? { fn: ([reader]) => EphemeralArray.fromSlot(reader.readField(), rowElement)
|
|
799
|
+
? { fn: ([reader]) => EphemeralArray.fromSlot(reader.readField(), rowElement) }
|
|
551
800
|
: undefined,
|
|
801
|
+
// A single slot carrying the array's service-slot id.
|
|
802
|
+
shape: ['scalar'],
|
|
552
803
|
};
|
|
553
804
|
}
|
|
805
|
+
|
|
806
|
+
/** A named field within a {@link STRUCT}: it owns however many wire slots its {@link TypeMapping} declares. */
|
|
807
|
+
type StructField<TName extends string = string, T = any> = { name: TName; type: TypeMapping<T> };
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* A Noir struct: its `shape` and (de)serialization are the concatenation of its fields', so callers never hand-write a
|
|
811
|
+
* `shape`. `T` is the struct's TS value type and must match the field layout — serialization reads each field by name
|
|
812
|
+
* off the value, deserialization returns the decoded bag as `T`; convert in the handler, not here, when `T` differs.
|
|
813
|
+
*/
|
|
814
|
+
function STRUCT<T>(fields: readonly StructField[]): TypeMapping<T> {
|
|
815
|
+
return {
|
|
816
|
+
serialization: fields.every(f => f.type.serialization)
|
|
817
|
+
? {
|
|
818
|
+
fn: (value: T) => {
|
|
819
|
+
const props = value as any;
|
|
820
|
+
return fields.flatMap(f => f.type.serialization!.fn(props[f.name]));
|
|
821
|
+
},
|
|
822
|
+
}
|
|
823
|
+
: undefined,
|
|
824
|
+
deserialization: fields.every(f => f.type.deserialization)
|
|
825
|
+
? {
|
|
826
|
+
fn: readers => {
|
|
827
|
+
const props: Record<string, unknown> = {};
|
|
828
|
+
let slot = 0;
|
|
829
|
+
for (const f of fields) {
|
|
830
|
+
const slotCount = f.type.shape.length;
|
|
831
|
+
props[f.name] = f.type.deserialization!.fn(readers.slice(slot, slot + slotCount));
|
|
832
|
+
slot += slotCount;
|
|
833
|
+
}
|
|
834
|
+
return props as T;
|
|
835
|
+
},
|
|
836
|
+
}
|
|
837
|
+
: undefined,
|
|
838
|
+
shape: fields.flatMap(f => f.type.shape),
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/** Number of InputSlots a deserializable type spans, derived from its {@link TypeMapping.shape}. */
|
|
843
|
+
export function slotsOf(mapping: TypeMapping): number {
|
|
844
|
+
return mapping.shape.length;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/** Number of fields a fully-static shape occupies, or `undefined` if any slot is variable-width. */
|
|
848
|
+
function tryFieldWidth(shape: SlotShape[]): number | undefined {
|
|
849
|
+
let total = 0;
|
|
850
|
+
for (const slot of shape) {
|
|
851
|
+
if (slot === 'scalar') {
|
|
852
|
+
total += 1;
|
|
853
|
+
} else if (typeof slot === 'object' && 'len' in slot) {
|
|
854
|
+
total += slot.len;
|
|
855
|
+
} else {
|
|
856
|
+
return undefined;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return total;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/** Number of fields a fully-static shape occupies. Throws on a variable-width shape, whose field count isn't known. */
|
|
863
|
+
function fieldWidth(shape: SlotShape[]): number {
|
|
864
|
+
const width = tryFieldWidth(shape);
|
|
865
|
+
if (width === undefined) {
|
|
866
|
+
throw new Error('Cannot compute a fixed field width for a variable-width shape');
|
|
867
|
+
}
|
|
868
|
+
return width;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
/** Reconstructs a value's per-slot readers from a flat run of fields, using its shape (inverse of slot-flattening). */
|
|
872
|
+
function splitByShape(fields: Fr[], shape: SlotShape[]): FieldReader[] {
|
|
873
|
+
const readers: FieldReader[] = [];
|
|
874
|
+
let cursor = 0;
|
|
875
|
+
shape.forEach((slot, i) => {
|
|
876
|
+
if (slot === 'scalar' || (typeof slot === 'object' && 'len' in slot)) {
|
|
877
|
+
const width = slot === 'scalar' ? 1 : slot.len;
|
|
878
|
+
if (cursor + width > fields.length) {
|
|
879
|
+
throw new Error(`Not enough fields to reconstruct shape: needed ${width}, had ${fields.length - cursor}`);
|
|
880
|
+
}
|
|
881
|
+
readers.push(new FieldReader(fields.slice(cursor, cursor + width)));
|
|
882
|
+
cursor += width;
|
|
883
|
+
} else {
|
|
884
|
+
// A variable slot (sized or not) takes whatever remains, so it must be last.
|
|
885
|
+
if (i !== shape.length - 1) {
|
|
886
|
+
throw new Error('A variable-width slot must be last to be reconstructed from a flat field array');
|
|
887
|
+
}
|
|
888
|
+
readers.push(new FieldReader(fields.slice(cursor)));
|
|
889
|
+
cursor = fields.length;
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
if (cursor !== fields.length) {
|
|
893
|
+
throw new Error(`Malformed flattened value: ${fields.length - cursor} unexpected trailing field(s)`);
|
|
894
|
+
}
|
|
895
|
+
return readers;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/** Serializes one element to its flat fields. Element must be serializable. */
|
|
899
|
+
function serializeElement<T>(element: TypeMapping<T>, value: T): Fr[] {
|
|
900
|
+
return element.serialization!.fn(value).flat();
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Deserializes one element from its exact flat fields, reconstructing its per-slot readers from its shape and asserting
|
|
905
|
+
* they are fully consumed (so trailing fields are rejected). Element must be deserializable.
|
|
906
|
+
*/
|
|
907
|
+
function deserializeElement<T>(element: TypeMapping<T>, fields: Fr[]): T {
|
|
908
|
+
const readers = splitByShape(fields, element.shape);
|
|
909
|
+
const value = element.deserialization!.fn(readers);
|
|
910
|
+
assertReadersConsumed(readers);
|
|
911
|
+
return value;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/** Flattens `values` into one contiguous run of fields by serializing each element. Element must be serializable. */
|
|
915
|
+
function packElements<T>(element: TypeMapping<T>, values: T[]): Fr[] {
|
|
916
|
+
return values.flatMap(v => serializeElement(element, v));
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Reads `count` fixed-width elements out of a packed run (the inverse of {@link packElements}). Element must be
|
|
921
|
+
* deserializable.
|
|
922
|
+
*/
|
|
923
|
+
function unpackElements<T>(element: TypeMapping<T>, reader: FieldReader, count: number): T[] {
|
|
924
|
+
const elementWidth = fieldWidth(element.shape);
|
|
925
|
+
return Array.from({ length: count }, () => deserializeElement(element, reader.readFieldArray(elementWidth)));
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/** Builds the zero-filled slots for a `None`, matching a `Some`'s wire shape (variable slots sized from `size`). */
|
|
929
|
+
function zeroSlotsFromShape(shape: SlotShape[], size: unknown): (Fr | Fr[])[] {
|
|
930
|
+
return shape.map(slot => {
|
|
931
|
+
if (slot === 'scalar') {
|
|
932
|
+
return Fr.ZERO;
|
|
933
|
+
}
|
|
934
|
+
if (slot === 'variable') {
|
|
935
|
+
throw new Error('Cannot zero-fill an unsized variable-width slot');
|
|
936
|
+
}
|
|
937
|
+
if ('len' in slot) {
|
|
938
|
+
return Array<Fr>(slot.len).fill(Fr.ZERO);
|
|
939
|
+
}
|
|
940
|
+
if (size === undefined) {
|
|
941
|
+
throw new Error(
|
|
942
|
+
'Serializing Option.none() over a variable-size inner needs a size, e.g. Option.none({ length: n })',
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
return Array<Fr>(slot.lenFrom(size)).fill(Fr.ZERO);
|
|
946
|
+
});
|
|
947
|
+
}
|