@aztec/pxe 0.0.0-test.1 → 0.0.1-commit.b655e406

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 (309) hide show
  1. package/README.md +5 -5
  2. package/dest/bin/check_oracle_version.d.ts +2 -0
  3. package/dest/bin/check_oracle_version.d.ts.map +1 -0
  4. package/dest/bin/check_oracle_version.js +39 -0
  5. package/dest/config/index.d.ts +10 -15
  6. package/dest/config/index.d.ts.map +1 -1
  7. package/dest/config/index.js +11 -20
  8. package/dest/config/package_info.js +1 -1
  9. package/dest/contract_function_simulator/contract_function_simulator.d.ts +56 -0
  10. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -0
  11. package/dest/contract_function_simulator/contract_function_simulator.js +301 -0
  12. package/dest/contract_function_simulator/execution_data_provider.d.ts +274 -0
  13. package/dest/contract_function_simulator/execution_data_provider.d.ts.map +1 -0
  14. package/dest/contract_function_simulator/execution_data_provider.js +14 -0
  15. package/dest/contract_function_simulator/execution_note_cache.d.ts +93 -0
  16. package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -0
  17. package/dest/contract_function_simulator/execution_note_cache.js +183 -0
  18. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +16 -0
  19. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -0
  20. package/dest/contract_function_simulator/execution_tagging_index_cache.js +26 -0
  21. package/dest/contract_function_simulator/hashed_values_cache.d.ts +28 -0
  22. package/dest/contract_function_simulator/hashed_values_cache.d.ts.map +1 -0
  23. package/dest/contract_function_simulator/hashed_values_cache.js +36 -0
  24. package/dest/contract_function_simulator/index.d.ts +14 -0
  25. package/dest/contract_function_simulator/index.d.ts.map +1 -0
  26. package/dest/contract_function_simulator/index.js +12 -0
  27. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +20 -0
  28. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -0
  29. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +37 -0
  30. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +15 -0
  31. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -0
  32. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +25 -0
  33. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +17 -0
  34. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -0
  35. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +65 -0
  36. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +22 -0
  37. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -0
  38. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +42 -0
  39. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +22 -0
  40. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -0
  41. package/dest/contract_function_simulator/noir-structs/utility_context.js +33 -0
  42. package/dest/contract_function_simulator/oracle/index.d.ts +14 -0
  43. package/dest/contract_function_simulator/oracle/index.d.ts.map +1 -0
  44. package/dest/contract_function_simulator/oracle/index.js +2 -0
  45. package/dest/contract_function_simulator/oracle/interfaces.d.ts +97 -0
  46. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -0
  47. package/dest/contract_function_simulator/oracle/interfaces.js +4 -0
  48. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +19 -0
  49. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -0
  50. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.js +24 -0
  51. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +22 -0
  52. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -0
  53. package/dest/contract_function_simulator/oracle/note_packing_utils.js +49 -0
  54. package/dest/contract_function_simulator/oracle/oracle.d.ts +57 -0
  55. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -0
  56. package/dest/contract_function_simulator/oracle/oracle.js +328 -0
  57. package/dest/contract_function_simulator/oracle/private_execution.d.ts +48 -0
  58. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -0
  59. package/dest/contract_function_simulator/oracle/private_execution.js +123 -0
  60. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +236 -0
  61. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -0
  62. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +417 -0
  63. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +154 -0
  64. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -0
  65. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +265 -0
  66. package/dest/contract_function_simulator/pick_notes.d.ts +85 -0
  67. package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -0
  68. package/dest/contract_function_simulator/pick_notes.js +51 -0
  69. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +6 -0
  70. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +1 -0
  71. package/dest/contract_function_simulator/proxied_contract_data_source.js +62 -0
  72. package/dest/contract_function_simulator/proxied_node.d.ts +9 -0
  73. package/dest/contract_function_simulator/proxied_node.d.ts.map +1 -0
  74. package/dest/contract_function_simulator/proxied_node.js +27 -0
  75. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts +122 -0
  76. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -0
  77. package/dest/contract_function_simulator/pxe_oracle_interface.js +701 -0
  78. package/dest/entrypoints/client/bundle/index.d.ts +4 -2
  79. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  80. package/dest/entrypoints/client/bundle/index.js +3 -2
  81. package/dest/entrypoints/client/bundle/utils.d.ts +9 -9
  82. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  83. package/dest/entrypoints/client/bundle/utils.js +18 -12
  84. package/dest/entrypoints/client/lazy/index.d.ts +4 -2
  85. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  86. package/dest/entrypoints/client/lazy/index.js +3 -2
  87. package/dest/entrypoints/client/lazy/utils.d.ts +8 -8
  88. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  89. package/dest/entrypoints/client/lazy/utils.js +17 -11
  90. package/dest/entrypoints/{client/pxe_creation_options.d.ts → pxe_creation_options.d.ts} +4 -1
  91. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -0
  92. package/dest/entrypoints/server/index.d.ts +5 -3
  93. package/dest/entrypoints/server/index.d.ts.map +1 -1
  94. package/dest/entrypoints/server/index.js +4 -3
  95. package/dest/entrypoints/server/utils.d.ts +7 -15
  96. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  97. package/dest/entrypoints/server/utils.js +34 -28
  98. package/dest/{pxe_service/error_enriching.d.ts → error_enriching.d.ts} +1 -1
  99. package/dest/error_enriching.d.ts.map +1 -0
  100. package/dest/{pxe_service/error_enriching.js → error_enriching.js} +26 -18
  101. package/dest/oracle_version.d.ts +3 -0
  102. package/dest/oracle_version.d.ts.map +1 -0
  103. package/dest/oracle_version.js +10 -0
  104. package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.d.ts +6 -6
  105. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -0
  106. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.js +271 -0
  107. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +4 -0
  108. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +1 -0
  109. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.js +41 -0
  110. package/dest/private_kernel/hints/index.d.ts +3 -0
  111. package/dest/private_kernel/hints/index.d.ts.map +1 -0
  112. package/dest/{kernel_prover → private_kernel}/hints/index.js +1 -0
  113. package/dest/private_kernel/index.d.ts +3 -0
  114. package/dest/private_kernel/index.d.ts.map +1 -0
  115. package/dest/private_kernel/index.js +2 -0
  116. package/dest/private_kernel/private_kernel_execution_prover.d.ts +44 -0
  117. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -0
  118. package/dest/private_kernel/private_kernel_execution_prover.js +285 -0
  119. package/dest/{kernel_prover/proving_data_oracle.d.ts → private_kernel/private_kernel_oracle.d.ts} +17 -28
  120. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -0
  121. package/dest/private_kernel/private_kernel_oracle.js +4 -0
  122. package/dest/{kernel_oracle/index.d.ts → private_kernel/private_kernel_oracle_impl.d.ts} +8 -8
  123. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -0
  124. package/dest/{kernel_oracle/index.js → private_kernel/private_kernel_oracle_impl.js} +19 -9
  125. package/dest/pxe.d.ts +233 -0
  126. package/dest/pxe.d.ts.map +1 -0
  127. package/dest/pxe.js +789 -0
  128. package/dest/storage/address_data_provider/address_data_provider.d.ts +1 -3
  129. package/dest/storage/address_data_provider/address_data_provider.d.ts.map +1 -1
  130. package/dest/storage/address_data_provider/address_data_provider.js +0 -3
  131. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +14 -5
  132. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -1
  133. package/dest/storage/capsule_data_provider/capsule_data_provider.js +85 -24
  134. package/dest/storage/contract_data_provider/contract_data_provider.d.ts +12 -47
  135. package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
  136. package/dest/storage/contract_data_provider/contract_data_provider.js +92 -70
  137. package/dest/storage/contract_data_provider/index.d.ts +0 -1
  138. package/dest/storage/contract_data_provider/index.d.ts.map +1 -1
  139. package/dest/storage/contract_data_provider/index.js +0 -1
  140. package/dest/storage/contract_data_provider/private_functions_tree.d.ts +2 -41
  141. package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
  142. package/dest/storage/contract_data_provider/private_functions_tree.js +9 -61
  143. package/dest/storage/index.d.ts +2 -3
  144. package/dest/storage/index.d.ts.map +1 -1
  145. package/dest/storage/index.js +2 -3
  146. package/dest/storage/metadata.d.ts +2 -0
  147. package/dest/storage/metadata.d.ts.map +1 -0
  148. package/dest/storage/metadata.js +1 -0
  149. package/dest/storage/note_data_provider/note_dao.d.ts +16 -22
  150. package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
  151. package/dest/storage/note_data_provider/note_dao.js +16 -20
  152. package/dest/storage/note_data_provider/note_data_provider.d.ts +71 -8
  153. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
  154. package/dest/storage/note_data_provider/note_data_provider.js +133 -74
  155. package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts +43 -0
  156. package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts.map +1 -0
  157. package/dest/storage/private_event_data_provider/private_event_data_provider.js +104 -0
  158. package/dest/storage/sync_data_provider/sync_data_provider.d.ts +2 -4
  159. package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +1 -1
  160. package/dest/storage/sync_data_provider/sync_data_provider.js +2 -5
  161. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +28 -6
  162. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +1 -1
  163. package/dest/storage/tagging_data_provider/tagging_data_provider.js +48 -24
  164. package/dest/synchronizer/synchronizer.d.ts +7 -9
  165. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  166. package/dest/synchronizer/synchronizer.js +17 -19
  167. package/dest/tagging/constants.d.ts +2 -0
  168. package/dest/tagging/constants.d.ts.map +1 -0
  169. package/dest/tagging/constants.js +2 -0
  170. package/dest/tagging/index.d.ts +7 -0
  171. package/dest/tagging/index.d.ts.map +1 -0
  172. package/dest/tagging/index.js +5 -0
  173. package/dest/tagging/siloed_tag.d.ts +14 -0
  174. package/dest/tagging/siloed_tag.d.ts.map +1 -0
  175. package/dest/tagging/siloed_tag.js +20 -0
  176. package/dest/tagging/tag.d.ts +12 -0
  177. package/dest/tagging/tag.d.ts.map +1 -0
  178. package/dest/tagging/tag.js +17 -0
  179. package/dest/tagging/utils.d.ts +18 -0
  180. package/dest/tagging/utils.d.ts.map +1 -0
  181. package/dest/tagging/utils.js +24 -0
  182. package/package.json +34 -32
  183. package/src/bin/check_oracle_version.ts +50 -0
  184. package/src/config/index.ts +20 -33
  185. package/src/config/package_info.ts +1 -1
  186. package/src/contract_function_simulator/contract_function_simulator.ts +548 -0
  187. package/src/contract_function_simulator/execution_data_provider.ts +343 -0
  188. package/src/contract_function_simulator/execution_note_cache.ts +222 -0
  189. package/src/contract_function_simulator/execution_tagging_index_cache.ts +32 -0
  190. package/src/contract_function_simulator/hashed_values_cache.ts +47 -0
  191. package/src/contract_function_simulator/index.ts +13 -0
  192. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +47 -0
  193. package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +27 -0
  194. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +69 -0
  195. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +52 -0
  196. package/src/contract_function_simulator/noir-structs/utility_context.ts +42 -0
  197. package/src/contract_function_simulator/oracle/index.ts +16 -0
  198. package/src/contract_function_simulator/oracle/interfaces.ts +160 -0
  199. package/src/contract_function_simulator/oracle/message_load_oracle_inputs.ts +23 -0
  200. package/src/contract_function_simulator/oracle/note_packing_utils.ts +52 -0
  201. package/src/contract_function_simulator/oracle/oracle.ts +575 -0
  202. package/src/contract_function_simulator/oracle/private_execution.ts +207 -0
  203. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +625 -0
  204. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +358 -0
  205. package/src/contract_function_simulator/pick_notes.ts +141 -0
  206. package/src/contract_function_simulator/proxied_contract_data_source.ts +66 -0
  207. package/src/contract_function_simulator/proxied_node.ts +33 -0
  208. package/src/contract_function_simulator/pxe_oracle_interface.ts +1019 -0
  209. package/src/entrypoints/client/bundle/index.ts +4 -2
  210. package/src/entrypoints/client/bundle/utils.ts +36 -36
  211. package/src/entrypoints/client/lazy/index.ts +4 -2
  212. package/src/entrypoints/client/lazy/utils.ts +36 -31
  213. package/src/entrypoints/{client/pxe_creation_options.ts → pxe_creation_options.ts} +4 -1
  214. package/src/entrypoints/server/index.ts +5 -3
  215. package/src/entrypoints/server/utils.ts +69 -47
  216. package/src/{pxe_service/error_enriching.ts → error_enriching.ts} +36 -27
  217. package/src/oracle_version.ts +11 -0
  218. package/src/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.ts +158 -142
  219. package/src/private_kernel/hints/compute_tx_include_by_timestamp.ts +58 -0
  220. package/src/{kernel_prover → private_kernel}/hints/index.ts +1 -0
  221. package/src/private_kernel/index.ts +2 -0
  222. package/src/private_kernel/private_kernel_execution_prover.ts +436 -0
  223. package/src/{kernel_prover/proving_data_oracle.ts → private_kernel/private_kernel_oracle.ts} +17 -29
  224. package/src/{kernel_oracle/index.ts → private_kernel/private_kernel_oracle_impl.ts} +30 -15
  225. package/src/pxe.ts +1113 -0
  226. package/src/storage/address_data_provider/address_data_provider.ts +1 -7
  227. package/src/storage/capsule_data_provider/capsule_data_provider.ts +97 -30
  228. package/src/storage/contract_data_provider/contract_data_provider.ts +114 -81
  229. package/src/storage/contract_data_provider/index.ts +0 -1
  230. package/src/storage/contract_data_provider/private_functions_tree.ts +11 -75
  231. package/src/storage/index.ts +2 -4
  232. package/src/storage/metadata.ts +1 -0
  233. package/src/storage/note_data_provider/note_dao.ts +19 -27
  234. package/src/storage/note_data_provider/note_data_provider.ts +161 -113
  235. package/src/storage/private_event_data_provider/private_event_data_provider.ts +148 -0
  236. package/src/storage/sync_data_provider/sync_data_provider.ts +4 -10
  237. package/src/storage/tagging_data_provider/tagging_data_provider.ts +58 -30
  238. package/src/synchronizer/synchronizer.ts +21 -22
  239. package/src/tagging/constants.ts +2 -0
  240. package/src/tagging/index.ts +6 -0
  241. package/src/tagging/siloed_tag.ts +22 -0
  242. package/src/tagging/tag.ts +16 -0
  243. package/src/tagging/utils.ts +31 -0
  244. package/dest/bin/index.d.ts +0 -3
  245. package/dest/bin/index.d.ts.map +0 -1
  246. package/dest/bin/index.js +0 -28
  247. package/dest/entrypoints/client/pxe_creation_options.d.ts.map +0 -1
  248. package/dest/kernel_oracle/index.d.ts.map +0 -1
  249. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
  250. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +0 -270
  251. package/dest/kernel_prover/hints/index.d.ts +0 -2
  252. package/dest/kernel_prover/hints/index.d.ts.map +0 -1
  253. package/dest/kernel_prover/index.d.ts +0 -3
  254. package/dest/kernel_prover/index.d.ts.map +0 -1
  255. package/dest/kernel_prover/index.js +0 -2
  256. package/dest/kernel_prover/kernel_prover.d.ts +0 -38
  257. package/dest/kernel_prover/kernel_prover.d.ts.map +0 -1
  258. package/dest/kernel_prover/kernel_prover.js +0 -217
  259. package/dest/kernel_prover/proving_data_oracle.d.ts.map +0 -1
  260. package/dest/kernel_prover/proving_data_oracle.js +0 -4
  261. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +0 -11
  262. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +0 -1
  263. package/dest/note_decryption_utils/add_public_values_to_payload.js +0 -47
  264. package/dest/pxe_http/index.d.ts +0 -2
  265. package/dest/pxe_http/index.d.ts.map +0 -1
  266. package/dest/pxe_http/index.js +0 -1
  267. package/dest/pxe_http/pxe_http_server.d.ts +0 -16
  268. package/dest/pxe_http/pxe_http_server.d.ts.map +0 -1
  269. package/dest/pxe_http/pxe_http_server.js +0 -27
  270. package/dest/pxe_oracle_interface/index.d.ts +0 -159
  271. package/dest/pxe_oracle_interface/index.d.ts.map +0 -1
  272. package/dest/pxe_oracle_interface/index.js +0 -692
  273. package/dest/pxe_oracle_interface/tagging_utils.d.ts +0 -17
  274. package/dest/pxe_oracle_interface/tagging_utils.d.ts.map +0 -1
  275. package/dest/pxe_oracle_interface/tagging_utils.js +0 -23
  276. package/dest/pxe_service/error_enriching.d.ts.map +0 -1
  277. package/dest/pxe_service/index.d.ts +0 -3
  278. package/dest/pxe_service/index.d.ts.map +0 -1
  279. package/dest/pxe_service/index.js +0 -2
  280. package/dest/pxe_service/pxe_service.d.ts +0 -111
  281. package/dest/pxe_service/pxe_service.d.ts.map +0 -1
  282. package/dest/pxe_service/pxe_service.js +0 -664
  283. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts +0 -11
  284. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts.map +0 -1
  285. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.js +0 -20
  286. package/dest/storage/auth_witness_data_provider/index.d.ts +0 -2
  287. package/dest/storage/auth_witness_data_provider/index.d.ts.map +0 -1
  288. package/dest/storage/auth_witness_data_provider/index.js +0 -1
  289. package/dest/storage/data_provider.d.ts +0 -4
  290. package/dest/storage/data_provider.d.ts.map +0 -1
  291. package/dest/storage/data_provider.js +0 -1
  292. package/dest/test/pxe_test_suite.d.ts +0 -3
  293. package/dest/test/pxe_test_suite.d.ts.map +0 -1
  294. package/dest/test/pxe_test_suite.js +0 -97
  295. package/src/bin/index.ts +0 -38
  296. package/src/kernel_prover/index.ts +0 -2
  297. package/src/kernel_prover/kernel_prover.ts +0 -351
  298. package/src/note_decryption_utils/add_public_values_to_payload.ts +0 -64
  299. package/src/pxe_http/index.ts +0 -1
  300. package/src/pxe_http/pxe_http_server.ts +0 -29
  301. package/src/pxe_oracle_interface/index.ts +0 -925
  302. package/src/pxe_oracle_interface/tagging_utils.ts +0 -32
  303. package/src/pxe_service/index.ts +0 -2
  304. package/src/pxe_service/pxe_service.ts +0 -949
  305. package/src/storage/auth_witness_data_provider/auth_witness_data_provider.ts +0 -34
  306. package/src/storage/auth_witness_data_provider/index.ts +0 -1
  307. package/src/storage/data_provider.ts +0 -3
  308. package/src/test/pxe_test_suite.ts +0 -111
  309. /package/dest/entrypoints/{client/pxe_creation_options.js → pxe_creation_options.js} +0 -0
package/src/pxe.ts ADDED
@@ -0,0 +1,1113 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import { type Logger, createLogger } from '@aztec/foundation/log';
3
+ import { SerialQueue } from '@aztec/foundation/queue';
4
+ import { Timer } from '@aztec/foundation/timer';
5
+ import { KeyStore } from '@aztec/key-store';
6
+ import type { AztecAsyncKVStore } from '@aztec/kv-store';
7
+ import { L2TipsKVStore } from '@aztec/kv-store/stores';
8
+ import { type ProtocolContractsProvider, protocolContractNames } from '@aztec/protocol-contracts';
9
+ import type { CircuitSimulator } from '@aztec/simulator/client';
10
+ import {
11
+ type ContractArtifact,
12
+ type EventMetadataDefinition,
13
+ FunctionCall,
14
+ FunctionSelector,
15
+ FunctionType,
16
+ decodeFromAbi,
17
+ decodeFunctionSignature,
18
+ encodeArguments,
19
+ } from '@aztec/stdlib/abi';
20
+ import type { AuthWitness } from '@aztec/stdlib/auth-witness';
21
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
22
+ import {
23
+ CompleteAddress,
24
+ type ContractClassWithId,
25
+ type ContractInstanceWithAddress,
26
+ type PartialAddress,
27
+ computeContractAddressFromInstance,
28
+ getContractClassFromArtifact,
29
+ } from '@aztec/stdlib/contract';
30
+ import { SimulationError } from '@aztec/stdlib/errors';
31
+ import { siloNullifier } from '@aztec/stdlib/hash';
32
+ import type { AztecNode, PrivateKernelProver } from '@aztec/stdlib/interfaces/client';
33
+ import type {
34
+ PrivateExecutionStep,
35
+ PrivateKernelExecutionProofOutput,
36
+ PrivateKernelTailCircuitPublicInputs,
37
+ } from '@aztec/stdlib/kernel';
38
+ import { type NotesFilter, UniqueNote } from '@aztec/stdlib/note';
39
+ import {
40
+ type ContractOverrides,
41
+ PrivateExecutionResult,
42
+ PrivateSimulationResult,
43
+ type ProvingTimings,
44
+ PublicSimulationOutput,
45
+ SimulationOverrides,
46
+ type SimulationTimings,
47
+ Tx,
48
+ TxExecutionRequest,
49
+ TxProfileResult,
50
+ TxProvingResult,
51
+ TxSimulationResult,
52
+ UtilitySimulationResult,
53
+ } from '@aztec/stdlib/tx';
54
+
55
+ import { inspect } from 'util';
56
+
57
+ import type { PXEConfig } from './config/index.js';
58
+ import {
59
+ ContractFunctionSimulator,
60
+ generateSimulatedProvingResult,
61
+ } from './contract_function_simulator/contract_function_simulator.js';
62
+ import { readCurrentClassId } from './contract_function_simulator/oracle/private_execution.js';
63
+ import { ProxiedContractDataProviderFactory } from './contract_function_simulator/proxied_contract_data_source.js';
64
+ import { ProxiedNodeFactory } from './contract_function_simulator/proxied_node.js';
65
+ import { PXEOracleInterface } from './contract_function_simulator/pxe_oracle_interface.js';
66
+ import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
67
+ import {
68
+ PrivateKernelExecutionProver,
69
+ type PrivateKernelExecutionProverConfig,
70
+ } from './private_kernel/private_kernel_execution_prover.js';
71
+ import { PrivateKernelOracleImpl } from './private_kernel/private_kernel_oracle_impl.js';
72
+ import { AddressDataProvider } from './storage/address_data_provider/address_data_provider.js';
73
+ import { CapsuleDataProvider } from './storage/capsule_data_provider/capsule_data_provider.js';
74
+ import { ContractDataProvider } from './storage/contract_data_provider/contract_data_provider.js';
75
+ import { NoteDataProvider } from './storage/note_data_provider/note_data_provider.js';
76
+ import {
77
+ type PrivateEvent,
78
+ PrivateEventDataProvider,
79
+ } from './storage/private_event_data_provider/private_event_data_provider.js';
80
+ import { SyncDataProvider } from './storage/sync_data_provider/sync_data_provider.js';
81
+ import { TaggingDataProvider } from './storage/tagging_data_provider/tagging_data_provider.js';
82
+ import { Synchronizer } from './synchronizer/index.js';
83
+
84
+ /**
85
+ * Private eXecution Environment (PXE) is a library used by wallets to simulate private phase of transactions and to
86
+ * manage private state of users.
87
+ */
88
+ export class PXE {
89
+ private constructor(
90
+ private node: AztecNode,
91
+ private synchronizer: Synchronizer,
92
+ private keyStore: KeyStore,
93
+ private contractDataProvider: ContractDataProvider,
94
+ private noteDataProvider: NoteDataProvider,
95
+ private capsuleDataProvider: CapsuleDataProvider,
96
+ private syncDataProvider: SyncDataProvider,
97
+ private taggingDataProvider: TaggingDataProvider,
98
+ private addressDataProvider: AddressDataProvider,
99
+ private privateEventDataProvider: PrivateEventDataProvider,
100
+ private simulator: CircuitSimulator,
101
+ private proverEnabled: boolean,
102
+ private proofCreator: PrivateKernelProver,
103
+ private protocolContractsProvider: ProtocolContractsProvider,
104
+ private log: Logger,
105
+ private jobQueue: SerialQueue,
106
+ ) {}
107
+
108
+ /**
109
+ * Creates an instance of a PXE by instantiating all the necessary data providers and services.
110
+ * Also triggers the registration of the protocol contracts and makes sure the provided node
111
+ * can be contacted.
112
+ *
113
+ * @returns A promise that resolves PXE is ready to be used.
114
+ */
115
+ public static async create(
116
+ node: AztecNode,
117
+ store: AztecAsyncKVStore,
118
+ proofCreator: PrivateKernelProver,
119
+ simulator: CircuitSimulator,
120
+ protocolContractsProvider: ProtocolContractsProvider,
121
+ config: PXEConfig,
122
+ loggerOrSuffix?: string | Logger,
123
+ ) {
124
+ const log =
125
+ !loggerOrSuffix || typeof loggerOrSuffix === 'string'
126
+ ? createLogger(loggerOrSuffix ? `pxe:service:${loggerOrSuffix}` : `pxe:service`)
127
+ : loggerOrSuffix;
128
+
129
+ const proverEnabled = !!config.proverEnabled;
130
+ const addressDataProvider = new AddressDataProvider(store);
131
+ const privateEventDataProvider = new PrivateEventDataProvider(store);
132
+ const contractDataProvider = new ContractDataProvider(store);
133
+ const noteDataProvider = await NoteDataProvider.create(store);
134
+ const syncDataProvider = new SyncDataProvider(store);
135
+ const taggingDataProvider = new TaggingDataProvider(store);
136
+ const capsuleDataProvider = new CapsuleDataProvider(store);
137
+ const keyStore = new KeyStore(store);
138
+ const tipsStore = new L2TipsKVStore(store, 'pxe');
139
+ const synchronizer = new Synchronizer(
140
+ node,
141
+ syncDataProvider,
142
+ noteDataProvider,
143
+ taggingDataProvider,
144
+ tipsStore,
145
+ config,
146
+ loggerOrSuffix,
147
+ );
148
+
149
+ const jobQueue = new SerialQueue();
150
+
151
+ const pxe = new PXE(
152
+ node,
153
+ synchronizer,
154
+ keyStore,
155
+ contractDataProvider,
156
+ noteDataProvider,
157
+ capsuleDataProvider,
158
+ syncDataProvider,
159
+ taggingDataProvider,
160
+ addressDataProvider,
161
+ privateEventDataProvider,
162
+ simulator,
163
+ proverEnabled,
164
+ proofCreator,
165
+ protocolContractsProvider,
166
+ log,
167
+ jobQueue,
168
+ );
169
+
170
+ pxe.jobQueue.start();
171
+
172
+ await pxe.#registerProtocolContracts();
173
+ const info = await node.getNodeInfo();
174
+ log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.rollupVersion}`);
175
+ return pxe;
176
+ }
177
+
178
+ // Internal methods
179
+
180
+ #getSimulatorForTx(overrides?: { contracts?: ContractOverrides }) {
181
+ const pxeOracleInterface = new PXEOracleInterface(
182
+ ProxiedNodeFactory.create(this.node),
183
+ this.keyStore,
184
+ ProxiedContractDataProviderFactory.create(this.contractDataProvider, overrides?.contracts),
185
+ this.noteDataProvider,
186
+ this.capsuleDataProvider,
187
+ this.syncDataProvider,
188
+ this.taggingDataProvider,
189
+ this.addressDataProvider,
190
+ this.privateEventDataProvider,
191
+ this.log,
192
+ );
193
+ return new ContractFunctionSimulator(pxeOracleInterface, this.simulator);
194
+ }
195
+
196
+ #contextualizeError(err: Error, ...context: string[]): Error {
197
+ let contextStr = '';
198
+ if (context.length > 0) {
199
+ contextStr = `\nContext:\n${context.join('\n')}`;
200
+ }
201
+ if (err instanceof SimulationError) {
202
+ err.setAztecContext(contextStr);
203
+ } else {
204
+ this.log.error(err.name, err);
205
+ this.log.debug(contextStr);
206
+ }
207
+ return err;
208
+ }
209
+
210
+ /**
211
+ * Enqueues a job for execution once no other jobs are running. Returns a promise that will resolve once the job is
212
+ * complete.
213
+ *
214
+ * Useful for tasks that cannot run concurrently, such as contract function simulation.
215
+ */
216
+ #putInJobQueue<T>(fn: () => Promise<T>): Promise<T> {
217
+ // TODO(#12636): relax the conditions under which we forbid concurrency.
218
+ if (this.jobQueue.length() != 0) {
219
+ this.log.warn(
220
+ `PXE is already processing ${this.jobQueue.length()} jobs, concurrent execution is not supported. Will run once those are complete.`,
221
+ );
222
+ }
223
+
224
+ return this.jobQueue.put(fn);
225
+ }
226
+
227
+ async #registerProtocolContracts() {
228
+ const registered: Record<string, string> = {};
229
+ for (const name of protocolContractNames) {
230
+ const { address, contractClass, instance, artifact } =
231
+ await this.protocolContractsProvider.getProtocolContractArtifact(name);
232
+ await this.contractDataProvider.addContractArtifact(contractClass.id, artifact);
233
+ await this.contractDataProvider.addContractInstance(instance);
234
+ registered[name] = address.toString();
235
+ }
236
+ this.log.verbose(`Registered protocol contracts in pxe`, registered);
237
+ }
238
+
239
+ async #isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
240
+ return !!(await this.node.getContractClass(id));
241
+ }
242
+
243
+ async #isContractPublished(address: AztecAddress): Promise<boolean> {
244
+ return !!(await this.node.getContract(address));
245
+ }
246
+
247
+ async #isContractInitialized(address: AztecAddress): Promise<boolean> {
248
+ const initNullifier = await siloNullifier(address, address.toField());
249
+ return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
250
+ }
251
+
252
+ async #getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall> {
253
+ const contract = await this.contractDataProvider.getContract(to);
254
+ if (!contract) {
255
+ throw new Error(
256
+ `Unknown contract ${to}: add it to PXE by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/resources/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
257
+ );
258
+ }
259
+
260
+ const functionDao = contract.functions.find(f => f.name === functionName);
261
+ if (!functionDao) {
262
+ throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
263
+ }
264
+
265
+ return {
266
+ name: functionDao.name,
267
+ args: encodeArguments(functionDao, args),
268
+ selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
269
+ type: functionDao.functionType,
270
+ to,
271
+ hideMsgSender: false,
272
+ isStatic: functionDao.isStatic,
273
+ returnTypes: functionDao.returnTypes,
274
+ };
275
+ }
276
+
277
+ // Executes the entrypoint private function, as well as all nested private
278
+ // functions that might arise.
279
+ async #executePrivate(
280
+ contractFunctionSimulator: ContractFunctionSimulator,
281
+ txRequest: TxExecutionRequest,
282
+ scopes?: AztecAddress[],
283
+ ): Promise<PrivateExecutionResult> {
284
+ const { origin: contractAddress, functionSelector } = txRequest;
285
+
286
+ try {
287
+ const result = await contractFunctionSimulator.run(
288
+ txRequest,
289
+ contractAddress,
290
+ functionSelector,
291
+ undefined,
292
+ // The sender for tags is set by contracts, typically by an account
293
+ // contract entrypoint
294
+ undefined, // senderForTags
295
+ scopes,
296
+ );
297
+ this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
298
+ return result;
299
+ } catch (err) {
300
+ if (err instanceof SimulationError) {
301
+ await enrichSimulationError(err, this.contractDataProvider, this.log);
302
+ }
303
+ throw err;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Simulate a utility function call on the given contract.
309
+ * @param contractFunctionSimulator - The simulator to use for the function call.
310
+ * @param call - The function call to execute.
311
+ * @param authWitnesses - Authentication witnesses required for the function call.
312
+ * @param scopes - Optional array of account addresses whose notes can be accessed in this call. Defaults to all
313
+ * accounts if not specified.
314
+ * @returns The simulation result containing the outputs of the utility function.
315
+ */
316
+ async #simulateUtility(
317
+ contractFunctionSimulator: ContractFunctionSimulator,
318
+ call: FunctionCall,
319
+ authWitnesses?: AuthWitness[],
320
+ scopes?: AztecAddress[],
321
+ ) {
322
+ try {
323
+ return contractFunctionSimulator.runUtility(call, authWitnesses ?? [], scopes);
324
+ } catch (err) {
325
+ if (err instanceof SimulationError) {
326
+ await enrichSimulationError(err, this.contractDataProvider, this.log);
327
+ }
328
+ throw err;
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Simulate the public part of a transaction.
334
+ * This allows to catch public execution errors before submitting the transaction.
335
+ * It can also be used for estimating gas in the future.
336
+ * @param tx - The transaction to be simulated.
337
+ */
338
+ async #simulatePublicCalls(tx: Tx, skipFeeEnforcement: boolean) {
339
+ // Simulating public calls can throw if the TX fails in a phase that doesn't allow reverts (setup)
340
+ // Or return as reverted if it fails in a phase that allows reverts (app logic, teardown)
341
+ try {
342
+ const result = await this.node.simulatePublicCalls(tx, skipFeeEnforcement);
343
+ if (result.revertReason) {
344
+ throw result.revertReason;
345
+ }
346
+ return result;
347
+ } catch (err) {
348
+ if (err instanceof SimulationError) {
349
+ try {
350
+ await enrichPublicSimulationError(err, this.contractDataProvider, this.log);
351
+ } catch (enrichErr) {
352
+ this.log.error(`Failed to enrich public simulation error: ${enrichErr}`);
353
+ }
354
+ }
355
+ throw err;
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Generate a kernel proof, and create a private kernel output.
361
+ * The function takes in a transaction execution request, and the result of private execution
362
+ * and then generates a kernel proof.
363
+ *
364
+ * @param txExecutionRequest - The transaction request to be simulated and proved.
365
+ * @param proofCreator - The proof creator to use for proving the execution.
366
+ * @param privateExecutionResult - The result of the private execution
367
+ * @param config - The configuration for the kernel execution prover.
368
+ * @returns An object that contains the output of the kernel execution, including the ChonkProof if proving is enabled.
369
+ */
370
+ async #prove(
371
+ txExecutionRequest: TxExecutionRequest,
372
+ proofCreator: PrivateKernelProver,
373
+ privateExecutionResult: PrivateExecutionResult,
374
+ config: PrivateKernelExecutionProverConfig,
375
+ ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
376
+ const simulationAnchorBlock = privateExecutionResult.getSimulationAnchorBlockNumber();
377
+ const kernelOracle = new PrivateKernelOracleImpl(
378
+ this.contractDataProvider,
379
+ this.keyStore,
380
+ this.node,
381
+ simulationAnchorBlock,
382
+ );
383
+ const kernelTraceProver = new PrivateKernelExecutionProver(kernelOracle, proofCreator, !this.proverEnabled);
384
+ this.log.debug(`Executing kernel trace prover (${JSON.stringify(config)})...`);
385
+ return await kernelTraceProver.proveWithKernels(txExecutionRequest.toTxRequest(), privateExecutionResult, config);
386
+ }
387
+
388
+ // Public API
389
+
390
+ public getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
391
+ return this.contractDataProvider.getContractInstance(address);
392
+ }
393
+
394
+ /**
395
+ * Returns the contract class metadata given a contract class id.
396
+ * The metadata consists of its contract class, whether it has been publicly registered, and its artifact.
397
+ * @remark - it queries the node to check whether the contract class with the given id has been publicly registered.
398
+ * @param id - Identifier of the class.
399
+ * @param includeArtifact - Identifier of the class.
400
+ * @returns - It returns the contract class metadata, with the artifact field being optional, and will only be returned if true is passed in
401
+ * for `includeArtifact`
402
+ * TODO(@spalladino): The PXE actually holds artifacts and not classes, what should we return? Also,
403
+ * should the pxe query the node for contract public info, and merge it with its own definitions?
404
+ * TODO(@spalladino): This method is strictly needed to decide whether to publicly register a class or not
405
+ * during a public deployment. We probably want a nicer and more general API for this, but it'll have to
406
+ * do for the time being.
407
+ */
408
+ public async getContractClassMetadata(
409
+ id: Fr,
410
+ includeArtifact: boolean = false,
411
+ ): Promise<{
412
+ contractClass: ContractClassWithId | undefined;
413
+ isContractClassPubliclyRegistered: boolean;
414
+ artifact: ContractArtifact | undefined;
415
+ }> {
416
+ const artifact = await this.contractDataProvider.getContractArtifact(id);
417
+ if (!artifact) {
418
+ this.log.warn(`No artifact found for contract class ${id.toString()} when looking for its metadata`);
419
+ }
420
+
421
+ return {
422
+ contractClass: artifact && (await getContractClassFromArtifact(artifact)),
423
+ isContractClassPubliclyRegistered: await this.#isContractClassPubliclyRegistered(id),
424
+ artifact: includeArtifact ? artifact : undefined,
425
+ };
426
+ }
427
+
428
+ /**
429
+ * Returns the contract metadata given an address.
430
+ * The metadata consists of its contract instance, which includes the contract class identifier,
431
+ * initialization hash, deployment salt, and public keys hash; whether the contract instance has been initialized;
432
+ * and whether the contract instance with the given address has been publicly deployed.
433
+ * @remark - it queries the node to check whether the contract instance has been initialized / publicly deployed through a node.
434
+ * This query is not dependent on the PXE.
435
+ * @param address - The address that the contract instance resides at.
436
+ * @returns - It returns the contract metadata
437
+ * TODO(@spalladino): Should we return the public keys in plain as well here?
438
+ */
439
+ public async getContractMetadata(address: AztecAddress): Promise<{
440
+ contractInstance: ContractInstanceWithAddress | undefined;
441
+ isContractInitialized: boolean;
442
+ isContractPublished: boolean;
443
+ }> {
444
+ let instance;
445
+ try {
446
+ instance = await this.contractDataProvider.getContractInstance(address);
447
+ } catch {
448
+ this.log.warn(`No instance found for contract ${address.toString()} when looking for its metadata`);
449
+ }
450
+ return {
451
+ contractInstance: instance,
452
+ isContractInitialized: await this.#isContractInitialized(address),
453
+ isContractPublished: await this.#isContractPublished(address),
454
+ };
455
+ }
456
+
457
+ /**
458
+ * Registers a user account in PXE given its master encryption private key.
459
+ * Once a new account is registered, the PXE will trial-decrypt all published notes on
460
+ * the chain and store those that correspond to the registered account. Will do nothing if the
461
+ * account is already registered.
462
+ *
463
+ * @param secretKey - Secret key of the corresponding user master public key.
464
+ * @param partialAddress - The partial address of the account contract corresponding to the account being registered.
465
+ * @returns The complete address of the account.
466
+ */
467
+ public async registerAccount(secretKey: Fr, partialAddress: PartialAddress): Promise<CompleteAddress> {
468
+ const accounts = await this.keyStore.getAccounts();
469
+ const accountCompleteAddress = await this.keyStore.addAccount(secretKey, partialAddress);
470
+ if (accounts.includes(accountCompleteAddress.address)) {
471
+ this.log.info(`Account:\n "${accountCompleteAddress.address.toString()}"\n already registered.`);
472
+ return accountCompleteAddress;
473
+ } else {
474
+ this.log.info(`Registered account ${accountCompleteAddress.address.toString()}`);
475
+ this.log.debug(`Registered account\n ${accountCompleteAddress.toReadableString()}`);
476
+ }
477
+
478
+ await this.addressDataProvider.addCompleteAddress(accountCompleteAddress);
479
+ await this.noteDataProvider.addScope(accountCompleteAddress.address);
480
+ return accountCompleteAddress;
481
+ }
482
+
483
+ /**
484
+ * Registers a user contact in PXE.
485
+ *
486
+ * Once a new contact is registered, the PXE will be able to receive notes tagged from this contact.
487
+ * Will do nothing if the account is already registered.
488
+ *
489
+ * @param address - Address of the user to add to the address book
490
+ * @returns The address address of the account.
491
+ */
492
+ public async registerSender(address: AztecAddress): Promise<AztecAddress> {
493
+ const accounts = await this.keyStore.getAccounts();
494
+ if (accounts.includes(address)) {
495
+ this.log.info(`Sender:\n "${address.toString()}"\n already registered.`);
496
+ return address;
497
+ }
498
+
499
+ const wasAdded = await this.taggingDataProvider.addSenderAddress(address);
500
+
501
+ if (wasAdded) {
502
+ this.log.info(`Added sender:\n ${address.toString()}`);
503
+ } else {
504
+ this.log.info(`Sender:\n "${address.toString()}"\n already registered.`);
505
+ }
506
+
507
+ return address;
508
+ }
509
+
510
+ /**
511
+ * Retrieves the addresses stored as senders on this PXE.
512
+ * @returns An array of the senders on this PXE.
513
+ */
514
+ public getSenders(): Promise<AztecAddress[]> {
515
+ return this.taggingDataProvider.getSenderAddresses();
516
+ }
517
+
518
+ /**
519
+ * Removes a sender in the address book.
520
+ */
521
+ public async removeSender(address: AztecAddress): Promise<void> {
522
+ const wasRemoved = await this.taggingDataProvider.removeSenderAddress(address);
523
+
524
+ if (wasRemoved) {
525
+ this.log.info(`Removed sender:\n ${address.toString()}`);
526
+ } else {
527
+ this.log.info(`Sender:\n "${address.toString()}"\n not in address book.`);
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Retrieves the user accounts registered on this PXE.
533
+ * @returns An array of the accounts registered on this PXE.
534
+ */
535
+ public async getRegisteredAccounts(): Promise<CompleteAddress[]> {
536
+ // Get complete addresses of both the recipients and the accounts
537
+ const completeAddresses = await this.addressDataProvider.getCompleteAddresses();
538
+ // Filter out the addresses not corresponding to accounts
539
+ const accounts = await this.keyStore.getAccounts();
540
+ return completeAddresses.filter(completeAddress =>
541
+ accounts.find(address => address.equals(completeAddress.address)),
542
+ );
543
+ }
544
+
545
+ /**
546
+ * Registers a contract class in the PXE without registering any associated contract instance with it.
547
+ *
548
+ * @param artifact - The build artifact for the contract class.
549
+ */
550
+ public async registerContractClass(artifact: ContractArtifact): Promise<void> {
551
+ const { id: contractClassId } = await getContractClassFromArtifact(artifact);
552
+ await this.contractDataProvider.addContractArtifact(contractClassId, artifact);
553
+ this.log.info(`Added contract class ${artifact.name} with id ${contractClassId}`);
554
+ }
555
+
556
+ /**
557
+ * Adds deployed contracts to the PXE. Deployed contract information is used to access the
558
+ * contract code when simulating local transactions. This is automatically called by aztec.js when
559
+ * deploying a contract. Dapps that wish to interact with contracts already deployed should register
560
+ * these contracts in their users' PXE through this method.
561
+ *
562
+ * @param contract - A contract instance to register, with an optional artifact which can be omitted if the contract class has already been registered.
563
+ */
564
+ public async registerContract(contract: { instance: ContractInstanceWithAddress; artifact?: ContractArtifact }) {
565
+ const { instance } = contract;
566
+ let { artifact } = contract;
567
+
568
+ if (artifact) {
569
+ // If the user provides an artifact, validate it against the expected class id and register it
570
+ const contractClass = await getContractClassFromArtifact(artifact);
571
+ const contractClassId = contractClass.id;
572
+ if (!contractClassId.equals(instance.currentContractClassId)) {
573
+ throw new Error(
574
+ `Artifact does not match expected class id (computed ${contractClassId} but instance refers to ${instance.currentContractClassId})`,
575
+ );
576
+ }
577
+ const computedAddress = await computeContractAddressFromInstance(instance);
578
+ if (!computedAddress.equals(instance.address)) {
579
+ throw new Error('Added a contract in which the address does not match the contract instance.');
580
+ }
581
+ await this.contractDataProvider.addContractArtifact(contractClass.id, artifact);
582
+
583
+ const publicFunctionSignatures = artifact.functions
584
+ .filter(fn => fn.functionType === FunctionType.PUBLIC)
585
+ .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
586
+ await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
587
+ } else {
588
+ // Otherwise, make sure there is an artifact already registered for that class id
589
+ artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
590
+ if (!artifact) {
591
+ throw new Error(
592
+ `Artifact not found when registering an instance. Contract class: ${instance.currentContractClassId}.`,
593
+ );
594
+ }
595
+ }
596
+
597
+ await this.contractDataProvider.addContractInstance(instance);
598
+ this.log.info(
599
+ `Added contract ${artifact.name} at ${instance.address.toString()} with class ${instance.currentContractClassId}`,
600
+ );
601
+ }
602
+
603
+ /**
604
+ * Updates a deployed contract in the PXE. This is used to update the contract artifact when
605
+ * an update has happened, so the new code can be used in the simulation of local transactions.
606
+ * This is called by aztec.js when instantiating a contract in a given address with a mismatching artifact.
607
+ * @param contractAddress - The address of the contract to update.
608
+ * @param artifact - The updated artifact for the contract.
609
+ * @throws If the artifact's contract class is not found in the PXE or if the contract class is different from
610
+ * the current one (current one from the point of view of the node to which the PXE is connected).
611
+ */
612
+ public updateContract(contractAddress: AztecAddress, artifact: ContractArtifact): Promise<void> {
613
+ // We disable concurrently updating contracts to avoid concurrently syncing with the node, or changing a contract's
614
+ // class while we're simulating it.
615
+ return this.#putInJobQueue(async () => {
616
+ const currentInstance = await this.contractDataProvider.getContractInstance(contractAddress);
617
+ if (!currentInstance) {
618
+ throw new Error(`Instance not found when updating a contract. Contract address: ${contractAddress}.`);
619
+ }
620
+ const contractClass = await getContractClassFromArtifact(artifact);
621
+ await this.synchronizer.sync();
622
+
623
+ const header = await this.syncDataProvider.getBlockHeader();
624
+
625
+ const currentClassId = await readCurrentClassId(
626
+ contractAddress,
627
+ currentInstance,
628
+ this.node,
629
+ header.globalVariables.blockNumber,
630
+ header.globalVariables.timestamp,
631
+ );
632
+ if (!contractClass.id.equals(currentClassId)) {
633
+ throw new Error('Could not update contract to a class different from the current one.');
634
+ }
635
+
636
+ await this.contractDataProvider.addContractArtifact(contractClass.id, artifact);
637
+
638
+ const publicFunctionSignatures = artifact.functions
639
+ .filter(fn => fn.functionType === FunctionType.PUBLIC)
640
+ .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
641
+ await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
642
+
643
+ currentInstance.currentContractClassId = contractClass.id;
644
+ await this.contractDataProvider.addContractInstance(currentInstance);
645
+ this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
646
+ });
647
+ }
648
+
649
+ /**
650
+ * Retrieves the addresses of contracts added to this PXE.
651
+ * @returns An array of contracts addresses registered on this PXE.
652
+ */
653
+ public getContracts(): Promise<AztecAddress[]> {
654
+ return this.contractDataProvider.getContractsAddresses();
655
+ }
656
+
657
+ /**
658
+ * A debugging utility to get notes based on the provided filter.
659
+ *
660
+ * Note that this should not be used in production code because the structure of notes is considered to be
661
+ * an implementation detail of contracts. This is only meant to be used for debugging purposes. If you need to obtain
662
+ * note-related information in production code, please implement a custom utility function on your contract and call
663
+ * that function instead (e.g. `get_balance(owner: AztecAddress) -> u128` utility function on a Token contract).
664
+ *
665
+ * @param filter - The filter to apply to the notes.
666
+ * @returns The requested notes.
667
+ */
668
+ public async getNotes(filter: NotesFilter): Promise<UniqueNote[]> {
669
+ // We need to manually trigger private state sync to have a guarantee that all the notes are available.
670
+ await this.simulateUtility('sync_private_state', [], filter.contractAddress);
671
+
672
+ const noteDaos = await this.noteDataProvider.getNotes(filter);
673
+
674
+ const uniqueNotes = noteDaos.map(async dao => {
675
+ const completeAddresses = await this.addressDataProvider.getCompleteAddresses();
676
+ const completeAddressIndex = completeAddresses.findIndex(completeAddress =>
677
+ completeAddress.address.equals(dao.recipient),
678
+ );
679
+ const completeAddress = completeAddresses[completeAddressIndex];
680
+ if (completeAddress === undefined) {
681
+ throw new Error(`Cannot find complete address for recipient ${dao.recipient.toString()}`);
682
+ }
683
+ const recipient = completeAddress.address;
684
+ return new UniqueNote(dao.note, recipient, dao.contractAddress, dao.storageSlot, dao.txHash, dao.noteNonce);
685
+ });
686
+ return Promise.all(uniqueNotes);
687
+ }
688
+
689
+ /**
690
+ * Proves the private portion of a simulated transaction, ready to send to the network
691
+ * (where validators prove the public portion).
692
+ *
693
+ * @param txRequest - An authenticated tx request ready for proving
694
+ * @returns A result containing the proof and public inputs of the tail circuit.
695
+ * @throws If contract code not found, or public simulation reverts.
696
+ * Also throws if simulatePublic is true and public simulation reverts.
697
+ */
698
+ public proveTx(txRequest: TxExecutionRequest): Promise<TxProvingResult> {
699
+ let privateExecutionResult: PrivateExecutionResult;
700
+ // We disable proving concurrently mostly out of caution, since it accesses some of our stores. Proving is so
701
+ // computationally demanding that it'd be rare for someone to try to do it concurrently regardless.
702
+ return this.#putInJobQueue(async () => {
703
+ const totalTimer = new Timer();
704
+ try {
705
+ const syncTimer = new Timer();
706
+ await this.synchronizer.sync();
707
+ const syncTime = syncTimer.ms();
708
+ const contractFunctionSimulator = this.#getSimulatorForTx();
709
+ privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest);
710
+
711
+ const {
712
+ publicInputs,
713
+ chonkProof,
714
+ executionSteps,
715
+ timings: { proving } = {},
716
+ } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
717
+ simulate: false,
718
+ skipFeeEnforcement: false,
719
+ profileMode: 'none',
720
+ });
721
+
722
+ const totalTime = totalTimer.ms();
723
+
724
+ const perFunction = executionSteps.map(({ functionName, timings: { witgen, oracles } }) => ({
725
+ functionName,
726
+ time: witgen,
727
+ oracles,
728
+ }));
729
+
730
+ const timings: ProvingTimings = {
731
+ total: totalTime,
732
+ sync: syncTime,
733
+ proving,
734
+ perFunction,
735
+ unaccounted:
736
+ totalTime - ((syncTime ?? 0) + (proving ?? 0) + perFunction.reduce((acc, { time }) => acc + time, 0)),
737
+ };
738
+
739
+ this.log.debug(`Proving completed in ${totalTime}ms`, { timings });
740
+
741
+ const txProvingResult = new TxProvingResult(privateExecutionResult, publicInputs, chonkProof!, {
742
+ timings,
743
+ nodeRPCCalls: contractFunctionSimulator?.getStats().nodeRPCCalls,
744
+ });
745
+
746
+ const preTagsUsedInTheTx = privateExecutionResult.entrypoint.preTags;
747
+ if (preTagsUsedInTheTx.length > 0) {
748
+ await this.taggingDataProvider.setLastUsedIndexesAsSender(preTagsUsedInTheTx);
749
+ this.log.debug(`Stored used pre tags as sender for the tx`, {
750
+ preTagsUsedInTheTx,
751
+ });
752
+ } else {
753
+ this.log.debug(`No pre tags used in the tx`);
754
+ }
755
+
756
+ return txProvingResult;
757
+ } catch (err: any) {
758
+ throw this.#contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
759
+ }
760
+ });
761
+ }
762
+
763
+ /**
764
+ * Profiles a transaction, reporting gate counts (unless disabled) and returns an execution trace.
765
+ *
766
+ * @param txRequest - An authenticated tx request ready for simulation
767
+ * @param msgSender - (Optional) The message sender to use for the simulation.
768
+ * @param skipTxValidation - (Optional) If false, this function throws if the transaction is unable to be included in a block at the current state.
769
+ * @returns A trace of the program execution with gate counts.
770
+ * @throws If the code for the functions executed in this transaction have not been made available via `addContracts`.
771
+ */
772
+ public profileTx(
773
+ txRequest: TxExecutionRequest,
774
+ profileMode: 'full' | 'execution-steps' | 'gates',
775
+ skipProofGeneration: boolean = true,
776
+ ): Promise<TxProfileResult> {
777
+ // We disable concurrent profiles for consistency with simulateTx.
778
+ return this.#putInJobQueue(async () => {
779
+ const totalTimer = new Timer();
780
+ try {
781
+ const txInfo = {
782
+ origin: txRequest.origin,
783
+ functionSelector: txRequest.functionSelector,
784
+ simulatePublic: false,
785
+ chainId: txRequest.txContext.chainId,
786
+ version: txRequest.txContext.version,
787
+ authWitnesses: txRequest.authWitnesses.map(w => w.requestHash),
788
+ };
789
+ this.log.info(
790
+ `Profiling transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
791
+ txInfo,
792
+ );
793
+ const syncTimer = new Timer();
794
+ await this.synchronizer.sync();
795
+ const syncTime = syncTimer.ms();
796
+
797
+ const contractFunctionSimulator = this.#getSimulatorForTx();
798
+ const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest);
799
+
800
+ const { executionSteps, timings: { proving } = {} } = await this.#prove(
801
+ txRequest,
802
+ this.proofCreator,
803
+ privateExecutionResult,
804
+ {
805
+ simulate: skipProofGeneration,
806
+ skipFeeEnforcement: false,
807
+ profileMode,
808
+ },
809
+ );
810
+
811
+ const totalTime = totalTimer.ms();
812
+
813
+ const perFunction = executionSteps.map(({ functionName, timings: { witgen, oracles } }) => {
814
+ return {
815
+ functionName,
816
+ time: witgen,
817
+ oracles,
818
+ };
819
+ });
820
+
821
+ // Gate computation is time is not relevant for profiling, so we subtract it from the total time.
822
+ const gateCountComputationTime =
823
+ executionSteps.reduce((acc, { timings }) => acc + (timings.gateCount ?? 0), 0) ?? 0;
824
+
825
+ const total = totalTime - gateCountComputationTime;
826
+
827
+ const timings: ProvingTimings = {
828
+ total,
829
+ sync: syncTime,
830
+ proving,
831
+ perFunction,
832
+ unaccounted:
833
+ total - ((syncTime ?? 0) + (proving ?? 0) + perFunction.reduce((acc, { time }) => acc + time, 0)),
834
+ };
835
+
836
+ const simulatorStats = contractFunctionSimulator.getStats();
837
+ return new TxProfileResult(executionSteps, { timings, nodeRPCCalls: simulatorStats.nodeRPCCalls });
838
+ } catch (err: any) {
839
+ throw this.#contextualizeError(err, inspect(txRequest), `profileMode=${profileMode}`);
840
+ }
841
+ });
842
+ }
843
+
844
+ /**
845
+ * Simulates a transaction based on the provided preauthenticated execution request.
846
+ * This will run a local simulation of private execution (and optionally of public as well), run the
847
+ * kernel circuits to ensure adherence to protocol rules (without generating a proof), and return the
848
+ * simulation results .
849
+ *
850
+ *
851
+ * Note that this is used with `ContractFunctionInteraction::simulateTx` to bypass certain checks.
852
+ * In that case, the transaction returned is only potentially ready to be sent to the network for execution.
853
+ *
854
+ *
855
+ * @param txRequest - An authenticated tx request ready for simulation
856
+ * @param simulatePublic - Whether to simulate the public part of the transaction.
857
+ * @param skipTxValidation - (Optional) If false, this function throws if the transaction is unable to be included in a block at the current state.
858
+ * @param skipFeeEnforcement - (Optional) If false, fees are enforced.
859
+ * @param overrides - (Optional) State overrides for the simulation, such as msgSender, contract instances and artifacts.
860
+ * @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will default to all.
861
+ * @returns A simulated transaction result object that includes public and private return values.
862
+ * @throws If the code for the functions executed in this transaction have not been made available via `addContracts`.
863
+ * Also throws if simulatePublic is true and public simulation reverts.
864
+ *
865
+ * TODO(#7456) Prevent msgSender being defined here for the first call
866
+ */
867
+ public simulateTx(
868
+ txRequest: TxExecutionRequest,
869
+ simulatePublic: boolean,
870
+ skipTxValidation: boolean = false,
871
+ skipFeeEnforcement: boolean = false,
872
+ overrides?: SimulationOverrides,
873
+ scopes?: AztecAddress[],
874
+ ): Promise<TxSimulationResult> {
875
+ // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
876
+ // to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
877
+ // delete the same read value, or reading values that another simulation is currently modifying).
878
+ return this.#putInJobQueue(async () => {
879
+ try {
880
+ const totalTimer = new Timer();
881
+ const txInfo = {
882
+ origin: txRequest.origin,
883
+ functionSelector: txRequest.functionSelector,
884
+ simulatePublic,
885
+ chainId: txRequest.txContext.chainId,
886
+ version: txRequest.txContext.version,
887
+ authWitnesses: txRequest.authWitnesses.map(w => w.requestHash),
888
+ };
889
+ this.log.info(
890
+ `Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
891
+ txInfo,
892
+ );
893
+ const syncTimer = new Timer();
894
+ await this.synchronizer.sync();
895
+ const syncTime = syncTimer.ms();
896
+
897
+ const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
898
+ // Temporary: in case there are overrides, we have to skip the kernels or validations
899
+ // will fail. Consider handing control to the user/wallet on whether they want to run them
900
+ // or not.
901
+ const skipKernels = overrides?.contracts !== undefined && Object.keys(overrides.contracts ?? {}).length > 0;
902
+
903
+ // Execution of private functions only; no proving, and no kernel logic.
904
+ const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, scopes);
905
+
906
+ let publicInputs: PrivateKernelTailCircuitPublicInputs | undefined;
907
+ let executionSteps: PrivateExecutionStep[] = [];
908
+
909
+ if (skipKernels) {
910
+ // According to the protocol rules, the nonce generator for the note hashes
911
+ // can either be the first nullifier in the tx or the hash of the initial tx request
912
+ // if there are none.
913
+ const nonceGenerator = privateExecutionResult.firstNullifier.equals(Fr.ZERO)
914
+ ? await txRequest.toTxRequest().hash()
915
+ : privateExecutionResult.firstNullifier;
916
+ ({ publicInputs, executionSteps } = await generateSimulatedProvingResult(
917
+ privateExecutionResult,
918
+ nonceGenerator,
919
+ this.contractDataProvider,
920
+ ));
921
+ } else {
922
+ // Kernel logic, plus proving of all private functions and kernels.
923
+ ({ publicInputs, executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
924
+ simulate: true,
925
+ skipFeeEnforcement,
926
+ profileMode: 'none',
927
+ }));
928
+ }
929
+
930
+ const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
931
+ const simulatedTx = await privateSimulationResult.toSimulatedTx();
932
+ let publicSimulationTime: number | undefined;
933
+ let publicOutput: PublicSimulationOutput | undefined;
934
+ if (simulatePublic && publicInputs.forPublic) {
935
+ const publicSimulationTimer = new Timer();
936
+ publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
937
+ publicSimulationTime = publicSimulationTimer.ms();
938
+ }
939
+
940
+ let validationTime: number | undefined;
941
+ if (!skipTxValidation) {
942
+ const validationTimer = new Timer();
943
+ const validationResult = await this.node.isValidTx(simulatedTx, { isSimulation: true, skipFeeEnforcement });
944
+ validationTime = validationTimer.ms();
945
+ if (validationResult.result === 'invalid') {
946
+ throw new Error('The simulated transaction is unable to be added to state and is invalid.');
947
+ }
948
+ }
949
+
950
+ const txHash = simulatedTx.getTxHash();
951
+
952
+ const totalTime = totalTimer.ms();
953
+
954
+ const perFunction = executionSteps.map(({ functionName, timings: { witgen, oracles } }) => ({
955
+ functionName,
956
+ time: witgen,
957
+ oracles,
958
+ }));
959
+
960
+ const timings: SimulationTimings = {
961
+ total: totalTime,
962
+ sync: syncTime,
963
+ publicSimulation: publicSimulationTime,
964
+ validation: validationTime,
965
+ perFunction,
966
+ unaccounted:
967
+ totalTime -
968
+ (syncTime +
969
+ (publicSimulationTime ?? 0) +
970
+ (validationTime ?? 0) +
971
+ perFunction.reduce((acc, { time }) => acc + time, 0)),
972
+ };
973
+
974
+ this.log.info(`Simulation completed for ${txHash.toString()} in ${totalTime}ms`, {
975
+ txHash,
976
+ ...txInfo,
977
+ ...(publicOutput
978
+ ? {
979
+ gasUsed: publicOutput.gasUsed,
980
+ revertCode: publicOutput.txEffect.revertCode.getCode(),
981
+ revertReason: publicOutput.revertReason,
982
+ }
983
+ : {}),
984
+ });
985
+
986
+ const simulatorStats = contractFunctionSimulator.getStats();
987
+ return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput, {
988
+ timings,
989
+ nodeRPCCalls: simulatorStats.nodeRPCCalls,
990
+ });
991
+ } catch (err: any) {
992
+ throw this.#contextualizeError(
993
+ err,
994
+ inspect(txRequest),
995
+ `simulatePublic=${simulatePublic}`,
996
+ `skipTxValidation=${skipTxValidation}`,
997
+ `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
998
+ );
999
+ }
1000
+ });
1001
+ }
1002
+
1003
+ /**
1004
+ * Simulate the execution of a contract utility function.
1005
+ *
1006
+ * @param functionName - The name of the utility contract function to be called.
1007
+ * @param args - The arguments to be provided to the function.
1008
+ * @param to - The address of the contract to be called.
1009
+ * @param authwits - (Optional) The authentication witnesses required for the function call.
1010
+ * @param from - (Optional) The msg sender to set for the call.
1011
+ * @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will
1012
+ * default to all.
1013
+ * @returns The result of the utility function call, structured based on the function ABI.
1014
+ */
1015
+ public simulateUtility(
1016
+ functionName: string,
1017
+ args: any[],
1018
+ to: AztecAddress,
1019
+ authwits?: AuthWitness[],
1020
+ _from?: AztecAddress,
1021
+ scopes?: AztecAddress[],
1022
+ ): Promise<UtilitySimulationResult> {
1023
+ // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
1024
+ // to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
1025
+ // delete the same read value, or reading values that another simulation is currently modifying).
1026
+ return this.#putInJobQueue(async () => {
1027
+ try {
1028
+ const totalTimer = new Timer();
1029
+ const syncTimer = new Timer();
1030
+ await this.synchronizer.sync();
1031
+ const syncTime = syncTimer.ms();
1032
+ const functionCall = await this.#getFunctionCall(functionName, args, to);
1033
+ const functionTimer = new Timer();
1034
+ const contractFunctionSimulator = this.#getSimulatorForTx();
1035
+ const executionResult = await this.#simulateUtility(
1036
+ contractFunctionSimulator,
1037
+ functionCall,
1038
+ authwits ?? [],
1039
+ scopes,
1040
+ );
1041
+ const functionTime = functionTimer.ms();
1042
+
1043
+ const totalTime = totalTimer.ms();
1044
+
1045
+ const perFunction = [{ functionName, time: functionTime }];
1046
+
1047
+ const timings: SimulationTimings = {
1048
+ total: totalTime,
1049
+ sync: syncTime,
1050
+ perFunction,
1051
+ unaccounted: totalTime - (syncTime + perFunction.reduce((acc, { time }) => acc + time, 0)),
1052
+ };
1053
+
1054
+ const simulationStats = contractFunctionSimulator.getStats();
1055
+ return { result: executionResult, stats: { timings, nodeRPCCalls: simulationStats.nodeRPCCalls } };
1056
+ } catch (err: any) {
1057
+ const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
1058
+ throw this.#contextualizeError(
1059
+ err,
1060
+ `simulateUtility ${to}:${functionName}(${stringifiedArgs})`,
1061
+ `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
1062
+ );
1063
+ }
1064
+ });
1065
+ }
1066
+
1067
+ /**
1068
+ * Returns the private events given search parameters.
1069
+ * @param contractAddress - The address of the contract to get events from.
1070
+ * @param eventMetadata - Metadata of the event. This should be the class generated from the contract. e.g. Contract.events.Event
1071
+ * @param from - The block number to search from.
1072
+ * @param numBlocks - The amount of blocks to search.
1073
+ * @param recipients - The addresses that decrypted the logs.
1074
+ * @returns - The deserialized events.
1075
+ */
1076
+ public async getPrivateEvents<T>(
1077
+ contractAddress: AztecAddress,
1078
+ eventMetadataDef: EventMetadataDefinition,
1079
+ from: number,
1080
+ numBlocks: number,
1081
+ recipients: AztecAddress[],
1082
+ ): Promise<T[]> {
1083
+ if (recipients.length === 0) {
1084
+ throw new Error('Recipients are required to get private events');
1085
+ }
1086
+
1087
+ this.log.verbose(`Getting private events for ${contractAddress.toString()} from ${from} to ${from + numBlocks}`);
1088
+
1089
+ // We need to manually trigger private state sync to have a guarantee that all the events are available.
1090
+ await this.simulateUtility('sync_private_state', [], contractAddress);
1091
+
1092
+ const events = await this.privateEventDataProvider.getPrivateEvents(
1093
+ contractAddress,
1094
+ from,
1095
+ numBlocks,
1096
+ recipients,
1097
+ eventMetadataDef.eventSelector,
1098
+ );
1099
+
1100
+ const decodedEvents = events.map(
1101
+ (event: PrivateEvent): T => decodeFromAbi([eventMetadataDef.abiType], event.msgContent) as T,
1102
+ );
1103
+
1104
+ return decodedEvents;
1105
+ }
1106
+
1107
+ /**
1108
+ * Stops the PXE's job queue.
1109
+ */
1110
+ public stop(): Promise<void> {
1111
+ return this.jobQueue.end();
1112
+ }
1113
+ }