@aztec/pxe 5.0.0-rc.1 → 5.0.0

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 (297) hide show
  1. package/dest/block_synchronizer/block_stream_source.d.ts +5 -5
  2. package/dest/block_synchronizer/block_stream_source.d.ts.map +1 -1
  3. package/dest/block_synchronizer/block_stream_source.js +4 -29
  4. package/dest/block_synchronizer/block_synchronizer.d.ts +16 -12
  5. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  6. package/dest/block_synchronizer/block_synchronizer.js +49 -15
  7. package/dest/config/index.d.ts +2 -1
  8. package/dest/config/index.d.ts.map +1 -1
  9. package/dest/config/index.js +1 -0
  10. package/dest/contract/contract_class_service.d.ts +31 -0
  11. package/dest/contract/contract_class_service.d.ts.map +1 -0
  12. package/dest/contract/contract_class_service.js +68 -0
  13. package/dest/{contract_sync → contract}/contract_sync_service.d.ts +7 -6
  14. package/dest/contract/contract_sync_service.d.ts.map +1 -0
  15. package/dest/{contract_sync → contract}/contract_sync_service.js +10 -30
  16. package/dest/contract/helpers.d.ts +7 -0
  17. package/dest/contract/helpers.d.ts.map +1 -0
  18. package/dest/contract/helpers.js +20 -0
  19. package/dest/contract_function_simulator/anchored_contract_data.d.ts +36 -0
  20. package/dest/contract_function_simulator/anchored_contract_data.d.ts.map +1 -0
  21. package/dest/contract_function_simulator/anchored_contract_data.js +54 -0
  22. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts +39 -0
  23. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts.map +1 -0
  24. package/dest/contract_function_simulator/aztec_node_read_cache.js +60 -0
  25. package/dest/contract_function_simulator/contract_function_simulator.d.ts +19 -18
  26. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  27. package/dest/contract_function_simulator/contract_function_simulator.js +52 -31
  28. package/dest/contract_function_simulator/execution_note_cache.d.ts +3 -9
  29. package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
  30. package/dest/contract_function_simulator/execution_note_cache.js +8 -28
  31. package/dest/contract_function_simulator/index.d.ts +17 -9
  32. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  33. package/dest/contract_function_simulator/index.js +4 -7
  34. package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts +8 -27
  35. package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts.map +1 -1
  36. package/dest/contract_function_simulator/noir-structs/bounded_vec.js +8 -23
  37. package/dest/contract_function_simulator/noir-structs/contract_class_log_data.d.ts +9 -0
  38. package/dest/contract_function_simulator/noir-structs/contract_class_log_data.d.ts.map +1 -0
  39. package/dest/contract_function_simulator/noir-structs/contract_class_log_data.js +1 -0
  40. package/dest/contract_function_simulator/noir-structs/embedded_curve_point.d.ts +7 -0
  41. package/dest/contract_function_simulator/noir-structs/embedded_curve_point.d.ts.map +1 -0
  42. package/dest/contract_function_simulator/noir-structs/embedded_curve_point.js +1 -0
  43. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
  44. package/dest/contract_function_simulator/noir-structs/fact.d.ts +16 -0
  45. package/dest/contract_function_simulator/noir-structs/fact.d.ts.map +1 -0
  46. package/dest/contract_function_simulator/noir-structs/fact.js +6 -0
  47. package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts +27 -0
  48. package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts.map +1 -0
  49. package/dest/contract_function_simulator/noir-structs/fact_collection.js +31 -0
  50. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +11 -12
  51. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -1
  52. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +6 -49
  53. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +10 -8
  54. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  55. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -60
  56. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +2 -2
  57. package/dest/contract_function_simulator/noir-structs/option.d.ts +9 -11
  58. package/dest/contract_function_simulator/noir-structs/option.d.ts.map +1 -1
  59. package/dest/contract_function_simulator/noir-structs/option.js +18 -13
  60. package/dest/contract_function_simulator/noir-structs/origin_block.d.ts +11 -0
  61. package/dest/contract_function_simulator/noir-structs/origin_block.d.ts.map +1 -0
  62. package/dest/contract_function_simulator/noir-structs/origin_block.js +5 -0
  63. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts +11 -0
  64. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts.map +1 -0
  65. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.js +4 -0
  66. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts +6 -9
  67. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts.map +1 -1
  68. package/dest/contract_function_simulator/noir-structs/provided_secret.js +1 -14
  69. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts +28 -0
  70. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts.map +1 -0
  71. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.js +50 -0
  72. package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts +21 -0
  73. package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts.map +1 -0
  74. package/dest/contract_function_simulator/noir-structs/resolved_tx.js +50 -0
  75. package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts +14 -0
  76. package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts.map +1 -0
  77. package/dest/contract_function_simulator/noir-structs/tx_effect_data.js +5 -0
  78. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +6 -11
  79. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -1
  80. package/dest/contract_function_simulator/noir-structs/utility_context.js +1 -20
  81. package/dest/contract_function_simulator/oracle/acir_callback.d.ts +7 -2
  82. package/dest/contract_function_simulator/oracle/acir_callback.d.ts.map +1 -1
  83. package/dest/contract_function_simulator/oracle/acir_callback.js +55 -11
  84. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts +39 -0
  85. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts.map +1 -0
  86. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.js +107 -0
  87. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +3 -14
  88. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
  89. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.js +1 -24
  90. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +86 -8
  91. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -1
  92. package/dest/contract_function_simulator/oracle/oracle_registry.js +168 -18
  93. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +123 -40
  94. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -1
  95. package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +947 -264
  96. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +21 -8
  97. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  98. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +126 -16
  99. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +63 -33
  100. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  101. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +175 -90
  102. package/dest/debug/pxe_debug_utils.d.ts +2 -2
  103. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  104. package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
  105. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  106. package/dest/entrypoints/client/bundle/utils.js +3 -2
  107. package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
  108. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  109. package/dest/entrypoints/client/lazy/utils.js +3 -2
  110. package/dest/entrypoints/pxe_creation_options.d.ts +8 -2
  111. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  112. package/dest/entrypoints/server/index.d.ts +5 -3
  113. package/dest/entrypoints/server/index.d.ts.map +1 -1
  114. package/dest/entrypoints/server/index.js +3 -2
  115. package/dest/entrypoints/server/utils.d.ts +1 -1
  116. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  117. package/dest/entrypoints/server/utils.js +3 -1
  118. package/dest/error_enriching.d.ts +5 -3
  119. package/dest/error_enriching.d.ts.map +1 -1
  120. package/dest/error_enriching.js +13 -11
  121. package/dest/hooks/execution_hooks.d.ts +27 -7
  122. package/dest/hooks/execution_hooks.d.ts.map +1 -1
  123. package/dest/hooks/execution_hooks.js +3 -3
  124. package/dest/hooks/index.d.ts +4 -3
  125. package/dest/hooks/index.d.ts.map +1 -1
  126. package/dest/hooks/index.js +1 -0
  127. package/dest/hooks/resolve_custom_request.d.ts +23 -0
  128. package/dest/hooks/resolve_custom_request.d.ts.map +1 -0
  129. package/dest/hooks/resolve_custom_request.js +3 -0
  130. package/dest/hooks/resolve_tagging_secret_strategy.d.ts +50 -0
  131. package/dest/hooks/resolve_tagging_secret_strategy.d.ts.map +1 -0
  132. package/dest/hooks/resolve_tagging_secret_strategy.js +3 -0
  133. package/dest/logs/log_service.d.ts +7 -6
  134. package/dest/logs/log_service.d.ts.map +1 -1
  135. package/dest/logs/log_service.js +79 -28
  136. package/dest/messages/tx_resolver_service.d.ts +17 -0
  137. package/dest/messages/tx_resolver_service.d.ts.map +1 -0
  138. package/dest/messages/{message_context_service.js → tx_resolver_service.js} +8 -8
  139. package/dest/oracle_version.d.ts +3 -3
  140. package/dest/oracle_version.js +3 -3
  141. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +1 -1
  142. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  143. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +6 -2
  144. package/dest/private_kernel/hints/test_utils.js +1 -1
  145. package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
  146. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  147. package/dest/private_kernel/private_kernel_execution_prover.js +17 -36
  148. package/dest/private_kernel/private_kernel_oracle.d.ts +4 -2
  149. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  150. package/dest/private_kernel/private_kernel_oracle.js +17 -5
  151. package/dest/pxe.d.ts +109 -47
  152. package/dest/pxe.d.ts.map +1 -1
  153. package/dest/pxe.js +222 -139
  154. package/dest/storage/allowed_scopes.d.ts +6 -0
  155. package/dest/storage/allowed_scopes.d.ts.map +1 -0
  156. package/dest/storage/allowed_scopes.js +7 -0
  157. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +1 -1
  158. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -1
  159. package/dest/storage/backwards_compatibility_tests/schema_tests.js +114 -37
  160. package/dest/storage/capsule_store/capsule_service.d.ts +1 -1
  161. package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -1
  162. package/dest/storage/capsule_store/capsule_service.js +6 -9
  163. package/dest/storage/contract_store/contract_store.d.ts +27 -24
  164. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  165. package/dest/storage/contract_store/contract_store.js +64 -75
  166. package/dest/storage/fact_store/fact_service.d.ts +22 -0
  167. package/dest/storage/fact_store/fact_service.d.ts.map +1 -0
  168. package/dest/storage/fact_store/fact_service.js +45 -0
  169. package/dest/storage/fact_store/fact_store.d.ts +95 -0
  170. package/dest/storage/fact_store/fact_store.d.ts.map +1 -0
  171. package/dest/storage/fact_store/fact_store.js +408 -0
  172. package/dest/storage/fact_store/fact_store_keys.d.ts +34 -0
  173. package/dest/storage/fact_store/fact_store_keys.d.ts.map +1 -0
  174. package/dest/storage/fact_store/fact_store_keys.js +50 -0
  175. package/dest/storage/fact_store/index.d.ts +6 -0
  176. package/dest/storage/fact_store/index.d.ts.map +1 -0
  177. package/dest/storage/fact_store/index.js +4 -0
  178. package/dest/storage/fact_store/origin_state.d.ts +57 -0
  179. package/dest/storage/fact_store/origin_state.d.ts.map +1 -0
  180. package/dest/storage/fact_store/origin_state.js +53 -0
  181. package/dest/storage/fact_store/stored_fact.d.ts +32 -0
  182. package/dest/storage/fact_store/stored_fact.d.ts.map +1 -0
  183. package/dest/storage/fact_store/stored_fact.js +64 -0
  184. package/dest/storage/index.d.ts +2 -1
  185. package/dest/storage/index.d.ts.map +1 -1
  186. package/dest/storage/index.js +1 -0
  187. package/dest/storage/metadata.d.ts +2 -2
  188. package/dest/storage/metadata.d.ts.map +1 -1
  189. package/dest/storage/metadata.js +1 -1
  190. package/dest/storage/open_pxe_stores.d.ts +5 -3
  191. package/dest/storage/open_pxe_stores.d.ts.map +1 -1
  192. package/dest/storage/open_pxe_stores.js +5 -3
  193. package/dest/storage/tagging_store/index.d.ts +2 -2
  194. package/dest/storage/tagging_store/index.d.ts.map +1 -1
  195. package/dest/storage/tagging_store/index.js +1 -1
  196. package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts +51 -0
  197. package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts.map +1 -0
  198. package/dest/storage/tagging_store/tagging_secret_sources_store.js +105 -0
  199. package/dest/tagging/constants.d.ts +2 -2
  200. package/dest/tagging/constants.d.ts.map +1 -1
  201. package/dest/tagging/constants.js +18 -9
  202. package/package.json +17 -17
  203. package/src/block_synchronizer/block_stream_source.ts +6 -45
  204. package/src/block_synchronizer/block_synchronizer.ts +65 -24
  205. package/src/config/index.ts +1 -0
  206. package/src/contract/contract_class_service.ts +83 -0
  207. package/src/{contract_sync → contract}/contract_sync_service.ts +18 -37
  208. package/src/contract/helpers.ts +35 -0
  209. package/src/contract_function_simulator/anchored_contract_data.ts +74 -0
  210. package/src/contract_function_simulator/aztec_node_read_cache.ts +89 -0
  211. package/src/contract_function_simulator/contract_function_simulator.ts +86 -43
  212. package/src/contract_function_simulator/execution_note_cache.ts +7 -28
  213. package/src/contract_function_simulator/index.ts +24 -9
  214. package/src/contract_function_simulator/noir-structs/bounded_vec.ts +12 -24
  215. package/src/contract_function_simulator/noir-structs/contract_class_log_data.ts +9 -0
  216. package/src/contract_function_simulator/noir-structs/embedded_curve_point.ts +4 -0
  217. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
  218. package/src/contract_function_simulator/noir-structs/fact.ts +13 -0
  219. package/src/contract_function_simulator/noir-structs/fact_collection.ts +64 -0
  220. package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +20 -46
  221. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +13 -60
  222. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +2 -2
  223. package/src/contract_function_simulator/noir-structs/option.ts +17 -11
  224. package/src/contract_function_simulator/noir-structs/origin_block.ts +8 -0
  225. package/src/contract_function_simulator/noir-structs/pending_tagged_log.ts +12 -0
  226. package/src/contract_function_simulator/noir-structs/provided_secret.ts +4 -15
  227. package/src/contract_function_simulator/noir-structs/resolved_tagging_strategy.ts +66 -0
  228. package/src/contract_function_simulator/noir-structs/resolved_tx.ts +53 -0
  229. package/src/contract_function_simulator/noir-structs/tx_effect_data.ts +15 -0
  230. package/src/contract_function_simulator/noir-structs/utility_context.ts +5 -17
  231. package/src/contract_function_simulator/oracle/acir_callback.ts +58 -12
  232. package/src/contract_function_simulator/oracle/legacy_oracle_registry.ts +147 -0
  233. package/src/contract_function_simulator/oracle/message_load_oracle_inputs.ts +6 -21
  234. package/src/contract_function_simulator/oracle/oracle_registry.ts +119 -86
  235. package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +659 -248
  236. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +155 -24
  237. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +300 -115
  238. package/src/debug/pxe_debug_utils.ts +1 -1
  239. package/src/entrypoints/client/bundle/utils.ts +3 -2
  240. package/src/entrypoints/client/lazy/utils.ts +3 -2
  241. package/src/entrypoints/pxe_creation_options.ts +7 -1
  242. package/src/entrypoints/server/index.ts +5 -2
  243. package/src/entrypoints/server/utils.ts +3 -1
  244. package/src/error_enriching.ts +27 -11
  245. package/src/hooks/execution_hooks.ts +28 -8
  246. package/src/hooks/index.ts +8 -2
  247. package/src/hooks/resolve_custom_request.ts +24 -0
  248. package/src/hooks/resolve_tagging_secret_strategy.ts +60 -0
  249. package/src/logs/log_service.ts +91 -37
  250. package/src/messages/{message_context_service.ts → tx_resolver_service.ts} +16 -9
  251. package/src/oracle_version.ts +3 -3
  252. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +11 -1
  253. package/src/private_kernel/hints/test_utils.ts +1 -1
  254. package/src/private_kernel/private_kernel_execution_prover.ts +22 -52
  255. package/src/private_kernel/private_kernel_oracle.ts +23 -4
  256. package/src/pxe.ts +320 -158
  257. package/src/storage/allowed_scopes.ts +14 -0
  258. package/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +6 -6
  259. package/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +1 -1
  260. package/src/storage/backwards_compatibility_tests/__snapshots__/FactStore.json +40 -0
  261. package/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +12 -12
  262. package/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json +1 -1
  263. package/src/storage/backwards_compatibility_tests/__snapshots__/RecipientTaggingStore.json +11 -3
  264. package/src/storage/backwards_compatibility_tests/__snapshots__/SenderTaggingStore.json +12 -4
  265. package/src/storage/backwards_compatibility_tests/__snapshots__/TaggingSecretSourcesStore.json +30 -0
  266. package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +21 -5
  267. package/src/storage/backwards_compatibility_tests/schema_tests.ts +125 -36
  268. package/src/storage/capsule_store/capsule_service.ts +8 -13
  269. package/src/storage/contract_store/contract_store.ts +86 -93
  270. package/src/storage/fact_store/fact_service.ts +69 -0
  271. package/src/storage/fact_store/fact_store.ts +487 -0
  272. package/src/storage/fact_store/fact_store_keys.ts +75 -0
  273. package/src/storage/fact_store/index.ts +14 -0
  274. package/src/storage/fact_store/origin_state.ts +75 -0
  275. package/src/storage/fact_store/stored_fact.ts +80 -0
  276. package/src/storage/index.ts +1 -0
  277. package/src/storage/metadata.ts +1 -1
  278. package/src/storage/open_pxe_stores.ts +6 -3
  279. package/src/storage/tagging_store/index.ts +1 -1
  280. package/src/storage/tagging_store/tagging_secret_sources_store.ts +138 -0
  281. package/src/tagging/constants.ts +19 -9
  282. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +0 -6
  283. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +0 -1
  284. package/dest/contract_function_simulator/proxied_contract_data_source.js +0 -51
  285. package/dest/contract_sync/contract_sync_service.d.ts.map +0 -1
  286. package/dest/contract_sync/helpers.d.ts +0 -27
  287. package/dest/contract_sync/helpers.d.ts.map +0 -1
  288. package/dest/contract_sync/helpers.js +0 -53
  289. package/dest/messages/message_context_service.d.ts +0 -17
  290. package/dest/messages/message_context_service.d.ts.map +0 -1
  291. package/dest/storage/tagging_store/sender_address_book_store.d.ts +0 -14
  292. package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +0 -1
  293. package/dest/storage/tagging_store/sender_address_book_store.js +0 -36
  294. package/src/contract_function_simulator/proxied_contract_data_source.ts +0 -60
  295. package/src/contract_sync/helpers.ts +0 -86
  296. package/src/storage/backwards_compatibility_tests/__snapshots__/SenderAddressBookStore.json +0 -16
  297. package/src/storage/tagging_store/sender_address_book_store.ts +0 -48
@@ -1,23 +1,22 @@
1
- import { BLOCK_HEADER_LENGTH, KEY_VALIDATION_REQUEST_LENGTH, MAX_CONTRACT_CLASS_LOGS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/constants';
1
+ import { CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH, L1_TO_L2_MSG_TREE_HEIGHT, MAX_CONTRACT_CLASS_LOGS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT, PRIVATE_LOG_CIPHERTEXT_LEN, PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_DATA_TREE_HEIGHT } from '@aztec/constants';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
3
  import { padArrayEnd } from '@aztec/foundation/collection';
4
4
  import { Fr } from '@aztec/foundation/curves/bn254';
5
- import { Point } from '@aztec/foundation/curves/grumpkin';
5
+ import { EthAddress } from '@aztec/foundation/eth-address';
6
+ import { FieldReader } from '@aztec/foundation/serialize';
6
7
  import { fromUintArray } from '@aztec/simulator/client';
7
8
  import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
8
- import { PublicDataWrite } from '@aztec/stdlib/avm';
9
9
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
10
10
  import { BlockHash } from '@aztec/stdlib/block';
11
- import { KeyValidationRequest } from '@aztec/stdlib/kernel';
12
- import { ContractClassLog, ContractClassLogFields, FlatPublicLogs, PrivateLog, Tag, appTaggingSecretKindFromDeliveryMode } from '@aztec/stdlib/logs';
13
- import { BlockHeader, TxHash } from '@aztec/stdlib/tx';
11
+ import { Tag, appTaggingSecretKindFromDeliveryMode } from '@aztec/stdlib/logs';
12
+ import { TxHash } from '@aztec/stdlib/tx';
14
13
  import { BoundedVec } from '../noir-structs/bounded_vec.js';
15
14
  import { EphemeralArray } from '../noir-structs/ephemeral_array.js';
16
15
  import { EventValidationRequest } from '../noir-structs/event_validation_request.js';
17
- import { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
16
+ import { logSourceFromField } from '../noir-structs/log_retrieval_request.js';
18
17
  import { NoteValidationRequest } from '../noir-structs/note_validation_request.js';
19
18
  import { Option } from '../noir-structs/option.js';
20
- import { ProvidedSecret } from '../noir-structs/provided_secret.js';
19
+ import { resolvedTaggingStrategyFromFields, resolvedTaggingStrategyToFields } from '../noir-structs/resolved_tagging_strategy.js';
21
20
  import { packAsHintedNote } from './note_packing_utils.js';
22
21
  /**
23
22
  * Asserts that every reader was fully consumed by a deserialization, throwing on leftover fields.
@@ -36,9 +35,11 @@ export const FIELD = {
36
35
  ]
37
36
  },
38
37
  deserialization: {
39
- fn: ([reader])=>reader.readField(),
40
- slots: 1
41
- }
38
+ fn: ([reader])=>reader.readField()
39
+ },
40
+ shape: [
41
+ 'scalar'
42
+ ]
42
43
  };
43
44
  export const BOOL = {
44
45
  serialization: {
@@ -47,9 +48,11 @@ export const BOOL = {
47
48
  ]
48
49
  },
49
50
  deserialization: {
50
- fn: ([reader])=>!reader.readField().isZero(),
51
- slots: 1
52
- }
51
+ fn: ([reader])=>!reader.readField().isZero()
52
+ },
53
+ shape: [
54
+ 'scalar'
55
+ ]
53
56
  };
54
57
  export const U32 = {
55
58
  serialization: {
@@ -64,9 +67,11 @@ export const U32 = {
64
67
  throw new Error(`U32 overflow: value ${value} exceeds u32 max (${0xffffffffn})`);
65
68
  }
66
69
  return Number(value);
67
- },
68
- slots: 1
69
- }
70
+ }
71
+ },
72
+ shape: [
73
+ 'scalar'
74
+ ]
70
75
  };
71
76
  export const BLOCK_NUMBER = {
72
77
  serialization: {
@@ -75,9 +80,11 @@ export const BLOCK_NUMBER = {
75
80
  ]
76
81
  },
77
82
  deserialization: {
78
- fn: ([reader])=>BlockNumber(reader.readField().toNumber()),
79
- slots: 1
80
- }
83
+ fn: ([reader])=>BlockNumber(reader.readField().toNumber())
84
+ },
85
+ shape: [
86
+ 'scalar'
87
+ ]
81
88
  };
82
89
  /** A u8 byte: serializes to a single Fr; deserializes from a single Fr to a number in [0, 255]. */ export const BYTE = {
83
90
  serialization: {
@@ -92,16 +99,30 @@ export const BLOCK_NUMBER = {
92
99
  throw new Error(`BYTE overflow: value ${value} exceeds u8 max (255)`);
93
100
  }
94
101
  return Number(value);
95
- },
96
- slots: 1
97
- }
102
+ }
103
+ },
104
+ shape: [
105
+ 'scalar'
106
+ ]
98
107
  };
99
108
  // Noir passes `MessageDelivery` onchain variants here.
100
109
  export const DELIVERY_MODE = {
101
110
  deserialization: {
102
- fn: (readers)=>appTaggingSecretKindFromDeliveryMode(BYTE.deserialization.fn(readers)),
103
- slots: BYTE.deserialization.slots
104
- }
111
+ fn: (readers)=>appTaggingSecretKindFromDeliveryMode(BYTE.deserialization.fn(readers))
112
+ },
113
+ shape: BYTE.shape
114
+ };
115
+ export const RESOLVED_TAGGING_STRATEGY = {
116
+ serialization: {
117
+ fn: (resolved)=>resolvedTaggingStrategyToFields(resolved)
118
+ },
119
+ deserialization: {
120
+ fn: ([kindReader, secretReader])=>resolvedTaggingStrategyFromFields(kindReader.readField().toNumber(), secretReader.readField())
121
+ },
122
+ shape: [
123
+ 'scalar',
124
+ 'scalar'
125
+ ]
105
126
  };
106
127
  export const BIGINT = {
107
128
  serialization: {
@@ -110,9 +131,11 @@ export const BIGINT = {
110
131
  ]
111
132
  },
112
133
  deserialization: {
113
- fn: ([reader])=>reader.readField().toBigInt(),
114
- slots: 1
115
- }
134
+ fn: ([reader])=>reader.readField().toBigInt()
135
+ },
136
+ shape: [
137
+ 'scalar'
138
+ ]
116
139
  };
117
140
  /** Reads every field in the slot as a UTF-8 character code. */ export const STR = {
118
141
  serialization: {
@@ -127,9 +150,11 @@ export const BIGINT = {
127
150
  chars.push(String.fromCharCode(reader.readField().toNumber()));
128
151
  }
129
152
  return chars.join('');
130
- },
131
- slots: 1
132
- }
153
+ }
154
+ },
155
+ shape: [
156
+ 'variable'
157
+ ]
133
158
  };
134
159
  export const AZTEC_ADDRESS = {
135
160
  serialization: {
@@ -138,9 +163,11 @@ export const AZTEC_ADDRESS = {
138
163
  ]
139
164
  },
140
165
  deserialization: {
141
- fn: ([reader])=>AztecAddress.fromField(reader.readField()),
142
- slots: 1
143
- }
166
+ fn: ([reader])=>AztecAddress.fromFieldUnsafe(reader.readField())
167
+ },
168
+ shape: [
169
+ 'scalar'
170
+ ]
144
171
  };
145
172
  export const BLOCK_HASH = {
146
173
  serialization: {
@@ -149,9 +176,11 @@ export const BLOCK_HASH = {
149
176
  ]
150
177
  },
151
178
  deserialization: {
152
- fn: ([reader])=>new BlockHash(reader.readField()),
153
- slots: 1
154
- }
179
+ fn: ([reader])=>new BlockHash(reader.readField())
180
+ },
181
+ shape: [
182
+ 'scalar'
183
+ ]
155
184
  };
156
185
  export const FUNCTION_SELECTOR = {
157
186
  serialization: {
@@ -160,9 +189,11 @@ export const FUNCTION_SELECTOR = {
160
189
  ]
161
190
  },
162
191
  deserialization: {
163
- fn: ([reader])=>FunctionSelector.fromField(reader.readField()),
164
- slots: 1
165
- }
192
+ fn: ([reader])=>FunctionSelector.fromField(reader.readField())
193
+ },
194
+ shape: [
195
+ 'scalar'
196
+ ]
166
197
  };
167
198
  export const NOTE_SELECTOR = {
168
199
  serialization: {
@@ -171,9 +202,11 @@ export const NOTE_SELECTOR = {
171
202
  ]
172
203
  },
173
204
  deserialization: {
174
- fn: ([reader])=>NoteSelector.fromField(reader.readField()),
175
- slots: 1
176
- }
205
+ fn: ([reader])=>NoteSelector.fromField(reader.readField())
206
+ },
207
+ shape: [
208
+ 'scalar'
209
+ ]
177
210
  };
178
211
  export const TX_HASH = {
179
212
  serialization: {
@@ -182,147 +215,465 @@ export const TX_HASH = {
182
215
  ]
183
216
  },
184
217
  deserialization: {
185
- fn: ([reader])=>TxHash.fromField(reader.readField()),
186
- slots: 1
187
- }
218
+ fn: ([reader])=>TxHash.fromField(reader.readField())
219
+ },
220
+ shape: [
221
+ 'scalar'
222
+ ]
188
223
  };
189
- export const TAG = {
224
+ const TAG = {
190
225
  serialization: {
191
226
  fn: (v)=>[
192
227
  v.value
193
228
  ]
194
229
  },
195
230
  deserialization: {
196
- fn: ([reader])=>new Tag(reader.readField()),
197
- slots: 1
198
- }
231
+ fn: ([reader])=>new Tag(reader.readField())
232
+ },
233
+ shape: [
234
+ 'scalar'
235
+ ]
199
236
  };
200
- export const POINT = {
201
- serialization: {
202
- fn: (p)=>[
203
- p.toFields()
204
- ]
237
+ export const POINT = STRUCT([
238
+ {
239
+ name: 'x',
240
+ type: FIELD
205
241
  },
206
- deserialization: {
207
- fn: ([reader])=>Point.fromFields([
208
- reader.readField(),
209
- reader.readField()
210
- ]),
211
- slots: 1
242
+ {
243
+ name: 'y',
244
+ type: FIELD
212
245
  }
213
- };
214
- // ─── Struct Type Mappings ────────────────────────────────────────────────────
215
- export const BLOCK_HEADER = {
246
+ ]);
247
+ const LOG_SOURCE = {
216
248
  serialization: {
217
- fn: (v)=>v.toFields()
249
+ fn: (v)=>[
250
+ new Fr(v)
251
+ ]
218
252
  },
219
253
  deserialization: {
220
- fn: ([reader])=>BlockHeader.fromFields(reader.readFieldArray(BLOCK_HEADER_LENGTH)),
221
- slots: 1
222
- }
254
+ fn: ([reader])=>logSourceFromField(reader.readField())
255
+ },
256
+ shape: [
257
+ 'scalar'
258
+ ]
223
259
  };
224
- export const KEY_VALIDATION_REQUEST = {
260
+ export const ETH_ADDRESS = {
225
261
  serialization: {
226
- fn: (v)=>v.toFields()
262
+ fn: (v)=>[
263
+ v.toField()
264
+ ]
227
265
  },
228
266
  deserialization: {
229
- fn: ([reader])=>KeyValidationRequest.fromFields(reader.readFieldArray(KEY_VALIDATION_REQUEST_LENGTH)),
230
- slots: 1
231
- }
267
+ fn: ([reader])=>EthAddress.fromField(reader.readField())
268
+ },
269
+ shape: [
270
+ 'scalar'
271
+ ]
232
272
  };
233
- export const CONTRACT_INSTANCE = {
273
+ export const SLOT_NUMBER = {
234
274
  serialization: {
235
275
  fn: (v)=>[
236
- v.salt,
237
- v.deployer.toField(),
238
- v.currentContractClassId,
239
- v.initializationHash,
240
- v.immutablesHash,
241
- ...v.publicKeys.toFields()
276
+ new Fr(v)
242
277
  ]
243
- }
278
+ },
279
+ shape: [
280
+ 'scalar'
281
+ ]
244
282
  };
245
- export const NULLIFIER_MEMBERSHIP_WITNESS = {
246
- serialization: {
247
- fn: (w)=>w.toNoirRepresentation().map((slot)=>Array.isArray(slot) ? slot.map((s)=>Fr.fromString(s)) : Fr.fromString(slot))
283
+ const APPEND_ONLY_TREE_SNAPSHOT = STRUCT([
284
+ {
285
+ name: 'root',
286
+ type: FIELD
287
+ },
288
+ {
289
+ name: 'nextAvailableLeafIndex',
290
+ type: U32
248
291
  }
249
- };
250
- export const PUBLIC_DATA_WITNESS = {
251
- serialization: {
252
- fn: (w)=>w.toNoirRepresentation().map((slot)=>Array.isArray(slot) ? slot.map((s)=>Fr.fromString(s)) : Fr.fromString(slot))
292
+ ]);
293
+ const PARTIAL_STATE_REFERENCE = STRUCT([
294
+ {
295
+ name: 'noteHashTree',
296
+ type: APPEND_ONLY_TREE_SNAPSHOT
297
+ },
298
+ {
299
+ name: 'nullifierTree',
300
+ type: APPEND_ONLY_TREE_SNAPSHOT
301
+ },
302
+ {
303
+ name: 'publicDataTree',
304
+ type: APPEND_ONLY_TREE_SNAPSHOT
253
305
  }
254
- };
255
- export const MESSAGE_LOAD_ORACLE_INPUTS = {
256
- serialization: {
257
- fn: (m)=>m.toNoirRepresentation().map((slot)=>Array.isArray(slot) ? slot.map((s)=>Fr.fromString(s)) : Fr.fromString(slot))
306
+ ]);
307
+ const STATE_REFERENCE = STRUCT([
308
+ {
309
+ name: 'l1ToL2MessageTree',
310
+ type: APPEND_ONLY_TREE_SNAPSHOT
311
+ },
312
+ {
313
+ name: 'partial',
314
+ type: PARTIAL_STATE_REFERENCE
258
315
  }
259
- };
260
- export const UTILITY_CONTEXT = {
261
- serialization: {
262
- fn: (ctx)=>[
263
- ...ctx.blockHeader.toFields(),
264
- ctx.contractAddress.toField()
265
- ]
316
+ ]);
317
+ const GAS_FEES = STRUCT([
318
+ {
319
+ name: 'feePerDaGas',
320
+ type: BIGINT
321
+ },
322
+ {
323
+ name: 'feePerL2Gas',
324
+ type: BIGINT
266
325
  }
267
- };
268
- export const CALL_PRIVATE_RESULT = {
269
- serialization: {
270
- fn: (v)=>[
271
- [
272
- v.endSideEffectCounter,
273
- v.returnsHash
274
- ]
275
- ]
326
+ ]);
327
+ const GLOBAL_VARIABLES = STRUCT([
328
+ {
329
+ name: 'chainId',
330
+ type: FIELD
331
+ },
332
+ {
333
+ name: 'version',
334
+ type: FIELD
335
+ },
336
+ {
337
+ name: 'blockNumber',
338
+ type: BLOCK_NUMBER
339
+ },
340
+ {
341
+ name: 'slotNumber',
342
+ type: SLOT_NUMBER
343
+ },
344
+ {
345
+ name: 'timestamp',
346
+ type: BIGINT
347
+ },
348
+ {
349
+ name: 'coinbase',
350
+ type: ETH_ADDRESS
351
+ },
352
+ {
353
+ name: 'feeRecipient',
354
+ type: AZTEC_ADDRESS
355
+ },
356
+ {
357
+ name: 'gasFees',
358
+ type: GAS_FEES
276
359
  }
277
- };
278
- export const PUBLIC_KEYS_AND_PARTIAL_ADDRESS = {
360
+ ]);
361
+ export const BLOCK_HEADER = STRUCT([
362
+ {
363
+ name: 'lastArchive',
364
+ type: APPEND_ONLY_TREE_SNAPSHOT
365
+ },
366
+ {
367
+ name: 'state',
368
+ type: STATE_REFERENCE
369
+ },
370
+ {
371
+ name: 'spongeBlobHash',
372
+ type: FIELD
373
+ },
374
+ {
375
+ name: 'globalVariables',
376
+ type: GLOBAL_VARIABLES
377
+ },
378
+ {
379
+ name: 'totalFees',
380
+ type: FIELD
381
+ },
382
+ {
383
+ name: 'totalManaUsed',
384
+ type: FIELD
385
+ }
386
+ ]);
387
+ export const KEY_VALIDATION_REQUEST = STRUCT([
388
+ {
389
+ name: 'pkMHash',
390
+ type: FIELD
391
+ },
392
+ {
393
+ name: 'skApp',
394
+ type: FIELD
395
+ }
396
+ ]);
397
+ const PUBLIC_KEYS = STRUCT([
398
+ {
399
+ name: 'npkMHash',
400
+ type: FIELD
401
+ },
402
+ {
403
+ name: 'ivpkM',
404
+ type: POINT
405
+ },
406
+ {
407
+ name: 'ovpkMHash',
408
+ type: FIELD
409
+ },
410
+ {
411
+ name: 'tpkMHash',
412
+ type: FIELD
413
+ },
414
+ {
415
+ name: 'mspkMHash',
416
+ type: FIELD
417
+ },
418
+ {
419
+ name: 'fbpkMHash',
420
+ type: FIELD
421
+ }
422
+ ]);
423
+ export const CONTRACT_INSTANCE = STRUCT([
424
+ {
425
+ name: 'salt',
426
+ type: FIELD
427
+ },
428
+ {
429
+ name: 'deployer',
430
+ type: AZTEC_ADDRESS
431
+ },
432
+ // Note that the nr side of this struct does not contain the current class, only original
433
+ {
434
+ name: 'originalContractClassId',
435
+ type: FIELD
436
+ },
437
+ {
438
+ name: 'initializationHash',
439
+ type: FIELD
440
+ },
441
+ {
442
+ name: 'immutablesHash',
443
+ type: FIELD
444
+ },
445
+ {
446
+ name: 'publicKeys',
447
+ type: PUBLIC_KEYS
448
+ }
449
+ ]);
450
+ const NULLIFIER_LEAF = STRUCT([
451
+ {
452
+ name: 'nullifier',
453
+ type: FIELD
454
+ }
455
+ ]);
456
+ const NULLIFIER_LEAF_PREIMAGE = STRUCT([
457
+ {
458
+ name: 'leaf',
459
+ type: NULLIFIER_LEAF
460
+ },
461
+ {
462
+ name: 'nextKey',
463
+ type: FIELD
464
+ },
465
+ {
466
+ name: 'nextIndex',
467
+ type: BIGINT
468
+ }
469
+ ]);
470
+ export const NULLIFIER_MEMBERSHIP_WITNESS = STRUCT([
471
+ {
472
+ name: 'leafPreimage',
473
+ type: NULLIFIER_LEAF_PREIMAGE
474
+ },
475
+ {
476
+ name: 'index',
477
+ type: BIGINT
478
+ },
479
+ {
480
+ name: 'siblingPath',
481
+ type: SIBLING_PATH(NULLIFIER_TREE_HEIGHT)
482
+ }
483
+ ]);
484
+ const PUBLIC_DATA_LEAF = STRUCT([
485
+ {
486
+ name: 'slot',
487
+ type: FIELD
488
+ },
489
+ {
490
+ name: 'value',
491
+ type: FIELD
492
+ }
493
+ ]);
494
+ const PUBLIC_DATA_LEAF_PREIMAGE = STRUCT([
495
+ {
496
+ name: 'leaf',
497
+ type: PUBLIC_DATA_LEAF
498
+ },
499
+ {
500
+ name: 'nextKey',
501
+ type: FIELD
502
+ },
503
+ {
504
+ name: 'nextIndex',
505
+ type: BIGINT
506
+ }
507
+ ]);
508
+ export const PUBLIC_DATA_WITNESS = STRUCT([
509
+ {
510
+ name: 'index',
511
+ type: BIGINT
512
+ },
513
+ {
514
+ name: 'leafPreimage',
515
+ type: PUBLIC_DATA_LEAF_PREIMAGE
516
+ },
517
+ {
518
+ name: 'siblingPath',
519
+ type: SIBLING_PATH(PUBLIC_DATA_TREE_HEIGHT)
520
+ }
521
+ ]);
522
+ export const MESSAGE_LOAD_ORACLE_INPUTS = STRUCT([
523
+ {
524
+ name: 'index',
525
+ type: BIGINT
526
+ },
527
+ {
528
+ name: 'siblingPath',
529
+ type: SIBLING_PATH(L1_TO_L2_MSG_TREE_HEIGHT)
530
+ }
531
+ ]);
532
+ export const UTILITY_CONTEXT = STRUCT([
533
+ {
534
+ name: 'blockHeader',
535
+ type: BLOCK_HEADER
536
+ },
537
+ {
538
+ name: 'contractAddress',
539
+ type: AZTEC_ADDRESS
540
+ },
541
+ {
542
+ name: 'msgSender',
543
+ type: AZTEC_ADDRESS
544
+ }
545
+ ]);
546
+ export const CALL_PRIVATE_RESULT = STRUCT([
547
+ {
548
+ name: 'endSideEffectCounter',
549
+ type: FIELD
550
+ },
551
+ {
552
+ name: 'returnsHash',
553
+ type: FIELD
554
+ }
555
+ ]);
556
+ export const PUBLIC_KEYS_AND_PARTIAL_ADDRESS = STRUCT([
557
+ {
558
+ name: 'publicKeys',
559
+ type: PUBLIC_KEYS
560
+ },
561
+ {
562
+ name: 'partialAddress',
563
+ type: FIELD
564
+ }
565
+ ]);
566
+ export const CONTRACT_CLASS_LOG = STRUCT([
567
+ {
568
+ name: 'contractAddress',
569
+ type: AZTEC_ADDRESS
570
+ },
571
+ {
572
+ name: 'fields',
573
+ type: FIXED_ARRAY(FIELD, CONTRACT_CLASS_LOG_SIZE_IN_FIELDS)
574
+ },
575
+ {
576
+ name: 'emittedLength',
577
+ type: U32
578
+ }
579
+ ]);
580
+ const REVERT_CODE = {
279
581
  serialization: {
280
- fn: (v)=>[
281
- [
282
- ...v.publicKeys.toFields(),
283
- v.partialAddress
284
- ]
582
+ fn: (rc)=>[
583
+ rc.toField()
285
584
  ]
286
- }
585
+ },
586
+ shape: [
587
+ 'scalar'
588
+ ]
287
589
  };
288
- export const CONTRACT_CLASS_LOG_INPUT = {
289
- deserialization: {
290
- fn: ([addrReader, fieldsReader, lengthReader])=>{
291
- const addr = AztecAddress.fromField(addrReader.readField());
292
- const fields = new ContractClassLogFields([
293
- ...fieldsReader.readFieldArray(fieldsReader.remainingFields())
294
- ]);
295
- const length = lengthReader.readField().toNumber();
296
- return new ContractClassLog(addr, fields, length);
297
- },
298
- // ContractClassLog input occupies 3 ACVM slots: [contractAddress], [message fields...], [length].
299
- slots: 3
590
+ const PUBLIC_DATA_WRITE = STRUCT([
591
+ {
592
+ name: 'leafSlot',
593
+ type: FIELD
594
+ },
595
+ {
596
+ name: 'value',
597
+ type: FIELD
300
598
  }
301
- };
302
- export const TX_EFFECT = {
303
- serialization: {
304
- fn: (effect)=>{
305
- const flatPublicLogs = FlatPublicLogs.fromLogs(effect.publicLogs);
306
- return [
307
- effect.revertCode.toField(),
308
- effect.txHash.hash,
309
- effect.transactionFee,
310
- padArrayEnd(effect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
311
- padArrayEnd(effect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX),
312
- padArrayEnd(effect.l2ToL1Msgs, Fr.ZERO, MAX_L2_TO_L1_MSGS_PER_TX),
313
- padArrayEnd(effect.publicDataWrites, PublicDataWrite.empty(), MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX).flatMap((w)=>w.toFields()),
314
- padArrayEnd(effect.privateLogs, PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX).flatMap((l)=>l.toFields()),
315
- new Fr(flatPublicLogs.length),
316
- flatPublicLogs.payload,
317
- padArrayEnd(effect.contractClassLogs, ContractClassLog.empty(), MAX_CONTRACT_CLASS_LOGS_PER_TX).flatMap((l)=>[
318
- ...l.fields.toFields(),
319
- new Fr(l.emittedLength),
320
- l.contractAddress.toField()
321
- ])
322
- ];
323
- }
599
+ ]);
600
+ const PRIVATE_LOG = STRUCT([
601
+ {
602
+ name: 'fields',
603
+ type: FIXED_ARRAY(FIELD, PRIVATE_LOG_SIZE_IN_FIELDS)
604
+ },
605
+ {
606
+ name: 'emittedLength',
607
+ type: U32
324
608
  }
325
- };
609
+ ]);
610
+ const FLAT_PUBLIC_LOGS = STRUCT([
611
+ {
612
+ name: 'length',
613
+ type: U32
614
+ },
615
+ {
616
+ name: 'payload',
617
+ type: FIXED_ARRAY(FIELD, FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH)
618
+ }
619
+ ]);
620
+ const CONTRACT_CLASS_LOG_ENTRY = STRUCT([
621
+ {
622
+ name: 'fields',
623
+ type: FIXED_ARRAY(FIELD, CONTRACT_CLASS_LOG_SIZE_IN_FIELDS)
624
+ },
625
+ {
626
+ name: 'emittedLength',
627
+ type: U32
628
+ },
629
+ {
630
+ name: 'contractAddress',
631
+ type: AZTEC_ADDRESS
632
+ }
633
+ ]);
634
+ const CONTRACT_CLASS_LOGS = FIXED_ARRAY(CONTRACT_CLASS_LOG_ENTRY, MAX_CONTRACT_CLASS_LOGS_PER_TX);
635
+ export const TX_EFFECT = STRUCT([
636
+ {
637
+ name: 'revertCode',
638
+ type: REVERT_CODE
639
+ },
640
+ {
641
+ name: 'txHash',
642
+ type: TX_HASH
643
+ },
644
+ {
645
+ name: 'transactionFee',
646
+ type: FIELD
647
+ },
648
+ {
649
+ name: 'noteHashes',
650
+ type: FIXED_ARRAY(FIELD, MAX_NOTE_HASHES_PER_TX)
651
+ },
652
+ {
653
+ name: 'nullifiers',
654
+ type: FIXED_ARRAY(FIELD, MAX_NULLIFIERS_PER_TX)
655
+ },
656
+ {
657
+ name: 'l2ToL1Msgs',
658
+ type: FIXED_ARRAY(FIELD, MAX_L2_TO_L1_MSGS_PER_TX)
659
+ },
660
+ {
661
+ name: 'publicDataWrites',
662
+ type: FIXED_ARRAY(PUBLIC_DATA_WRITE, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX)
663
+ },
664
+ {
665
+ name: 'privateLogs',
666
+ type: FIXED_ARRAY(PRIVATE_LOG, MAX_PRIVATE_LOGS_PER_TX)
667
+ },
668
+ {
669
+ name: 'publicLogs',
670
+ type: FLAT_PUBLIC_LOGS
671
+ },
672
+ {
673
+ name: 'contractClassLogs',
674
+ type: CONTRACT_CLASS_LOGS
675
+ }
676
+ ]);
326
677
  export const NOTE = {
327
678
  serialization: {
328
679
  fn: (noteData)=>packAsHintedNote({
@@ -334,90 +685,260 @@ export const NOTE = {
334
685
  isPending: noteData.isPending,
335
686
  note: noteData.note
336
687
  })
337
- }
338
- };
339
- export const PENDING_TAGGED_LOG = {
340
- serialization: {
341
- fn: (log)=>[
342
- log.toFields()
343
- ]
344
- }
688
+ },
689
+ // A packed note is the note's (variable-count) field items followed by 6 metadata scalars, emitted as one field
690
+ // output per element. Its length depends on the note, so it is described as a single variable-width run.
691
+ shape: [
692
+ 'variable'
693
+ ]
345
694
  };
346
695
  export const NOTE_VALIDATION_REQUEST = {
347
696
  deserialization: {
348
- fn: ([reader])=>NoteValidationRequest.fromFields(reader),
349
- slots: 1
350
- }
697
+ fn: ([reader])=>NoteValidationRequest.fromFields(reader)
698
+ },
699
+ shape: [
700
+ 'variable'
701
+ ]
351
702
  };
352
703
  export const EVENT_VALIDATION_REQUEST = {
353
704
  deserialization: {
354
- fn: ([reader])=>EventValidationRequest.fromFields(reader),
355
- slots: 1
705
+ fn: ([reader])=>EventValidationRequest.fromFields(reader)
706
+ },
707
+ shape: [
708
+ 'variable'
709
+ ]
710
+ };
711
+ export const LOG_RETRIEVAL_REQUEST = STRUCT([
712
+ {
713
+ name: 'contractAddress',
714
+ type: AZTEC_ADDRESS
715
+ },
716
+ {
717
+ name: 'tag',
718
+ type: TAG
719
+ },
720
+ {
721
+ name: 'source',
722
+ type: LOG_SOURCE
723
+ },
724
+ {
725
+ name: 'fromBlock',
726
+ type: OPTION(BLOCK_NUMBER)
727
+ },
728
+ {
729
+ name: 'toBlock',
730
+ type: OPTION(BLOCK_NUMBER)
731
+ }
732
+ ]);
733
+ export const LOG_RETRIEVAL_RESPONSE = STRUCT([
734
+ {
735
+ name: 'logPayload',
736
+ type: FIXED_BOUNDED_VEC(FIELD, PRIVATE_LOG_CIPHERTEXT_LEN)
737
+ },
738
+ {
739
+ name: 'txHash',
740
+ type: TX_HASH
741
+ },
742
+ {
743
+ name: 'uniqueNoteHashesInTx',
744
+ type: FIXED_BOUNDED_VEC(FIELD, MAX_NOTE_HASHES_PER_TX)
745
+ },
746
+ {
747
+ name: 'firstNullifierInTx',
748
+ type: FIELD
749
+ },
750
+ {
751
+ name: 'blockNumber',
752
+ type: BLOCK_NUMBER
753
+ },
754
+ {
755
+ name: 'blockTimestamp',
756
+ type: BIGINT
757
+ },
758
+ {
759
+ name: 'blockHash',
760
+ type: BLOCK_HASH
356
761
  }
762
+ ]);
763
+ // `ResolvedTx.toFields()` packs the whole struct into a single slot: txHash, the uniqueNoteHashesInTx BoundedVec
764
+ // (MAX_NOTE_HASHES_PER_TX storage fields + length), firstNullifierInTx, blockNumber and blockHash.
765
+ export const RESOLVED_TX = {
766
+ serialization: {
767
+ fn: (resolved)=>[
768
+ resolved.toFields()
769
+ ]
770
+ },
771
+ shape: [
772
+ {
773
+ len: MAX_NOTE_HASHES_PER_TX + 5
774
+ }
775
+ ]
357
776
  };
358
- export const LOG_RETRIEVAL_REQUEST = {
777
+ export const PENDING_TAGGED_LOG = STRUCT([
778
+ {
779
+ name: 'log',
780
+ type: FIXED_BOUNDED_VEC(FIELD, PRIVATE_LOG_SIZE_IN_FIELDS)
781
+ },
782
+ {
783
+ name: 'context',
784
+ type: RESOLVED_TX
785
+ }
786
+ ]);
787
+ export const ORIGIN_BLOCK = {
359
788
  serialization: {
360
- fn: (req)=>[
361
- req.toFields()
789
+ fn: (ob)=>[
790
+ new Fr(ob.blockNumber),
791
+ ob.blockHash
362
792
  ]
363
793
  },
364
794
  deserialization: {
365
- fn: ([reader])=>LogRetrievalRequest.fromFields(reader),
366
- slots: 1
367
- }
795
+ fn: ([blockNumberReader, blockHashReader])=>({
796
+ blockNumber: blockNumberReader.readField().toNumber(),
797
+ blockHash: blockHashReader.readField()
798
+ })
799
+ },
800
+ shape: [
801
+ 'scalar',
802
+ 'scalar'
803
+ ]
368
804
  };
369
- export const LOG_RETRIEVAL_RESPONSE = {
805
+ /** Read-side origin of a retractable fact, carrying the chain state of its origin block. */ export const RETRACTABLE_FACT_ORIGIN = {
370
806
  serialization: {
371
- fn: (resp)=>[
372
- resp.toFields()
807
+ fn: (o)=>[
808
+ new Fr(o.blockNumber),
809
+ o.blockHash,
810
+ new Fr(o.blockState)
373
811
  ]
374
- }
812
+ },
813
+ shape: [
814
+ 'scalar',
815
+ 'scalar',
816
+ 'scalar'
817
+ ]
375
818
  };
376
- export const MESSAGE_CONTEXT = {
819
+ // `facts` and `payload` each materialize to a single service-slot id, so a Fact occupies: factTypeId, the payload
820
+ // array slot, and `OPTION(RETRACTABLE_FACT_ORIGIN)` (its discriminant plus RETRACTABLE_FACT_ORIGIN's three slots).
821
+ export const FACT = {
377
822
  serialization: {
378
- fn: (mc)=>[
379
- mc.toFields()
823
+ fn: (f)=>[
824
+ f.factTypeId,
825
+ f.payload.materializeSlot((v)=>FIELD.serialization.fn(v).flat()),
826
+ ...OPTION(RETRACTABLE_FACT_ORIGIN).serialization.fn(f.originBlock)
380
827
  ]
381
- }
828
+ },
829
+ shape: [
830
+ 'scalar',
831
+ 'scalar',
832
+ 'scalar',
833
+ 'scalar',
834
+ 'scalar',
835
+ 'scalar'
836
+ ]
837
+ };
838
+ export const FACT_COLLECTION = {
839
+ serialization: {
840
+ fn: (c)=>[
841
+ c.contractAddress.toField(),
842
+ c.scope.toField(),
843
+ c.factCollectionTypeId,
844
+ c.factCollectionId,
845
+ c.facts.materializeSlot((v)=>FACT.serialization.fn(v).flat())
846
+ ]
847
+ },
848
+ shape: [
849
+ 'scalar',
850
+ 'scalar',
851
+ 'scalar',
852
+ 'scalar',
853
+ 'scalar'
854
+ ]
382
855
  };
383
856
  export const PROVIDED_SECRET = {
384
857
  deserialization: {
385
- fn: ([reader])=>ProvidedSecret.fromFields(reader),
386
- slots: 1
387
- }
858
+ fn: ([reader])=>({
859
+ secret: reader.readField(),
860
+ mode: appTaggingSecretKindFromDeliveryMode(BYTE.deserialization.fn([
861
+ reader
862
+ ]))
863
+ })
864
+ },
865
+ shape: [
866
+ {
867
+ len: 2
868
+ }
869
+ ]
388
870
  };
389
871
  // ─── Combinator Type Mappings ────────────────────────────────────────────────
390
- /** `_height` is unused at runtime but lets TypeScript infer the exact `N` for `MembershipWitness<N>`. */ export function MEMBERSHIP_WITNESS(_height) {
872
+ function SIBLING_PATH(height) {
391
873
  return {
392
874
  serialization: {
393
- fn: (witness)=>[
394
- new Fr(witness.leafIndex),
395
- [
396
- ...witness.siblingPath
397
- ]
875
+ fn: (sp)=>[
876
+ sp.toFields()
398
877
  ]
878
+ },
879
+ shape: [
880
+ {
881
+ len: height
882
+ }
883
+ ]
884
+ };
885
+ }
886
+ export function MEMBERSHIP_WITNESS(height) {
887
+ return STRUCT([
888
+ {
889
+ name: 'leafIndex',
890
+ type: BIGINT
891
+ },
892
+ {
893
+ name: 'siblingPath',
894
+ type: FIXED_ARRAY(FIELD, height)
399
895
  }
896
+ ]);
897
+ }
898
+ export function ARRAY(inner) {
899
+ return {
900
+ kind: 'array',
901
+ inner,
902
+ serialization: inner.serialization ? {
903
+ fn: (values)=>[
904
+ packElements(inner, values)
905
+ ]
906
+ } : undefined,
907
+ deserialization: inner.deserialization ? {
908
+ // The whole slot is the array, so read as many elements as its fields hold.
909
+ fn: ([reader])=>unpackElements(inner, reader, reader.remainingFields() / fieldWidth(inner.shape))
910
+ } : undefined,
911
+ // One slot of variable length (all elements flattened into it).
912
+ shape: [
913
+ {
914
+ lenFrom: (size)=>size.length * fieldWidth(inner.shape)
915
+ }
916
+ ]
400
917
  };
401
918
  }
402
- export function ARRAY(element) {
919
+ /**
920
+ * Noir's fixed-length array `[T; length]` in one slot: serializes `values` (each flattened via `element`)
921
+ * zero-padded to exactly `length * elementWidth` fields, and deserializes all `length` elements back. An absent
922
+ * element is the zero encoding, so the padding is derived from the shape.
923
+ */ export function FIXED_ARRAY(element, length) {
924
+ const elementWidth = fieldWidth(element.shape);
403
925
  return {
926
+ kind: 'fixed-array',
927
+ inner: element,
928
+ length,
404
929
  serialization: element.serialization ? {
405
930
  fn: (values)=>[
406
- values.flatMap((v)=>element.serialization.fn(v).flat())
931
+ padArrayEnd(packElements(element, values), Fr.ZERO, length * elementWidth)
407
932
  ]
408
933
  } : undefined,
409
934
  deserialization: element.deserialization ? {
410
- fn: ([reader])=>{
411
- const result = [];
412
- while(!reader.isFinished()){
413
- result.push(element.deserialization.fn([
414
- reader
415
- ]));
416
- }
417
- return result;
418
- },
419
- slots: 1
420
- } : undefined
935
+ fn: ([reader])=>unpackElements(element, reader, length)
936
+ } : undefined,
937
+ shape: [
938
+ {
939
+ len: length * elementWidth
940
+ }
941
+ ]
421
942
  };
422
943
  }
423
944
  /**
@@ -432,92 +953,131 @@ export function ARRAY(element) {
432
953
  * slot 0: [Fr(0x41), Fr(0x42), Fr(0), Fr(0)] // data padded to maxLength
433
954
  * slot 1: Fr(2) // actual length
434
955
  * ```
435
- */ export function BOUNDED_VEC(element) {
956
+ */ export function BOUNDED_VEC(inner) {
436
957
  return {
437
- serialization: element.serialization ? {
958
+ kind: 'bounded-vec',
959
+ inner,
960
+ serialization: inner.serialization ? {
438
961
  fn: (bv)=>{
439
962
  if (bv.data.length > bv.maxLength) {
440
963
  throw new Error(`Got ${bv.data.length} items, but maxLength is ${bv.maxLength}`);
441
964
  }
442
- const flat = bv.data.flatMap((item)=>element.serialization.fn(item).flat());
965
+ // Fixed-width elements take their width from the shape (consistent with deserialization); only a
966
+ // variable-width element (e.g. a packed note) falls back to the runtime `elementSize` the value carries.
967
+ const elementWidth = tryFieldWidth(inner.shape) ?? bv.elementSize;
968
+ const flat = padArrayEnd(packElements(inner, bv.data), Fr.ZERO, bv.maxLength * elementWidth);
443
969
  return [
444
- padArrayEnd(flat, Fr.ZERO, bv.maxLength * bv.elementSize),
970
+ flat,
445
971
  new Fr(bv.data.length)
446
972
  ];
447
973
  }
448
974
  } : undefined,
449
- deserialization: element.deserialization ? {
975
+ deserialization: inner.deserialization ? {
450
976
  fn: ([storageReader, lengthReader])=>{
451
- const maxLength = storageReader.remainingFields();
977
+ // slot 0 is the padded storage, slot 1 the actual length. Parse only the first `length` elements out of
978
+ // storage, then drain the trailing zero-padding so the storage reader is fully consumed.
979
+ const maxLength = storageReader.remainingFields() / fieldWidth(inner.shape);
452
980
  const length = lengthReader.readField().toNumber();
453
- const elements = [];
454
- for(let i = 0; i < length; i++){
455
- elements.push(element.deserialization.fn([
456
- storageReader
457
- ]));
458
- }
459
- // Drain the trailing zero-padding (maxLength - length unused element slots) so the storage reader is
460
- // fully consumed.
981
+ const elements = unpackElements(inner, storageReader, length);
461
982
  storageReader.skip(storageReader.remainingFields());
462
983
  return BoundedVec.from({
463
984
  data: elements,
464
985
  maxLength
465
986
  });
987
+ }
988
+ } : undefined,
989
+ // slot 0: variable-length storage; slot 1: the length scalar.
990
+ shape: [
991
+ {
992
+ lenFrom: (size)=>size.maxLength * fieldWidth(inner.shape)
466
993
  },
467
- slots: 2
468
- } : undefined
994
+ 'scalar'
995
+ ]
996
+ };
997
+ }
998
+ /**
999
+ * Noir's `BoundedVec<T, MaxLen>` in its padded form (one fixed-width slot): `maxLength * elementWidth` storage fields
1000
+ * (zero-padded) followed by the actual length, with no length prefix, so the width is statically known. Serialize-only.
1001
+ * Throws if the input exceeds `maxLength`.
1002
+ */ export function FIXED_BOUNDED_VEC(element, maxLength) {
1003
+ const width = fieldWidth(element.shape);
1004
+ return {
1005
+ kind: 'fixed-bounded-vec',
1006
+ inner: element,
1007
+ maxLength,
1008
+ serialization: element.serialization ? {
1009
+ fn: (values)=>{
1010
+ if (values.length > maxLength) {
1011
+ throw new Error(`Got ${values.length} items, but maxLength is ${maxLength}`);
1012
+ }
1013
+ const flat = padArrayEnd(packElements(element, values), Fr.ZERO, maxLength * width);
1014
+ return [
1015
+ [
1016
+ ...flat,
1017
+ new Fr(values.length)
1018
+ ]
1019
+ ];
1020
+ }
1021
+ } : undefined,
1022
+ shape: [
1023
+ {
1024
+ len: maxLength * width + 1
1025
+ }
1026
+ ]
469
1027
  };
470
1028
  }
471
1029
  /**
472
- * Wraps an inner TypeMapping in Noir-style `Option<T>`. Adds a discriminant slot and uses the handler-provided
473
- * `Option.none(shape)` template to produce a correctly-sized zero-filled output for the None case.
1030
+ * Wraps an inner TypeMapping in Noir-style `Option<T>`, adding a leading discriminant slot.
474
1031
  *
475
- * @example Serializing `Option.some(AztecAddress.fromField(Fr(42)))` with `OPTION(AZTEC_ADDRESS)`:
1032
+ * For the `None` case, the inner's slots must still be present on the wire as zero-padding (so `Some` and `None` have
1033
+ * identical size). That padding is derived entirely from `inner.shape`.
1034
+ *
1035
+ * @example Serializing `Option.some(AztecAddress.fromFieldUnsafe(Fr(42)))` with `OPTION(AZTEC_ADDRESS)`:
476
1036
  * ```
477
1037
  * slot 0: Fr(1) // discriminant: Some
478
1038
  * slot 1: Fr(42) // inner value
479
1039
  * ```
480
1040
  *
481
- * @example Serializing `Option.empty(AztecAddress.ZERO)` with `OPTION(AZTEC_ADDRESS)`:
1041
+ * @example Serializing `Option.none()` with `OPTION(AZTEC_ADDRESS)`:
482
1042
  * ```
483
1043
  * slot 0: Fr(0) // discriminant: None
484
- * slot 1: Fr(0) // zero-filled using shape
1044
+ * slot 1: Fr(0) // zero-filled from AZTEC_ADDRESS.shape
485
1045
  * ```
486
1046
  */ export function OPTION(inner) {
487
1047
  return {
1048
+ kind: 'option',
1049
+ inner,
488
1050
  serialization: inner.serialization ? {
489
- fn: (opt)=>{
490
- if (opt.isSome()) {
491
- return [
492
- Fr.ONE,
493
- ...inner.serialization.fn(opt.value)
494
- ];
495
- }
496
- if (opt.template === undefined) {
497
- throw new Error('Cannot serialize Option.empty() without an emptyTemplate — provide one via Option.empty(emptyTemplate)');
498
- }
499
- const zeroSlots = inner.serialization.fn(opt.template).map((s)=>Array.isArray(s) ? Array(s.length).fill(Fr.ZERO) : Fr.ZERO);
500
- return [
1051
+ fn: (opt)=>opt.isSome() ? [
1052
+ Fr.ONE,
1053
+ ...inner.serialization.fn(opt.value)
1054
+ ] : [
501
1055
  Fr.ZERO,
502
- ...zeroSlots
503
- ];
504
- }
1056
+ ...zeroSlotsFromShape(inner.shape, opt.size)
1057
+ ]
505
1058
  } : undefined,
506
1059
  deserialization: inner.deserialization ? {
507
1060
  fn: ([discriminant, ...innerReaders])=>{
508
1061
  if (discriminant.readField().isZero()) {
509
- // None still carries zero-filled inner slots on the wire; drain them so the inner readers are fully
510
- // consumed.
1062
+ // None still carries the inner's zero-padded slots; consume them without parsing, since an inner that
1063
+ // validates its fields would reject the zeros.
511
1064
  innerReaders.forEach((reader)=>reader.skip(reader.remainingFields()));
512
- return Option.none(undefined);
1065
+ return Option.none();
513
1066
  }
514
1067
  return Option.some(inner.deserialization.fn(innerReaders));
515
- },
516
- slots: inner.deserialization.slots + 1
517
- } : undefined
1068
+ }
1069
+ } : undefined,
1070
+ // A leading discriminant slot followed by the inner's slots.
1071
+ shape: [
1072
+ 'scalar',
1073
+ ...inner.shape
1074
+ ]
518
1075
  };
519
1076
  }
520
- /** A packed uint buffer (e.g. `[u8; N]` in Noir): 1 slot of packed uint values ↔ `Buffer`. */ export function BUFFER(bitSize) {
1077
+ /**
1078
+ * A fixed packed uint buffer (Noir `[u8; length]` at `bitSize` 8): one slot of `length` packed uint values ↔ `Buffer`.
1079
+ * `length` is the field count, which equals the byte count at `bitSize` 8.
1080
+ */ export function BUFFER(bitSize, length) {
521
1081
  return {
522
1082
  serialization: {
523
1083
  fn: (buf)=>[
@@ -525,36 +1085,159 @@ export function ARRAY(element) {
525
1085
  ]
526
1086
  },
527
1087
  deserialization: {
528
- fn: ([reader])=>{
529
- const fields = reader.readFieldArray(reader.remainingFields()).map((f)=>f.toString());
530
- return fromUintArray(fields, bitSize);
531
- },
532
- slots: 1
533
- }
1088
+ fn: ([reader])=>fromUintArray(reader.readFieldArray(length).map((f)=>f.toString()), bitSize)
1089
+ },
1090
+ shape: [
1091
+ {
1092
+ len: length
1093
+ }
1094
+ ]
534
1095
  };
535
1096
  }
536
1097
  export function EPHEMERAL_ARRAY(element) {
537
- // An EphemeralArray param is a single slot; the per-param assert covers that slot but never sees the
538
- // per-row readers materialized in readAll(). Assert full consumption per row here.
1098
+ // EphemeralArray.readAll hands each row's flat fields in as a single reader; reconstruct the element's per-slot
1099
+ // readers from its shape, deserialize, and assert the row was fully consumed so a row with trailing fields is
1100
+ // rejected.
539
1101
  const rowElement = element.deserialization ? {
540
1102
  deserialization: {
541
- fn: (readers)=>{
542
- const value = element.deserialization.fn(readers);
543
- assertReadersConsumed(readers);
544
- return value;
545
- },
546
- slots: element.deserialization.slots
547
- }
1103
+ fn: ([rowReader])=>deserializeElement(element, rowReader.readFieldArray(rowReader.remainingFields()))
1104
+ },
1105
+ // `fn` reads the whole row from one reader, so this is one variable-width slot, not the element's multi-slot
1106
+ // shape.
1107
+ shape: [
1108
+ 'variable'
1109
+ ]
548
1110
  } : undefined;
549
1111
  return {
550
1112
  serialization: element.serialization ? {
551
1113
  fn: (ea)=>[
552
- ea.materializeSlot((v)=>element.serialization.fn(v).flat())
1114
+ ea.materializeSlot((v)=>serializeElement(element, v))
553
1115
  ]
554
1116
  } : undefined,
555
1117
  deserialization: rowElement ? {
556
- fn: ([reader])=>EphemeralArray.fromSlot(reader.readField(), rowElement),
557
- slots: 1
558
- } : undefined
1118
+ fn: ([reader])=>EphemeralArray.fromSlot(reader.readField(), rowElement)
1119
+ } : undefined,
1120
+ // A single slot carrying the array's service-slot id.
1121
+ shape: [
1122
+ 'scalar'
1123
+ ]
1124
+ };
1125
+ }
1126
+ /**
1127
+ * A Noir struct: its `shape` and (de)serialization are the concatenation of its fields', so callers never hand-write a
1128
+ * `shape`. `T` is the struct's TS value type and must match the field layout — serialization reads each field by name
1129
+ * off the value, deserialization returns the decoded bag as `T`; convert in the handler, not here, when `T` differs.
1130
+ */ export function STRUCT(fields) {
1131
+ return {
1132
+ kind: 'struct',
1133
+ fields,
1134
+ serialization: fields.every((f)=>f.type.serialization) ? {
1135
+ fn: (value)=>{
1136
+ const props = value;
1137
+ return fields.flatMap((f)=>f.type.serialization.fn(props[f.name]));
1138
+ }
1139
+ } : undefined,
1140
+ deserialization: fields.every((f)=>f.type.deserialization) ? {
1141
+ fn: (readers)=>{
1142
+ const props = {};
1143
+ let slot = 0;
1144
+ for (const f of fields){
1145
+ const slotCount = f.type.shape.length;
1146
+ props[f.name] = f.type.deserialization.fn(readers.slice(slot, slot + slotCount));
1147
+ slot += slotCount;
1148
+ }
1149
+ return props;
1150
+ }
1151
+ } : undefined,
1152
+ shape: fields.flatMap((f)=>f.type.shape)
559
1153
  };
560
1154
  }
1155
+ /** Number of InputSlots a deserializable type spans, derived from its {@link TypeMapping.shape}. */ export function slotsOf(mapping) {
1156
+ return mapping.shape.length;
1157
+ }
1158
+ /** Number of fields a fully-static shape occupies, or `undefined` if any slot is variable-width. */ export function tryFieldWidth(shape) {
1159
+ let total = 0;
1160
+ for (const slot of shape){
1161
+ if (slot === 'scalar') {
1162
+ total += 1;
1163
+ } else if (typeof slot === 'object' && 'len' in slot) {
1164
+ total += slot.len;
1165
+ } else {
1166
+ return undefined;
1167
+ }
1168
+ }
1169
+ return total;
1170
+ }
1171
+ /** Number of fields a fully-static shape occupies. Throws on a variable-width shape, whose field count isn't known. */ function fieldWidth(shape) {
1172
+ const width = tryFieldWidth(shape);
1173
+ if (width === undefined) {
1174
+ throw new Error('Cannot compute a fixed field width for a variable-width shape');
1175
+ }
1176
+ return width;
1177
+ }
1178
+ /** Reconstructs a value's per-slot readers from a flat run of fields, using its shape (inverse of slot-flattening). */ function splitByShape(fields, shape) {
1179
+ const readers = [];
1180
+ let cursor = 0;
1181
+ shape.forEach((slot, i)=>{
1182
+ if (slot === 'scalar' || typeof slot === 'object' && 'len' in slot) {
1183
+ const width = slot === 'scalar' ? 1 : slot.len;
1184
+ if (cursor + width > fields.length) {
1185
+ throw new Error(`Not enough fields to reconstruct shape: needed ${width}, had ${fields.length - cursor}`);
1186
+ }
1187
+ readers.push(new FieldReader(fields.slice(cursor, cursor + width)));
1188
+ cursor += width;
1189
+ } else {
1190
+ // A variable slot (sized or not) takes whatever remains, so it must be last.
1191
+ if (i !== shape.length - 1) {
1192
+ throw new Error('A variable-width slot must be last to be reconstructed from a flat field array');
1193
+ }
1194
+ readers.push(new FieldReader(fields.slice(cursor)));
1195
+ cursor = fields.length;
1196
+ }
1197
+ });
1198
+ if (cursor !== fields.length) {
1199
+ throw new Error(`Malformed flattened value: ${fields.length - cursor} unexpected trailing field(s)`);
1200
+ }
1201
+ return readers;
1202
+ }
1203
+ /** Serializes one element to its flat fields. Element must be serializable. */ function serializeElement(element, value) {
1204
+ return element.serialization.fn(value).flat();
1205
+ }
1206
+ /**
1207
+ * Deserializes one element from its exact flat fields, reconstructing its per-slot readers from its shape and asserting
1208
+ * they are fully consumed (so trailing fields are rejected). Element must be deserializable.
1209
+ */ function deserializeElement(element, fields) {
1210
+ const readers = splitByShape(fields, element.shape);
1211
+ const value = element.deserialization.fn(readers);
1212
+ assertReadersConsumed(readers);
1213
+ return value;
1214
+ }
1215
+ /** Flattens `values` into one contiguous run of fields by serializing each element. Element must be serializable. */ function packElements(element, values) {
1216
+ return values.flatMap((v)=>serializeElement(element, v));
1217
+ }
1218
+ /**
1219
+ * Reads `count` fixed-width elements out of a packed run (the inverse of {@link packElements}). Element must be
1220
+ * deserializable.
1221
+ */ function unpackElements(element, reader, count) {
1222
+ const elementWidth = fieldWidth(element.shape);
1223
+ return Array.from({
1224
+ length: count
1225
+ }, ()=>deserializeElement(element, reader.readFieldArray(elementWidth)));
1226
+ }
1227
+ /** Builds the zero-filled slots for a `None`, matching a `Some`'s wire shape (variable slots sized from `size`). */ function zeroSlotsFromShape(shape, size) {
1228
+ return shape.map((slot)=>{
1229
+ if (slot === 'scalar') {
1230
+ return Fr.ZERO;
1231
+ }
1232
+ if (slot === 'variable') {
1233
+ throw new Error('Cannot zero-fill an unsized variable-width slot');
1234
+ }
1235
+ if ('len' in slot) {
1236
+ return Array(slot.len).fill(Fr.ZERO);
1237
+ }
1238
+ if (size === undefined) {
1239
+ throw new Error('Serializing Option.none() over a variable-size inner needs a size, e.g. Option.none({ length: n })');
1240
+ }
1241
+ return Array(slot.lenFrom(size)).fill(Fr.ZERO);
1242
+ });
1243
+ }