@aztec/pxe 0.0.1-commit.a89ec08 → 0.0.1-commit.aa0c64f

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 (486) hide show
  1. package/dest/bin/check_oracle_version.js +39 -110
  2. package/dest/bin/index.d.ts +2 -0
  3. package/dest/bin/index.d.ts.map +1 -0
  4. package/dest/bin/index.js +1 -0
  5. package/dest/bin/oracle_version_helpers.d.ts +34 -0
  6. package/dest/bin/oracle_version_helpers.d.ts.map +1 -0
  7. package/dest/bin/oracle_version_helpers.js +46 -0
  8. package/dest/block_synchronizer/block_stream_source.d.ts +10 -0
  9. package/dest/block_synchronizer/block_stream_source.d.ts.map +1 -0
  10. package/dest/block_synchronizer/block_stream_source.js +37 -0
  11. package/dest/block_synchronizer/block_synchronizer.d.ts +23 -15
  12. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  13. package/dest/block_synchronizer/block_synchronizer.js +78 -28
  14. package/dest/config/index.d.ts +9 -2
  15. package/dest/config/index.d.ts.map +1 -1
  16. package/dest/config/index.js +14 -15
  17. package/dest/config/package_info.js +1 -1
  18. package/dest/contract/contract_class_service.d.ts +31 -0
  19. package/dest/contract/contract_class_service.d.ts.map +1 -0
  20. package/dest/contract/contract_class_service.js +68 -0
  21. package/dest/contract/contract_sync_service.d.ts +48 -0
  22. package/dest/contract/contract_sync_service.d.ts.map +1 -0
  23. package/dest/{contract_sync → contract}/contract_sync_service.js +42 -42
  24. package/dest/contract/helpers.d.ts +7 -0
  25. package/dest/contract/helpers.d.ts.map +1 -0
  26. package/dest/contract/helpers.js +20 -0
  27. package/dest/contract/skip_sync_contracts.d.ts +11 -0
  28. package/dest/contract/skip_sync_contracts.d.ts.map +1 -0
  29. package/dest/contract/skip_sync_contracts.js +18 -0
  30. package/dest/contract_function_simulator/anchored_contract_data.d.ts +36 -0
  31. package/dest/contract_function_simulator/anchored_contract_data.d.ts.map +1 -0
  32. package/dest/contract_function_simulator/anchored_contract_data.js +54 -0
  33. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts +39 -0
  34. package/dest/contract_function_simulator/aztec_node_read_cache.d.ts.map +1 -0
  35. package/dest/contract_function_simulator/aztec_node_read_cache.js +60 -0
  36. package/dest/contract_function_simulator/contract_function_simulator.d.ts +22 -18
  37. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  38. package/dest/contract_function_simulator/contract_function_simulator.js +80 -41
  39. package/dest/contract_function_simulator/execution_note_cache.d.ts +4 -10
  40. package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
  41. package/dest/contract_function_simulator/execution_note_cache.js +8 -28
  42. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +5 -9
  43. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
  44. package/dest/contract_function_simulator/execution_tagging_index_cache.js +3 -7
  45. package/dest/contract_function_simulator/index.d.ts +26 -6
  46. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  47. package/dest/contract_function_simulator/index.js +11 -4
  48. package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts +29 -0
  49. package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts.map +1 -0
  50. package/dest/contract_function_simulator/noir-structs/bounded_vec.js +30 -0
  51. package/dest/contract_function_simulator/noir-structs/contract_class_log_data.d.ts +9 -0
  52. package/dest/contract_function_simulator/noir-structs/contract_class_log_data.d.ts.map +1 -0
  53. package/dest/contract_function_simulator/noir-structs/contract_class_log_data.js +1 -0
  54. package/dest/contract_function_simulator/noir-structs/embedded_curve_point.d.ts +7 -0
  55. package/dest/contract_function_simulator/noir-structs/embedded_curve_point.d.ts.map +1 -0
  56. package/dest/contract_function_simulator/noir-structs/embedded_curve_point.js +1 -0
  57. package/dest/contract_function_simulator/noir-structs/ephemeral_array.d.ts +37 -0
  58. package/dest/contract_function_simulator/noir-structs/ephemeral_array.d.ts.map +1 -0
  59. package/dest/contract_function_simulator/noir-structs/ephemeral_array.js +59 -0
  60. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -2
  61. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  62. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +4 -3
  63. package/dest/contract_function_simulator/noir-structs/fact.d.ts +16 -0
  64. package/dest/contract_function_simulator/noir-structs/fact.d.ts.map +1 -0
  65. package/dest/contract_function_simulator/noir-structs/fact.js +6 -0
  66. package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts +27 -0
  67. package/dest/contract_function_simulator/noir-structs/fact_collection.d.ts.map +1 -0
  68. package/dest/contract_function_simulator/noir-structs/fact_collection.js +31 -0
  69. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +18 -9
  70. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -1
  71. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +12 -24
  72. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +10 -8
  73. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  74. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -60
  75. package/dest/contract_function_simulator/noir-structs/note_data.d.ts +27 -0
  76. package/dest/contract_function_simulator/noir-structs/note_data.d.ts.map +1 -0
  77. package/dest/contract_function_simulator/noir-structs/note_data.js +3 -0
  78. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +3 -2
  79. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
  80. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +5 -4
  81. package/dest/contract_function_simulator/noir-structs/option.d.ts +59 -0
  82. package/dest/contract_function_simulator/noir-structs/option.d.ts.map +1 -0
  83. package/dest/contract_function_simulator/noir-structs/option.js +67 -0
  84. package/dest/contract_function_simulator/noir-structs/origin_block.d.ts +11 -0
  85. package/dest/contract_function_simulator/noir-structs/origin_block.d.ts.map +1 -0
  86. package/dest/contract_function_simulator/noir-structs/origin_block.js +5 -0
  87. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts +11 -0
  88. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.d.ts.map +1 -0
  89. package/dest/contract_function_simulator/noir-structs/pending_tagged_log.js +4 -0
  90. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts +8 -0
  91. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts.map +1 -0
  92. package/dest/contract_function_simulator/noir-structs/provided_secret.js +1 -0
  93. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts +28 -0
  94. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.d.ts.map +1 -0
  95. package/dest/contract_function_simulator/noir-structs/resolved_tagging_strategy.js +50 -0
  96. package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts +19 -0
  97. package/dest/contract_function_simulator/noir-structs/resolved_tx.d.ts.map +1 -0
  98. package/dest/contract_function_simulator/noir-structs/resolved_tx.js +9 -0
  99. package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts +15 -0
  100. package/dest/contract_function_simulator/noir-structs/tx_effect_data.d.ts.map +1 -0
  101. package/dest/contract_function_simulator/noir-structs/tx_effect_data.js +5 -0
  102. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +6 -11
  103. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -1
  104. package/dest/contract_function_simulator/noir-structs/utility_context.js +1 -20
  105. package/dest/contract_function_simulator/oracle/acir_callback.d.ts +21 -0
  106. package/dest/contract_function_simulator/oracle/acir_callback.d.ts.map +1 -0
  107. package/dest/contract_function_simulator/oracle/acir_callback.js +115 -0
  108. package/dest/contract_function_simulator/oracle/index.d.ts +2 -13
  109. package/dest/contract_function_simulator/oracle/index.d.ts.map +1 -1
  110. package/dest/contract_function_simulator/oracle/index.js +1 -1
  111. package/dest/contract_function_simulator/oracle/interfaces.d.ts +15 -114
  112. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  113. package/dest/contract_function_simulator/oracle/interfaces.js +2 -2
  114. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts +39 -0
  115. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.d.ts.map +1 -0
  116. package/dest/contract_function_simulator/oracle/legacy_oracle_registry.js +107 -0
  117. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +3 -14
  118. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
  119. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.js +1 -24
  120. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +2 -2
  121. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
  122. package/dest/contract_function_simulator/oracle/note_packing_utils.js +2 -2
  123. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +139 -0
  124. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -0
  125. package/dest/contract_function_simulator/oracle/oracle_registry.js +1016 -0
  126. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +274 -0
  127. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -0
  128. package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +1243 -0
  129. package/dest/contract_function_simulator/oracle/private_execution.d.ts +1 -1
  130. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
  131. package/dest/contract_function_simulator/oracle/private_execution.js +2 -3
  132. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +47 -36
  133. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  134. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +181 -63
  135. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +126 -64
  136. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  137. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +430 -195
  138. package/dest/contract_function_simulator/pick_notes.d.ts +1 -1
  139. package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -1
  140. package/dest/contract_function_simulator/pick_notes.js +6 -0
  141. package/dest/contract_function_simulator/transient_array_service.d.ts +31 -0
  142. package/dest/contract_function_simulator/transient_array_service.d.ts.map +1 -0
  143. package/dest/contract_function_simulator/transient_array_service.js +62 -0
  144. package/dest/debug/pxe_debug_utils.d.ts +2 -7
  145. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  146. package/dest/debug/pxe_debug_utils.js +0 -6
  147. package/dest/entrypoints/client/bundle/index.d.ts +2 -1
  148. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  149. package/dest/entrypoints/client/bundle/index.js +1 -0
  150. package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
  151. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  152. package/dest/entrypoints/client/bundle/utils.js +25 -6
  153. package/dest/entrypoints/client/lazy/index.d.ts +2 -1
  154. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  155. package/dest/entrypoints/client/lazy/index.js +1 -0
  156. package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
  157. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  158. package/dest/entrypoints/client/lazy/utils.js +25 -6
  159. package/dest/entrypoints/client/store.d.ts +14 -0
  160. package/dest/entrypoints/client/store.d.ts.map +1 -0
  161. package/dest/entrypoints/client/store.js +42 -0
  162. package/dest/entrypoints/pxe_creation_options.d.ts +14 -2
  163. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  164. package/dest/entrypoints/server/index.d.ts +6 -2
  165. package/dest/entrypoints/server/index.d.ts.map +1 -1
  166. package/dest/entrypoints/server/index.js +4 -1
  167. package/dest/entrypoints/server/store.d.ts +18 -0
  168. package/dest/entrypoints/server/store.d.ts.map +1 -0
  169. package/dest/entrypoints/server/store.js +28 -0
  170. package/dest/entrypoints/server/utils.d.ts +3 -2
  171. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  172. package/dest/entrypoints/server/utils.js +26 -6
  173. package/dest/error_enriching.d.ts +5 -3
  174. package/dest/error_enriching.d.ts.map +1 -1
  175. package/dest/error_enriching.js +13 -11
  176. package/dest/events/event_service.d.ts +13 -5
  177. package/dest/events/event_service.d.ts.map +1 -1
  178. package/dest/events/event_service.js +30 -9
  179. package/dest/hooks/authorize_utility_call.d.ts +41 -0
  180. package/dest/hooks/authorize_utility_call.d.ts.map +1 -0
  181. package/dest/hooks/authorize_utility_call.js +4 -0
  182. package/dest/hooks/execution_hooks.d.ts +62 -0
  183. package/dest/hooks/execution_hooks.d.ts.map +1 -0
  184. package/dest/hooks/execution_hooks.js +9 -0
  185. package/dest/hooks/index.d.ts +5 -0
  186. package/dest/hooks/index.d.ts.map +1 -0
  187. package/dest/hooks/index.js +2 -0
  188. package/dest/hooks/resolve_custom_request.d.ts +23 -0
  189. package/dest/hooks/resolve_custom_request.d.ts.map +1 -0
  190. package/dest/hooks/resolve_custom_request.js +3 -0
  191. package/dest/hooks/resolve_tagging_secret_strategy.d.ts +50 -0
  192. package/dest/hooks/resolve_tagging_secret_strategy.d.ts.map +1 -0
  193. package/dest/hooks/resolve_tagging_secret_strategy.js +3 -0
  194. package/dest/logs/log_service.d.ts +12 -9
  195. package/dest/logs/log_service.d.ts.map +1 -1
  196. package/dest/logs/log_service.js +186 -62
  197. package/dest/messages/tx_resolver_service.d.ts +17 -0
  198. package/dest/messages/tx_resolver_service.d.ts.map +1 -0
  199. package/dest/messages/tx_resolver_service.js +60 -0
  200. package/dest/notes/note_service.d.ts +26 -4
  201. package/dest/notes/note_service.d.ts.map +1 -1
  202. package/dest/notes/note_service.js +81 -66
  203. package/dest/oracle_version.d.ts +3 -3
  204. package/dest/oracle_version.js +6 -6
  205. package/dest/private_kernel/batch_planner.d.ts +47 -0
  206. package/dest/private_kernel/batch_planner.d.ts.map +1 -0
  207. package/dest/private_kernel/batch_planner.js +104 -0
  208. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +1 -1
  209. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  210. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +7 -3
  211. package/dest/private_kernel/hints/test_utils.d.ts +1 -1
  212. package/dest/private_kernel/hints/test_utils.d.ts.map +1 -1
  213. package/dest/private_kernel/hints/test_utils.js +3 -4
  214. package/dest/private_kernel/private_kernel_execution_prover.d.ts +6 -2
  215. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  216. package/dest/private_kernel/private_kernel_execution_prover.js +200 -83
  217. package/dest/private_kernel/private_kernel_oracle.d.ts +12 -10
  218. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  219. package/dest/private_kernel/private_kernel_oracle.js +40 -26
  220. package/dest/pxe.d.ts +165 -52
  221. package/dest/pxe.d.ts.map +1 -1
  222. package/dest/pxe.js +337 -209
  223. package/dest/storage/allowed_scopes.d.ts +6 -0
  224. package/dest/storage/allowed_scopes.d.ts.map +1 -0
  225. package/dest/storage/allowed_scopes.js +7 -0
  226. package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -6
  227. package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
  228. package/dest/storage/anchor_block_store/anchor_block_store.js +8 -6
  229. package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.d.ts +42 -0
  230. package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.d.ts.map +1 -0
  231. package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.js +93 -0
  232. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +15 -0
  233. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -0
  234. package/dest/storage/backwards_compatibility_tests/schema_tests.js +671 -0
  235. package/dest/storage/backwards_compatibility_tests/store_spy.d.ts +19 -0
  236. package/dest/storage/backwards_compatibility_tests/store_spy.d.ts.map +1 -0
  237. package/dest/storage/backwards_compatibility_tests/store_spy.js +63 -0
  238. package/dest/storage/capsule_store/capsule_service.d.ts +1 -1
  239. package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -1
  240. package/dest/storage/capsule_store/capsule_service.js +6 -9
  241. package/dest/storage/contract_store/contract_store.d.ts +27 -24
  242. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  243. package/dest/storage/contract_store/contract_store.js +67 -97
  244. package/dest/storage/fact_store/fact_service.d.ts +22 -0
  245. package/dest/storage/fact_store/fact_service.d.ts.map +1 -0
  246. package/dest/storage/fact_store/fact_service.js +45 -0
  247. package/dest/storage/fact_store/fact_store.d.ts +95 -0
  248. package/dest/storage/fact_store/fact_store.d.ts.map +1 -0
  249. package/dest/storage/fact_store/fact_store.js +408 -0
  250. package/dest/storage/fact_store/fact_store_keys.d.ts +34 -0
  251. package/dest/storage/fact_store/fact_store_keys.d.ts.map +1 -0
  252. package/dest/storage/fact_store/fact_store_keys.js +50 -0
  253. package/dest/storage/fact_store/index.d.ts +6 -0
  254. package/dest/storage/fact_store/index.d.ts.map +1 -0
  255. package/dest/storage/fact_store/index.js +4 -0
  256. package/dest/storage/fact_store/origin_state.d.ts +59 -0
  257. package/dest/storage/fact_store/origin_state.d.ts.map +1 -0
  258. package/dest/storage/fact_store/origin_state.js +60 -0
  259. package/dest/storage/fact_store/stored_fact.d.ts +32 -0
  260. package/dest/storage/fact_store/stored_fact.d.ts.map +1 -0
  261. package/dest/storage/fact_store/stored_fact.js +64 -0
  262. package/dest/storage/index.d.ts +3 -2
  263. package/dest/storage/index.d.ts.map +1 -1
  264. package/dest/storage/index.js +2 -1
  265. package/dest/storage/metadata.d.ts +2 -2
  266. package/dest/storage/metadata.d.ts.map +1 -1
  267. package/dest/storage/metadata.js +1 -1
  268. package/dest/storage/note_store/note_store.d.ts +42 -33
  269. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  270. package/dest/storage/note_store/note_store.js +197 -168
  271. package/dest/storage/note_store/stored_note.d.ts +3 -8
  272. package/dest/storage/note_store/stored_note.d.ts.map +1 -1
  273. package/dest/storage/note_store/stored_note.js +4 -20
  274. package/dest/storage/open_pxe_stores.d.ts +35 -0
  275. package/dest/storage/open_pxe_stores.d.ts.map +1 -0
  276. package/dest/storage/open_pxe_stores.js +29 -0
  277. package/dest/storage/private_event_store/private_event_store.d.ts +13 -16
  278. package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
  279. package/dest/storage/private_event_store/private_event_store.js +43 -43
  280. package/dest/storage/private_event_store/stored_private_event.js +1 -1
  281. package/dest/storage/store_identity.d.ts +35 -0
  282. package/dest/storage/store_identity.d.ts.map +1 -0
  283. package/dest/storage/store_identity.js +44 -0
  284. package/dest/storage/tagging_store/index.d.ts +2 -2
  285. package/dest/storage/tagging_store/index.d.ts.map +1 -1
  286. package/dest/storage/tagging_store/index.js +1 -1
  287. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
  288. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  289. package/dest/storage/tagging_store/sender_tagging_store.d.ts +23 -7
  290. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  291. package/dest/storage/tagging_store/sender_tagging_store.js +51 -14
  292. package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts +51 -0
  293. package/dest/storage/tagging_store/tagging_secret_sources_store.d.ts.map +1 -0
  294. package/dest/storage/tagging_store/tagging_secret_sources_store.js +105 -0
  295. package/dest/tagging/constants.d.ts +3 -2
  296. package/dest/tagging/constants.d.ts.map +1 -1
  297. package/dest/tagging/constants.js +28 -10
  298. package/dest/tagging/get_all_logs_by_tags.d.ts +34 -10
  299. package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
  300. package/dest/tagging/get_all_logs_by_tags.js +36 -37
  301. package/dest/tagging/index.d.ts +6 -5
  302. package/dest/tagging/index.d.ts.map +1 -1
  303. package/dest/tagging/index.js +5 -4
  304. package/dest/tagging/persist_sender_tagging_index_ranges.d.ts +29 -0
  305. package/dest/tagging/persist_sender_tagging_index_ranges.d.ts.map +1 -0
  306. package/dest/tagging/persist_sender_tagging_index_ranges.js +42 -0
  307. package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts +74 -0
  308. package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts.map +1 -0
  309. package/dest/tagging/recipient_sync/sync_tagged_private_logs.js +238 -0
  310. package/dest/tagging/recipient_sync/utils/find_highest_indexes.d.ts +3 -3
  311. package/dest/tagging/recipient_sync/utils/find_highest_indexes.d.ts.map +1 -1
  312. package/dest/tagging/reconcile_tagging_index_ranges.d.ts +36 -0
  313. package/dest/tagging/reconcile_tagging_index_ranges.d.ts.map +1 -0
  314. package/dest/tagging/reconcile_tagging_index_ranges.js +74 -0
  315. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -5
  316. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  317. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +26 -14
  318. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +11 -6
  319. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  320. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +21 -0
  321. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +4 -4
  322. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  323. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +8 -4
  324. package/dest/tagging/testing/tag_query_test_utils.d.ts +6 -0
  325. package/dest/tagging/testing/tag_query_test_utils.d.ts.map +1 -0
  326. package/dest/tagging/testing/tag_query_test_utils.js +10 -0
  327. package/package.json +20 -17
  328. package/src/bin/check_oracle_version.ts +44 -133
  329. package/src/bin/index.ts +1 -0
  330. package/src/bin/oracle_version_helpers.ts +54 -0
  331. package/src/block_synchronizer/block_stream_source.ts +42 -0
  332. package/src/block_synchronizer/block_synchronizer.ts +96 -39
  333. package/src/config/index.ts +16 -9
  334. package/src/config/package_info.ts +1 -1
  335. package/src/contract/contract_class_service.ts +83 -0
  336. package/src/{contract_sync → contract}/contract_sync_service.ts +61 -61
  337. package/src/contract/helpers.ts +35 -0
  338. package/src/contract/skip_sync_contracts.ts +23 -0
  339. package/src/contract_function_simulator/anchored_contract_data.ts +74 -0
  340. package/src/contract_function_simulator/aztec_node_read_cache.ts +89 -0
  341. package/src/contract_function_simulator/contract_function_simulator.ts +130 -53
  342. package/src/contract_function_simulator/execution_note_cache.ts +8 -29
  343. package/src/contract_function_simulator/execution_tagging_index_cache.ts +5 -9
  344. package/src/contract_function_simulator/index.ts +89 -5
  345. package/src/contract_function_simulator/noir-structs/bounded_vec.ts +43 -0
  346. package/src/contract_function_simulator/noir-structs/contract_class_log_data.ts +9 -0
  347. package/src/contract_function_simulator/noir-structs/embedded_curve_point.ts +4 -0
  348. package/src/contract_function_simulator/noir-structs/ephemeral_array.ts +66 -0
  349. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +4 -3
  350. package/src/contract_function_simulator/noir-structs/fact.ts +13 -0
  351. package/src/contract_function_simulator/noir-structs/fact_collection.ts +64 -0
  352. package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +26 -19
  353. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +13 -60
  354. package/src/contract_function_simulator/noir-structs/note_data.ts +27 -0
  355. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +5 -4
  356. package/src/contract_function_simulator/noir-structs/option.ts +75 -0
  357. package/src/contract_function_simulator/noir-structs/origin_block.ts +8 -0
  358. package/src/contract_function_simulator/noir-structs/pending_tagged_log.ts +12 -0
  359. package/src/contract_function_simulator/noir-structs/provided_secret.ts +5 -0
  360. package/src/contract_function_simulator/noir-structs/resolved_tagging_strategy.ts +66 -0
  361. package/src/contract_function_simulator/noir-structs/resolved_tx.ts +19 -0
  362. package/src/contract_function_simulator/noir-structs/tx_effect_data.ts +16 -0
  363. package/src/contract_function_simulator/noir-structs/utility_context.ts +5 -17
  364. package/src/contract_function_simulator/oracle/acir_callback.ts +154 -0
  365. package/src/contract_function_simulator/oracle/index.ts +1 -15
  366. package/src/contract_function_simulator/oracle/interfaces.ts +11 -204
  367. package/src/contract_function_simulator/oracle/legacy_oracle_registry.ts +147 -0
  368. package/src/contract_function_simulator/oracle/message_load_oracle_inputs.ts +6 -21
  369. package/src/contract_function_simulator/oracle/note_packing_utils.ts +3 -3
  370. package/src/contract_function_simulator/oracle/oracle_registry.ts +710 -0
  371. package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +1052 -0
  372. package/src/contract_function_simulator/oracle/private_execution.ts +2 -3
  373. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +232 -83
  374. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +676 -367
  375. package/src/contract_function_simulator/pick_notes.ts +8 -0
  376. package/src/contract_function_simulator/transient_array_service.ts +91 -0
  377. package/src/debug/pxe_debug_utils.ts +1 -9
  378. package/src/entrypoints/client/bundle/index.ts +1 -0
  379. package/src/entrypoints/client/bundle/utils.ts +30 -5
  380. package/src/entrypoints/client/lazy/index.ts +1 -0
  381. package/src/entrypoints/client/lazy/utils.ts +30 -5
  382. package/src/entrypoints/client/store.ts +54 -0
  383. package/src/entrypoints/pxe_creation_options.ts +14 -1
  384. package/src/entrypoints/server/index.ts +6 -1
  385. package/src/entrypoints/server/store.ts +47 -0
  386. package/src/entrypoints/server/utils.ts +43 -11
  387. package/src/error_enriching.ts +27 -11
  388. package/src/events/event_service.ts +54 -19
  389. package/src/hooks/authorize_utility_call.ts +44 -0
  390. package/src/hooks/execution_hooks.ts +68 -0
  391. package/src/hooks/index.ts +13 -0
  392. package/src/hooks/resolve_custom_request.ts +24 -0
  393. package/src/hooks/resolve_tagging_secret_strategy.ts +60 -0
  394. package/src/logs/log_service.ts +220 -112
  395. package/src/messages/tx_resolver_service.ts +69 -0
  396. package/src/notes/note_service.ts +116 -92
  397. package/src/oracle_version.ts +6 -6
  398. package/src/private_kernel/batch_planner.ts +168 -0
  399. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +12 -2
  400. package/src/private_kernel/hints/test_utils.ts +3 -10
  401. package/src/private_kernel/private_kernel_execution_prover.ts +333 -114
  402. package/src/private_kernel/private_kernel_oracle.ts +58 -29
  403. package/src/pxe.ts +529 -237
  404. package/src/storage/allowed_scopes.ts +14 -0
  405. package/src/storage/anchor_block_store/anchor_block_store.ts +8 -6
  406. package/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +22 -0
  407. package/src/storage/backwards_compatibility_tests/__snapshots__/AnchorBlockStore.json +3 -0
  408. package/src/storage/backwards_compatibility_tests/__snapshots__/CapsuleStore.json +16 -0
  409. package/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +28 -0
  410. package/src/storage/backwards_compatibility_tests/__snapshots__/FactStore.json +40 -0
  411. package/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +52 -0
  412. package/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json +40 -0
  413. package/src/storage/backwards_compatibility_tests/__snapshots__/NoteStore.json +56 -0
  414. package/src/storage/backwards_compatibility_tests/__snapshots__/PrivateEventStore.json +44 -0
  415. package/src/storage/backwards_compatibility_tests/__snapshots__/RecipientTaggingStore.json +26 -0
  416. package/src/storage/backwards_compatibility_tests/__snapshots__/SenderTaggingStore.json +30 -0
  417. package/src/storage/backwards_compatibility_tests/__snapshots__/TaggingSecretSourcesStore.json +30 -0
  418. package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +117 -0
  419. package/src/storage/backwards_compatibility_tests/kv_store_snapshot.ts +122 -0
  420. package/src/storage/backwards_compatibility_tests/schema_tests.ts +803 -0
  421. package/src/storage/backwards_compatibility_tests/store_spy.ts +73 -0
  422. package/src/storage/capsule_store/capsule_service.ts +8 -13
  423. package/src/storage/contract_store/contract_store.ts +90 -120
  424. package/src/storage/fact_store/fact_service.ts +69 -0
  425. package/src/storage/fact_store/fact_store.ts +487 -0
  426. package/src/storage/fact_store/fact_store_keys.ts +75 -0
  427. package/src/storage/fact_store/index.ts +15 -0
  428. package/src/storage/fact_store/origin_state.ts +84 -0
  429. package/src/storage/fact_store/stored_fact.ts +80 -0
  430. package/src/storage/index.ts +2 -1
  431. package/src/storage/metadata.ts +1 -1
  432. package/src/storage/note_store/note_store.ts +226 -187
  433. package/src/storage/note_store/stored_note.ts +5 -27
  434. package/src/storage/open_pxe_stores.ts +52 -0
  435. package/src/storage/private_event_store/private_event_store.ts +52 -54
  436. package/src/storage/private_event_store/stored_private_event.ts +1 -1
  437. package/src/storage/store_identity.ts +72 -0
  438. package/src/storage/tagging_store/index.ts +1 -1
  439. package/src/storage/tagging_store/recipient_tagging_store.ts +5 -9
  440. package/src/storage/tagging_store/sender_tagging_store.ts +68 -21
  441. package/src/storage/tagging_store/tagging_secret_sources_store.ts +138 -0
  442. package/src/tagging/constants.ts +30 -10
  443. package/src/tagging/get_all_logs_by_tags.ts +78 -50
  444. package/src/tagging/index.ts +5 -4
  445. package/src/tagging/persist_sender_tagging_index_ranges.ts +57 -0
  446. package/src/tagging/recipient_sync/sync_tagged_private_logs.ts +358 -0
  447. package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
  448. package/src/tagging/reconcile_tagging_index_ranges.ts +102 -0
  449. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +41 -19
  450. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +23 -8
  451. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +10 -7
  452. package/src/tagging/testing/tag_query_test_utils.ts +11 -0
  453. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts +0 -9
  454. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts.map +0 -1
  455. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.js +0 -47
  456. package/dest/contract_function_simulator/oracle/oracle.d.ts +0 -91
  457. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +0 -1
  458. package/dest/contract_function_simulator/oracle/oracle.js +0 -553
  459. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +0 -6
  460. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +0 -1
  461. package/dest/contract_function_simulator/proxied_contract_data_source.js +0 -83
  462. package/dest/contract_sync/contract_sync_service.d.ts +0 -44
  463. package/dest/contract_sync/contract_sync_service.d.ts.map +0 -1
  464. package/dest/contract_sync/helpers.d.ts +0 -28
  465. package/dest/contract_sync/helpers.d.ts.map +0 -1
  466. package/dest/contract_sync/helpers.js +0 -60
  467. package/dest/messages/message_context_service.d.ts +0 -17
  468. package/dest/messages/message_context_service.d.ts.map +0 -1
  469. package/dest/messages/message_context_service.js +0 -36
  470. package/dest/storage/tagging_store/sender_address_book_store.d.ts +0 -14
  471. package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +0 -1
  472. package/dest/storage/tagging_store/sender_address_book_store.js +0 -36
  473. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +0 -14
  474. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +0 -1
  475. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +0 -85
  476. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +0 -14
  477. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +0 -1
  478. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +0 -33
  479. package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +0 -104
  480. package/src/contract_function_simulator/oracle/oracle.ts +0 -861
  481. package/src/contract_function_simulator/proxied_contract_data_source.ts +0 -90
  482. package/src/contract_sync/helpers.ts +0 -98
  483. package/src/messages/message_context_service.ts +0 -44
  484. package/src/storage/tagging_store/sender_address_book_store.ts +0 -48
  485. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +0 -128
  486. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +0 -44
@@ -1,72 +1,113 @@
1
- import type { ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
1
+ import { ARCHIVE_HEIGHT, type NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
2
2
  import type { BlockNumber } from '@aztec/foundation/branded-types';
3
+ import { uniqueBy } from '@aztec/foundation/collection';
3
4
  import { Aes128 } from '@aztec/foundation/crypto/aes128';
4
5
  import { Fr } from '@aztec/foundation/curves/bn254';
5
6
  import { Point } from '@aztec/foundation/curves/grumpkin';
6
7
  import { LogLevels, type Logger, createLogger } from '@aztec/foundation/log';
7
- import type { MembershipWitness } from '@aztec/foundation/trees';
8
+ import { MembershipWitness } from '@aztec/foundation/trees';
8
9
  import type { KeyStore } from '@aztec/key-store';
9
- import { isProtocolContract } from '@aztec/protocol-contracts';
10
+ import {
11
+ type CircuitSimulator,
12
+ ExecutionError,
13
+ extractCallStack,
14
+ resolveAssertionMessageFromError,
15
+ toACVMWitness,
16
+ witnessMapToFields,
17
+ } from '@aztec/simulator/client';
18
+ import { STANDARD_HANDSHAKE_REGISTRY_ADDRESS } from '@aztec/standard-contracts/handshake-registry/constants';
19
+ import { type FunctionCall, FunctionSelector } from '@aztec/stdlib/abi';
10
20
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
11
21
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
12
22
  import { BlockHash, type L2TipsProvider } from '@aztec/stdlib/block';
13
- import type { CompleteAddress, ContractInstance, PartialAddress } from '@aztec/stdlib/contract';
23
+ import type { CompleteAddress, ContractInstancePreimageWithAddress, PartialAddress } from '@aztec/stdlib/contract';
14
24
  import { siloNullifier } from '@aztec/stdlib/hash';
15
25
  import type { AztecNode } from '@aztec/stdlib/interfaces/server';
16
26
  import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
17
- import { type PublicKeys, computeAddressSecret } from '@aztec/stdlib/keys';
18
- import { MessageContext, deriveAppSiloedSharedSecret } from '@aztec/stdlib/logs';
19
- import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
27
+ import { PublicKeys, computeAddressSecret, hashPublicKey } from '@aztec/stdlib/keys';
28
+ import { AppTaggingSecret, FlatPublicLogs, appSiloEcdhSharedSecret } from '@aztec/stdlib/logs';
29
+ import { type UnsiloedMessageNullifier, getL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
20
30
  import type { NoteStatus } from '@aztec/stdlib/note';
21
31
  import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
22
- import type { BlockHeader, Capsule, OffchainEffect } from '@aztec/stdlib/tx';
23
-
32
+ import {
33
+ type BlockHeader,
34
+ CallContext,
35
+ type Capsule,
36
+ type IndexedTxEffect,
37
+ type OffchainEffect,
38
+ type TxEffect,
39
+ type TxHash,
40
+ } from '@aztec/stdlib/tx';
41
+
42
+ import type { ContractSyncService } from '../../contract/contract_sync_service.js';
24
43
  import { createContractLogger, logContractMessage, stripAztecnrLogPrefix } from '../../contract_logging.js';
25
- import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
26
44
  import { EventService } from '../../events/event_service.js';
45
+ import type { UtilityCallAuthorizationRequest } from '../../hooks/authorize_utility_call.js';
46
+ import type { ExecutionHooks } from '../../hooks/index.js';
27
47
  import { LogService } from '../../logs/log_service.js';
28
- import { MessageContextService } from '../../messages/message_context_service.js';
48
+ import { TxResolverService } from '../../messages/tx_resolver_service.js';
29
49
  import { NoteService } from '../../notes/note_service.js';
30
50
  import { ORACLE_VERSION_MAJOR } from '../../oracle_version.js';
31
51
  import type { AddressStore } from '../../storage/address_store/address_store.js';
52
+ import { assertAllowedScope } from '../../storage/allowed_scopes.js';
32
53
  import type { CapsuleService } from '../../storage/capsule_store/capsule_service.js';
33
- import type { ContractStore } from '../../storage/contract_store/contract_store.js';
54
+ import { FactCollectionKey, FactCollectionTypeKey, anchoredTipBlockNumbers } from '../../storage/fact_store/index.js';
55
+ import type { FactService, OriginBlock } from '../../storage/fact_store/index.js';
34
56
  import type { NoteStore } from '../../storage/note_store/note_store.js';
35
57
  import type { PrivateEventStore } from '../../storage/private_event_store/private_event_store.js';
36
58
  import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
37
- import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_address_book_store.js';
59
+ import type { TaggingSecretSourcesStore } from '../../storage/tagging_store/tagging_secret_sources_store.js';
60
+ import type { AnchoredContractData } from '../anchored_contract_data.js';
61
+ import { AztecNodeReadCache } from '../aztec_node_read_cache.js';
38
62
  import { EphemeralArrayService } from '../ephemeral_array_service.js';
39
- import { EventValidationRequest } from '../noir-structs/event_validation_request.js';
40
- import { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
41
- import { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
42
- import { NoteValidationRequest } from '../noir-structs/note_validation_request.js';
43
- import { UtilityContext } from '../noir-structs/utility_context.js';
63
+ import { BoundedVec } from '../noir-structs/bounded_vec.js';
64
+ import type { EmbeddedCurvePoint } from '../noir-structs/embedded_curve_point.js';
65
+ import { EphemeralArray } from '../noir-structs/ephemeral_array.js';
66
+ import type { EventValidationRequest } from '../noir-structs/event_validation_request.js';
67
+ import { type FactCollection, emptyFactCollection, toNoirFactCollection } from '../noir-structs/fact_collection.js';
68
+ import type { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
69
+ import type { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
70
+ import type { NoteData } from '../noir-structs/note_data.js';
71
+ import type { NoteValidationRequest } from '../noir-structs/note_validation_request.js';
72
+ import { Option } from '../noir-structs/option.js';
73
+ import type { PendingTaggedLog } from '../noir-structs/pending_tagged_log.js';
74
+ import type { ProvidedSecret } from '../noir-structs/provided_secret.js';
75
+ import type { ResolvedTx } from '../noir-structs/resolved_tx.js';
76
+ import type { TxEffectData } from '../noir-structs/tx_effect_data.js';
77
+ import type { UtilityContext } from '../noir-structs/utility_context.js';
44
78
  import { pickNotes } from '../pick_notes.js';
45
- import type { IMiscOracle, IUtilityExecutionOracle, NoteData } from './interfaces.js';
46
- import { MessageLoadOracleInputs } from './message_load_oracle_inputs.js';
79
+ import type { TransientArrayService } from '../transient_array_service.js';
80
+ import { buildACIRCallback } from './acir_callback.js';
81
+ import type { IMiscOracle, IUtilityExecutionOracle } from './interfaces.js';
47
82
 
48
83
  /** Args for UtilityExecutionOracle constructor. */
49
84
  export type UtilityExecutionOracleArgs = {
50
- contractAddress: AztecAddress;
85
+ callContext: CallContext;
51
86
  /** List of transient auth witnesses to be used during this simulation */
52
87
  authWitnesses: AuthWitness[];
53
88
  capsules: Capsule[]; // TODO(#12425): Rename to transientCapsules
54
89
  anchorBlockHeader: BlockHeader;
55
- contractStore: ContractStore;
90
+ anchoredContractData: AnchoredContractData;
56
91
  noteStore: NoteStore;
57
92
  keyStore: KeyStore;
58
93
  addressStore: AddressStore;
59
94
  aztecNode: AztecNode;
60
95
  recipientTaggingStore: RecipientTaggingStore;
61
- senderAddressBookStore: SenderAddressBookStore;
96
+ taggingSecretSourcesStore: TaggingSecretSourcesStore;
62
97
  capsuleService: CapsuleService;
98
+ factService: FactService;
63
99
  privateEventStore: PrivateEventStore;
64
- messageContextService: MessageContextService;
100
+ txResolver: TxResolverService;
65
101
  contractSyncService: ContractSyncService;
66
102
  l2TipsStore: L2TipsProvider;
67
103
  jobId: string;
68
104
  log?: ReturnType<typeof createLogger>;
69
105
  scopes: AztecAddress[];
106
+ simulator: CircuitSimulator;
107
+ hooks?: ExecutionHooks;
108
+ /** Needed to trigger contract synchronization before nested cross-contract calls. */
109
+ utilityExecutor: (call: FunctionCall, scopes: AztecAddress[]) => Promise<void>;
110
+ transientArrayService: TransientArrayService;
70
111
  };
71
112
 
72
113
  /**
@@ -80,73 +121,65 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
80
121
  private aztecnrLogger: Logger | undefined;
81
122
  private offchainEffects: OffchainEffect[] = [];
82
123
  private readonly ephemeralArrayService = new EphemeralArrayService();
124
+ protected readonly transientArrayService: TransientArrayService;
125
+ private readonly aztecNodeReadCache: AztecNodeReadCache;
83
126
 
84
127
  // We store oracle version to be able to show a nice error message when an oracle handler is missing.
85
128
  private contractOracleVersion: { major: number; minor: number } | undefined;
86
129
 
87
- protected readonly contractAddress: AztecAddress;
130
+ protected readonly callContext: CallContext;
88
131
  protected readonly authWitnesses: AuthWitness[];
89
132
  protected readonly capsules: Capsule[];
90
133
  protected readonly anchorBlockHeader: BlockHeader;
91
- protected readonly contractStore: ContractStore;
134
+ protected readonly anchoredContractData: AnchoredContractData;
92
135
  protected readonly noteStore: NoteStore;
93
136
  protected readonly keyStore: KeyStore;
94
137
  protected readonly addressStore: AddressStore;
95
138
  protected readonly aztecNode: AztecNode;
96
139
  protected readonly recipientTaggingStore: RecipientTaggingStore;
97
- protected readonly senderAddressBookStore: SenderAddressBookStore;
140
+ protected readonly taggingSecretSourcesStore: TaggingSecretSourcesStore;
98
141
  protected readonly capsuleService: CapsuleService;
142
+ protected readonly factService: FactService;
99
143
  protected readonly privateEventStore: PrivateEventStore;
100
- protected readonly messageContextService: MessageContextService;
144
+ protected readonly txResolver: TxResolverService;
101
145
  protected readonly contractSyncService: ContractSyncService;
102
146
  protected readonly l2TipsStore: L2TipsProvider;
103
147
  protected readonly jobId: string;
104
148
  protected logger: ReturnType<typeof createLogger>;
105
149
  protected readonly scopes: AztecAddress[];
150
+ protected readonly simulator: CircuitSimulator;
151
+ protected readonly hooks: ExecutionHooks | undefined;
152
+ protected readonly utilityExecutor: (call: FunctionCall, scopes: AztecAddress[]) => Promise<void>;
106
153
 
107
154
  constructor(args: UtilityExecutionOracleArgs) {
108
- this.contractAddress = args.contractAddress;
155
+ this.callContext = args.callContext;
109
156
  this.authWitnesses = args.authWitnesses;
110
157
  this.capsules = args.capsules;
111
158
  this.anchorBlockHeader = args.anchorBlockHeader;
112
- this.contractStore = args.contractStore;
159
+ this.anchoredContractData = args.anchoredContractData;
113
160
  this.noteStore = args.noteStore;
114
161
  this.keyStore = args.keyStore;
115
162
  this.addressStore = args.addressStore;
116
163
  this.aztecNode = args.aztecNode;
117
164
  this.recipientTaggingStore = args.recipientTaggingStore;
118
- this.senderAddressBookStore = args.senderAddressBookStore;
165
+ this.taggingSecretSourcesStore = args.taggingSecretSourcesStore;
119
166
  this.capsuleService = args.capsuleService;
167
+ this.factService = args.factService;
120
168
  this.privateEventStore = args.privateEventStore;
121
- this.messageContextService = args.messageContextService;
169
+ this.txResolver = args.txResolver;
122
170
  this.contractSyncService = args.contractSyncService;
123
171
  this.l2TipsStore = args.l2TipsStore;
124
172
  this.jobId = args.jobId;
125
173
  this.logger = args.log ?? createLogger('simulator:client_view_context');
126
174
  this.scopes = args.scopes;
175
+ this.simulator = args.simulator;
176
+ this.hooks = args.hooks;
177
+ this.utilityExecutor = args.utilityExecutor;
178
+ this.transientArrayService = args.transientArrayService;
179
+ this.aztecNodeReadCache = new AztecNodeReadCache(args.aztecNode);
127
180
  }
128
181
 
129
182
  public assertCompatibleOracleVersion(major: number, minor: number): void {
130
- // TODO(F-416): Remove this hack on v5 when protocol contracts are redeployed.
131
- // Protocol contracts/canonical contracts shipped with committed bytecode that cannot be changed. Assert they use
132
- // the expected pinned version or the current one. We want to allow for both the pinned and the current versions
133
- // because we want this code to work with both the pinned and unpinned version since some branches do not have the
134
- // pinned contracts (like e.g. next)
135
- const LEGACY_ORACLE_VERSION = 12;
136
- if (isProtocolContract(this.contractAddress)) {
137
- if (major !== LEGACY_ORACLE_VERSION && major !== ORACLE_VERSION_MAJOR) {
138
- const hint =
139
- major > ORACLE_VERSION_MAJOR
140
- ? 'The contract was compiled with a newer version of Aztec.nr than your private environment supports. Upgrade your private environment to a compatible version.'
141
- : 'The contract was compiled with an older version of Aztec.nr than your private environment supports. Recompile the contract with a compatible version of Aztec.nr.';
142
- throw new Error(
143
- `Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${LEGACY_ORACLE_VERSION} or ${ORACLE_VERSION_MAJOR}, got ${major})`,
144
- );
145
- }
146
- this.contractOracleVersion = { major, minor };
147
- return;
148
- }
149
-
150
183
  if (major !== ORACLE_VERSION_MAJOR) {
151
184
  const hint =
152
185
  major > ORACLE_VERSION_MAJOR
@@ -157,7 +190,6 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
157
190
  );
158
191
  }
159
192
 
160
- // Major matches - store both major and minor for later diagnostics (e.g. when an oracle is not found)
161
193
  this.contractOracleVersion = { major, minor };
162
194
  }
163
195
 
@@ -171,17 +203,22 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
171
203
  }
172
204
 
173
205
  public getUtilityContext(): UtilityContext {
174
- return new UtilityContext(this.anchorBlockHeader, this.contractAddress);
206
+ return {
207
+ blockHeader: this.anchorBlockHeader,
208
+ contractAddress: this.callContext.contractAddress,
209
+ msgSender: this.callContext.msgSender,
210
+ };
175
211
  }
176
212
 
177
213
  /**
178
214
  * Retrieve keys associated with a specific master public key and app address.
179
215
  * @param pkMHash - The master public key hash.
216
+ * @param _keyIndex - Sent by the Noir oracle caller but unused here; kept to match the oracle signature.
180
217
  * @returns A Promise that resolves to nullifier keys.
181
218
  * @throws If the keys are not registered in the key store.
182
219
  * @throws If scopes are defined and the account is not in the scopes.
183
220
  */
184
- public async getKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
221
+ public async getKeyValidationRequest(pkMHash: Fr, _keyIndex: Fr): Promise<KeyValidationRequest> {
185
222
  let hasAccess = false;
186
223
  for (let i = 0; i < this.scopes.length && !hasAccess; i++) {
187
224
  if (await this.keyStore.accountHasKey(this.scopes[i], pkMHash)) {
@@ -201,13 +238,17 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
201
238
  * @param noteHash - The note hash to find in the note hash tree.
202
239
  * @returns The membership witness containing the leaf index and sibling path
203
240
  */
204
- public getNoteHashMembershipWitness(
241
+ public async getNoteHashMembershipWitness(
205
242
  blockHash: BlockHash,
206
243
  noteHash: Fr,
207
- ): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
208
- return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
244
+ ): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT>> {
245
+ const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
209
246
  this.aztecNode.getNoteHashMembershipWitness(blockHash, noteHash),
210
247
  );
248
+ if (!witness) {
249
+ throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
250
+ }
251
+ return witness;
211
252
  }
212
253
 
213
254
  /**
@@ -221,16 +262,33 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
221
262
  * @param blockHash - The block hash to find in the archive tree.
222
263
  * @returns The membership witness containing the leaf index and sibling path
223
264
  */
224
- public getBlockHashMembershipWitness(
265
+ public async getBlockHashMembershipWitness(
225
266
  referenceBlockHash: BlockHash,
226
267
  blockHash: BlockHash,
227
- ): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
268
+ ): Promise<Option<MembershipWitness<typeof ARCHIVE_HEIGHT>>> {
228
269
  // Note that we validate that the reference block hash is at or before the anchor block - we don't test the block
229
270
  // hash at all. If the block hash did not exist by the reference block hash, then the node will not return the
230
271
  // membership witness as there is none.
231
- return this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
232
- this.aztecNode.getBlockHashMembershipWitness(referenceBlockHash, blockHash),
272
+ const witness = await this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
273
+ this.aztecNodeReadCache.getBlockHashMembershipWitness(referenceBlockHash, blockHash),
233
274
  );
275
+ return witness ? Option.some(witness) : Option.none();
276
+ }
277
+
278
+ /** Returns whether each block hash is present in the archive tree at the referenced block. */
279
+ public async areBlockHashesInArchive(
280
+ referenceBlockHash: BlockHash,
281
+ blockHashes: EphemeralArray<BlockHash>,
282
+ ): Promise<EphemeralArray<boolean>> {
283
+ const hashes = blockHashes.readAll(this.ephemeralArrayService);
284
+ const memberships = await this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
285
+ Promise.all(
286
+ hashes.map(blockHash =>
287
+ this.aztecNodeReadCache.getBlockHashMembershipWitness(referenceBlockHash, blockHash).then(Boolean),
288
+ ),
289
+ ),
290
+ );
291
+ return EphemeralArray.fromValues(this.ephemeralArrayService, memberships);
234
292
  }
235
293
 
236
294
  /**
@@ -239,13 +297,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
239
297
  * @param nullifier - Nullifier we try to find witness for.
240
298
  * @returns The nullifier membership witness (if found).
241
299
  */
242
- public getNullifierMembershipWitness(
243
- blockHash: BlockHash,
244
- nullifier: Fr,
245
- ): Promise<NullifierMembershipWitness | undefined> {
246
- return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
300
+ public async getNullifierMembershipWitness(blockHash: BlockHash, nullifier: Fr): Promise<NullifierMembershipWitness> {
301
+ const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
247
302
  this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier),
248
303
  );
304
+ if (!witness) {
305
+ throw new Error(`Nullifier membership witness not found at block ${blockHash.toString()}.`);
306
+ }
307
+ return witness;
249
308
  }
250
309
 
251
310
  /**
@@ -257,13 +316,19 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
257
316
  * list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier
258
317
  * we are trying to prove non-inclusion for.
259
318
  */
260
- public getLowNullifierMembershipWitness(
319
+ public async getLowNullifierMembershipWitness(
261
320
  blockHash: BlockHash,
262
321
  nullifier: Fr,
263
- ): Promise<NullifierMembershipWitness | undefined> {
264
- return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
322
+ ): Promise<NullifierMembershipWitness> {
323
+ const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
265
324
  this.aztecNode.getLowNullifierMembershipWitness(blockHash, nullifier),
266
325
  );
326
+ if (!witness) {
327
+ throw new Error(
328
+ `Low nullifier witness not found for nullifier ${nullifier} at block hash ${blockHash.toString()}.`,
329
+ );
330
+ }
331
+ return witness;
267
332
  }
268
333
 
269
334
  /**
@@ -272,10 +337,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
272
337
  * @param leafSlot - The slot of the public data tree to get the witness for.
273
338
  * @returns - The witness
274
339
  */
275
- public getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
276
- return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
277
- this.aztecNode.getPublicDataWitness(blockHash, leafSlot),
340
+ public async getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness> {
341
+ const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
342
+ this.aztecNodeReadCache.getPublicDataWitness(blockHash, leafSlot),
278
343
  );
344
+ if (!witness) {
345
+ throw new Error(`Public data witness not found for slot ${leafSlot} at block hash ${blockHash.toString()}.`);
346
+ }
347
+ return witness;
279
348
  }
280
349
 
281
350
  /**
@@ -283,14 +352,22 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
283
352
  * @param blockNumber - The number of a block of which to get the block header.
284
353
  * @returns Block extracted from a block with block number `blockNumber`.
285
354
  */
286
- public async getBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader | undefined> {
355
+ public async getBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader> {
287
356
  const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber();
288
357
  if (blockNumber > anchorBlockNumber) {
289
358
  throw new Error(`Block number ${blockNumber} is higher than current block ${anchorBlockNumber}`);
290
359
  }
291
360
 
361
+ // Most contracts query state at the "current" block, which is the anchor. Skip the RPC when we can.
362
+ if (blockNumber === anchorBlockNumber) {
363
+ return this.anchorBlockHeader;
364
+ }
365
+
292
366
  const block = await this.aztecNode.getBlock(blockNumber);
293
- return block?.header;
367
+ if (!block?.header) {
368
+ throw new Error(`Block header not found for block ${blockNumber}.`);
369
+ }
370
+ return block.header;
294
371
  }
295
372
 
296
373
  /**
@@ -300,12 +377,12 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
300
377
  */
301
378
  public async getPublicKeysAndPartialAddress(
302
379
  account: AztecAddress,
303
- ): Promise<{ publicKeys: PublicKeys; partialAddress: PartialAddress } | undefined> {
380
+ ): Promise<Option<{ publicKeys: PublicKeys; partialAddress: PartialAddress }>> {
304
381
  const completeAddress = await this.addressStore.getCompleteAddress(account);
305
382
  if (!completeAddress) {
306
- return undefined;
383
+ return Option.none();
307
384
  }
308
- return { publicKeys: completeAddress.publicKeys, partialAddress: completeAddress.partialAddress };
385
+ return Option.some({ publicKeys: completeAddress.publicKeys, partialAddress: completeAddress.partialAddress });
309
386
  }
310
387
 
311
388
  protected async getCompleteAddressOrFail(account: AztecAddress): Promise<CompleteAddress> {
@@ -313,7 +390,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
313
390
  if (!completeAddress) {
314
391
  throw new Error(
315
392
  `No public key registered for address ${account}.
316
- Register it by calling pxe.addAccount(...).\nSee docs for context: https://docs.aztec.network/developers/resources/debugging/aztecnr-errors#simulation-error-no-public-key-registered-for-address-0x0-register-it-by-calling-pxeregisterrecipient-or-pxeregisteraccount`,
393
+ Register it by calling wallet.registerSender(...).\nSee docs for context: https://docs.aztec.network/errors/14`,
317
394
  );
318
395
  }
319
396
  return completeAddress;
@@ -324,8 +401,8 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
324
401
  * @param address - Address.
325
402
  * @returns A contract instance.
326
403
  */
327
- public async getContractInstance(address: AztecAddress): Promise<ContractInstance> {
328
- const instance = await this.contractStore.getContractInstance(address);
404
+ public async getContractInstance(address: AztecAddress): Promise<ContractInstancePreimageWithAddress> {
405
+ const instance = await this.anchoredContractData.getContractInstance(address);
329
406
  if (!instance) {
330
407
  throw new Error(`No contract instance found for address ${address.toString()}`);
331
408
  }
@@ -333,13 +410,16 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
333
410
  }
334
411
 
335
412
  /**
336
- * Returns an auth witness for the given message hash. Checks on the list of transient witnesses
337
- * for this transaction first, and falls back to the local database if not found.
413
+ * Returns an auth witness for the given message hash from the list of transient witnesses for this transaction.
338
414
  * @param messageHash - Hash of the message to authenticate.
339
- * @returns Authentication witness for the requested message hash.
415
+ * @returns Authentication witness for the requested message hash, or undefined if not found.
340
416
  */
341
- public getAuthWitness(messageHash: Fr): Promise<Fr[] | undefined> {
342
- return Promise.resolve(this.authWitnesses.find(w => w.requestHash.equals(messageHash))?.witness);
417
+ public getAuthWitness(messageHash: Fr): Promise<Fr[]> {
418
+ const witness = this.authWitnesses.find(w => w.requestHash.equals(messageHash))?.witness;
419
+ if (!witness) {
420
+ throw new Error(`Unknown auth witness for message hash ${messageHash}`);
421
+ }
422
+ return Promise.resolve(witness);
343
423
  }
344
424
 
345
425
  /**
@@ -365,7 +445,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
365
445
  * @returns Array of note data.
366
446
  */
367
447
  public async getNotes(
368
- owner: AztecAddress | undefined,
448
+ owner: Option<AztecAddress>,
369
449
  storageSlot: Fr,
370
450
  numSelects: number,
371
451
  selectByIndexes: number[],
@@ -380,11 +460,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
380
460
  limit: number,
381
461
  offset: number,
382
462
  status: NoteStatus,
383
- ): Promise<NoteData[]> {
463
+ maxNotes: number,
464
+ packedHintedNoteLength: number,
465
+ ): Promise<BoundedVec<NoteData>> {
384
466
  const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
385
467
 
386
- const dbNotes = await noteService.getNotes(this.contractAddress, owner, storageSlot, status, this.scopes);
387
- return pickNotes<NoteData>(dbNotes, {
468
+ const dbNotes = await noteService.getNotes(this.contractAddress, owner.value, storageSlot, status, this.scopes);
469
+ const picked = pickNotes<NoteData>(dbNotes, {
388
470
  selects: selectByIndexes.slice(0, numSelects).map((index, i) => ({
389
471
  selector: { index, offset: selectByOffsets[i], length: selectByLengths[i] },
390
472
  value: selectValues[i],
@@ -397,6 +479,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
397
479
  limit,
398
480
  offset,
399
481
  });
482
+ return BoundedVec.from({ data: picked, maxLength: maxNotes, elementSize: packedHintedNoteLength });
400
483
  }
401
484
 
402
485
  /**
@@ -416,23 +499,21 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
416
499
  }
417
500
 
418
501
  /**
419
- * Returns the membership witness of an un-nullified L1 to L2 message.
420
- * @param contractAddress - Address of a contract by which the message was emitted.
502
+ * Returns the membership witness of an L1 to L2 message.
421
503
  * @param messageHash - Hash of the message.
422
- * @param secret - Secret used to compute a nullifier.
423
- * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages
504
+ * @param nullifier - When present, the unsiloed nullifier of the message and the address to silo it with. The witness
505
+ * is only returned if the siloed nullifier is absent from the nullifier tree, i.e. the message has not been consumed.
424
506
  * @returns The l1 to l2 membership witness (index of message in the tree and sibling path).
425
507
  */
426
- public async getL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) {
427
- const [messageIndex, siblingPath] = await getNonNullifiedL1ToL2MessageWitness(
508
+ public async getL1ToL2MembershipWitnessV2(messageHash: Fr, nullifier: Option<UnsiloedMessageNullifier>) {
509
+ const [messageIndex, siblingPath] = await getL1ToL2MessageWitness(
428
510
  this.aztecNode,
429
- contractAddress,
430
511
  messageHash,
431
- secret,
512
+ nullifier.value,
432
513
  await this.anchorBlockHeader.hash(),
433
514
  );
434
515
 
435
- return new MessageLoadOracleInputs(messageIndex, siblingPath);
516
+ return { index: messageIndex, siblingPath };
436
517
  }
437
518
 
438
519
  /**
@@ -449,16 +530,16 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
449
530
  numberOfElements: number,
450
531
  ) {
451
532
  return this.#queryWithBlockHashNotAfterAnchor(blockHash, async () => {
452
- const slots = Array(numberOfElements)
453
- .fill(0)
454
- .map((_, i) => new Fr(startStorageSlot.value + BigInt(i)));
455
-
456
- const values = await Promise.all(
457
- slots.map(storageSlot => this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot)),
533
+ const values = await this.aztecNodeReadCache.getPublicStorageRange(
534
+ blockHash,
535
+ contractAddress,
536
+ startStorageSlot,
537
+ numberOfElements,
458
538
  );
459
539
 
460
540
  this.logger.debug(
461
- `Oracle storage read: slots=[${slots.map(slot => slot.toString()).join(', ')}] address=${contractAddress.toString()} values=[${values.join(', ')}]`,
541
+ `Oracle storage read: start=${startStorageSlot.toString()} count=${numberOfElements} ` +
542
+ `address=${contractAddress.toString()} values=[${values.join(', ')}]`,
462
543
  );
463
544
 
464
545
  return values;
@@ -474,7 +555,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
474
555
  // to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
475
556
  this.contractLogger = await createContractLogger(
476
557
  this.contractAddress,
477
- addr => this.contractStore.getDebugContractName(addr),
558
+ addr => this.anchoredContractData.getDebugContractName(addr),
478
559
  'user',
479
560
  { instanceId: this.jobId },
480
561
  );
@@ -491,7 +572,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
491
572
  // to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
492
573
  this.aztecnrLogger = await createContractLogger(
493
574
  this.contractAddress,
494
- addr => this.contractStore.getDebugContractName(addr),
575
+ addr => this.anchoredContractData.getDebugContractName(addr),
495
576
  'aztecnr',
496
577
  { instanceId: this.jobId },
497
578
  );
@@ -499,7 +580,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
499
580
  return this.aztecnrLogger;
500
581
  }
501
582
 
502
- public async log(level: number, message: string, fields: Fr[]): Promise<void> {
583
+ public async log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
503
584
  if (!LogLevels[level]) {
504
585
  throw new Error(`Invalid log level: ${level}`);
505
586
  }
@@ -510,24 +591,18 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
510
591
  logContractMessage(logger, LogLevels[level], strippedMessage, fields);
511
592
  }
512
593
 
513
- // Deprecated, only kept for backwards compatibility until Alpha v5 rolls out.
514
- public async getPendingTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr, scope: AztecAddress) {
515
- const logService = this.#createLogService();
516
- const logs = await logService.fetchTaggedLogs(this.contractAddress, scope);
517
- await this.capsuleService.appendToCapsuleArray(
518
- this.contractAddress,
519
- pendingTaggedLogArrayBaseSlot,
520
- logs.map(log => log.toFields()),
521
- this.jobId,
522
- scope,
523
- );
524
- }
594
+ /** Fetches pending tagged logs into a freshly allocated ephemeral array and returns it. */
595
+ public async getPendingTaggedLogsV2(
596
+ scope: AztecAddress,
597
+ providedSecrets: EphemeralArray<ProvidedSecret>,
598
+ ): Promise<EphemeralArray<PendingTaggedLog>> {
599
+ const secrets = providedSecrets
600
+ .readAll(this.ephemeralArrayService)
601
+ .map(ps => new AppTaggingSecret(ps.secret, this.contractAddress, ps.mode));
525
602
 
526
- /** Fetches pending tagged logs into a freshly allocated ephemeral array and returns its base slot. */
527
- public async getPendingTaggedLogsV2(scope: AztecAddress): Promise<Fr> {
528
603
  const logService = this.#createLogService();
529
- const logs = await logService.fetchTaggedLogs(this.contractAddress, scope);
530
- return this.ephemeralArrayService.newArray(logs.map(log => log.toFields()));
604
+ const logs = await logService.fetchTaggedLogs(this.contractAddress, scope, secrets);
605
+ return EphemeralArray.fromValues(this.ephemeralArrayService, logs);
531
606
  }
532
607
 
533
608
  #createLogService(): LogService {
@@ -537,276 +612,119 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
537
612
  this.l2TipsStore,
538
613
  this.keyStore,
539
614
  this.recipientTaggingStore,
540
- this.senderAddressBookStore,
615
+ this.taggingSecretSourcesStore,
541
616
  this.addressStore,
617
+ this.scopes,
542
618
  this.jobId,
543
619
  this.logger.getBindings(),
544
620
  );
545
621
  }
546
622
 
547
- /**
548
- * Legacy: validates note/event requests stored in capsule arrays.
549
- *
550
- * Deprecated, only kept for backwards compatibility until Alpha v5 rolls out.
551
- */
552
623
  public async validateAndStoreEnqueuedNotesAndEvents(
553
- contractAddress: AztecAddress,
554
- noteValidationRequestsArrayBaseSlot: Fr,
555
- eventValidationRequestsArrayBaseSlot: Fr,
556
- maxNotePackedLen: number,
557
- maxEventSerializedLen: number,
624
+ noteValidationRequests: EphemeralArray<NoteValidationRequest>,
625
+ eventValidationRequests: EphemeralArray<EventValidationRequest>,
558
626
  scope: AztecAddress,
559
627
  ) {
560
- // TODO(#10727): allow other contracts to store notes
561
- if (!this.contractAddress.equals(contractAddress)) {
562
- throw new Error(`Got a note validation request from ${contractAddress}, expected ${this.contractAddress}`);
563
- }
564
-
565
- const noteValidationRequests = (
566
- await this.capsuleService.readCapsuleArray(
567
- contractAddress,
568
- noteValidationRequestsArrayBaseSlot,
569
- this.jobId,
570
- scope,
571
- )
572
- ).map(fields => NoteValidationRequest.fromFields(fields, maxNotePackedLen));
573
-
574
- const eventValidationRequests = (
575
- await this.capsuleService.readCapsuleArray(
576
- contractAddress,
577
- eventValidationRequestsArrayBaseSlot,
578
- this.jobId,
579
- scope,
580
- )
581
- ).map(fields => EventValidationRequest.fromFields(fields, maxEventSerializedLen));
582
-
583
- await this.#processValidationRequests(noteValidationRequests, eventValidationRequests, scope);
584
-
585
- await this.capsuleService.setCapsuleArray(
586
- contractAddress,
587
- noteValidationRequestsArrayBaseSlot,
588
- [],
589
- this.jobId,
628
+ await this.#processValidationRequests(
629
+ noteValidationRequests.readAll(this.ephemeralArrayService),
630
+ eventValidationRequests.readAll(this.ephemeralArrayService),
590
631
  scope,
591
632
  );
592
- await this.capsuleService.setCapsuleArray(
593
- contractAddress,
594
- eventValidationRequestsArrayBaseSlot,
595
- [],
596
- this.jobId,
597
- scope,
598
- );
599
- }
600
-
601
- public async validateAndStoreEnqueuedNotesAndEventsV2(
602
- noteValidationRequestsArrayBaseSlot: Fr,
603
- eventValidationRequestsArrayBaseSlot: Fr,
604
- maxNotePackedLen: number,
605
- maxEventSerializedLen: number,
606
- scope: AztecAddress,
607
- ) {
608
- const noteValidationRequests = this.ephemeralArrayService
609
- .readArrayAt(noteValidationRequestsArrayBaseSlot)
610
- .map(fields => NoteValidationRequest.fromFields(fields, maxNotePackedLen));
611
-
612
- const eventValidationRequests = this.ephemeralArrayService
613
- .readArrayAt(eventValidationRequestsArrayBaseSlot)
614
- .map(fields => EventValidationRequest.fromFields(fields, maxEventSerializedLen));
615
-
616
- await this.#processValidationRequests(noteValidationRequests, eventValidationRequests, scope);
617
633
  }
618
634
 
619
- /**
620
- * Dispatches note and event validation requests to the service layer.
621
- *
622
- * This function is an auxiliary to support legacy (capsule backed) and new (ephemeral array backed) versions of the
623
- * `validateAndStoreEnqueuedNotesAndEvents` oracle.
624
- */
625
635
  async #processValidationRequests(
626
636
  noteValidationRequests: NoteValidationRequest[],
627
637
  eventValidationRequests: EventValidationRequest[],
628
638
  scope: AztecAddress,
629
639
  ) {
630
- const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
631
- const noteStorePromises = noteValidationRequests.map(request =>
632
- noteService.validateAndStoreNote(
633
- request.contractAddress,
634
- request.owner,
635
- request.storageSlot,
636
- request.randomness,
637
- request.noteNonce,
638
- request.content,
639
- request.noteHash,
640
- request.nullifier,
641
- request.txHash,
642
- scope,
643
- ),
644
- );
640
+ const txEffects = await this.#fetchTxEffects([
641
+ ...noteValidationRequests.map(r => r.txHash),
642
+ ...eventValidationRequests.map(r => r.txHash),
643
+ ]);
645
644
 
645
+ const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
646
646
  const eventService = new EventService(this.anchorBlockHeader, this.aztecNode, this.privateEventStore, this.jobId);
647
- const eventStorePromises = eventValidationRequests.map(request =>
648
- eventService.validateAndStoreEvent(
649
- request.contractAddress,
650
- request.eventTypeId,
651
- request.randomness,
652
- request.serializedEvent,
653
- request.eventCommitment,
654
- request.txHash,
655
- scope,
656
- ),
657
- );
658
647
 
659
- await Promise.all([...noteStorePromises, ...eventStorePromises]);
648
+ await Promise.all([
649
+ noteService.validateAndStoreNotes(noteValidationRequests, scope, txEffects),
650
+ eventService.validateAndStoreEvents(eventValidationRequests, scope, txEffects),
651
+ ]);
660
652
  }
661
653
 
662
- public async getLogsByTag(
663
- contractAddress: AztecAddress,
664
- logRetrievalRequestsArrayBaseSlot: Fr,
665
- logRetrievalResponsesArrayBaseSlot: Fr,
666
- scope: AztecAddress,
667
- ) {
668
- // TODO(#10727): allow other contracts to process partial notes
669
- if (!this.contractAddress.equals(contractAddress)) {
670
- throw new Error(`Got a note validation request from ${contractAddress}, expected ${this.contractAddress}`);
671
- }
672
-
673
- // We read all log retrieval requests and process them all concurrently. This makes the process much faster as we
674
- // don't need to wait for the network round-trip.
675
- const logRetrievalRequests = (
676
- await this.capsuleService.readCapsuleArray(contractAddress, logRetrievalRequestsArrayBaseSlot, this.jobId, scope)
677
- ).map(LogRetrievalRequest.fromFields);
678
-
654
+ public async getLogsByTagV2(
655
+ requests: EphemeralArray<LogRetrievalRequest>,
656
+ ): Promise<EphemeralArray<EphemeralArray<LogRetrievalResponse>>> {
657
+ const logRetrievalRequests = requests.readAll(this.ephemeralArrayService);
679
658
  const logService = this.#createLogService();
680
- const maybeLogRetrievalResponses = await logService.fetchLogsByTag(contractAddress, logRetrievalRequests);
681
659
 
682
- // Requests are cleared once we're done.
683
- await this.capsuleService.setCapsuleArray(
684
- contractAddress,
685
- logRetrievalRequestsArrayBaseSlot,
686
- [],
687
- this.jobId,
688
- scope,
689
- );
660
+ const logRetrievalResponses = await logService.fetchLogsByTag(this.contractAddress, logRetrievalRequests);
690
661
 
691
- // The responses are stored as Option<LogRetrievalResponse> in a second CapsuleArray.
692
- await this.capsuleService.setCapsuleArray(
693
- contractAddress,
694
- logRetrievalResponsesArrayBaseSlot,
695
- maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption),
696
- this.jobId,
697
- scope,
662
+ // Create an inner ephemeral array for each request's matching logs, then wrap all slots in an outer array.
663
+ const innerArrays = logRetrievalResponses.map(responses =>
664
+ EphemeralArray.fromValues(this.ephemeralArrayService, responses),
698
665
  );
699
- }
700
-
701
- public async getLogsByTagV2(requestArrayBaseSlot: Fr): Promise<Fr> {
702
- const logRetrievalRequests = this.ephemeralArrayService
703
- .readArrayAt(requestArrayBaseSlot)
704
- .map(LogRetrievalRequest.fromFields);
705
- const logService = this.#createLogService();
706
666
 
707
- const maybeLogRetrievalResponses = await logService.fetchLogsByTag(this.contractAddress, logRetrievalRequests);
708
-
709
- return this.ephemeralArrayService.newArray(maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption));
667
+ return EphemeralArray.fromValues(this.ephemeralArrayService, innerArrays);
710
668
  }
711
669
 
712
- // Deprecated, only kept for backwards compatibility until Alpha v5 rolls out.
713
- public async getMessageContextsByTxHash(
714
- contractAddress: AztecAddress,
715
- messageContextRequestsArrayBaseSlot: Fr,
716
- messageContextResponsesArrayBaseSlot: Fr,
717
- scope: AztecAddress,
718
- ) {
719
- try {
720
- if (!this.contractAddress.equals(contractAddress)) {
721
- throw new Error(`Got a message context request from ${contractAddress}, expected ${this.contractAddress}`);
722
- }
670
+ /** Given an array of tx hashes, returns an aligned array of tx info if the tx is available. */
671
+ public async getResolvedTxs(requests: EphemeralArray<Fr>): Promise<EphemeralArray<Option<ResolvedTx>>> {
672
+ const txHashes = requests.readAll(this.ephemeralArrayService);
723
673
 
724
- // TODO(@mverzilli): this is a prime example of where using an ephemeral array would make much more sense, we don't
725
- // need scopes here, we just need a bit of shared memory to cross boundaries between Noir and TS.
726
- // At the same time, we don't want to allow any global scope access other than where backwards compatibility
727
- // forces us to. Hence we need the scope here to be artificial.
728
- const requestCapsules = await this.capsuleService.readCapsuleArray(
729
- contractAddress,
730
- messageContextRequestsArrayBaseSlot,
731
- this.jobId,
732
- scope,
733
- );
674
+ const resolved = await this.txResolver.resolveTxs(txHashes, this.anchorBlockHeader.getBlockNumber());
734
675
 
735
- const txHashes = requestCapsules.map((fields, i) => {
736
- if (fields.length !== 1) {
737
- throw new Error(
738
- `Malformed message context request at index ${i}: expected 1 field (tx hash), got ${fields.length}`,
739
- );
740
- }
741
- return fields[0];
742
- });
743
-
744
- const maybeMessageContexts = await this.messageContextService.getMessageContextsByTxHash(
745
- txHashes,
746
- this.anchorBlockHeader.getBlockNumber(),
747
- );
676
+ const options = resolved.map(r => (r ? Option.some(r) : Option.none<ResolvedTx>()));
677
+ return EphemeralArray.fromValues(this.ephemeralArrayService, options);
678
+ }
748
679
 
749
- // Leave response in response capsule array.
750
- await this.capsuleService.setCapsuleArray(
751
- contractAddress,
752
- messageContextResponsesArrayBaseSlot,
753
- maybeMessageContexts.map(MessageContext.toSerializedOption),
754
- this.jobId,
755
- scope,
756
- );
757
- } finally {
758
- await this.capsuleService.setCapsuleArray(
759
- contractAddress,
760
- messageContextRequestsArrayBaseSlot,
761
- [],
762
- this.jobId,
763
- scope,
764
- );
680
+ /**
681
+ * Fetches the effects of a transaction by its hash. Returns null if the tx is not found or is beyond the anchor
682
+ * block.
683
+ */
684
+ public async getTxEffect(txHash: TxHash): Promise<Option<TxEffectData>> {
685
+ if (txHash.hash.isZero()) {
686
+ throw new Error('Invalid tx hash passed into aztec_utl_getTxEffect oracle handler');
765
687
  }
688
+
689
+ return await this.#getTxEffectOption(txHash);
766
690
  }
767
691
 
768
- /** Reads tx hash requests from an ephemeral array, resolves their contexts, and returns the response slot. */
769
- public async getMessageContextsByTxHashV2(requestArrayBaseSlot: Fr): Promise<Fr> {
770
- const requestFields = this.ephemeralArrayService.readArrayAt(requestArrayBaseSlot);
692
+ /** Fetches transaction effects for all hashes, preserving request order. */
693
+ public async getTxEffects(txHashes: EphemeralArray<TxHash>): Promise<EphemeralArray<Option<TxEffectData>>> {
694
+ const hashes = txHashes.readAll(this.ephemeralArrayService);
695
+ const invalidHash = hashes.find(txHash => txHash.hash.isZero());
696
+ if (invalidHash) {
697
+ throw new Error('Invalid tx hash passed into aztec_utl_getTxEffects oracle handler');
698
+ }
771
699
 
772
- const txHashes = requestFields.map((fields, i) => {
773
- if (fields.length !== 1) {
774
- throw new Error(
775
- `Malformed message context request at index ${i}: expected 1 field (tx hash), got ${fields.length}`,
776
- );
777
- }
778
- return fields[0];
779
- });
700
+ const uniqueTxHashes = uniqueBy(hashes, h => h.toString());
701
+ const options = await Promise.all(uniqueTxHashes.map(txHash => this.#getTxEffectOption(txHash)));
702
+ const optionsByHash = new Map(uniqueTxHashes.map((txHash, i) => [txHash.toString(), options[i]]));
780
703
 
781
- const maybeMessageContexts = await this.messageContextService.getMessageContextsByTxHash(
782
- txHashes,
783
- this.anchorBlockHeader.getBlockNumber(),
704
+ return EphemeralArray.fromValues(
705
+ this.ephemeralArrayService,
706
+ hashes.map(txHash => optionsByHash.get(txHash.toString())!),
784
707
  );
785
-
786
- return this.ephemeralArrayService.newArray(maybeMessageContexts.map(MessageContext.toSerializedOption));
787
708
  }
788
709
 
789
710
  public setCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[], scope: AztecAddress): void {
790
- if (!contractAddress.equals(this.contractAddress)) {
791
- // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
792
- throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
793
- }
711
+ this.#assertOwnContract(contractAddress);
794
712
  this.capsuleService.setCapsule(contractAddress, slot, capsule, this.jobId, scope);
795
713
  }
796
714
 
797
- public getCapsule(contractAddress: AztecAddress, slot: Fr, scope: AztecAddress): Promise<Fr[] | null> {
798
- if (!contractAddress.equals(this.contractAddress)) {
799
- // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
800
- throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
801
- }
802
- return this.capsuleService.getCapsule(contractAddress, slot, this.jobId, scope, this.capsules);
715
+ public async getCapsule(
716
+ contractAddress: AztecAddress,
717
+ slot: Fr,
718
+ tSize: number,
719
+ scope: AztecAddress,
720
+ ): Promise<Option<Fr[]>> {
721
+ this.#assertOwnContract(contractAddress);
722
+ const values = await this.capsuleService.getCapsule(contractAddress, slot, this.jobId, scope, this.capsules);
723
+ return values ? Option.some(values) : Option.none({ length: tSize });
803
724
  }
804
725
 
805
726
  public deleteCapsule(contractAddress: AztecAddress, slot: Fr, scope: AztecAddress): void {
806
- if (!contractAddress.equals(this.contractAddress)) {
807
- // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
808
- throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
809
- }
727
+ this.#assertOwnContract(contractAddress);
810
728
  this.capsuleService.deleteCapsule(contractAddress, slot, this.jobId, scope);
811
729
  }
812
730
 
@@ -817,49 +735,192 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
817
735
  numEntries: number,
818
736
  scope: AztecAddress,
819
737
  ): Promise<void> {
738
+ this.#assertOwnContract(contractAddress);
739
+ return this.capsuleService.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, this.jobId, scope);
740
+ }
741
+
742
+ /**
743
+ * Asserts the executing contract may only access its own slice of PXE DB.
744
+ */
745
+ #assertOwnContract(contractAddress: AztecAddress): void {
820
746
  if (!contractAddress.equals(this.contractAddress)) {
821
- // TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
822
747
  throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
823
748
  }
824
- return this.capsuleService.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, this.jobId, scope);
749
+ }
750
+
751
+ /**
752
+ * Records a fact into a collection. A `Some` origin block makes the fact retractable (pruned on reorg of that
753
+ * block), a `None` origin block makes it non-retractable, surviving reorgs.
754
+ */
755
+ public recordFact(
756
+ contractAddress: AztecAddress,
757
+ scope: AztecAddress,
758
+ factCollectionTypeId: Fr,
759
+ factCollectionId: Fr,
760
+ factTypeId: Fr,
761
+ payload: EphemeralArray<Fr>,
762
+ originBlock: Option<OriginBlock>,
763
+ ): Promise<void> {
764
+ this.#assertOwnContract(contractAddress);
765
+ return this.factService.recordFact(
766
+ new FactCollectionKey(contractAddress, scope, factCollectionTypeId, factCollectionId),
767
+ factTypeId,
768
+ payload.readAll(this.ephemeralArrayService),
769
+ originBlock.isSome() ? originBlock.value : undefined,
770
+ this.jobId,
771
+ );
772
+ }
773
+
774
+ /**
775
+ * Deletes a fact collection, removing all its facts. A no-op if no such collection exists.
776
+ */
777
+ public deleteFactCollection(
778
+ contractAddress: AztecAddress,
779
+ scope: AztecAddress,
780
+ factCollectionTypeId: Fr,
781
+ factCollectionId: Fr,
782
+ ): Promise<void> {
783
+ this.#assertOwnContract(contractAddress);
784
+ return this.factService.deleteFactCollection(
785
+ new FactCollectionKey(contractAddress, scope, factCollectionTypeId, factCollectionId),
786
+ this.jobId,
787
+ );
788
+ }
789
+
790
+ /**
791
+ * Returns a fact collection.
792
+ */
793
+ public async getFactCollection(
794
+ contractAddress: AztecAddress,
795
+ scope: AztecAddress,
796
+ factCollectionTypeId: Fr,
797
+ factCollectionId: Fr,
798
+ ): Promise<Option<FactCollection>> {
799
+ this.#assertOwnContract(contractAddress);
800
+ const tips = anchoredTipBlockNumbers(await this.l2TipsStore.getL2Tips(), this.anchorBlockHeader.getBlockNumber());
801
+ const collection = await this.factService.getFactCollection(
802
+ new FactCollectionKey(contractAddress, scope, factCollectionTypeId, factCollectionId),
803
+ tips,
804
+ this.jobId,
805
+ );
806
+ return collection
807
+ ? Option.some(
808
+ toNoirFactCollection(
809
+ this.ephemeralArrayService,
810
+ contractAddress,
811
+ scope,
812
+ factCollectionTypeId,
813
+ factCollectionId,
814
+ collection.facts,
815
+ ),
816
+ )
817
+ : Option.none(emptyFactCollection(this.ephemeralArrayService));
818
+ }
819
+
820
+ /** Returns every fact collection of `factCollectionTypeId`. */
821
+ public async getFactCollectionsByType(
822
+ contractAddress: AztecAddress,
823
+ scope: AztecAddress,
824
+ factCollectionTypeId: Fr,
825
+ ): Promise<EphemeralArray<FactCollection>> {
826
+ this.#assertOwnContract(contractAddress);
827
+ const tips = anchoredTipBlockNumbers(await this.l2TipsStore.getL2Tips(), this.anchorBlockHeader.getBlockNumber());
828
+ const collections = await this.factService.getFactCollectionsByType(
829
+ new FactCollectionTypeKey(contractAddress, scope, factCollectionTypeId),
830
+ tips,
831
+ this.jobId,
832
+ );
833
+ return EphemeralArray.fromValues(
834
+ this.ephemeralArrayService,
835
+ collections.map(collection =>
836
+ toNoirFactCollection(
837
+ this.ephemeralArrayService,
838
+ collection.key.contractAddress,
839
+ collection.key.scope,
840
+ collection.key.factCollectionTypeId,
841
+ collection.key.factCollectionId,
842
+ collection.facts,
843
+ ),
844
+ ),
845
+ );
825
846
  }
826
847
 
827
848
  /**
828
849
  * Clears cached sync state for a contract for a set of scopes, forcing re-sync on the next query so that newly
829
850
  * stored notes or events are discovered.
830
851
  */
831
- public setContractSyncCacheInvalid(contractAddress: AztecAddress, scopes: AztecAddress[]): void {
852
+ public setContractSyncCacheInvalid(contractAddress: AztecAddress, scopes: BoundedVec<AztecAddress>): void {
832
853
  if (!contractAddress.equals(this.contractAddress)) {
833
854
  throw new Error(`Contract ${this.contractAddress} cannot invalidate sync cache of ${contractAddress}`);
834
855
  }
835
- this.contractSyncService.invalidateContractForScopes(contractAddress, scopes);
856
+ this.contractSyncService.invalidateContractForScopes(contractAddress, scopes.data);
836
857
  }
837
858
 
838
859
  // TODO(#11849): consider replacing this oracle with a pure Noir implementation of aes decryption.
839
- public decryptAes128(ciphertext: Buffer, iv: Buffer, symKey: Buffer): Promise<Buffer> {
840
- const aes128 = new Aes128();
841
- return aes128.decryptBufferCBC(ciphertext, iv, symKey);
860
+ public async decryptAes128(
861
+ ciphertext: BoundedVec<number>,
862
+ iv: number[],
863
+ symKey: number[],
864
+ ): Promise<Option<BoundedVec<number>>> {
865
+ const capacity = ciphertext.maxLength;
866
+ try {
867
+ const aes128 = new Aes128();
868
+ const plaintext = await aes128.decryptBufferCBC(
869
+ Buffer.from(ciphertext.data),
870
+ Buffer.from(iv),
871
+ Buffer.from(symKey),
872
+ );
873
+ return Option.some(BoundedVec.from<number>({ data: [...plaintext], maxLength: capacity }));
874
+ } catch {
875
+ return Option.none({ maxLength: capacity });
876
+ }
842
877
  }
843
878
 
844
879
  /**
845
- * Retrieves the app-siloed shared secret for a given address and ephemeral public key.
846
- * @param address - The address to get the secret for.
847
- * @param ephPk - The ephemeral public key to get the secret for.
880
+ * Retrieves app-siloed shared secrets for multiple ephemeral public keys stored in an ephemeral array.
881
+ * @param address - The recipient address.
882
+ * @param ephPks - Ephemeral array containing the serialized Points.
848
883
  * @param contractAddress - The contract address for app-siloing (validated against execution context).
849
- * @returns The app-siloed shared secret as a Field.
884
+ * @returns A new ephemeral array containing the computed shared secrets, or an empty array when the PXE does not
885
+ * hold the keys for `address`.
886
+ * @throws If `address` is not in the execution's allowed scopes.
850
887
  */
851
- public async getSharedSecret(address: AztecAddress, ephPk: Point, contractAddress: AztecAddress): Promise<Fr> {
888
+ public async getSharedSecrets(
889
+ address: AztecAddress,
890
+ ephPks: EphemeralArray<EmbeddedCurvePoint>,
891
+ contractAddress: AztecAddress,
892
+ ): Promise<EphemeralArray<Fr>> {
852
893
  if (!contractAddress.equals(this.contractAddress)) {
853
894
  throw new Error(
854
- `getSharedSecret called with contract address ${contractAddress}, expected ${this.contractAddress}`,
895
+ `getSharedSecrets called with contract address ${contractAddress}, expected ${this.contractAddress}`,
855
896
  );
856
897
  }
857
- const recipientCompleteAddress = await this.getCompleteAddressOrFail(address);
858
- const ivskM = await this.keyStore.getMasterSecretKey(
859
- recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
860
- );
898
+
899
+ assertAllowedScope(address, this.scopes);
900
+
901
+ // An address can be in scope without the PXE holding its keys (e.g. syncing a registered but non-owned account),
902
+ // in which case no secrets can be derived and we return an empty array rather than failing.
903
+ const recipientCompleteAddress = await this.addressStore.getCompleteAddress(address);
904
+ if (!recipientCompleteAddress) {
905
+ this.logger.warn(
906
+ `Computing shared secrets for address ${address} whose keys are not held - returning no secrets`,
907
+ {
908
+ address,
909
+ contractAddress: this.contractAddress,
910
+ },
911
+ );
912
+ return EphemeralArray.fromValues<Fr>(this.ephemeralArrayService, []);
913
+ }
914
+ const ivpkMHash = await hashPublicKey(recipientCompleteAddress.publicKeys.ivpkM);
915
+ const ivskM = await this.keyStore.getMasterSecretKey(ivpkMHash);
861
916
  const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
862
- return deriveAppSiloedSharedSecret(addressSecret, ephPk, this.contractAddress);
917
+
918
+ const ephPkPoints = ephPks.readAll(this.ephemeralArrayService);
919
+ const secrets = await Promise.all(
920
+ ephPkPoints.map(({ x, y }) => appSiloEcdhSharedSecret(addressSecret, new Point(x, y), this.contractAddress)),
921
+ );
922
+
923
+ return EphemeralArray.fromValues(this.ephemeralArrayService, secrets);
863
924
  }
864
925
 
865
926
  public pushEphemeral(slot: Fr, elements: Fr[]): number {
@@ -890,33 +951,281 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
890
951
  this.ephemeralArrayService.clear(slot);
891
952
  }
892
953
 
954
+ public pushTransient(slot: Fr, elements: Fr[]): number {
955
+ return this.transientArrayService.push(this.contractAddress, slot, elements);
956
+ }
957
+
958
+ public popTransient(slot: Fr): Fr[] {
959
+ return this.transientArrayService.pop(this.contractAddress, slot);
960
+ }
961
+
962
+ public getTransient(slot: Fr, index: number): Fr[] {
963
+ return this.transientArrayService.get(this.contractAddress, slot, index);
964
+ }
965
+
966
+ public setTransient(slot: Fr, index: number, elements: Fr[]): void {
967
+ this.transientArrayService.set(this.contractAddress, slot, index, elements);
968
+ }
969
+
970
+ public getTransientLen(slot: Fr): number {
971
+ return this.transientArrayService.len(this.contractAddress, slot);
972
+ }
973
+
974
+ public removeTransient(slot: Fr, index: number): void {
975
+ this.transientArrayService.remove(this.contractAddress, slot, index);
976
+ }
977
+
978
+ public clearTransient(slot: Fr): void {
979
+ this.transientArrayService.clear(this.contractAddress, slot);
980
+ }
981
+
893
982
  public emitOffchainEffect(data: Fr[]): Promise<void> {
894
983
  this.offchainEffects.push({ data, contractAddress: this.contractAddress });
895
984
  return Promise.resolve();
896
985
  }
897
986
 
987
+ /** Executes another utility function from within this one and returns its serialized return values. */
988
+ public async callUtilityFunction(
989
+ targetContractAddress: AztecAddress,
990
+ functionSelector: FunctionSelector,
991
+ args: Fr[],
992
+ ): Promise<Fr[]> {
993
+ const targetArtifact = await this.anchoredContractData.getFunctionArtifactWithDebugMetadata(
994
+ targetContractAddress,
995
+ functionSelector,
996
+ );
997
+ if (!targetArtifact) {
998
+ throw new Error(
999
+ `Cannot call ${targetContractAddress}:${functionSelector}: the contract is not registered. ` +
1000
+ `Register it via wallet.registerContract(...).`,
1001
+ );
1002
+ }
1003
+
1004
+ if (!targetContractAddress.equals(this.contractAddress)) {
1005
+ // Standard handshake registry reads are authorized by default; every other cross-contract call needs the hook.
1006
+ if (!(await isStandardHandshakeRegistryUtilityRead(targetContractAddress, functionSelector))) {
1007
+ const [callerClassId, targetClassId] = await Promise.all([
1008
+ this.anchoredContractData.getCurrentClassId(this.contractAddress),
1009
+ this.anchoredContractData.getCurrentClassId(targetContractAddress),
1010
+ ]);
1011
+ if (!callerClassId || !targetClassId) {
1012
+ throw new Error(
1013
+ `Cannot authorize utility call from ${this.contractAddress} to ${targetContractAddress}: ` +
1014
+ `${!callerClassId ? this.contractAddress : targetContractAddress} is not registered.`,
1015
+ );
1016
+ }
1017
+ const request: UtilityCallAuthorizationRequest = {
1018
+ caller: this.contractAddress,
1019
+ callerClassId,
1020
+ target: targetContractAddress,
1021
+ targetClassId,
1022
+ functionSelector,
1023
+ functionName: targetArtifact.name,
1024
+ args,
1025
+ callerContext: this.callerContext,
1026
+ };
1027
+
1028
+ const response = this.hooks?.authorizeUtilityCall
1029
+ ? await this.hooks.authorizeUtilityCall(request)
1030
+ : { authorized: false, reason: 'No authorizeUtilityCall hook configured' };
1031
+
1032
+ if (!response.authorized) {
1033
+ const reason = response.reason ? `: ${response.reason}` : '';
1034
+ throw new Error(
1035
+ `Cross-contract utility call denied${reason}. ${this.contractAddress} attempted to call ` +
1036
+ `${targetContractAddress}:${functionSelector} (${targetArtifact.name}). ` +
1037
+ `See https://docs.aztec.network/errors/11`,
1038
+ );
1039
+ }
1040
+ }
1041
+
1042
+ await this.contractSyncService.ensureContractSynced(
1043
+ targetContractAddress,
1044
+ functionSelector,
1045
+ this.utilityExecutor,
1046
+ this.anchorBlockHeader,
1047
+ this.jobId,
1048
+ this.scopes,
1049
+ );
1050
+ }
1051
+
1052
+ this.logger.debug(
1053
+ `Calling nested utility function ${targetContractAddress}:${functionSelector} from ${this.contractAddress}`,
1054
+ );
1055
+
1056
+ const nestedOracle = new UtilityExecutionOracle({
1057
+ callContext: CallContext.from({
1058
+ msgSender: this.contractAddress,
1059
+ contractAddress: targetContractAddress,
1060
+ functionSelector,
1061
+ isStaticCall: true,
1062
+ }),
1063
+ authWitnesses: this.authWitnesses,
1064
+ capsules: this.capsules,
1065
+ anchorBlockHeader: this.anchorBlockHeader,
1066
+ anchoredContractData: this.anchoredContractData,
1067
+ noteStore: this.noteStore,
1068
+ keyStore: this.keyStore,
1069
+ addressStore: this.addressStore,
1070
+ aztecNode: this.aztecNode,
1071
+ recipientTaggingStore: this.recipientTaggingStore,
1072
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
1073
+ capsuleService: this.capsuleService,
1074
+ factService: this.factService,
1075
+ privateEventStore: this.privateEventStore,
1076
+ txResolver: this.txResolver,
1077
+ contractSyncService: this.contractSyncService,
1078
+ l2TipsStore: this.l2TipsStore,
1079
+ jobId: this.jobId,
1080
+ scopes: this.scopes,
1081
+ simulator: this.simulator,
1082
+ hooks: this.hooks,
1083
+ utilityExecutor: this.utilityExecutor,
1084
+ log: this.logger,
1085
+ // Shared across the whole execution tree: nested utility frames inherit the caller's transient-array store.
1086
+ transientArrayService: this.transientArrayService,
1087
+ });
1088
+
1089
+ const initialWitness = toACVMWitness(0, args);
1090
+ const acirExecutionResult = await this.simulator
1091
+ .executeUserCircuit(initialWitness, targetArtifact, buildACIRCallback(nestedOracle))
1092
+ .catch((err: Error) => {
1093
+ err.message = resolveAssertionMessageFromError(err, targetArtifact);
1094
+ throw new ExecutionError(
1095
+ err.message,
1096
+ { contractAddress: targetContractAddress, functionSelector },
1097
+ extractCallStack(err, targetArtifact.debug),
1098
+ { cause: err },
1099
+ );
1100
+ });
1101
+
1102
+ return witnessMapToFields(acirExecutionResult.returnWitness);
1103
+ }
1104
+
898
1105
  /** Returns offchain effects collected during execution. */
899
1106
  public getOffchainEffects(): OffchainEffect[] {
900
1107
  return this.offchainEffects;
901
1108
  }
902
1109
 
1110
+ /**
1111
+ * Fetches tx effects for the given hashes in parallel, deduplicating repeated hashes so each tx is only requested
1112
+ * once. Returns a map keyed by `TxHash.toString()`; hashes for which the node has no tx effect are omitted.
1113
+ */
1114
+ async #fetchTxEffects(txHashes: TxHash[]): Promise<Map<string, IndexedTxEffect>> {
1115
+ const uniqueTxHashes = uniqueBy(txHashes, h => h.toString());
1116
+ const fetched = await Promise.all(uniqueTxHashes.map(h => this.aztecNodeReadCache.getTxReceiptWithEffect(h)));
1117
+ return new Map(
1118
+ uniqueTxHashes
1119
+ .map((h, i): [string, IndexedTxEffect | undefined] => {
1120
+ const receipt = fetched[i];
1121
+ if (!receipt.isMined() || !receipt.txEffect) {
1122
+ return [h.toString(), undefined];
1123
+ }
1124
+ return [
1125
+ h.toString(),
1126
+ {
1127
+ data: receipt.txEffect,
1128
+ l2BlockNumber: receipt.blockNumber,
1129
+ l2BlockHash: receipt.blockHash,
1130
+ txIndexInBlock: receipt.txIndexInBlock,
1131
+ slotNumber: receipt.slotNumber,
1132
+ },
1133
+ ];
1134
+ })
1135
+ .filter((entry): entry is [string, IndexedTxEffect] => entry[1] !== undefined),
1136
+ );
1137
+ }
1138
+
1139
+ async #getTxEffectOption(txHash: TxHash): Promise<Option<TxEffectData>> {
1140
+ const receipt = await this.aztecNodeReadCache.getTxReceiptWithEffect(txHash);
1141
+ if (!receipt.isMined() || !receipt.txEffect || receipt.blockNumber > this.anchorBlockHeader.getBlockNumber()) {
1142
+ return Option.none();
1143
+ }
1144
+ return Option.some(this.#toTxEffectData(receipt.txEffect));
1145
+ }
1146
+
1147
+ #toTxEffectData(txEffect: TxEffect): TxEffectData {
1148
+ return {
1149
+ ...txEffect,
1150
+ revertCode: txEffect.revertCode.getCode(),
1151
+ publicLogs: FlatPublicLogs.fromLogs(txEffect.publicLogs),
1152
+ contractClassLogs: txEffect.contractClassLogs.map(log => ({
1153
+ contractAddress: log.contractAddress,
1154
+ fields: log.fields.toFields(),
1155
+ emittedLength: log.emittedLength,
1156
+ })),
1157
+ };
1158
+ }
1159
+
903
1160
  /** Runs a query concurrently with a validation that the block hash is not ahead of the anchor block. */
904
1161
  async #queryWithBlockHashNotAfterAnchor<T>(blockHash: BlockHash, query: () => Promise<T>): Promise<T> {
1162
+ // Most contracts query state at the "current" block, which is the anchor. Skip the validation when we can.
1163
+ const anchorHash = await this.anchorBlockHeader.hash();
1164
+ if (blockHash.equals(anchorHash)) {
1165
+ return query();
1166
+ }
1167
+
905
1168
  const [response] = await Promise.all([
906
1169
  query(),
907
1170
  (async () => {
908
- const header = await this.aztecNode.getBlockHeader(blockHash);
1171
+ const block = await this.aztecNodeReadCache.getBlock(blockHash);
1172
+ const header = block?.header;
909
1173
  if (!header) {
910
1174
  throw new Error(`Could not find block header for block hash ${blockHash}`);
911
1175
  }
912
1176
 
913
1177
  if (header.getBlockNumber() > this.anchorBlockHeader.getBlockNumber()) {
914
1178
  throw new Error(
915
- `Made a node query with a reference block hash ${blockHash} with block number ${header.getBlockNumber()}, which is ahead of the anchor block number ${this.anchorBlockHeader.getBlockNumber()} (from anchor block hash ${await this.anchorBlockHeader.hash()}).`,
1179
+ `Made a node query with a reference block hash ${blockHash} with block number ${header.getBlockNumber()}, which is ahead of the anchor block number ${this.anchorBlockHeader.getBlockNumber()} (from anchor block hash ${anchorHash}).`,
916
1180
  );
917
1181
  }
918
1182
  })(),
919
1183
  ]);
920
1184
  return response;
921
1185
  }
1186
+
1187
+ /** The execution context of the current call. */
1188
+ protected get callerContext(): 'private' | 'private view' | 'utility' {
1189
+ return 'utility';
1190
+ }
1191
+
1192
+ /** The address of the contract whose function is being executed, from the call context. */
1193
+ protected get contractAddress(): AztecAddress {
1194
+ return this.callContext.contractAddress;
1195
+ }
1196
+ }
1197
+
1198
+ // Registry reads that any contract may issue without an `authorizeUtilityCall` hook. The constrained-delivery
1199
+ // library calls these implicitly for the app, and they are safe to default-authorize: `get_app_siloed_secrets`
1200
+ // siloes every returned secret to `msg_sender`, and `get_non_interactive_handshakes` only exposes ephemeral public
1201
+ // keys, from which the shared secret cannot be derived without the recipient's secret keys.
1202
+ const STANDARD_HANDSHAKE_REGISTRY_DEFAULT_AUTHORIZED_READ_SIGNATURES = [
1203
+ 'get_non_interactive_handshakes((Field),u32)',
1204
+ 'get_app_siloed_secrets((Field),(Field))',
1205
+ ];
1206
+
1207
+ async function doesSelectorHaveSignature(functionSelector: FunctionSelector, signature: string): Promise<boolean> {
1208
+ return functionSelector.equals(await FunctionSelector.fromSignature(signature));
1209
+ }
1210
+
1211
+ /**
1212
+ * Whether a cross-contract utility call targets one of the standard handshake registry's read functions.
1213
+ *
1214
+ * These reads are authorized by PXE for every wallet, without consulting the `authorizeUtilityCall` hook, so that
1215
+ * wallets don't need to know the handshake registry exists in order to deliver and discover messages through it.
1216
+ */
1217
+ async function isStandardHandshakeRegistryUtilityRead(
1218
+ targetContractAddress: AztecAddress,
1219
+ functionSelector: FunctionSelector,
1220
+ ): Promise<boolean> {
1221
+ if (!targetContractAddress.equals(STANDARD_HANDSHAKE_REGISTRY_ADDRESS)) {
1222
+ return false;
1223
+ }
1224
+
1225
+ const matches = await Promise.all(
1226
+ STANDARD_HANDSHAKE_REGISTRY_DEFAULT_AUTHORIZED_READ_SIGNATURES.map(signature =>
1227
+ doesSelectorHaveSignature(functionSelector, signature),
1228
+ ),
1229
+ );
1230
+ return matches.some(Boolean);
922
1231
  }