chia-blockchain 2.5.1rc1__py3-none-any.whl

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 (1042) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +195 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +145 -0
  9. chia/_tests/blockchain/test_blockchain.py +4202 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
  11. chia/_tests/blockchain/test_build_chains.py +59 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
  14. chia/_tests/build-init-files.py +92 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +72 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +149 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +55 -0
  26. chia/_tests/clvm/test_message_conditions.py +184 -0
  27. chia/_tests/clvm/test_program.py +150 -0
  28. chia/_tests/clvm/test_puzzle_compression.py +143 -0
  29. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  30. chia/_tests/clvm/test_puzzles.py +242 -0
  31. chia/_tests/clvm/test_singletons.py +540 -0
  32. chia/_tests/clvm/test_spend_sim.py +181 -0
  33. chia/_tests/cmds/__init__.py +0 -0
  34. chia/_tests/cmds/cmd_test_utils.py +469 -0
  35. chia/_tests/cmds/config.py +3 -0
  36. chia/_tests/cmds/conftest.py +23 -0
  37. chia/_tests/cmds/test_click_types.py +200 -0
  38. chia/_tests/cmds/test_cmd_framework.py +620 -0
  39. chia/_tests/cmds/test_cmds_util.py +97 -0
  40. chia/_tests/cmds/test_daemon.py +92 -0
  41. chia/_tests/cmds/test_dev_gh.py +131 -0
  42. chia/_tests/cmds/test_farm_cmd.py +66 -0
  43. chia/_tests/cmds/test_show.py +116 -0
  44. chia/_tests/cmds/test_sim.py +207 -0
  45. chia/_tests/cmds/test_timelock_args.py +75 -0
  46. chia/_tests/cmds/test_tx_config_args.py +154 -0
  47. chia/_tests/cmds/testing_classes.py +59 -0
  48. chia/_tests/cmds/wallet/__init__.py +0 -0
  49. chia/_tests/cmds/wallet/test_consts.py +47 -0
  50. chia/_tests/cmds/wallet/test_dao.py +565 -0
  51. chia/_tests/cmds/wallet/test_did.py +403 -0
  52. chia/_tests/cmds/wallet/test_nft.py +471 -0
  53. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  54. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  55. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  56. chia/_tests/cmds/wallet/test_vcs.py +400 -0
  57. chia/_tests/cmds/wallet/test_wallet.py +1125 -0
  58. chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
  59. chia/_tests/conftest.py +1419 -0
  60. chia/_tests/connection_utils.py +125 -0
  61. chia/_tests/core/__init__.py +0 -0
  62. chia/_tests/core/cmds/__init__.py +0 -0
  63. chia/_tests/core/cmds/test_beta.py +382 -0
  64. chia/_tests/core/cmds/test_keys.py +1734 -0
  65. chia/_tests/core/cmds/test_wallet.py +126 -0
  66. chia/_tests/core/config.py +3 -0
  67. chia/_tests/core/consensus/__init__.py +0 -0
  68. chia/_tests/core/consensus/test_block_creation.py +54 -0
  69. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  70. chia/_tests/core/custom_types/__init__.py +0 -0
  71. chia/_tests/core/custom_types/test_coin.py +107 -0
  72. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  73. chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
  74. chia/_tests/core/daemon/__init__.py +0 -0
  75. chia/_tests/core/daemon/config.py +4 -0
  76. chia/_tests/core/daemon/test_daemon.py +2128 -0
  77. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  78. chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
  79. chia/_tests/core/data_layer/__init__.py +0 -0
  80. chia/_tests/core/data_layer/config.py +5 -0
  81. chia/_tests/core/data_layer/conftest.py +106 -0
  82. chia/_tests/core/data_layer/test_data_cli.py +56 -0
  83. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  84. chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
  85. chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
  86. chia/_tests/core/data_layer/test_data_store.py +2424 -0
  87. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  88. chia/_tests/core/data_layer/test_plugin.py +91 -0
  89. chia/_tests/core/data_layer/util.py +233 -0
  90. chia/_tests/core/farmer/__init__.py +0 -0
  91. chia/_tests/core/farmer/config.py +3 -0
  92. chia/_tests/core/farmer/test_farmer_api.py +103 -0
  93. chia/_tests/core/full_node/__init__.py +0 -0
  94. chia/_tests/core/full_node/config.py +4 -0
  95. chia/_tests/core/full_node/dos/__init__.py +0 -0
  96. chia/_tests/core/full_node/dos/config.py +3 -0
  97. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  98. chia/_tests/core/full_node/full_sync/config.py +4 -0
  99. chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
  100. chia/_tests/core/full_node/ram_db.py +27 -0
  101. chia/_tests/core/full_node/stores/__init__.py +0 -0
  102. chia/_tests/core/full_node/stores/config.py +4 -0
  103. chia/_tests/core/full_node/stores/test_block_store.py +590 -0
  104. chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
  105. chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
  106. chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
  107. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  108. chia/_tests/core/full_node/test_address_manager.py +588 -0
  109. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  110. chia/_tests/core/full_node/test_conditions.py +556 -0
  111. chia/_tests/core/full_node/test_full_node.py +2700 -0
  112. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  113. chia/_tests/core/full_node/test_hint_management.py +104 -0
  114. chia/_tests/core/full_node/test_node_load.py +34 -0
  115. chia/_tests/core/full_node/test_performance.py +179 -0
  116. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  117. chia/_tests/core/full_node/test_transactions.py +203 -0
  118. chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
  119. chia/_tests/core/large_block.py +2388 -0
  120. chia/_tests/core/make_block_generator.py +70 -0
  121. chia/_tests/core/mempool/__init__.py +0 -0
  122. chia/_tests/core/mempool/config.py +4 -0
  123. chia/_tests/core/mempool/test_mempool.py +3255 -0
  124. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  125. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  126. chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
  127. chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
  128. chia/_tests/core/mempool/test_mempool_performance.py +64 -0
  129. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  130. chia/_tests/core/node_height.py +28 -0
  131. chia/_tests/core/server/__init__.py +0 -0
  132. chia/_tests/core/server/config.py +3 -0
  133. chia/_tests/core/server/flood.py +84 -0
  134. chia/_tests/core/server/serve.py +135 -0
  135. chia/_tests/core/server/test_api_protocol.py +21 -0
  136. chia/_tests/core/server/test_capabilities.py +66 -0
  137. chia/_tests/core/server/test_dos.py +319 -0
  138. chia/_tests/core/server/test_event_loop.py +109 -0
  139. chia/_tests/core/server/test_loop.py +294 -0
  140. chia/_tests/core/server/test_node_discovery.py +73 -0
  141. chia/_tests/core/server/test_rate_limits.py +482 -0
  142. chia/_tests/core/server/test_server.py +226 -0
  143. chia/_tests/core/server/test_upnp.py +8 -0
  144. chia/_tests/core/services/__init__.py +0 -0
  145. chia/_tests/core/services/config.py +3 -0
  146. chia/_tests/core/services/test_services.py +188 -0
  147. chia/_tests/core/ssl/__init__.py +0 -0
  148. chia/_tests/core/ssl/config.py +3 -0
  149. chia/_tests/core/ssl/test_ssl.py +202 -0
  150. chia/_tests/core/test_coins.py +33 -0
  151. chia/_tests/core/test_cost_calculation.py +313 -0
  152. chia/_tests/core/test_crawler.py +175 -0
  153. chia/_tests/core/test_crawler_rpc.py +53 -0
  154. chia/_tests/core/test_daemon_rpc.py +24 -0
  155. chia/_tests/core/test_db_conversion.py +130 -0
  156. chia/_tests/core/test_db_validation.py +162 -0
  157. chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
  158. chia/_tests/core/test_filter.py +35 -0
  159. chia/_tests/core/test_full_node_rpc.py +768 -0
  160. chia/_tests/core/test_merkle_set.py +343 -0
  161. chia/_tests/core/test_program.py +47 -0
  162. chia/_tests/core/test_rpc_util.py +86 -0
  163. chia/_tests/core/test_seeder.py +420 -0
  164. chia/_tests/core/test_setproctitle.py +13 -0
  165. chia/_tests/core/util/__init__.py +0 -0
  166. chia/_tests/core/util/config.py +4 -0
  167. chia/_tests/core/util/test_block_cache.py +44 -0
  168. chia/_tests/core/util/test_cached_bls.py +57 -0
  169. chia/_tests/core/util/test_config.py +337 -0
  170. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  171. chia/_tests/core/util/test_files.py +391 -0
  172. chia/_tests/core/util/test_jsonify.py +146 -0
  173. chia/_tests/core/util/test_keychain.py +522 -0
  174. chia/_tests/core/util/test_keyring_wrapper.py +491 -0
  175. chia/_tests/core/util/test_lockfile.py +380 -0
  176. chia/_tests/core/util/test_log_exceptions.py +187 -0
  177. chia/_tests/core/util/test_lru_cache.py +56 -0
  178. chia/_tests/core/util/test_significant_bits.py +40 -0
  179. chia/_tests/core/util/test_streamable.py +883 -0
  180. chia/_tests/db/__init__.py +0 -0
  181. chia/_tests/db/test_db_wrapper.py +566 -0
  182. chia/_tests/environments/__init__.py +0 -0
  183. chia/_tests/environments/common.py +35 -0
  184. chia/_tests/environments/full_node.py +47 -0
  185. chia/_tests/environments/wallet.py +429 -0
  186. chia/_tests/ether.py +19 -0
  187. chia/_tests/farmer_harvester/__init__.py +0 -0
  188. chia/_tests/farmer_harvester/config.py +3 -0
  189. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  190. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  191. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
  192. chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
  193. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  194. chia/_tests/fee_estimation/__init__.py +0 -0
  195. chia/_tests/fee_estimation/config.py +3 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  197. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  198. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
  199. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  200. chia/_tests/generator/__init__.py +0 -0
  201. chia/_tests/generator/puzzles/__init__.py +0 -0
  202. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  203. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  204. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  205. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  206. chia/_tests/generator/test_compression.py +201 -0
  207. chia/_tests/generator/test_generator_types.py +44 -0
  208. chia/_tests/generator/test_rom.py +180 -0
  209. chia/_tests/plot_sync/__init__.py +0 -0
  210. chia/_tests/plot_sync/config.py +3 -0
  211. chia/_tests/plot_sync/test_delta.py +101 -0
  212. chia/_tests/plot_sync/test_plot_sync.py +618 -0
  213. chia/_tests/plot_sync/test_receiver.py +451 -0
  214. chia/_tests/plot_sync/test_sender.py +116 -0
  215. chia/_tests/plot_sync/test_sync_simulated.py +451 -0
  216. chia/_tests/plot_sync/util.py +68 -0
  217. chia/_tests/plotting/__init__.py +0 -0
  218. chia/_tests/plotting/config.py +3 -0
  219. chia/_tests/plotting/test_plot_manager.py +781 -0
  220. chia/_tests/plotting/util.py +12 -0
  221. chia/_tests/pools/__init__.py +0 -0
  222. chia/_tests/pools/config.py +5 -0
  223. chia/_tests/pools/test_pool_cli_parsing.py +128 -0
  224. chia/_tests/pools/test_pool_cmdline.py +1001 -0
  225. chia/_tests/pools/test_pool_config.py +42 -0
  226. chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
  227. chia/_tests/pools/test_pool_rpc.py +1123 -0
  228. chia/_tests/pools/test_pool_wallet.py +205 -0
  229. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  230. chia/_tests/process_junit.py +348 -0
  231. chia/_tests/rpc/__init__.py +0 -0
  232. chia/_tests/rpc/test_rpc_client.py +138 -0
  233. chia/_tests/rpc/test_rpc_server.py +183 -0
  234. chia/_tests/simulation/__init__.py +0 -0
  235. chia/_tests/simulation/config.py +6 -0
  236. chia/_tests/simulation/test_simulation.py +501 -0
  237. chia/_tests/simulation/test_simulator.py +232 -0
  238. chia/_tests/simulation/test_start_simulator.py +107 -0
  239. chia/_tests/testconfig.py +13 -0
  240. chia/_tests/timelord/__init__.py +0 -0
  241. chia/_tests/timelord/config.py +3 -0
  242. chia/_tests/timelord/test_new_peak.py +437 -0
  243. chia/_tests/timelord/test_timelord.py +11 -0
  244. chia/_tests/tools/1315537.json +170 -0
  245. chia/_tests/tools/1315544.json +160 -0
  246. chia/_tests/tools/1315630.json +150 -0
  247. chia/_tests/tools/300000.json +105 -0
  248. chia/_tests/tools/442734.json +140 -0
  249. chia/_tests/tools/466212.json +130 -0
  250. chia/_tests/tools/__init__.py +0 -0
  251. chia/_tests/tools/config.py +5 -0
  252. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  253. chia/_tests/tools/test_full_sync.py +30 -0
  254. chia/_tests/tools/test_legacy_keyring.py +82 -0
  255. chia/_tests/tools/test_run_block.py +128 -0
  256. chia/_tests/tools/test_virtual_project.py +591 -0
  257. chia/_tests/util/__init__.py +0 -0
  258. chia/_tests/util/benchmark_cost.py +170 -0
  259. chia/_tests/util/benchmarks.py +153 -0
  260. chia/_tests/util/bip39_test_vectors.json +148 -0
  261. chia/_tests/util/blockchain.py +134 -0
  262. chia/_tests/util/blockchain_mock.py +132 -0
  263. chia/_tests/util/build_network_protocol_files.py +302 -0
  264. chia/_tests/util/clvm_generator.bin +0 -0
  265. chia/_tests/util/config.py +3 -0
  266. chia/_tests/util/constants.py +20 -0
  267. chia/_tests/util/db_connection.py +37 -0
  268. chia/_tests/util/full_sync.py +253 -0
  269. chia/_tests/util/gen_ssl_certs.py +114 -0
  270. chia/_tests/util/generator_tools_testing.py +45 -0
  271. chia/_tests/util/get_name_puzzle_conditions.py +52 -0
  272. chia/_tests/util/key_tool.py +36 -0
  273. chia/_tests/util/misc.py +675 -0
  274. chia/_tests/util/network_protocol_data.py +1072 -0
  275. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  276. chia/_tests/util/protocol_messages_json.py +2701 -0
  277. chia/_tests/util/rpc.py +26 -0
  278. chia/_tests/util/run_block.py +163 -0
  279. chia/_tests/util/setup_nodes.py +481 -0
  280. chia/_tests/util/spend_sim.py +492 -0
  281. chia/_tests/util/split_managers.py +102 -0
  282. chia/_tests/util/temp_file.py +14 -0
  283. chia/_tests/util/test_action_scope.py +144 -0
  284. chia/_tests/util/test_async_pool.py +366 -0
  285. chia/_tests/util/test_build_job_matrix.py +42 -0
  286. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  287. chia/_tests/util/test_chia_version.py +50 -0
  288. chia/_tests/util/test_collection.py +11 -0
  289. chia/_tests/util/test_condition_tools.py +229 -0
  290. chia/_tests/util/test_config.py +426 -0
  291. chia/_tests/util/test_dump_keyring.py +60 -0
  292. chia/_tests/util/test_errors.py +10 -0
  293. chia/_tests/util/test_full_block_utils.py +279 -0
  294. chia/_tests/util/test_installed.py +20 -0
  295. chia/_tests/util/test_limited_semaphore.py +53 -0
  296. chia/_tests/util/test_logging_filter.py +42 -0
  297. chia/_tests/util/test_misc.py +445 -0
  298. chia/_tests/util/test_network.py +73 -0
  299. chia/_tests/util/test_network_protocol_files.py +578 -0
  300. chia/_tests/util/test_network_protocol_json.py +267 -0
  301. chia/_tests/util/test_network_protocol_test.py +256 -0
  302. chia/_tests/util/test_paginator.py +71 -0
  303. chia/_tests/util/test_pprint.py +17 -0
  304. chia/_tests/util/test_priority_mutex.py +488 -0
  305. chia/_tests/util/test_recursive_replace.py +116 -0
  306. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  307. chia/_tests/util/test_service_groups.py +15 -0
  308. chia/_tests/util/test_ssl_check.py +31 -0
  309. chia/_tests/util/test_testnet_overrides.py +19 -0
  310. chia/_tests/util/test_tests_misc.py +38 -0
  311. chia/_tests/util/test_timing.py +37 -0
  312. chia/_tests/util/test_trusted_peer.py +51 -0
  313. chia/_tests/util/time_out_assert.py +191 -0
  314. chia/_tests/wallet/__init__.py +0 -0
  315. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  316. chia/_tests/wallet/cat_wallet/config.py +4 -0
  317. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  318. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  319. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
  320. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  321. chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
  322. chia/_tests/wallet/clawback/__init__.py +0 -0
  323. chia/_tests/wallet/clawback/config.py +3 -0
  324. chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
  325. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  326. chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
  327. chia/_tests/wallet/config.py +4 -0
  328. chia/_tests/wallet/conftest.py +278 -0
  329. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  330. chia/_tests/wallet/dao_wallet/config.py +3 -0
  331. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
  332. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  333. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  334. chia/_tests/wallet/db_wallet/config.py +3 -0
  335. chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
  336. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  337. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  338. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  339. chia/_tests/wallet/did_wallet/config.py +4 -0
  340. chia/_tests/wallet/did_wallet/test_did.py +2284 -0
  341. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  342. chia/_tests/wallet/nft_wallet/config.py +4 -0
  343. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
  344. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
  345. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
  346. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  347. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  348. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
  349. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  350. chia/_tests/wallet/rpc/__init__.py +0 -0
  351. chia/_tests/wallet/rpc/config.py +4 -0
  352. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
  353. chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
  354. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  355. chia/_tests/wallet/simple_sync/config.py +3 -0
  356. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
  357. chia/_tests/wallet/sync/__init__.py +0 -0
  358. chia/_tests/wallet/sync/config.py +4 -0
  359. chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
  360. chia/_tests/wallet/test_address_type.py +189 -0
  361. chia/_tests/wallet/test_bech32m.py +45 -0
  362. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  363. chia/_tests/wallet/test_coin_management.py +354 -0
  364. chia/_tests/wallet/test_coin_selection.py +588 -0
  365. chia/_tests/wallet/test_conditions.py +400 -0
  366. chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
  367. chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
  368. chia/_tests/wallet/test_nft_store.py +192 -0
  369. chia/_tests/wallet/test_notifications.py +196 -0
  370. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  371. chia/_tests/wallet/test_puzzle_store.py +132 -0
  372. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  373. chia/_tests/wallet/test_signer_protocol.py +947 -0
  374. chia/_tests/wallet/test_singleton.py +122 -0
  375. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  376. chia/_tests/wallet/test_singleton_store.py +152 -0
  377. chia/_tests/wallet/test_taproot.py +19 -0
  378. chia/_tests/wallet/test_transaction_store.py +945 -0
  379. chia/_tests/wallet/test_util.py +185 -0
  380. chia/_tests/wallet/test_wallet.py +2139 -0
  381. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  382. chia/_tests/wallet/test_wallet_blockchain.py +111 -0
  383. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  384. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  385. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  386. chia/_tests/wallet/test_wallet_node.py +780 -0
  387. chia/_tests/wallet/test_wallet_retry.py +95 -0
  388. chia/_tests/wallet/test_wallet_state_manager.py +259 -0
  389. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  390. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  391. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  392. chia/_tests/wallet/test_wallet_utils.py +156 -0
  393. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  394. chia/_tests/wallet/vc_wallet/config.py +3 -0
  395. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  396. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  397. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
  398. chia/_tests/wallet/wallet_block_tools.py +327 -0
  399. chia/_tests/weight_proof/__init__.py +0 -0
  400. chia/_tests/weight_proof/config.py +3 -0
  401. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  402. chia/apis.py +19 -0
  403. chia/clvm/__init__.py +0 -0
  404. chia/cmds/__init__.py +0 -0
  405. chia/cmds/beta.py +184 -0
  406. chia/cmds/beta_funcs.py +137 -0
  407. chia/cmds/check_wallet_db.py +420 -0
  408. chia/cmds/chia.py +151 -0
  409. chia/cmds/cmd_classes.py +323 -0
  410. chia/cmds/cmd_helpers.py +242 -0
  411. chia/cmds/cmds_util.py +488 -0
  412. chia/cmds/coin_funcs.py +275 -0
  413. chia/cmds/coins.py +182 -0
  414. chia/cmds/completion.py +49 -0
  415. chia/cmds/configure.py +332 -0
  416. chia/cmds/dao.py +1064 -0
  417. chia/cmds/dao_funcs.py +598 -0
  418. chia/cmds/data.py +708 -0
  419. chia/cmds/data_funcs.py +385 -0
  420. chia/cmds/db.py +87 -0
  421. chia/cmds/db_backup_func.py +77 -0
  422. chia/cmds/db_upgrade_func.py +452 -0
  423. chia/cmds/db_validate_func.py +184 -0
  424. chia/cmds/dev.py +18 -0
  425. chia/cmds/farm.py +100 -0
  426. chia/cmds/farm_funcs.py +200 -0
  427. chia/cmds/gh.py +275 -0
  428. chia/cmds/init.py +63 -0
  429. chia/cmds/init_funcs.py +367 -0
  430. chia/cmds/installers.py +131 -0
  431. chia/cmds/keys.py +527 -0
  432. chia/cmds/keys_funcs.py +863 -0
  433. chia/cmds/netspace.py +50 -0
  434. chia/cmds/netspace_funcs.py +54 -0
  435. chia/cmds/options.py +32 -0
  436. chia/cmds/param_types.py +238 -0
  437. chia/cmds/passphrase.py +131 -0
  438. chia/cmds/passphrase_funcs.py +292 -0
  439. chia/cmds/peer.py +51 -0
  440. chia/cmds/peer_funcs.py +129 -0
  441. chia/cmds/plotnft.py +260 -0
  442. chia/cmds/plotnft_funcs.py +405 -0
  443. chia/cmds/plots.py +230 -0
  444. chia/cmds/plotters.py +18 -0
  445. chia/cmds/rpc.py +208 -0
  446. chia/cmds/show.py +72 -0
  447. chia/cmds/show_funcs.py +215 -0
  448. chia/cmds/signer.py +296 -0
  449. chia/cmds/sim.py +225 -0
  450. chia/cmds/sim_funcs.py +509 -0
  451. chia/cmds/start.py +24 -0
  452. chia/cmds/start_funcs.py +109 -0
  453. chia/cmds/stop.py +62 -0
  454. chia/cmds/units.py +9 -0
  455. chia/cmds/wallet.py +1901 -0
  456. chia/cmds/wallet_funcs.py +1874 -0
  457. chia/consensus/__init__.py +0 -0
  458. chia/consensus/block_body_validation.py +562 -0
  459. chia/consensus/block_creation.py +546 -0
  460. chia/consensus/block_header_validation.py +1059 -0
  461. chia/consensus/block_record.py +31 -0
  462. chia/consensus/block_rewards.py +53 -0
  463. chia/consensus/blockchain.py +1087 -0
  464. chia/consensus/blockchain_interface.py +56 -0
  465. chia/consensus/coinbase.py +30 -0
  466. chia/consensus/condition_costs.py +9 -0
  467. chia/consensus/constants.py +49 -0
  468. chia/consensus/cost_calculator.py +15 -0
  469. chia/consensus/default_constants.py +89 -0
  470. chia/consensus/deficit.py +55 -0
  471. chia/consensus/difficulty_adjustment.py +412 -0
  472. chia/consensus/find_fork_point.py +111 -0
  473. chia/consensus/full_block_to_block_record.py +167 -0
  474. chia/consensus/get_block_challenge.py +106 -0
  475. chia/consensus/get_block_generator.py +27 -0
  476. chia/consensus/make_sub_epoch_summary.py +210 -0
  477. chia/consensus/multiprocess_validation.py +268 -0
  478. chia/consensus/pos_quality.py +19 -0
  479. chia/consensus/pot_iterations.py +67 -0
  480. chia/consensus/puzzles/__init__.py +0 -0
  481. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  482. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  483. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  484. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  485. chia/consensus/vdf_info_computation.py +156 -0
  486. chia/daemon/__init__.py +0 -0
  487. chia/daemon/client.py +252 -0
  488. chia/daemon/keychain_proxy.py +502 -0
  489. chia/daemon/keychain_server.py +365 -0
  490. chia/daemon/server.py +1606 -0
  491. chia/daemon/windows_signal.py +56 -0
  492. chia/data_layer/__init__.py +0 -0
  493. chia/data_layer/data_layer.py +1291 -0
  494. chia/data_layer/data_layer_api.py +33 -0
  495. chia/data_layer/data_layer_errors.py +50 -0
  496. chia/data_layer/data_layer_server.py +170 -0
  497. chia/data_layer/data_layer_util.py +985 -0
  498. chia/data_layer/data_layer_wallet.py +1311 -0
  499. chia/data_layer/data_store.py +2267 -0
  500. chia/data_layer/dl_wallet_store.py +407 -0
  501. chia/data_layer/download_data.py +389 -0
  502. chia/data_layer/puzzles/__init__.py +0 -0
  503. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  504. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  505. chia/data_layer/s3_plugin_config.yml +33 -0
  506. chia/data_layer/s3_plugin_service.py +468 -0
  507. chia/data_layer/util/__init__.py +0 -0
  508. chia/data_layer/util/benchmark.py +107 -0
  509. chia/data_layer/util/plugin.py +40 -0
  510. chia/farmer/__init__.py +0 -0
  511. chia/farmer/farmer.py +923 -0
  512. chia/farmer/farmer_api.py +820 -0
  513. chia/full_node/__init__.py +0 -0
  514. chia/full_node/bitcoin_fee_estimator.py +85 -0
  515. chia/full_node/block_height_map.py +271 -0
  516. chia/full_node/block_store.py +576 -0
  517. chia/full_node/bundle_tools.py +19 -0
  518. chia/full_node/coin_store.py +647 -0
  519. chia/full_node/fee_estimate.py +54 -0
  520. chia/full_node/fee_estimate_store.py +24 -0
  521. chia/full_node/fee_estimation.py +92 -0
  522. chia/full_node/fee_estimator.py +90 -0
  523. chia/full_node/fee_estimator_constants.py +38 -0
  524. chia/full_node/fee_estimator_interface.py +42 -0
  525. chia/full_node/fee_history.py +25 -0
  526. chia/full_node/fee_tracker.py +564 -0
  527. chia/full_node/full_node.py +3327 -0
  528. chia/full_node/full_node_api.py +2025 -0
  529. chia/full_node/full_node_store.py +1033 -0
  530. chia/full_node/hint_management.py +56 -0
  531. chia/full_node/hint_store.py +93 -0
  532. chia/full_node/mempool.py +589 -0
  533. chia/full_node/mempool_check_conditions.py +146 -0
  534. chia/full_node/mempool_manager.py +853 -0
  535. chia/full_node/pending_tx_cache.py +112 -0
  536. chia/full_node/puzzles/__init__.py +0 -0
  537. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  538. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  539. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  540. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  541. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  542. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  543. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  544. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  545. chia/full_node/signage_point.py +16 -0
  546. chia/full_node/subscriptions.py +247 -0
  547. chia/full_node/sync_store.py +146 -0
  548. chia/full_node/tx_processing_queue.py +78 -0
  549. chia/full_node/util/__init__.py +0 -0
  550. chia/full_node/weight_proof.py +1720 -0
  551. chia/harvester/__init__.py +0 -0
  552. chia/harvester/harvester.py +272 -0
  553. chia/harvester/harvester_api.py +380 -0
  554. chia/introducer/__init__.py +0 -0
  555. chia/introducer/introducer.py +122 -0
  556. chia/introducer/introducer_api.py +70 -0
  557. chia/legacy/__init__.py +0 -0
  558. chia/legacy/keyring.py +155 -0
  559. chia/plot_sync/__init__.py +0 -0
  560. chia/plot_sync/delta.py +61 -0
  561. chia/plot_sync/exceptions.py +56 -0
  562. chia/plot_sync/receiver.py +386 -0
  563. chia/plot_sync/sender.py +340 -0
  564. chia/plot_sync/util.py +43 -0
  565. chia/plotters/__init__.py +0 -0
  566. chia/plotters/bladebit.py +388 -0
  567. chia/plotters/chiapos.py +63 -0
  568. chia/plotters/madmax.py +224 -0
  569. chia/plotters/plotters.py +577 -0
  570. chia/plotters/plotters_util.py +133 -0
  571. chia/plotting/__init__.py +0 -0
  572. chia/plotting/cache.py +213 -0
  573. chia/plotting/check_plots.py +283 -0
  574. chia/plotting/create_plots.py +278 -0
  575. chia/plotting/manager.py +436 -0
  576. chia/plotting/util.py +336 -0
  577. chia/pools/__init__.py +0 -0
  578. chia/pools/pool_config.py +110 -0
  579. chia/pools/pool_puzzles.py +459 -0
  580. chia/pools/pool_wallet.py +933 -0
  581. chia/pools/pool_wallet_info.py +118 -0
  582. chia/pools/puzzles/__init__.py +0 -0
  583. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  584. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  585. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  586. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  587. chia/protocols/__init__.py +0 -0
  588. chia/protocols/farmer_protocol.py +102 -0
  589. chia/protocols/full_node_protocol.py +219 -0
  590. chia/protocols/harvester_protocol.py +216 -0
  591. chia/protocols/introducer_protocol.py +25 -0
  592. chia/protocols/pool_protocol.py +177 -0
  593. chia/protocols/protocol_message_types.py +139 -0
  594. chia/protocols/protocol_state_machine.py +87 -0
  595. chia/protocols/protocol_timing.py +8 -0
  596. chia/protocols/shared_protocol.py +86 -0
  597. chia/protocols/timelord_protocol.py +93 -0
  598. chia/protocols/wallet_protocol.py +401 -0
  599. chia/py.typed +0 -0
  600. chia/rpc/__init__.py +0 -0
  601. chia/rpc/crawler_rpc_api.py +80 -0
  602. chia/rpc/data_layer_rpc_api.py +644 -0
  603. chia/rpc/data_layer_rpc_client.py +188 -0
  604. chia/rpc/data_layer_rpc_util.py +58 -0
  605. chia/rpc/farmer_rpc_api.py +365 -0
  606. chia/rpc/farmer_rpc_client.py +86 -0
  607. chia/rpc/full_node_rpc_api.py +959 -0
  608. chia/rpc/full_node_rpc_client.py +292 -0
  609. chia/rpc/harvester_rpc_api.py +141 -0
  610. chia/rpc/harvester_rpc_client.py +54 -0
  611. chia/rpc/rpc_client.py +164 -0
  612. chia/rpc/rpc_server.py +521 -0
  613. chia/rpc/timelord_rpc_api.py +32 -0
  614. chia/rpc/util.py +93 -0
  615. chia/rpc/wallet_request_types.py +904 -0
  616. chia/rpc/wallet_rpc_api.py +4943 -0
  617. chia/rpc/wallet_rpc_client.py +1814 -0
  618. chia/seeder/__init__.py +0 -0
  619. chia/seeder/crawl_store.py +425 -0
  620. chia/seeder/crawler.py +410 -0
  621. chia/seeder/crawler_api.py +135 -0
  622. chia/seeder/dns_server.py +593 -0
  623. chia/seeder/peer_record.py +146 -0
  624. chia/seeder/start_crawler.py +92 -0
  625. chia/server/__init__.py +0 -0
  626. chia/server/address_manager.py +658 -0
  627. chia/server/address_manager_store.py +237 -0
  628. chia/server/api_protocol.py +116 -0
  629. chia/server/capabilities.py +24 -0
  630. chia/server/chia_policy.py +346 -0
  631. chia/server/introducer_peers.py +76 -0
  632. chia/server/node_discovery.py +714 -0
  633. chia/server/outbound_message.py +33 -0
  634. chia/server/rate_limit_numbers.py +214 -0
  635. chia/server/rate_limits.py +153 -0
  636. chia/server/server.py +741 -0
  637. chia/server/signal_handlers.py +120 -0
  638. chia/server/ssl_context.py +32 -0
  639. chia/server/start_data_layer.py +151 -0
  640. chia/server/start_farmer.py +98 -0
  641. chia/server/start_full_node.py +112 -0
  642. chia/server/start_harvester.py +93 -0
  643. chia/server/start_introducer.py +81 -0
  644. chia/server/start_service.py +316 -0
  645. chia/server/start_timelord.py +89 -0
  646. chia/server/start_wallet.py +113 -0
  647. chia/server/upnp.py +118 -0
  648. chia/server/ws_connection.py +766 -0
  649. chia/simulator/__init__.py +0 -0
  650. chia/simulator/add_blocks_in_batches.py +54 -0
  651. chia/simulator/block_tools.py +2054 -0
  652. chia/simulator/full_node_simulator.py +794 -0
  653. chia/simulator/keyring.py +128 -0
  654. chia/simulator/setup_services.py +506 -0
  655. chia/simulator/simulator_constants.py +13 -0
  656. chia/simulator/simulator_full_node_rpc_api.py +99 -0
  657. chia/simulator/simulator_full_node_rpc_client.py +60 -0
  658. chia/simulator/simulator_protocol.py +29 -0
  659. chia/simulator/simulator_test_tools.py +164 -0
  660. chia/simulator/socket.py +24 -0
  661. chia/simulator/ssl_certs.py +114 -0
  662. chia/simulator/ssl_certs_1.py +697 -0
  663. chia/simulator/ssl_certs_10.py +697 -0
  664. chia/simulator/ssl_certs_2.py +697 -0
  665. chia/simulator/ssl_certs_3.py +697 -0
  666. chia/simulator/ssl_certs_4.py +697 -0
  667. chia/simulator/ssl_certs_5.py +697 -0
  668. chia/simulator/ssl_certs_6.py +697 -0
  669. chia/simulator/ssl_certs_7.py +697 -0
  670. chia/simulator/ssl_certs_8.py +697 -0
  671. chia/simulator/ssl_certs_9.py +697 -0
  672. chia/simulator/start_simulator.py +143 -0
  673. chia/simulator/wallet_tools.py +246 -0
  674. chia/ssl/__init__.py +0 -0
  675. chia/ssl/chia_ca.crt +19 -0
  676. chia/ssl/chia_ca.key +28 -0
  677. chia/ssl/create_ssl.py +249 -0
  678. chia/ssl/dst_root_ca.pem +20 -0
  679. chia/timelord/__init__.py +0 -0
  680. chia/timelord/iters_from_block.py +50 -0
  681. chia/timelord/timelord.py +1226 -0
  682. chia/timelord/timelord_api.py +138 -0
  683. chia/timelord/timelord_launcher.py +190 -0
  684. chia/timelord/timelord_state.py +244 -0
  685. chia/timelord/types.py +22 -0
  686. chia/types/__init__.py +0 -0
  687. chia/types/aliases.py +35 -0
  688. chia/types/block_protocol.py +20 -0
  689. chia/types/blockchain_format/__init__.py +0 -0
  690. chia/types/blockchain_format/classgroup.py +5 -0
  691. chia/types/blockchain_format/coin.py +28 -0
  692. chia/types/blockchain_format/foliage.py +8 -0
  693. chia/types/blockchain_format/pool_target.py +5 -0
  694. chia/types/blockchain_format/program.py +269 -0
  695. chia/types/blockchain_format/proof_of_space.py +135 -0
  696. chia/types/blockchain_format/reward_chain_block.py +6 -0
  697. chia/types/blockchain_format/serialized_program.py +5 -0
  698. chia/types/blockchain_format/sized_bytes.py +11 -0
  699. chia/types/blockchain_format/slots.py +9 -0
  700. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  701. chia/types/blockchain_format/tree_hash.py +72 -0
  702. chia/types/blockchain_format/vdf.py +86 -0
  703. chia/types/clvm_cost.py +13 -0
  704. chia/types/coin_record.py +43 -0
  705. chia/types/coin_spend.py +115 -0
  706. chia/types/condition_opcodes.py +73 -0
  707. chia/types/condition_with_args.py +16 -0
  708. chia/types/eligible_coin_spends.py +365 -0
  709. chia/types/end_of_slot_bundle.py +5 -0
  710. chia/types/fee_rate.py +38 -0
  711. chia/types/full_block.py +5 -0
  712. chia/types/generator_types.py +13 -0
  713. chia/types/header_block.py +5 -0
  714. chia/types/internal_mempool_item.py +18 -0
  715. chia/types/mempool_inclusion_status.py +9 -0
  716. chia/types/mempool_item.py +85 -0
  717. chia/types/mempool_submission_status.py +30 -0
  718. chia/types/mojos.py +7 -0
  719. chia/types/peer_info.py +64 -0
  720. chia/types/signing_mode.py +29 -0
  721. chia/types/spend_bundle.py +30 -0
  722. chia/types/spend_bundle_conditions.py +7 -0
  723. chia/types/transaction_queue_entry.py +55 -0
  724. chia/types/unfinished_block.py +5 -0
  725. chia/types/unfinished_header_block.py +37 -0
  726. chia/types/validation_state.py +14 -0
  727. chia/types/weight_proof.py +49 -0
  728. chia/util/__init__.py +0 -0
  729. chia/util/action_scope.py +168 -0
  730. chia/util/async_pool.py +226 -0
  731. chia/util/augmented_chain.py +134 -0
  732. chia/util/batches.py +42 -0
  733. chia/util/bech32m.py +126 -0
  734. chia/util/beta_metrics.py +119 -0
  735. chia/util/block_cache.py +56 -0
  736. chia/util/byte_types.py +12 -0
  737. chia/util/check_fork_next_block.py +33 -0
  738. chia/util/chia_logging.py +144 -0
  739. chia/util/chia_version.py +33 -0
  740. chia/util/collection.py +17 -0
  741. chia/util/condition_tools.py +201 -0
  742. chia/util/config.py +367 -0
  743. chia/util/cpu.py +22 -0
  744. chia/util/db_synchronous.py +23 -0
  745. chia/util/db_version.py +32 -0
  746. chia/util/db_wrapper.py +430 -0
  747. chia/util/default_root.py +27 -0
  748. chia/util/dump_keyring.py +93 -0
  749. chia/util/english.txt +2048 -0
  750. chia/util/errors.py +353 -0
  751. chia/util/file_keyring.py +469 -0
  752. chia/util/files.py +97 -0
  753. chia/util/full_block_utils.py +345 -0
  754. chia/util/generator_tools.py +72 -0
  755. chia/util/hash.py +31 -0
  756. chia/util/initial-config.yaml +694 -0
  757. chia/util/inline_executor.py +26 -0
  758. chia/util/ints.py +19 -0
  759. chia/util/ip_address.py +39 -0
  760. chia/util/json_util.py +37 -0
  761. chia/util/keychain.py +676 -0
  762. chia/util/keyring_wrapper.py +327 -0
  763. chia/util/limited_semaphore.py +41 -0
  764. chia/util/lock.py +49 -0
  765. chia/util/log_exceptions.py +32 -0
  766. chia/util/logging.py +36 -0
  767. chia/util/lru_cache.py +31 -0
  768. chia/util/math.py +20 -0
  769. chia/util/network.py +182 -0
  770. chia/util/paginator.py +48 -0
  771. chia/util/path.py +31 -0
  772. chia/util/permissions.py +20 -0
  773. chia/util/prev_transaction_block.py +21 -0
  774. chia/util/priority_mutex.py +95 -0
  775. chia/util/profiler.py +197 -0
  776. chia/util/recursive_replace.py +24 -0
  777. chia/util/safe_cancel_task.py +16 -0
  778. chia/util/service_groups.py +47 -0
  779. chia/util/setproctitle.py +22 -0
  780. chia/util/significant_bits.py +32 -0
  781. chia/util/ssl_check.py +213 -0
  782. chia/util/streamable.py +642 -0
  783. chia/util/task_referencer.py +59 -0
  784. chia/util/task_timing.py +382 -0
  785. chia/util/timing.py +67 -0
  786. chia/util/vdf_prover.py +30 -0
  787. chia/util/virtual_project_analysis.py +540 -0
  788. chia/util/ws_message.py +66 -0
  789. chia/wallet/__init__.py +0 -0
  790. chia/wallet/cat_wallet/__init__.py +0 -0
  791. chia/wallet/cat_wallet/cat_constants.py +75 -0
  792. chia/wallet/cat_wallet/cat_info.py +47 -0
  793. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  794. chia/wallet/cat_wallet/cat_utils.py +164 -0
  795. chia/wallet/cat_wallet/cat_wallet.py +855 -0
  796. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  797. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  798. chia/wallet/cat_wallet/lineage_store.py +74 -0
  799. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  800. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  801. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  802. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  803. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  804. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  805. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  806. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  807. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  808. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  809. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  810. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  811. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  812. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  813. chia/wallet/coin_selection.py +188 -0
  814. chia/wallet/conditions.py +1512 -0
  815. chia/wallet/dao_wallet/__init__.py +0 -0
  816. chia/wallet/dao_wallet/dao_info.py +61 -0
  817. chia/wallet/dao_wallet/dao_utils.py +811 -0
  818. chia/wallet/dao_wallet/dao_wallet.py +2119 -0
  819. chia/wallet/db_wallet/__init__.py +0 -0
  820. chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
  821. chia/wallet/derivation_record.py +30 -0
  822. chia/wallet/derive_keys.py +146 -0
  823. chia/wallet/did_wallet/__init__.py +0 -0
  824. chia/wallet/did_wallet/did_info.py +39 -0
  825. chia/wallet/did_wallet/did_wallet.py +1494 -0
  826. chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
  827. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  828. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  829. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  830. chia/wallet/driver_protocol.py +26 -0
  831. chia/wallet/key_val_store.py +55 -0
  832. chia/wallet/lineage_proof.py +58 -0
  833. chia/wallet/nft_wallet/__init__.py +0 -0
  834. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  835. chia/wallet/nft_wallet/nft_info.py +120 -0
  836. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  837. chia/wallet/nft_wallet/nft_wallet.py +1687 -0
  838. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  839. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  840. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  841. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  842. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  843. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  844. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  845. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  846. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  847. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  848. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  849. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  850. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  851. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  852. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  853. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  854. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  855. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  856. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  857. chia/wallet/notification_manager.py +117 -0
  858. chia/wallet/notification_store.py +178 -0
  859. chia/wallet/outer_puzzles.py +84 -0
  860. chia/wallet/payment.py +33 -0
  861. chia/wallet/puzzle_drivers.py +118 -0
  862. chia/wallet/puzzles/__init__.py +0 -0
  863. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  864. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  865. chia/wallet/puzzles/clawback/__init__.py +0 -0
  866. chia/wallet/puzzles/clawback/drivers.py +188 -0
  867. chia/wallet/puzzles/clawback/metadata.py +38 -0
  868. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  869. chia/wallet/puzzles/condition_codes.clib +77 -0
  870. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  871. chia/wallet/puzzles/curry.clib +135 -0
  872. chia/wallet/puzzles/curry_by_index.clib +16 -0
  873. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  874. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  876. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  877. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  878. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  879. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  880. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  881. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  882. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  883. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  884. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  885. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  886. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  887. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  888. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  889. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  890. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  891. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  892. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  893. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  894. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  895. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  896. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  897. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  898. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  899. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  900. chia/wallet/puzzles/json.clib +25 -0
  901. chia/wallet/puzzles/load_clvm.py +161 -0
  902. chia/wallet/puzzles/merkle_utils.clib +18 -0
  903. chia/wallet/puzzles/notification.clsp +7 -0
  904. chia/wallet/puzzles/notification.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  906. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  907. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  908. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  909. chia/wallet/puzzles/p2_conditions.py +26 -0
  910. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  911. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  912. chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
  913. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  914. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  915. chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
  916. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  917. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
  919. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  920. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  921. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
  922. chia/wallet/puzzles/p2_parent.clsp +19 -0
  923. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  924. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  925. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  926. chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
  927. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  928. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  929. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  930. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  931. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  932. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  933. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  934. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  935. chia/wallet/puzzles/puzzle_utils.py +34 -0
  936. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  937. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  938. chia/wallet/puzzles/sha256tree.clib +11 -0
  939. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  940. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  941. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  942. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  943. chia/wallet/puzzles/singleton_top_layer.py +296 -0
  944. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  945. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  946. chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
  947. chia/wallet/puzzles/singleton_truths.clib +21 -0
  948. chia/wallet/puzzles/tails.py +348 -0
  949. chia/wallet/puzzles/utility_macros.clib +48 -0
  950. chia/wallet/signer_protocol.py +125 -0
  951. chia/wallet/singleton.py +106 -0
  952. chia/wallet/singleton_record.py +30 -0
  953. chia/wallet/trade_manager.py +1102 -0
  954. chia/wallet/trade_record.py +67 -0
  955. chia/wallet/trading/__init__.py +0 -0
  956. chia/wallet/trading/offer.py +702 -0
  957. chia/wallet/trading/trade_status.py +13 -0
  958. chia/wallet/trading/trade_store.py +526 -0
  959. chia/wallet/transaction_record.py +158 -0
  960. chia/wallet/transaction_sorting.py +14 -0
  961. chia/wallet/uncurried_puzzle.py +17 -0
  962. chia/wallet/util/__init__.py +0 -0
  963. chia/wallet/util/address_type.py +55 -0
  964. chia/wallet/util/blind_signer_tl.py +164 -0
  965. chia/wallet/util/clvm_streamable.py +203 -0
  966. chia/wallet/util/compute_hints.py +66 -0
  967. chia/wallet/util/compute_memos.py +43 -0
  968. chia/wallet/util/curry_and_treehash.py +91 -0
  969. chia/wallet/util/debug_spend_bundle.py +232 -0
  970. chia/wallet/util/merkle_tree.py +100 -0
  971. chia/wallet/util/merkle_utils.py +102 -0
  972. chia/wallet/util/new_peak_queue.py +82 -0
  973. chia/wallet/util/notifications.py +12 -0
  974. chia/wallet/util/peer_request_cache.py +174 -0
  975. chia/wallet/util/pprint.py +39 -0
  976. chia/wallet/util/puzzle_compression.py +95 -0
  977. chia/wallet/util/puzzle_decorator.py +100 -0
  978. chia/wallet/util/puzzle_decorator_type.py +7 -0
  979. chia/wallet/util/query_filter.py +59 -0
  980. chia/wallet/util/transaction_type.py +23 -0
  981. chia/wallet/util/tx_config.py +158 -0
  982. chia/wallet/util/wallet_sync_utils.py +351 -0
  983. chia/wallet/util/wallet_types.py +72 -0
  984. chia/wallet/vc_wallet/__init__.py +0 -0
  985. chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
  986. chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
  987. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  988. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  989. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  990. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  992. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  994. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  996. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  997. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  998. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  1002. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  1003. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  1004. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  1005. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  1006. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  1007. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  1008. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  1009. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  1010. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  1011. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  1012. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  1013. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1014. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1015. chia/wallet/vc_wallet/vc_store.py +263 -0
  1016. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1017. chia/wallet/wallet.py +698 -0
  1018. chia/wallet/wallet_action_scope.py +96 -0
  1019. chia/wallet/wallet_blockchain.py +244 -0
  1020. chia/wallet/wallet_coin_record.py +72 -0
  1021. chia/wallet/wallet_coin_store.py +351 -0
  1022. chia/wallet/wallet_info.py +35 -0
  1023. chia/wallet/wallet_interested_store.py +188 -0
  1024. chia/wallet/wallet_nft_store.py +279 -0
  1025. chia/wallet/wallet_node.py +1765 -0
  1026. chia/wallet/wallet_node_api.py +207 -0
  1027. chia/wallet/wallet_pool_store.py +119 -0
  1028. chia/wallet/wallet_protocol.py +90 -0
  1029. chia/wallet/wallet_puzzle_store.py +396 -0
  1030. chia/wallet/wallet_retry_store.py +70 -0
  1031. chia/wallet/wallet_singleton_store.py +259 -0
  1032. chia/wallet/wallet_spend_bundle.py +25 -0
  1033. chia/wallet/wallet_state_manager.py +2819 -0
  1034. chia/wallet/wallet_transaction_store.py +496 -0
  1035. chia/wallet/wallet_user_store.py +110 -0
  1036. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1037. chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
  1038. chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
  1039. chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
  1040. chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
  1041. chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
  1042. mozilla-ca/cacert.pem +3611 -0
@@ -0,0 +1,1311 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import logging
5
+ import time
6
+ from typing import TYPE_CHECKING, Any, ClassVar, Optional, cast
7
+
8
+ from chia_rs import G1Element, G2Element
9
+ from clvm.EvalError import EvalError
10
+ from typing_extensions import Unpack, final
11
+
12
+ from chia.consensus.block_record import BlockRecord
13
+ from chia.data_layer.data_layer_errors import LauncherCoinNotFoundError, OfferIntegrityError
14
+ from chia.data_layer.data_layer_util import OfferStore, ProofOfInclusion, ProofOfInclusionLayer, StoreProofs, leaf_hash
15
+ from chia.protocols.wallet_protocol import CoinState
16
+ from chia.server.ws_connection import WSChiaConnection
17
+ from chia.types.blockchain_format.coin import Coin
18
+ from chia.types.blockchain_format.program import Program
19
+ from chia.types.blockchain_format.serialized_program import SerializedProgram
20
+ from chia.types.blockchain_format.sized_bytes import bytes32
21
+ from chia.types.coin_spend import CoinSpend, compute_additions
22
+ from chia.types.condition_opcodes import ConditionOpcode
23
+ from chia.util.ints import uint8, uint32, uint64, uint128
24
+ from chia.util.streamable import Streamable, streamable
25
+ from chia.wallet.conditions import (
26
+ AssertAnnouncement,
27
+ AssertCoinAnnouncement,
28
+ AssertPuzzleAnnouncement,
29
+ Condition,
30
+ CreateCoinAnnouncement,
31
+ UnknownCondition,
32
+ parse_timelock_info,
33
+ )
34
+ from chia.wallet.db_wallet.db_wallet_puzzles import (
35
+ ACS_MU,
36
+ ACS_MU_PH,
37
+ GRAFTROOT_DL_OFFERS,
38
+ SINGLETON_LAUNCHER,
39
+ create_graftroot_offer_puz,
40
+ create_host_fullpuz,
41
+ create_host_layer_puzzle,
42
+ create_mirror_puzzle,
43
+ get_mirror_info,
44
+ launch_solution_to_singleton_info,
45
+ launcher_to_struct,
46
+ match_dl_singleton,
47
+ )
48
+ from chia.wallet.derivation_record import DerivationRecord
49
+ from chia.wallet.lineage_proof import LineageProof
50
+ from chia.wallet.outer_puzzles import AssetType
51
+ from chia.wallet.payment import Payment
52
+ from chia.wallet.puzzle_drivers import PuzzleInfo, Solver
53
+ from chia.wallet.puzzles.singleton_top_layer_v1_1 import SINGLETON_LAUNCHER_HASH
54
+ from chia.wallet.trading.offer import NotarizedPayment, Offer
55
+ from chia.wallet.transaction_record import TransactionRecord
56
+ from chia.wallet.util.compute_memos import compute_memos
57
+ from chia.wallet.util.merkle_utils import _simplify_merkle_proof
58
+ from chia.wallet.util.transaction_type import TransactionType
59
+ from chia.wallet.util.wallet_sync_utils import fetch_coin_spend, fetch_coin_spend_for_coin_state
60
+ from chia.wallet.util.wallet_types import WalletType
61
+ from chia.wallet.wallet import Wallet
62
+ from chia.wallet.wallet_action_scope import WalletActionScope
63
+ from chia.wallet.wallet_coin_record import WalletCoinRecord
64
+ from chia.wallet.wallet_info import WalletInfo
65
+ from chia.wallet.wallet_protocol import GSTOptionalArgs, WalletProtocol
66
+ from chia.wallet.wallet_spend_bundle import WalletSpendBundle
67
+
68
+ if TYPE_CHECKING:
69
+ from chia.wallet.wallet_state_manager import WalletStateManager
70
+
71
+
72
+ @streamable
73
+ @dataclasses.dataclass(frozen=True)
74
+ class SingletonRecord(Streamable):
75
+ coin_id: bytes32
76
+ launcher_id: bytes32
77
+ root: bytes32
78
+ inner_puzzle_hash: bytes32
79
+ confirmed: bool
80
+ confirmed_at_height: uint32
81
+ lineage_proof: LineageProof
82
+ generation: uint32
83
+ timestamp: uint64
84
+
85
+
86
+ @dataclasses.dataclass(frozen=True)
87
+ class Mirror:
88
+ coin_id: bytes32
89
+ launcher_id: bytes32
90
+ amount: uint64
91
+ urls: list[bytes]
92
+ ours: bool
93
+ confirmed_at_height: Optional[uint32]
94
+
95
+ def to_json_dict(self) -> dict[str, Any]:
96
+ return {
97
+ "coin_id": self.coin_id.hex(),
98
+ "launcher_id": self.launcher_id.hex(),
99
+ "amount": self.amount,
100
+ "urls": [url.decode("utf8") for url in self.urls],
101
+ "ours": self.ours,
102
+ "confirmed_at_height": self.confirmed_at_height,
103
+ }
104
+
105
+ @classmethod
106
+ def from_json_dict(cls, json_dict: dict[str, Any]) -> Mirror:
107
+ return cls(
108
+ bytes32.from_hexstr(json_dict["coin_id"]),
109
+ bytes32.from_hexstr(json_dict["launcher_id"]),
110
+ json_dict["amount"],
111
+ [bytes(url, "utf8") for url in json_dict["urls"]],
112
+ json_dict["ours"],
113
+ json_dict["confirmed_at_height"],
114
+ )
115
+
116
+
117
+ @final
118
+ class DataLayerWallet:
119
+ if TYPE_CHECKING:
120
+ # TODO Create DataLayer coin data model if necessary
121
+ _protocol_check: ClassVar[WalletProtocol[object]] = cast("DataLayerWallet", None)
122
+
123
+ wallet_state_manager: WalletStateManager
124
+ log: logging.Logger
125
+ wallet_info: WalletInfo
126
+ wallet_id: uint8
127
+ standard_wallet: Wallet
128
+ """
129
+ interface used by datalayer for interacting with the chain
130
+ """
131
+
132
+ @classmethod
133
+ async def create(
134
+ cls,
135
+ wallet_state_manager: WalletStateManager,
136
+ wallet_info: WalletInfo,
137
+ ) -> DataLayerWallet:
138
+ self = cls()
139
+ self.wallet_state_manager = wallet_state_manager
140
+ self.log = logging.getLogger(__name__)
141
+ self.standard_wallet = wallet_state_manager.main_wallet
142
+ self.wallet_info = wallet_info
143
+ self.wallet_id = uint8(self.wallet_info.id)
144
+
145
+ return self
146
+
147
+ @classmethod
148
+ def type(cls) -> WalletType:
149
+ return WalletType.DATA_LAYER
150
+
151
+ def id(self) -> uint32:
152
+ return self.wallet_info.id
153
+
154
+ @classmethod
155
+ async def create_new_dl_wallet(cls, wallet_state_manager: WalletStateManager) -> DataLayerWallet:
156
+ """
157
+ This must be called under the wallet state manager lock
158
+ """
159
+
160
+ self = cls()
161
+ self.wallet_state_manager = wallet_state_manager
162
+ self.log = logging.getLogger(__name__)
163
+ self.standard_wallet = wallet_state_manager.main_wallet
164
+
165
+ for _, w in self.wallet_state_manager.wallets.items():
166
+ if w.type() == WalletType.DATA_LAYER:
167
+ raise ValueError("DataLayer Wallet already exists for this key")
168
+
169
+ self.wallet_info = await wallet_state_manager.user_store.create_wallet(
170
+ "DataLayer Wallet",
171
+ WalletType.DATA_LAYER.value,
172
+ "",
173
+ )
174
+ await self.wallet_state_manager.add_new_wallet(self)
175
+
176
+ return self
177
+
178
+ #############
179
+ # LAUNCHING #
180
+ #############
181
+
182
+ @staticmethod
183
+ async def match_dl_launcher(launcher_spend: CoinSpend) -> tuple[bool, Optional[bytes32]]:
184
+ # Sanity check it's a launcher
185
+ if launcher_spend.puzzle_reveal.to_program() != SINGLETON_LAUNCHER:
186
+ return False, None
187
+
188
+ # Let's make sure the solution looks how we expect it to
189
+ try:
190
+ full_puzhash, amount, root, inner_puzhash = launch_solution_to_singleton_info(
191
+ launcher_spend.solution.to_program()
192
+ )
193
+ except ValueError:
194
+ return False, None
195
+
196
+ # Now let's check that the full puzzle is an odd data layer singleton
197
+ if (
198
+ full_puzhash
199
+ != create_host_fullpuz(inner_puzhash, root, launcher_spend.coin.name()).get_tree_hash_precalc(inner_puzhash)
200
+ or amount % 2 == 0
201
+ ):
202
+ return False, None
203
+
204
+ return True, inner_puzhash
205
+
206
+ async def get_launcher_coin_state(self, launcher_id: bytes32, peer: WSChiaConnection) -> CoinState:
207
+ coin_states: list[CoinState] = await self.wallet_state_manager.wallet_node.get_coin_state(
208
+ [launcher_id], peer=peer
209
+ )
210
+
211
+ if len(coin_states) == 0:
212
+ raise LauncherCoinNotFoundError(f"Launcher ID {launcher_id} is not a valid coin")
213
+ if coin_states[0].coin.puzzle_hash != SINGLETON_LAUNCHER.get_tree_hash():
214
+ raise ValueError(f"Coin with ID {launcher_id} is not a singleton launcher")
215
+ if coin_states[0].created_height is None:
216
+ raise ValueError(f"Launcher with ID {launcher_id} has not been created (maybe reorged)")
217
+ if coin_states[0].spent_height is None:
218
+ raise ValueError(f"Launcher with ID {launcher_id} has not been spent")
219
+
220
+ return coin_states[0]
221
+
222
+ # This is the entry point for non-owned singletons
223
+ async def track_new_launcher_id(
224
+ self,
225
+ launcher_id: bytes32,
226
+ peer: WSChiaConnection,
227
+ spend: Optional[CoinSpend] = None,
228
+ height: Optional[uint32] = None,
229
+ ) -> None:
230
+ if await self.wallet_state_manager.dl_store.get_launcher(launcher_id) is not None:
231
+ self.log.info(f"Spend of launcher {launcher_id} has already been processed")
232
+ return None
233
+ if spend is None or height is None:
234
+ launcher_state: CoinState = await self.get_launcher_coin_state(launcher_id, peer)
235
+ spend = await fetch_coin_spend_for_coin_state(launcher_state, peer)
236
+ assert launcher_state.spent_height is not None
237
+ height = uint32(launcher_state.spent_height)
238
+
239
+ assert spend.coin.name() == launcher_id, "coin_id should always match the launcher_id here"
240
+
241
+ full_puzhash, amount, root, inner_puzhash = launch_solution_to_singleton_info(spend.solution.to_program())
242
+ new_singleton = Coin(launcher_id, full_puzhash, amount)
243
+
244
+ singleton_record: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_latest_singleton(
245
+ launcher_id
246
+ )
247
+ if singleton_record is not None:
248
+ if ( # This is an unconfirmed singleton that we know about
249
+ singleton_record.coin_id == new_singleton.name() and not singleton_record.confirmed
250
+ ):
251
+ timestamp = await self.wallet_state_manager.wallet_node.get_timestamp_for_height(height)
252
+ await self.wallet_state_manager.dl_store.set_confirmed(singleton_record.coin_id, height, timestamp)
253
+ else:
254
+ self.log.info(f"Spend of launcher {launcher_id} has already been processed")
255
+ return None
256
+ else:
257
+ timestamp = await self.wallet_state_manager.wallet_node.get_timestamp_for_height(height)
258
+ await self.wallet_state_manager.dl_store.add_singleton_record(
259
+ SingletonRecord(
260
+ coin_id=new_singleton.name(),
261
+ launcher_id=launcher_id,
262
+ root=root,
263
+ inner_puzzle_hash=inner_puzhash,
264
+ confirmed=True,
265
+ confirmed_at_height=height,
266
+ timestamp=timestamp,
267
+ lineage_proof=LineageProof(
268
+ launcher_id,
269
+ create_host_layer_puzzle(inner_puzhash, root).get_tree_hash_precalc(inner_puzhash),
270
+ amount,
271
+ ),
272
+ generation=uint32(0),
273
+ )
274
+ )
275
+
276
+ await self.wallet_state_manager.dl_store.add_launcher(spend.coin, height)
277
+ await self.wallet_state_manager.add_interested_puzzle_hashes([launcher_id], [self.id()])
278
+ await self.wallet_state_manager.add_interested_coin_ids([new_singleton.name()])
279
+
280
+ new_singleton_coin_record: Optional[
281
+ WalletCoinRecord
282
+ ] = await self.wallet_state_manager.coin_store.get_coin_record(new_singleton.name())
283
+ while new_singleton_coin_record is not None and new_singleton_coin_record.spent_block_height > 0:
284
+ # We've already synced this before, so we need to sort of force a resync
285
+ parent_spend = await fetch_coin_spend(new_singleton_coin_record.spent_block_height, new_singleton, peer)
286
+ await self.singleton_removed(parent_spend, new_singleton_coin_record.spent_block_height)
287
+ try:
288
+ additions = compute_additions(parent_spend)
289
+ new_singleton = next(coin for coin in additions if coin.amount % 2 != 0)
290
+ new_singleton_coin_record = await self.wallet_state_manager.coin_store.get_coin_record(
291
+ new_singleton.name()
292
+ )
293
+ except StopIteration:
294
+ new_singleton_coin_record = None
295
+
296
+ ################
297
+ # TRANSACTIONS #
298
+ ################
299
+
300
+ async def generate_new_reporter(
301
+ self,
302
+ initial_root: bytes32,
303
+ action_scope: WalletActionScope,
304
+ fee: uint64 = uint64(0),
305
+ extra_conditions: tuple[Condition, ...] = tuple(),
306
+ ) -> bytes32:
307
+ """
308
+ Creates the initial singleton, which includes spending an origin coin, the launcher, and creating a singleton
309
+ """
310
+
311
+ coins: set[Coin] = await self.standard_wallet.select_coins(uint64(fee + 1), action_scope)
312
+ if coins is None:
313
+ raise ValueError("Not enough coins to create new data layer singleton")
314
+
315
+ launcher_parent: Coin = next(iter(coins))
316
+ launcher_coin: Coin = Coin(launcher_parent.name(), SINGLETON_LAUNCHER.get_tree_hash(), uint64(1))
317
+
318
+ inner_puzzle: Program = await self.standard_wallet.get_puzzle(
319
+ new=not action_scope.config.tx_config.reuse_puzhash
320
+ )
321
+ full_puzzle: Program = create_host_fullpuz(inner_puzzle, initial_root, launcher_coin.name())
322
+
323
+ genesis_launcher_solution: Program = Program.to(
324
+ [full_puzzle.get_tree_hash(), 1, [initial_root, inner_puzzle.get_tree_hash()]]
325
+ )
326
+ announcement_message: bytes32 = genesis_launcher_solution.get_tree_hash()
327
+ announcement = AssertCoinAnnouncement(asserted_id=launcher_coin.name(), asserted_msg=announcement_message)
328
+
329
+ await self.standard_wallet.generate_signed_transaction(
330
+ amount=uint64(1),
331
+ puzzle_hash=SINGLETON_LAUNCHER.get_tree_hash(),
332
+ action_scope=action_scope,
333
+ fee=fee,
334
+ origin_id=launcher_parent.name(),
335
+ coins=coins,
336
+ primaries=None,
337
+ extra_conditions=(*extra_conditions, announcement),
338
+ )
339
+
340
+ launcher_cs: CoinSpend = CoinSpend(
341
+ launcher_coin,
342
+ SerializedProgram.from_program(SINGLETON_LAUNCHER),
343
+ SerializedProgram.from_program(genesis_launcher_solution),
344
+ )
345
+ launcher_sb = WalletSpendBundle([launcher_cs], G2Element())
346
+
347
+ async with action_scope.use() as interface:
348
+ interface.side_effects.extra_spends.append(launcher_sb)
349
+
350
+ singleton_record = SingletonRecord(
351
+ coin_id=Coin(launcher_coin.name(), full_puzzle.get_tree_hash(), uint64(1)).name(),
352
+ launcher_id=launcher_coin.name(),
353
+ root=initial_root,
354
+ inner_puzzle_hash=inner_puzzle.get_tree_hash(),
355
+ confirmed=False,
356
+ confirmed_at_height=uint32(0),
357
+ timestamp=uint64(0),
358
+ lineage_proof=LineageProof(
359
+ launcher_coin.name(),
360
+ create_host_layer_puzzle(inner_puzzle, initial_root).get_tree_hash(),
361
+ uint64(1),
362
+ ),
363
+ generation=uint32(0),
364
+ )
365
+
366
+ await self.wallet_state_manager.dl_store.add_singleton_record(singleton_record)
367
+ await self.wallet_state_manager.add_interested_puzzle_hashes([singleton_record.launcher_id], [self.id()])
368
+
369
+ return launcher_coin.name()
370
+
371
+ async def create_tandem_xch_tx(
372
+ self,
373
+ fee: uint64,
374
+ announcement_to_assert: AssertAnnouncement,
375
+ action_scope: WalletActionScope,
376
+ ) -> None:
377
+ await self.standard_wallet.generate_signed_transaction(
378
+ amount=uint64(0),
379
+ puzzle_hash=await self.standard_wallet.get_puzzle_hash(new=not action_scope.config.tx_config.reuse_puzhash),
380
+ action_scope=action_scope,
381
+ fee=fee,
382
+ negative_change_allowed=False,
383
+ extra_conditions=(announcement_to_assert,),
384
+ )
385
+
386
+ async def create_update_state_spend(
387
+ self,
388
+ launcher_id: bytes32,
389
+ root_hash: Optional[bytes32],
390
+ action_scope: WalletActionScope,
391
+ new_puz_hash: Optional[bytes32] = None,
392
+ new_amount: Optional[uint64] = None,
393
+ fee: uint64 = uint64(0),
394
+ add_pending_singleton: bool = True,
395
+ announce_new_state: bool = False,
396
+ extra_conditions: tuple[Condition, ...] = tuple(),
397
+ ) -> None:
398
+ singleton_record, parent_lineage = await self.get_spendable_singleton_info(launcher_id)
399
+
400
+ if root_hash is None:
401
+ root_hash = singleton_record.root
402
+
403
+ inner_puzzle_derivation: Optional[
404
+ DerivationRecord
405
+ ] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(
406
+ singleton_record.inner_puzzle_hash
407
+ )
408
+ if inner_puzzle_derivation is None:
409
+ raise ValueError(f"DL Wallet does not have permission to update Singleton with launcher ID {launcher_id}")
410
+
411
+ # Make the child's puzzles
412
+ if new_puz_hash is None:
413
+ new_puz_hash = await self.standard_wallet.get_puzzle_hash(
414
+ new=not action_scope.config.tx_config.reuse_puzhash
415
+ )
416
+ assert new_puz_hash is not None
417
+ next_full_puz_hash: bytes32 = create_host_fullpuz(new_puz_hash, root_hash, launcher_id).get_tree_hash_precalc(
418
+ new_puz_hash
419
+ )
420
+
421
+ # Construct the current puzzles
422
+ current_inner_puzzle: Program = self.standard_wallet.puzzle_for_pk(inner_puzzle_derivation.pubkey)
423
+ current_full_puz = create_host_fullpuz(
424
+ current_inner_puzzle,
425
+ singleton_record.root,
426
+ launcher_id,
427
+ )
428
+ assert singleton_record.lineage_proof.parent_name is not None
429
+ assert singleton_record.lineage_proof.amount is not None
430
+ current_coin = Coin(
431
+ singleton_record.lineage_proof.parent_name,
432
+ current_full_puz.get_tree_hash(),
433
+ singleton_record.lineage_proof.amount,
434
+ )
435
+
436
+ new_singleton_record = SingletonRecord(
437
+ coin_id=Coin(current_coin.name(), next_full_puz_hash, singleton_record.lineage_proof.amount).name(),
438
+ launcher_id=launcher_id,
439
+ root=root_hash,
440
+ inner_puzzle_hash=new_puz_hash,
441
+ confirmed=False,
442
+ confirmed_at_height=uint32(0),
443
+ timestamp=uint64(0),
444
+ lineage_proof=LineageProof(
445
+ singleton_record.coin_id,
446
+ new_puz_hash,
447
+ singleton_record.lineage_proof.amount,
448
+ ),
449
+ generation=uint32(singleton_record.generation + 1),
450
+ )
451
+
452
+ # Optionally add an ephemeral spend to announce
453
+ if announce_new_state:
454
+ announce_only: Program = Program.to(
455
+ (
456
+ 1,
457
+ [
458
+ [
459
+ 51,
460
+ new_puz_hash,
461
+ singleton_record.lineage_proof.amount,
462
+ [launcher_id, root_hash, new_puz_hash],
463
+ ],
464
+ [62, b"$"],
465
+ ],
466
+ )
467
+ )
468
+ second_full_puz: Program = create_host_fullpuz(
469
+ announce_only,
470
+ root_hash,
471
+ launcher_id,
472
+ )
473
+ second_coin = Coin(
474
+ current_coin.name(), second_full_puz.get_tree_hash(), singleton_record.lineage_proof.amount
475
+ )
476
+ second_coin_spend = CoinSpend(
477
+ second_coin,
478
+ SerializedProgram.from_program(second_full_puz),
479
+ SerializedProgram.to(
480
+ [
481
+ LineageProof(
482
+ current_coin.parent_coin_info,
483
+ create_host_layer_puzzle(current_inner_puzzle, singleton_record.root).get_tree_hash(),
484
+ singleton_record.lineage_proof.amount,
485
+ ).to_program(),
486
+ singleton_record.lineage_proof.amount,
487
+ [[]],
488
+ ]
489
+ ),
490
+ )
491
+ extra_conditions += (
492
+ AssertPuzzleAnnouncement(asserted_ph=second_full_puz.get_tree_hash(), asserted_msg=b"$"),
493
+ )
494
+ second_singleton_record = SingletonRecord(
495
+ coin_id=second_coin.name(),
496
+ launcher_id=launcher_id,
497
+ root=root_hash,
498
+ inner_puzzle_hash=announce_only.get_tree_hash(),
499
+ confirmed=False,
500
+ confirmed_at_height=uint32(0),
501
+ timestamp=uint64(0),
502
+ lineage_proof=LineageProof(
503
+ second_coin.parent_coin_info,
504
+ announce_only.get_tree_hash(),
505
+ singleton_record.lineage_proof.amount,
506
+ ),
507
+ generation=uint32(singleton_record.generation + 1),
508
+ )
509
+ new_singleton_record = dataclasses.replace(
510
+ new_singleton_record,
511
+ coin_id=Coin(second_coin.name(), next_full_puz_hash, singleton_record.lineage_proof.amount).name(),
512
+ lineage_proof=LineageProof(
513
+ second_coin.name(),
514
+ next_full_puz_hash,
515
+ singleton_record.lineage_proof.amount,
516
+ ),
517
+ generation=uint32(second_singleton_record.generation + 1),
518
+ )
519
+
520
+ # Create the solution
521
+ primaries = [
522
+ Payment(
523
+ announce_only.get_tree_hash() if announce_new_state else new_puz_hash,
524
+ singleton_record.lineage_proof.amount if new_amount is None else new_amount,
525
+ [
526
+ launcher_id,
527
+ root_hash,
528
+ announce_only.get_tree_hash() if announce_new_state else new_puz_hash,
529
+ ],
530
+ )
531
+ ]
532
+ if root_hash != singleton_record.root:
533
+ extra_conditions = (
534
+ *extra_conditions,
535
+ UnknownCondition(
536
+ opcode=Program.to(-24),
537
+ args=[
538
+ ACS_MU,
539
+ Program.to([[(root_hash, None), ACS_MU_PH], None]),
540
+ ],
541
+ ),
542
+ )
543
+ inner_sol: Program = self.standard_wallet.make_solution(
544
+ primaries=primaries,
545
+ conditions=(*extra_conditions, CreateCoinAnnouncement(b"$")) if fee > 0 else extra_conditions,
546
+ )
547
+ db_layer_sol = Program.to([inner_sol])
548
+ full_sol = Program.to(
549
+ [
550
+ parent_lineage.to_program(),
551
+ singleton_record.lineage_proof.amount,
552
+ db_layer_sol,
553
+ ]
554
+ )
555
+
556
+ # Create the spend
557
+ coin_spend = CoinSpend(
558
+ current_coin,
559
+ SerializedProgram.from_program(current_full_puz),
560
+ SerializedProgram.from_program(full_sol),
561
+ )
562
+
563
+ spend_bundle = WalletSpendBundle([coin_spend], G2Element())
564
+
565
+ if announce_new_state:
566
+ spend_bundle = WalletSpendBundle([coin_spend, second_coin_spend], spend_bundle.aggregated_signature)
567
+
568
+ dl_tx = TransactionRecord(
569
+ confirmed_at_height=uint32(0),
570
+ created_at_time=uint64(int(time.time())),
571
+ to_puzzle_hash=new_puz_hash,
572
+ amount=uint64(singleton_record.lineage_proof.amount),
573
+ fee_amount=fee,
574
+ confirmed=False,
575
+ sent=uint32(10),
576
+ spend_bundle=spend_bundle,
577
+ additions=spend_bundle.additions(),
578
+ removals=spend_bundle.removals(),
579
+ memos=list(compute_memos(spend_bundle).items()),
580
+ wallet_id=self.id(),
581
+ sent_to=[],
582
+ trade_id=None,
583
+ type=uint32(TransactionType.OUTGOING_TX.value),
584
+ name=singleton_record.coin_id,
585
+ valid_times=parse_timelock_info(extra_conditions),
586
+ )
587
+ assert dl_tx.spend_bundle is not None
588
+ if fee > 0:
589
+ await self.create_tandem_xch_tx(
590
+ fee,
591
+ AssertAnnouncement(True, asserted_origin_id=current_coin.name(), asserted_msg=b"$"),
592
+ action_scope,
593
+ )
594
+
595
+ if add_pending_singleton:
596
+ await self.wallet_state_manager.dl_store.add_singleton_record(
597
+ new_singleton_record,
598
+ )
599
+ if announce_new_state:
600
+ await self.wallet_state_manager.dl_store.add_singleton_record(
601
+ second_singleton_record,
602
+ )
603
+
604
+ async with action_scope.use() as interface:
605
+ interface.side_effects.transactions.append(dl_tx)
606
+
607
+ async def generate_signed_transaction(
608
+ self,
609
+ amounts: list[uint64],
610
+ puzzle_hashes: list[bytes32],
611
+ action_scope: WalletActionScope,
612
+ fee: uint64 = uint64(0),
613
+ coins: set[Coin] = set(),
614
+ memos: Optional[list[list[bytes]]] = None, # ignored
615
+ extra_conditions: tuple[Condition, ...] = tuple(),
616
+ **kwargs: Unpack[GSTOptionalArgs],
617
+ ) -> None:
618
+ launcher_id: Optional[bytes32] = kwargs.get("launcher_id", None)
619
+ new_root_hash: Optional[bytes32] = kwargs.get("new_root_hash", None)
620
+ add_pending_singleton: bool = kwargs.get("add_pending_singleton", True)
621
+ announce_new_state: bool = kwargs.get("announce_new_state", False)
622
+ # Figure out the launcher ID
623
+ if len(coins) == 0:
624
+ if launcher_id is None:
625
+ raise ValueError("Not enough info to know which DL coin to send")
626
+ else:
627
+ if len(coins) != 1:
628
+ raise ValueError("The wallet can only send one DL coin at a time")
629
+ else:
630
+ record = await self.wallet_state_manager.dl_store.get_singleton_record(next(iter(coins)).name())
631
+ if record is None:
632
+ raise ValueError("The specified coin is not a tracked DL")
633
+ else:
634
+ launcher_id = record.launcher_id
635
+
636
+ if len(amounts) != 1 or len(puzzle_hashes) != 1:
637
+ raise ValueError("The wallet can only send one DL coin to one place at a time")
638
+
639
+ await self.create_update_state_spend(
640
+ launcher_id,
641
+ new_root_hash,
642
+ action_scope,
643
+ puzzle_hashes[0],
644
+ amounts[0],
645
+ fee,
646
+ add_pending_singleton,
647
+ announce_new_state,
648
+ extra_conditions,
649
+ )
650
+
651
+ async def get_spendable_singleton_info(self, launcher_id: bytes32) -> tuple[SingletonRecord, LineageProof]:
652
+ # First, let's make sure this is a singleton that we track and that we can spend
653
+ singleton_record: Optional[SingletonRecord] = await self.get_latest_singleton(launcher_id)
654
+ if singleton_record is None:
655
+ raise ValueError(f"Singleton with launcher ID {launcher_id} is not tracked by DL Wallet")
656
+
657
+ # Next, the singleton should be confirmed or else we shouldn't be ready to spend it
658
+ if not singleton_record.confirmed:
659
+ raise ValueError(f"Singleton with launcher ID {launcher_id} is currently pending")
660
+
661
+ # Next, let's verify we have all of the relevant coin information
662
+ if singleton_record.lineage_proof.parent_name is None or singleton_record.lineage_proof.amount is None:
663
+ raise ValueError(f"Singleton with launcher ID {launcher_id} has insufficient information to spend")
664
+
665
+ # Finally, let's get the parent record for its lineage proof
666
+ parent_singleton: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singleton_record(
667
+ singleton_record.lineage_proof.parent_name
668
+ )
669
+ parent_lineage: LineageProof
670
+ if parent_singleton is None:
671
+ if singleton_record.lineage_proof.parent_name != launcher_id:
672
+ raise ValueError(f"Have not found the parent of singleton with launcher ID {launcher_id}")
673
+ else:
674
+ launcher_coin: Optional[Coin] = await self.wallet_state_manager.dl_store.get_launcher(launcher_id)
675
+ if launcher_coin is None:
676
+ raise ValueError(f"DL Wallet does not have launcher info for id {launcher_id}")
677
+ else:
678
+ parent_lineage = LineageProof(launcher_coin.parent_coin_info, None, uint64(launcher_coin.amount))
679
+ else:
680
+ parent_lineage = parent_singleton.lineage_proof
681
+
682
+ return singleton_record, parent_lineage
683
+
684
+ async def get_owned_singletons(self) -> list[SingletonRecord]:
685
+ launcher_ids = await self.wallet_state_manager.dl_store.get_all_launchers()
686
+
687
+ collected = []
688
+
689
+ for launcher_id in launcher_ids:
690
+ singleton_record = await self.wallet_state_manager.dl_store.get_latest_singleton(launcher_id=launcher_id)
691
+ if singleton_record is None:
692
+ # this is likely due to a race between getting the list and acquiring the extra data
693
+ continue
694
+
695
+ inner_puzzle_derivation: Optional[
696
+ DerivationRecord
697
+ ] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(
698
+ singleton_record.inner_puzzle_hash
699
+ )
700
+ if inner_puzzle_derivation is not None:
701
+ collected.append(singleton_record)
702
+
703
+ return collected
704
+
705
+ async def create_new_mirror(
706
+ self,
707
+ launcher_id: bytes32,
708
+ amount: uint64,
709
+ urls: list[bytes],
710
+ action_scope: WalletActionScope,
711
+ fee: uint64 = uint64(0),
712
+ extra_conditions: tuple[Condition, ...] = tuple(),
713
+ ) -> None:
714
+ await self.standard_wallet.generate_signed_transaction(
715
+ amount=amount,
716
+ puzzle_hash=create_mirror_puzzle().get_tree_hash(),
717
+ action_scope=action_scope,
718
+ fee=fee,
719
+ primaries=[],
720
+ memos=[launcher_id, *(url for url in urls)],
721
+ extra_conditions=extra_conditions,
722
+ )
723
+
724
+ async def delete_mirror(
725
+ self,
726
+ mirror_id: bytes32,
727
+ peer: WSChiaConnection,
728
+ action_scope: WalletActionScope,
729
+ fee: uint64 = uint64(0),
730
+ extra_conditions: tuple[Condition, ...] = tuple(),
731
+ ) -> None:
732
+ mirror: Mirror = await self.get_mirror(mirror_id)
733
+ mirror_coin: Coin = (await self.wallet_state_manager.wallet_node.get_coin_state([mirror.coin_id], peer=peer))[
734
+ 0
735
+ ].coin
736
+ parent_coin: Coin = (
737
+ await self.wallet_state_manager.wallet_node.get_coin_state([mirror_coin.parent_coin_info], peer=peer)
738
+ )[0].coin
739
+ inner_puzzle_derivation: Optional[
740
+ DerivationRecord
741
+ ] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(parent_coin.puzzle_hash)
742
+ if inner_puzzle_derivation is None:
743
+ raise ValueError(f"DL Wallet does not have permission to delete mirror with ID {mirror_id}")
744
+
745
+ parent_inner_puzzle: Program = self.standard_wallet.puzzle_for_pk(inner_puzzle_derivation.pubkey)
746
+ new_puzhash: bytes32 = await self.standard_wallet.get_puzzle_hash(
747
+ new=not action_scope.config.tx_config.reuse_puzhash
748
+ )
749
+ excess_fee: int = fee - mirror_coin.amount
750
+ inner_sol: Program = self.standard_wallet.make_solution(
751
+ primaries=[Payment(new_puzhash, uint64(mirror_coin.amount - fee))] if excess_fee < 0 else [],
752
+ conditions=(*extra_conditions, CreateCoinAnnouncement(b"$")) if excess_fee > 0 else extra_conditions,
753
+ )
754
+ mirror_spend = CoinSpend(
755
+ mirror_coin,
756
+ SerializedProgram.from_program(create_mirror_puzzle()),
757
+ SerializedProgram.to(
758
+ [
759
+ parent_coin.parent_coin_info,
760
+ parent_inner_puzzle,
761
+ parent_coin.amount,
762
+ inner_sol,
763
+ ]
764
+ ),
765
+ )
766
+ mirror_bundle = WalletSpendBundle([mirror_spend], G2Element())
767
+
768
+ async with action_scope.use() as interface:
769
+ interface.side_effects.transactions.append(
770
+ TransactionRecord(
771
+ confirmed_at_height=uint32(0),
772
+ created_at_time=uint64(int(time.time())),
773
+ to_puzzle_hash=new_puzhash,
774
+ amount=uint64(mirror_coin.amount),
775
+ fee_amount=fee,
776
+ confirmed=False,
777
+ sent=uint32(10),
778
+ spend_bundle=mirror_bundle,
779
+ additions=mirror_bundle.additions(),
780
+ removals=mirror_bundle.removals(),
781
+ memos=list(compute_memos(mirror_bundle).items()),
782
+ wallet_id=self.id(), # This is being called before the wallet is created so we're using a ID of 0
783
+ sent_to=[],
784
+ trade_id=None,
785
+ type=uint32(TransactionType.OUTGOING_TX.value),
786
+ name=mirror_bundle.name(),
787
+ valid_times=parse_timelock_info(extra_conditions),
788
+ )
789
+ )
790
+
791
+ if excess_fee > 0:
792
+ await self.wallet_state_manager.main_wallet.generate_signed_transaction(
793
+ uint64(1),
794
+ new_puzhash,
795
+ action_scope,
796
+ fee=uint64(excess_fee),
797
+ extra_conditions=(AssertCoinAnnouncement(asserted_id=mirror_coin.name(), asserted_msg=b"$"),),
798
+ )
799
+
800
+ ###########
801
+ # SYNCING #
802
+ ###########
803
+
804
+ async def coin_added(self, coin: Coin, height: uint32, peer: WSChiaConnection, coin_data: Optional[object]) -> None:
805
+ if coin.puzzle_hash == create_mirror_puzzle().get_tree_hash():
806
+ parent_state: CoinState = (
807
+ await self.wallet_state_manager.wallet_node.get_coin_state([coin.parent_coin_info], peer=peer)
808
+ )[0]
809
+ parent_spend = await fetch_coin_spend(height, parent_state.coin, peer)
810
+ assert parent_spend is not None
811
+ launcher_id, urls = get_mirror_info(parent_spend.puzzle_reveal, parent_spend.solution)
812
+ # Don't track mirrors with empty url list.
813
+ if not urls:
814
+ return
815
+ if await self.wallet_state_manager.dl_store.is_launcher_tracked(launcher_id):
816
+ ours: bool = await self.wallet_state_manager.get_wallet_for_coin(coin.parent_coin_info) is not None
817
+ await self.wallet_state_manager.dl_store.add_mirror(
818
+ Mirror(
819
+ coin.name(),
820
+ launcher_id,
821
+ uint64(coin.amount),
822
+ urls,
823
+ ours,
824
+ height,
825
+ )
826
+ )
827
+ await self.wallet_state_manager.add_interested_coin_ids([coin.name()])
828
+
829
+ async def singleton_removed(self, parent_spend: CoinSpend, height: uint32) -> None:
830
+ parent_name = parent_spend.coin.name()
831
+ puzzle = parent_spend.puzzle_reveal
832
+ solution = parent_spend.solution
833
+
834
+ matched, _ = match_dl_singleton(puzzle)
835
+ if matched:
836
+ self.log.info(f"DL singleton removed: {parent_spend.coin}")
837
+ singleton_record: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singleton_record(
838
+ parent_name
839
+ )
840
+ if singleton_record is None:
841
+ self.log.warning(f"DL wallet received coin it does not have parent for. Expected parent {parent_name}.")
842
+ return
843
+
844
+ # Information we need to create the singleton record
845
+ full_puzzle_hash: bytes32
846
+ amount: uint64
847
+ root: bytes32
848
+ inner_puzzle_hash: bytes32
849
+
850
+ conditions = puzzle.run_with_cost(self.wallet_state_manager.constants.MAX_BLOCK_COST_CLVM, solution)[
851
+ 1
852
+ ].as_python()
853
+ found_singleton: bool = False
854
+ for condition in conditions:
855
+ if condition[0] == ConditionOpcode.CREATE_COIN and int.from_bytes(condition[2], "big") % 2 == 1:
856
+ full_puzzle_hash = bytes32(condition[1])
857
+ amount = uint64(int.from_bytes(condition[2], "big"))
858
+ try:
859
+ root = bytes32(condition[3][1])
860
+ inner_puzzle_hash = bytes32(condition[3][2])
861
+ except IndexError:
862
+ self.log.warning(
863
+ f"Parent {parent_name} with launcher {singleton_record.launcher_id} "
864
+ "did not hint its child properly"
865
+ )
866
+ return
867
+ found_singleton = True
868
+ break
869
+
870
+ if not found_singleton:
871
+ self.log.warning(f"Singleton with launcher ID {singleton_record.launcher_id} was melted")
872
+ return
873
+
874
+ new_singleton = Coin(parent_name, full_puzzle_hash, amount)
875
+ timestamp = await self.wallet_state_manager.wallet_node.get_timestamp_for_height(height)
876
+ await self.wallet_state_manager.dl_store.add_singleton_record(
877
+ SingletonRecord(
878
+ coin_id=new_singleton.name(),
879
+ launcher_id=singleton_record.launcher_id,
880
+ root=root,
881
+ inner_puzzle_hash=inner_puzzle_hash,
882
+ confirmed=True,
883
+ confirmed_at_height=height,
884
+ timestamp=timestamp,
885
+ lineage_proof=LineageProof(
886
+ parent_name,
887
+ create_host_layer_puzzle(inner_puzzle_hash, root).get_tree_hash_precalc(inner_puzzle_hash),
888
+ amount,
889
+ ),
890
+ generation=uint32(singleton_record.generation + 1),
891
+ )
892
+ )
893
+ await self.wallet_state_manager.add_interested_coin_ids(
894
+ [new_singleton.name()],
895
+ )
896
+ elif parent_spend.coin.puzzle_hash == create_mirror_puzzle().get_tree_hash():
897
+ await self.wallet_state_manager.dl_store.delete_mirror(parent_name)
898
+
899
+ async def stop_tracking_singleton(self, launcher_id: bytes32) -> None:
900
+ await self.wallet_state_manager.dl_store.delete_singleton_records_by_launcher_id(launcher_id)
901
+ await self.wallet_state_manager.dl_store.delete_launcher(launcher_id)
902
+
903
+ ###########
904
+ # UTILITY #
905
+ ###########
906
+
907
+ async def get_latest_singleton(
908
+ self, launcher_id: bytes32, only_confirmed: bool = False
909
+ ) -> Optional[SingletonRecord]:
910
+ singleton: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_latest_singleton(
911
+ launcher_id, only_confirmed
912
+ )
913
+ return singleton
914
+
915
+ async def get_history(
916
+ self,
917
+ launcher_id: bytes32,
918
+ min_generation: Optional[uint32] = None,
919
+ max_generation: Optional[uint32] = None,
920
+ num_results: Optional[uint32] = None,
921
+ ) -> list[SingletonRecord]:
922
+ history: list[SingletonRecord] = await self.wallet_state_manager.dl_store.get_all_singletons_for_launcher(
923
+ launcher_id,
924
+ min_generation,
925
+ max_generation,
926
+ num_results,
927
+ )
928
+ return history
929
+
930
+ async def get_singleton_record(self, coin_id: bytes32) -> Optional[SingletonRecord]:
931
+ singleton: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singleton_record(coin_id)
932
+ return singleton
933
+
934
+ async def get_singletons_by_root(self, launcher_id: bytes32, root: bytes32) -> list[SingletonRecord]:
935
+ singletons: list[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singletons_by_root(
936
+ launcher_id, root
937
+ )
938
+ return singletons
939
+
940
+ async def get_mirrors_for_launcher(self, launcher_id: bytes32) -> list[Mirror]:
941
+ return await self.wallet_state_manager.dl_store.get_mirrors(launcher_id)
942
+
943
+ async def get_mirror(self, coin_id: bytes32) -> Mirror:
944
+ return await self.wallet_state_manager.dl_store.get_mirror(coin_id)
945
+
946
+ ##########
947
+ # WALLET #
948
+ ##########
949
+
950
+ def require_derivation_paths(self) -> bool:
951
+ return True
952
+
953
+ def puzzle_hash_for_pk(self, pubkey: G1Element) -> bytes32:
954
+ puzzle: Program = self.puzzle_for_pk(pubkey)
955
+ return puzzle.get_tree_hash()
956
+
957
+ def puzzle_for_pk(self, pubkey: G1Element) -> Program:
958
+ return self.standard_wallet.puzzle_for_pk(pubkey)
959
+
960
+ async def get_new_puzzle(self) -> Program:
961
+ return self.puzzle_for_pk(
962
+ (await self.wallet_state_manager.get_unused_derivation_record(self.wallet_info.id)).pubkey
963
+ )
964
+
965
+ async def get_new_puzzlehash(self) -> bytes32:
966
+ return (await self.get_new_puzzle()).get_tree_hash()
967
+
968
+ async def new_peak(self, peak: BlockRecord) -> None:
969
+ pass
970
+
971
+ async def get_confirmed_balance(self, record_list: Optional[set[WalletCoinRecord]] = None) -> uint128:
972
+ return uint128(0)
973
+
974
+ async def get_unconfirmed_balance(self, record_list: Optional[set[WalletCoinRecord]] = None) -> uint128:
975
+ return uint128(0)
976
+
977
+ async def get_spendable_balance(self, unspent_records: Optional[set[WalletCoinRecord]] = None) -> uint128:
978
+ return uint128(0)
979
+
980
+ async def get_pending_change_balance(self) -> uint64:
981
+ return uint64(0)
982
+
983
+ async def get_max_send_amount(self, unspent_records: Optional[set[WalletCoinRecord]] = None) -> uint128:
984
+ return uint128(0)
985
+
986
+ def get_name(self) -> str:
987
+ return self.wallet_info.name
988
+
989
+ ##########
990
+ # OFFERS #
991
+ ##########
992
+
993
+ async def get_puzzle_info(self, launcher_id: bytes32) -> PuzzleInfo:
994
+ record = await self.get_latest_singleton(launcher_id)
995
+ if record is None:
996
+ raise ValueError(f"DL wallet does not know about launcher ID {launcher_id}")
997
+ return PuzzleInfo(
998
+ {
999
+ "type": AssetType.SINGLETON.value,
1000
+ "launcher_id": "0x" + launcher_id.hex(),
1001
+ "launcher_ph": "0x" + SINGLETON_LAUNCHER_HASH.hex(),
1002
+ "also": {
1003
+ "type": AssetType.METADATA.value,
1004
+ "metadata": f"(0x{record.root} . ())",
1005
+ "updater_hash": "0x" + ACS_MU_PH.hex(),
1006
+ },
1007
+ }
1008
+ )
1009
+
1010
+ async def get_coins_to_offer(self, launcher_id: bytes32, *args: Any, **kwargs: Any) -> set[Coin]:
1011
+ record = await self.get_latest_singleton(launcher_id)
1012
+ if record is None:
1013
+ raise ValueError(f"DL wallet does not know about launcher ID {launcher_id}")
1014
+ puzhash: bytes32 = create_host_fullpuz(
1015
+ record.inner_puzzle_hash, record.root, launcher_id
1016
+ ).get_tree_hash_precalc(record.inner_puzzle_hash)
1017
+ assert record.lineage_proof.parent_name is not None
1018
+ assert record.lineage_proof.amount is not None
1019
+ return {Coin(record.lineage_proof.parent_name, puzhash, record.lineage_proof.amount)}
1020
+
1021
+ @staticmethod
1022
+ async def make_update_offer(
1023
+ wallet_state_manager: Any,
1024
+ offer_dict: dict[Optional[bytes32], int],
1025
+ driver_dict: dict[bytes32, PuzzleInfo],
1026
+ solver: Solver,
1027
+ action_scope: WalletActionScope,
1028
+ fee: uint64 = uint64(0),
1029
+ extra_conditions: tuple[Condition, ...] = tuple(),
1030
+ ) -> Offer:
1031
+ dl_wallet = None
1032
+ for wallet in wallet_state_manager.wallets.values():
1033
+ if wallet.type() == WalletType.DATA_LAYER.value:
1034
+ dl_wallet = wallet
1035
+ break
1036
+ if dl_wallet is None:
1037
+ raise ValueError("DL Wallet is not initialized")
1038
+
1039
+ offered_launchers: list[bytes32] = [k for k, v in offer_dict.items() if v < 0 and k is not None]
1040
+ fee_left_to_pay: uint64 = fee
1041
+ all_transactions: list[TransactionRecord] = []
1042
+ for launcher in offered_launchers:
1043
+ try:
1044
+ this_solver: Solver = solver[launcher.hex()]
1045
+ except KeyError:
1046
+ this_solver = solver["0x" + launcher.hex()]
1047
+ new_root: bytes32 = this_solver["new_root"]
1048
+ new_ph: bytes32 = await wallet_state_manager.main_wallet.get_puzzle_hash(
1049
+ new=not action_scope.config.tx_config.reuse_puzhash
1050
+ )
1051
+ async with wallet_state_manager.new_action_scope(
1052
+ action_scope.config.tx_config, push=False
1053
+ ) as inner_action_scope:
1054
+ await dl_wallet.generate_signed_transaction(
1055
+ [uint64(1)],
1056
+ [new_ph],
1057
+ inner_action_scope,
1058
+ fee=fee_left_to_pay,
1059
+ launcher_id=launcher,
1060
+ new_root_hash=new_root,
1061
+ add_pending_singleton=False,
1062
+ announce_new_state=True,
1063
+ extra_conditions=extra_conditions,
1064
+ )
1065
+ fee_left_to_pay = uint64(0)
1066
+ extra_conditions = tuple()
1067
+
1068
+ async with inner_action_scope.use() as interface:
1069
+ dl_spend: CoinSpend = next(
1070
+ cs
1071
+ for tx in interface.side_effects.transactions
1072
+ for cs in tx.spend_bundle.coin_spends
1073
+ if tx.spend_bundle is not None and match_dl_singleton(cs.puzzle_reveal)[0]
1074
+ )
1075
+ dl_solution: Program = dl_spend.solution.to_program()
1076
+ old_graftroot: Program = dl_solution.at("rrffrf")
1077
+ new_graftroot: Program = create_graftroot_offer_puz(
1078
+ [bytes32(dep["launcher_id"]) for dep in this_solver["dependencies"]],
1079
+ [list(v for v in dep["values_to_prove"]) for dep in this_solver["dependencies"]],
1080
+ old_graftroot,
1081
+ )
1082
+
1083
+ new_solution: Program = dl_solution.replace(rrffrf=new_graftroot, rrffrrf=Program.to([None] * 5))
1084
+ new_spend: CoinSpend = dl_spend.replace(solution=SerializedProgram.from_program(new_solution))
1085
+ async with inner_action_scope.use() as interface:
1086
+ for i, tx in enumerate(interface.side_effects.transactions):
1087
+ if tx.spend_bundle is not None and dl_spend in tx.spend_bundle.coin_spends:
1088
+ break
1089
+ else:
1090
+ # No test coverage for this line because it should never be reached
1091
+ raise RuntimeError("Internal logic error while constructing update offer") # pragma: no cover
1092
+ new_bundle = WalletSpendBundle(
1093
+ [
1094
+ *(
1095
+ cs
1096
+ for cs in interface.side_effects.transactions[i].spend_bundle.coin_spends
1097
+ if cs != dl_spend
1098
+ ),
1099
+ new_spend,
1100
+ ],
1101
+ G2Element(),
1102
+ )
1103
+ interface.side_effects.transactions[i] = dataclasses.replace(
1104
+ interface.side_effects.transactions[i], spend_bundle=new_bundle, name=new_bundle.name()
1105
+ )
1106
+
1107
+ all_transactions.extend(inner_action_scope.side_effects.transactions)
1108
+
1109
+ # create some dummy requested payments
1110
+ requested_payments = {
1111
+ k: [NotarizedPayment(bytes32.zeros, uint64(v), [], bytes32.zeros)] for k, v in offer_dict.items() if v > 0
1112
+ }
1113
+
1114
+ async with action_scope.use() as interface:
1115
+ interface.side_effects.transactions.extend(all_transactions)
1116
+
1117
+ return Offer(
1118
+ requested_payments,
1119
+ WalletSpendBundle.aggregate([tx.spend_bundle for tx in all_transactions if tx.spend_bundle is not None]),
1120
+ driver_dict,
1121
+ )
1122
+
1123
+ @staticmethod
1124
+ async def finish_graftroot_solutions(offer: Offer, solver: Solver) -> Offer:
1125
+ # Build a mapping of launcher IDs to their new innerpuz
1126
+ singleton_to_innerpuzhash: dict[bytes32, bytes32] = {}
1127
+ singleton_to_root: dict[bytes32, bytes32] = {}
1128
+ all_parent_ids: list[bytes32] = [cs.coin.parent_coin_info for cs in offer.coin_spends()]
1129
+ for spend in offer.coin_spends():
1130
+ matched, curried_args = match_dl_singleton(spend.puzzle_reveal)
1131
+ if matched and spend.coin.name() not in all_parent_ids:
1132
+ innerpuz, root_prg, launcher_id = curried_args
1133
+ singleton_struct = launcher_to_struct(bytes32(launcher_id.as_python())).get_tree_hash()
1134
+ singleton_to_root[singleton_struct] = bytes32(root_prg.as_python())
1135
+ singleton_to_innerpuzhash[singleton_struct] = innerpuz.get_tree_hash()
1136
+
1137
+ # Create all of the new solutions
1138
+ new_spends: list[CoinSpend] = []
1139
+ for spend in offer.coin_spends():
1140
+ solution = spend.solution.to_program()
1141
+ if match_dl_singleton(spend.puzzle_reveal)[0]:
1142
+ try:
1143
+ graftroot: Program = solution.at("rrffrf")
1144
+ except EvalError:
1145
+ new_spends.append(spend)
1146
+ continue
1147
+ mod, curried_args_prg = graftroot.uncurry()
1148
+ if mod == GRAFTROOT_DL_OFFERS:
1149
+ _, singleton_structs, _, values_to_prove = curried_args_prg.as_iter()
1150
+ all_proofs = []
1151
+ roots = []
1152
+ for singleton, values in zip(singleton_structs.as_iter(), values_to_prove.as_python()):
1153
+ asserted_root: Optional[str] = None
1154
+ proofs_of_inclusion = []
1155
+ for value in values:
1156
+ for proof_of_inclusion in solver["proofs_of_inclusion"]:
1157
+ root: str = proof_of_inclusion[0]
1158
+ proof: tuple[int, list[bytes32]] = (proof_of_inclusion[1], proof_of_inclusion[2])
1159
+ calculated_root: bytes32 = _simplify_merkle_proof(value, proof)
1160
+ if (
1161
+ calculated_root == bytes32.from_hexstr(root)
1162
+ and calculated_root == singleton_to_root[singleton.get_tree_hash()]
1163
+ ):
1164
+ proofs_of_inclusion.append(proof)
1165
+ if asserted_root is None:
1166
+ asserted_root = root
1167
+ elif asserted_root != root:
1168
+ raise ValueError("Malformed DL offer")
1169
+ break
1170
+ roots.append(asserted_root)
1171
+ all_proofs.append(proofs_of_inclusion)
1172
+ if sum(len(proofs) for proofs in all_proofs) < sum(1 for _ in values_to_prove.as_iter()):
1173
+ raise ValueError("One or more proofs of inclusion were invalid")
1174
+ new_solution: Program = solution.replace(
1175
+ rrffrrf=Program.to(
1176
+ [
1177
+ all_proofs,
1178
+ [Program.to((bytes32.from_hexstr(root), None)) for root in roots if root is not None],
1179
+ [ACS_MU_PH] * len(all_proofs),
1180
+ [
1181
+ singleton_to_innerpuzhash[struct.get_tree_hash()]
1182
+ for struct in singleton_structs.as_iter()
1183
+ ],
1184
+ solution.at("rrffrrfrrrrf"),
1185
+ ]
1186
+ )
1187
+ )
1188
+ new_spend: CoinSpend = spend.replace(solution=SerializedProgram.from_program(new_solution))
1189
+ spend = new_spend
1190
+ new_spends.append(spend)
1191
+
1192
+ return Offer({}, WalletSpendBundle(new_spends, offer.aggregated_signature()), offer.driver_dict)
1193
+
1194
+ @staticmethod
1195
+ async def get_offer_summary(offer: Offer) -> dict[str, Any]:
1196
+ summary: dict[str, Any] = {"offered": []}
1197
+ for spend in offer.coin_spends():
1198
+ solution = spend.solution.to_program()
1199
+ matched, curried_args = match_dl_singleton(spend.puzzle_reveal)
1200
+ if matched:
1201
+ try:
1202
+ graftroot: Program = solution.at("rrffrf")
1203
+ except EvalError:
1204
+ continue
1205
+ mod, graftroot_curried_args = graftroot.uncurry()
1206
+ if mod == GRAFTROOT_DL_OFFERS:
1207
+ child_spend: CoinSpend = next(
1208
+ cs for cs in offer.coin_spends() if cs.coin.parent_coin_info == spend.coin.name()
1209
+ )
1210
+ _, child_curried_args = match_dl_singleton(child_spend.puzzle_reveal)
1211
+ singleton_summary = {
1212
+ "launcher_id": list(curried_args)[2].as_python().hex(),
1213
+ "new_root": list(child_curried_args)[1].as_python().hex(),
1214
+ "dependencies": [],
1215
+ }
1216
+ _, singleton_structs, _, values_to_prove = graftroot_curried_args.as_iter()
1217
+ for struct, values in zip(singleton_structs.as_iter(), values_to_prove.as_iter()):
1218
+ singleton_summary["dependencies"].append(
1219
+ {
1220
+ "launcher_id": struct.at("rf").as_python().hex(),
1221
+ "values_to_prove": [value.as_python().hex() for value in values.as_iter()],
1222
+ }
1223
+ )
1224
+ summary["offered"].append(singleton_summary)
1225
+ return summary
1226
+
1227
+ async def select_coins(
1228
+ self,
1229
+ amount: uint64,
1230
+ action_scope: WalletActionScope,
1231
+ ) -> set[Coin]:
1232
+ raise RuntimeError("DataLayerWallet does not support select_coins()")
1233
+
1234
+ async def match_hinted_coin(self, coin: Coin, hint: bytes32) -> bool:
1235
+ return coin.amount % 2 == 1 and await self.wallet_state_manager.dl_store.get_launcher(hint) is not None
1236
+
1237
+
1238
+ def verify_offer(
1239
+ maker: tuple[StoreProofs, ...],
1240
+ taker: tuple[OfferStore, ...],
1241
+ summary: dict[str, Any],
1242
+ ) -> None:
1243
+ # TODO: consistency in error messages
1244
+ # TODO: custom exceptions
1245
+ # TODO: show data in errors?
1246
+ # TODO: collect and report all failures
1247
+ # TODO: review for case coverage (and test those cases)
1248
+
1249
+ if len({store_proof.store_id for store_proof in maker}) != len(maker):
1250
+ raise OfferIntegrityError("maker: repeated store id")
1251
+
1252
+ for store_proof in maker:
1253
+ proofs: list[ProofOfInclusion] = []
1254
+ for reference_proof in store_proof.proofs:
1255
+ proof = ProofOfInclusion(
1256
+ node_hash=reference_proof.node_hash,
1257
+ layers=[
1258
+ ProofOfInclusionLayer(
1259
+ other_hash_side=layer.other_hash_side,
1260
+ other_hash=layer.other_hash,
1261
+ combined_hash=layer.combined_hash,
1262
+ )
1263
+ for layer in reference_proof.layers
1264
+ ],
1265
+ )
1266
+
1267
+ proofs.append(proof)
1268
+
1269
+ if leaf_hash(key=reference_proof.key, value=reference_proof.value) != proof.node_hash:
1270
+ raise OfferIntegrityError("maker: node hash does not match key and value")
1271
+
1272
+ if not proof.valid():
1273
+ raise OfferIntegrityError("maker: invalid proof of inclusion found")
1274
+
1275
+ # TODO: verify each kv hash to the proof's node hash
1276
+ roots = {proof.root_hash for proof in proofs}
1277
+ if len(roots) > 1:
1278
+ raise OfferIntegrityError("maker: multiple roots referenced for a single store id")
1279
+ if len(roots) < 1:
1280
+ raise OfferIntegrityError("maker: no roots referenced for store id")
1281
+
1282
+ # TODO: what about validating duplicate entries are consistent?
1283
+ maker_from_offer = {
1284
+ bytes32.from_hexstr(offered["launcher_id"]): bytes32.from_hexstr(offered["new_root"])
1285
+ for offered in summary["offered"]
1286
+ }
1287
+
1288
+ maker_from_reference = {
1289
+ # verified above that there is at least one proof and all combined hashes match
1290
+ store_proof.store_id: store_proof.proofs[0].root()
1291
+ for store_proof in maker
1292
+ }
1293
+
1294
+ if maker_from_offer != maker_from_reference:
1295
+ raise OfferIntegrityError("maker: offered stores and their roots do not match the reference data")
1296
+
1297
+ taker_from_offer = {
1298
+ bytes32.from_hexstr(dependency["launcher_id"]): [
1299
+ bytes32.from_hexstr(value) for value in dependency["values_to_prove"]
1300
+ ]
1301
+ for offered in summary["offered"]
1302
+ for dependency in offered["dependencies"]
1303
+ }
1304
+
1305
+ taker_from_reference = {
1306
+ store.store_id: [leaf_hash(key=inclusion.key, value=inclusion.value) for inclusion in store.inclusions]
1307
+ for store in taker
1308
+ }
1309
+
1310
+ if taker_from_offer != taker_from_reference:
1311
+ raise OfferIntegrityError("taker: reference and offer inclusions do not match")