chia-blockchain 2.4.4__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 (1028) 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 +197 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +147 -0
  9. chia/_tests/blockchain/test_blockchain.py +4100 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1050 -0
  11. chia/_tests/blockchain/test_build_chains.py +61 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +195 -0
  14. chia/_tests/build-init-files.py +93 -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 +73 -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 +147 -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 +57 -0
  26. chia/_tests/clvm/test_program.py +150 -0
  27. chia/_tests/clvm/test_puzzle_compression.py +144 -0
  28. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  29. chia/_tests/clvm/test_puzzles.py +247 -0
  30. chia/_tests/clvm/test_singletons.py +540 -0
  31. chia/_tests/clvm/test_spend_sim.py +181 -0
  32. chia/_tests/cmds/__init__.py +0 -0
  33. chia/_tests/cmds/cmd_test_utils.py +472 -0
  34. chia/_tests/cmds/config.py +3 -0
  35. chia/_tests/cmds/conftest.py +23 -0
  36. chia/_tests/cmds/test_click_types.py +195 -0
  37. chia/_tests/cmds/test_cmd_framework.py +400 -0
  38. chia/_tests/cmds/test_cmds_util.py +97 -0
  39. chia/_tests/cmds/test_daemon.py +92 -0
  40. chia/_tests/cmds/test_farm_cmd.py +67 -0
  41. chia/_tests/cmds/test_show.py +116 -0
  42. chia/_tests/cmds/test_sim.py +207 -0
  43. chia/_tests/cmds/test_timelock_args.py +75 -0
  44. chia/_tests/cmds/test_tx_config_args.py +153 -0
  45. chia/_tests/cmds/testing_classes.py +59 -0
  46. chia/_tests/cmds/wallet/__init__.py +0 -0
  47. chia/_tests/cmds/wallet/test_coins.py +195 -0
  48. chia/_tests/cmds/wallet/test_consts.py +47 -0
  49. chia/_tests/cmds/wallet/test_dao.py +565 -0
  50. chia/_tests/cmds/wallet/test_did.py +403 -0
  51. chia/_tests/cmds/wallet/test_nft.py +470 -0
  52. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  53. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  54. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  55. chia/_tests/cmds/wallet/test_vcs.py +376 -0
  56. chia/_tests/cmds/wallet/test_wallet.py +1126 -0
  57. chia/_tests/cmds/wallet/test_wallet_check.py +111 -0
  58. chia/_tests/conftest.py +1304 -0
  59. chia/_tests/connection_utils.py +124 -0
  60. chia/_tests/core/__init__.py +0 -0
  61. chia/_tests/core/cmds/__init__.py +0 -0
  62. chia/_tests/core/cmds/test_beta.py +382 -0
  63. chia/_tests/core/cmds/test_keys.py +1734 -0
  64. chia/_tests/core/cmds/test_wallet.py +126 -0
  65. chia/_tests/core/config.py +3 -0
  66. chia/_tests/core/consensus/__init__.py +0 -0
  67. chia/_tests/core/consensus/test_block_creation.py +56 -0
  68. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  69. chia/_tests/core/custom_types/__init__.py +0 -0
  70. chia/_tests/core/custom_types/test_coin.py +109 -0
  71. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  72. chia/_tests/core/custom_types/test_spend_bundle.py +71 -0
  73. chia/_tests/core/daemon/__init__.py +0 -0
  74. chia/_tests/core/daemon/config.py +4 -0
  75. chia/_tests/core/daemon/test_daemon.py +2128 -0
  76. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  77. chia/_tests/core/daemon/test_keychain_proxy.py +100 -0
  78. chia/_tests/core/data_layer/__init__.py +0 -0
  79. chia/_tests/core/data_layer/config.py +5 -0
  80. chia/_tests/core/data_layer/conftest.py +105 -0
  81. chia/_tests/core/data_layer/test_data_cli.py +57 -0
  82. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  83. chia/_tests/core/data_layer/test_data_layer_util.py +219 -0
  84. chia/_tests/core/data_layer/test_data_rpc.py +3865 -0
  85. chia/_tests/core/data_layer/test_data_store.py +2423 -0
  86. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  87. chia/_tests/core/data_layer/test_plugin.py +91 -0
  88. chia/_tests/core/data_layer/util.py +232 -0
  89. chia/_tests/core/farmer/__init__.py +0 -0
  90. chia/_tests/core/farmer/config.py +3 -0
  91. chia/_tests/core/farmer/test_farmer_api.py +101 -0
  92. chia/_tests/core/full_node/__init__.py +0 -0
  93. chia/_tests/core/full_node/config.py +4 -0
  94. chia/_tests/core/full_node/dos/__init__.py +0 -0
  95. chia/_tests/core/full_node/dos/config.py +3 -0
  96. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  97. chia/_tests/core/full_node/full_sync/config.py +4 -0
  98. chia/_tests/core/full_node/full_sync/test_full_sync.py +448 -0
  99. chia/_tests/core/full_node/ram_db.py +27 -0
  100. chia/_tests/core/full_node/stores/__init__.py +0 -0
  101. chia/_tests/core/full_node/stores/config.py +4 -0
  102. chia/_tests/core/full_node/stores/test_block_store.py +488 -0
  103. chia/_tests/core/full_node/stores/test_coin_store.py +888 -0
  104. chia/_tests/core/full_node/stores/test_full_node_store.py +1215 -0
  105. chia/_tests/core/full_node/stores/test_hint_store.py +230 -0
  106. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  107. chia/_tests/core/full_node/test_address_manager.py +588 -0
  108. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  109. chia/_tests/core/full_node/test_conditions.py +558 -0
  110. chia/_tests/core/full_node/test_full_node.py +2445 -0
  111. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  112. chia/_tests/core/full_node/test_hint_management.py +104 -0
  113. chia/_tests/core/full_node/test_node_load.py +34 -0
  114. chia/_tests/core/full_node/test_performance.py +182 -0
  115. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  116. chia/_tests/core/full_node/test_transactions.py +203 -0
  117. chia/_tests/core/full_node/test_tx_processing_queue.py +154 -0
  118. chia/_tests/core/large_block.py +2388 -0
  119. chia/_tests/core/make_block_generator.py +72 -0
  120. chia/_tests/core/mempool/__init__.py +0 -0
  121. chia/_tests/core/mempool/config.py +4 -0
  122. chia/_tests/core/mempool/test_mempool.py +3180 -0
  123. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  124. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  125. chia/_tests/core/mempool/test_mempool_item_queries.py +192 -0
  126. chia/_tests/core/mempool/test_mempool_manager.py +2054 -0
  127. chia/_tests/core/mempool/test_mempool_performance.py +65 -0
  128. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  129. chia/_tests/core/node_height.py +28 -0
  130. chia/_tests/core/server/__init__.py +0 -0
  131. chia/_tests/core/server/config.py +3 -0
  132. chia/_tests/core/server/flood.py +82 -0
  133. chia/_tests/core/server/serve.py +132 -0
  134. chia/_tests/core/server/test_capabilities.py +68 -0
  135. chia/_tests/core/server/test_dos.py +320 -0
  136. chia/_tests/core/server/test_event_loop.py +109 -0
  137. chia/_tests/core/server/test_loop.py +290 -0
  138. chia/_tests/core/server/test_node_discovery.py +74 -0
  139. chia/_tests/core/server/test_rate_limits.py +370 -0
  140. chia/_tests/core/server/test_server.py +225 -0
  141. chia/_tests/core/server/test_upnp.py +8 -0
  142. chia/_tests/core/services/__init__.py +0 -0
  143. chia/_tests/core/services/config.py +3 -0
  144. chia/_tests/core/services/test_services.py +166 -0
  145. chia/_tests/core/ssl/__init__.py +0 -0
  146. chia/_tests/core/ssl/config.py +3 -0
  147. chia/_tests/core/ssl/test_ssl.py +198 -0
  148. chia/_tests/core/test_coins.py +33 -0
  149. chia/_tests/core/test_cost_calculation.py +314 -0
  150. chia/_tests/core/test_crawler.py +175 -0
  151. chia/_tests/core/test_crawler_rpc.py +53 -0
  152. chia/_tests/core/test_daemon_rpc.py +24 -0
  153. chia/_tests/core/test_db_conversion.py +129 -0
  154. chia/_tests/core/test_db_validation.py +161 -0
  155. chia/_tests/core/test_farmer_harvester_rpc.py +504 -0
  156. chia/_tests/core/test_filter.py +37 -0
  157. chia/_tests/core/test_full_node_rpc.py +794 -0
  158. chia/_tests/core/test_merkle_set.py +343 -0
  159. chia/_tests/core/test_program.py +49 -0
  160. chia/_tests/core/test_rpc_util.py +87 -0
  161. chia/_tests/core/test_seeder.py +308 -0
  162. chia/_tests/core/test_setproctitle.py +13 -0
  163. chia/_tests/core/util/__init__.py +0 -0
  164. chia/_tests/core/util/config.py +4 -0
  165. chia/_tests/core/util/test_block_cache.py +44 -0
  166. chia/_tests/core/util/test_cached_bls.py +57 -0
  167. chia/_tests/core/util/test_config.py +337 -0
  168. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  169. chia/_tests/core/util/test_files.py +391 -0
  170. chia/_tests/core/util/test_jsonify.py +146 -0
  171. chia/_tests/core/util/test_keychain.py +514 -0
  172. chia/_tests/core/util/test_keyring_wrapper.py +490 -0
  173. chia/_tests/core/util/test_lockfile.py +380 -0
  174. chia/_tests/core/util/test_log_exceptions.py +187 -0
  175. chia/_tests/core/util/test_lru_cache.py +56 -0
  176. chia/_tests/core/util/test_significant_bits.py +40 -0
  177. chia/_tests/core/util/test_streamable.py +883 -0
  178. chia/_tests/db/__init__.py +0 -0
  179. chia/_tests/db/test_db_wrapper.py +565 -0
  180. chia/_tests/environments/__init__.py +0 -0
  181. chia/_tests/environments/common.py +35 -0
  182. chia/_tests/environments/full_node.py +47 -0
  183. chia/_tests/environments/wallet.py +368 -0
  184. chia/_tests/ether.py +19 -0
  185. chia/_tests/farmer_harvester/__init__.py +0 -0
  186. chia/_tests/farmer_harvester/config.py +3 -0
  187. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  188. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  189. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +130 -0
  190. chia/_tests/farmer_harvester/test_third_party_harvesters.py +501 -0
  191. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  192. chia/_tests/fee_estimation/__init__.py +0 -0
  193. chia/_tests/fee_estimation/config.py +3 -0
  194. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  195. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +145 -0
  197. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  198. chia/_tests/generator/__init__.py +0 -0
  199. chia/_tests/generator/puzzles/__init__.py +0 -0
  200. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  201. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  202. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  203. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  204. chia/_tests/generator/test_compression.py +218 -0
  205. chia/_tests/generator/test_generator_types.py +44 -0
  206. chia/_tests/generator/test_rom.py +182 -0
  207. chia/_tests/plot_sync/__init__.py +0 -0
  208. chia/_tests/plot_sync/config.py +3 -0
  209. chia/_tests/plot_sync/test_delta.py +102 -0
  210. chia/_tests/plot_sync/test_plot_sync.py +617 -0
  211. chia/_tests/plot_sync/test_receiver.py +451 -0
  212. chia/_tests/plot_sync/test_sender.py +116 -0
  213. chia/_tests/plot_sync/test_sync_simulated.py +450 -0
  214. chia/_tests/plot_sync/util.py +67 -0
  215. chia/_tests/plotting/__init__.py +0 -0
  216. chia/_tests/plotting/config.py +3 -0
  217. chia/_tests/plotting/test_plot_manager.py +738 -0
  218. chia/_tests/plotting/util.py +13 -0
  219. chia/_tests/pools/__init__.py +0 -0
  220. chia/_tests/pools/config.py +5 -0
  221. chia/_tests/pools/test_pool_cmdline.py +23 -0
  222. chia/_tests/pools/test_pool_config.py +44 -0
  223. chia/_tests/pools/test_pool_puzzles_lifecycle.py +398 -0
  224. chia/_tests/pools/test_pool_rpc.py +1010 -0
  225. chia/_tests/pools/test_pool_wallet.py +201 -0
  226. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  227. chia/_tests/process_junit.py +349 -0
  228. chia/_tests/rpc/__init__.py +0 -0
  229. chia/_tests/rpc/test_rpc_client.py +81 -0
  230. chia/_tests/simulation/__init__.py +0 -0
  231. chia/_tests/simulation/config.py +6 -0
  232. chia/_tests/simulation/test_simulation.py +501 -0
  233. chia/_tests/simulation/test_simulator.py +234 -0
  234. chia/_tests/simulation/test_start_simulator.py +106 -0
  235. chia/_tests/testconfig.py +13 -0
  236. chia/_tests/timelord/__init__.py +0 -0
  237. chia/_tests/timelord/config.py +3 -0
  238. chia/_tests/timelord/test_new_peak.py +437 -0
  239. chia/_tests/timelord/test_timelord.py +11 -0
  240. chia/_tests/tools/1315537.json +170 -0
  241. chia/_tests/tools/1315544.json +160 -0
  242. chia/_tests/tools/1315630.json +150 -0
  243. chia/_tests/tools/300000.json +105 -0
  244. chia/_tests/tools/442734.json +140 -0
  245. chia/_tests/tools/466212.json +130 -0
  246. chia/_tests/tools/__init__.py +0 -0
  247. chia/_tests/tools/config.py +5 -0
  248. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  249. chia/_tests/tools/test_full_sync.py +30 -0
  250. chia/_tests/tools/test_legacy_keyring.py +82 -0
  251. chia/_tests/tools/test_run_block.py +129 -0
  252. chia/_tests/util/__init__.py +0 -0
  253. chia/_tests/util/benchmark_cost.py +170 -0
  254. chia/_tests/util/benchmarks.py +154 -0
  255. chia/_tests/util/bip39_test_vectors.json +148 -0
  256. chia/_tests/util/blockchain.py +133 -0
  257. chia/_tests/util/blockchain_mock.py +132 -0
  258. chia/_tests/util/build_network_protocol_files.py +302 -0
  259. chia/_tests/util/clvm_generator.bin +0 -0
  260. chia/_tests/util/config.py +3 -0
  261. chia/_tests/util/constants.py +20 -0
  262. chia/_tests/util/db_connection.py +36 -0
  263. chia/_tests/util/full_sync.py +245 -0
  264. chia/_tests/util/gen_ssl_certs.py +115 -0
  265. chia/_tests/util/generator_tools_testing.py +47 -0
  266. chia/_tests/util/key_tool.py +37 -0
  267. chia/_tests/util/misc.py +722 -0
  268. chia/_tests/util/network_protocol_data.py +1074 -0
  269. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  270. chia/_tests/util/protocol_messages_json.py +2700 -0
  271. chia/_tests/util/rpc.py +23 -0
  272. chia/_tests/util/run_block.py +163 -0
  273. chia/_tests/util/setup_nodes.py +479 -0
  274. chia/_tests/util/split_managers.py +99 -0
  275. chia/_tests/util/temp_file.py +14 -0
  276. chia/_tests/util/test_action_scope.py +143 -0
  277. chia/_tests/util/test_async_pool.py +366 -0
  278. chia/_tests/util/test_build_job_matrix.py +43 -0
  279. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  280. chia/_tests/util/test_chia_version.py +50 -0
  281. chia/_tests/util/test_collection.py +11 -0
  282. chia/_tests/util/test_condition_tools.py +231 -0
  283. chia/_tests/util/test_config.py +426 -0
  284. chia/_tests/util/test_dump_keyring.py +60 -0
  285. chia/_tests/util/test_errors.py +10 -0
  286. chia/_tests/util/test_full_block_utils.py +271 -0
  287. chia/_tests/util/test_installed.py +20 -0
  288. chia/_tests/util/test_limited_semaphore.py +52 -0
  289. chia/_tests/util/test_logging_filter.py +43 -0
  290. chia/_tests/util/test_misc.py +444 -0
  291. chia/_tests/util/test_network.py +74 -0
  292. chia/_tests/util/test_network_protocol_files.py +579 -0
  293. chia/_tests/util/test_network_protocol_json.py +266 -0
  294. chia/_tests/util/test_network_protocol_test.py +257 -0
  295. chia/_tests/util/test_paginator.py +72 -0
  296. chia/_tests/util/test_pprint.py +17 -0
  297. chia/_tests/util/test_priority_mutex.py +487 -0
  298. chia/_tests/util/test_recursive_replace.py +116 -0
  299. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  300. chia/_tests/util/test_service_groups.py +15 -0
  301. chia/_tests/util/test_ssl_check.py +31 -0
  302. chia/_tests/util/test_testnet_overrides.py +19 -0
  303. chia/_tests/util/test_tests_misc.py +38 -0
  304. chia/_tests/util/test_timing.py +37 -0
  305. chia/_tests/util/test_trusted_peer.py +51 -0
  306. chia/_tests/util/time_out_assert.py +154 -0
  307. chia/_tests/wallet/__init__.py +0 -0
  308. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  309. chia/_tests/wallet/cat_wallet/config.py +4 -0
  310. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  311. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  312. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1738 -0
  313. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  314. chia/_tests/wallet/cat_wallet/test_trades.py +2578 -0
  315. chia/_tests/wallet/clawback/__init__.py +0 -0
  316. chia/_tests/wallet/clawback/config.py +3 -0
  317. chia/_tests/wallet/clawback/test_clawback_decorator.py +80 -0
  318. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  319. chia/_tests/wallet/clawback/test_clawback_metadata.py +51 -0
  320. chia/_tests/wallet/config.py +4 -0
  321. chia/_tests/wallet/conftest.py +217 -0
  322. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  323. chia/_tests/wallet/dao_wallet/config.py +3 -0
  324. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1322 -0
  325. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  326. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  327. chia/_tests/wallet/db_wallet/config.py +3 -0
  328. chia/_tests/wallet/db_wallet/test_db_graftroot.py +143 -0
  329. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  330. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  331. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  332. chia/_tests/wallet/did_wallet/config.py +4 -0
  333. chia/_tests/wallet/did_wallet/test_did.py +1481 -0
  334. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  335. chia/_tests/wallet/nft_wallet/config.py +4 -0
  336. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1492 -0
  337. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1014 -0
  338. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +376 -0
  339. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  340. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  341. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2558 -0
  342. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  343. chia/_tests/wallet/rpc/__init__.py +0 -0
  344. chia/_tests/wallet/rpc/config.py +4 -0
  345. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +287 -0
  346. chia/_tests/wallet/rpc/test_wallet_rpc.py +3106 -0
  347. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  348. chia/_tests/wallet/simple_sync/config.py +3 -0
  349. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +719 -0
  350. chia/_tests/wallet/sync/__init__.py +0 -0
  351. chia/_tests/wallet/sync/config.py +4 -0
  352. chia/_tests/wallet/sync/test_wallet_sync.py +1529 -0
  353. chia/_tests/wallet/test_address_type.py +189 -0
  354. chia/_tests/wallet/test_bech32m.py +45 -0
  355. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  356. chia/_tests/wallet/test_coin_selection.py +589 -0
  357. chia/_tests/wallet/test_conditions.py +388 -0
  358. chia/_tests/wallet/test_debug_spend_bundle.py +76 -0
  359. chia/_tests/wallet/test_new_wallet_protocol.py +1176 -0
  360. chia/_tests/wallet/test_nft_store.py +193 -0
  361. chia/_tests/wallet/test_notifications.py +196 -0
  362. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  363. chia/_tests/wallet/test_puzzle_store.py +133 -0
  364. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  365. chia/_tests/wallet/test_signer_protocol.py +948 -0
  366. chia/_tests/wallet/test_singleton.py +122 -0
  367. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  368. chia/_tests/wallet/test_singleton_store.py +152 -0
  369. chia/_tests/wallet/test_taproot.py +19 -0
  370. chia/_tests/wallet/test_transaction_store.py +941 -0
  371. chia/_tests/wallet/test_util.py +181 -0
  372. chia/_tests/wallet/test_wallet.py +2139 -0
  373. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  374. chia/_tests/wallet/test_wallet_blockchain.py +113 -0
  375. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  376. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  377. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  378. chia/_tests/wallet/test_wallet_node.py +783 -0
  379. chia/_tests/wallet/test_wallet_retry.py +95 -0
  380. chia/_tests/wallet/test_wallet_state_manager.py +252 -0
  381. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  382. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  383. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  384. chia/_tests/wallet/test_wallet_utils.py +155 -0
  385. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  386. chia/_tests/wallet/vc_wallet/config.py +3 -0
  387. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  388. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  389. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +801 -0
  390. chia/_tests/wallet/wallet_block_tools.py +327 -0
  391. chia/_tests/weight_proof/__init__.py +0 -0
  392. chia/_tests/weight_proof/config.py +3 -0
  393. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  394. chia/clvm/__init__.py +0 -0
  395. chia/clvm/spend_sim.py +488 -0
  396. chia/cmds/__init__.py +0 -0
  397. chia/cmds/beta.py +183 -0
  398. chia/cmds/beta_funcs.py +133 -0
  399. chia/cmds/check_wallet_db.py +418 -0
  400. chia/cmds/chia.py +143 -0
  401. chia/cmds/cmd_classes.py +315 -0
  402. chia/cmds/cmds_util.py +498 -0
  403. chia/cmds/coin_funcs.py +260 -0
  404. chia/cmds/coins.py +220 -0
  405. chia/cmds/completion.py +49 -0
  406. chia/cmds/configure.py +331 -0
  407. chia/cmds/dao.py +1008 -0
  408. chia/cmds/dao_funcs.py +576 -0
  409. chia/cmds/data.py +707 -0
  410. chia/cmds/data_funcs.py +380 -0
  411. chia/cmds/db.py +86 -0
  412. chia/cmds/db_backup_func.py +77 -0
  413. chia/cmds/db_upgrade_func.py +452 -0
  414. chia/cmds/db_validate_func.py +184 -0
  415. chia/cmds/dev.py +16 -0
  416. chia/cmds/farm.py +87 -0
  417. chia/cmds/farm_funcs.py +207 -0
  418. chia/cmds/init.py +70 -0
  419. chia/cmds/init_funcs.py +367 -0
  420. chia/cmds/installers.py +129 -0
  421. chia/cmds/keys.py +510 -0
  422. chia/cmds/keys_funcs.py +864 -0
  423. chia/cmds/netspace.py +47 -0
  424. chia/cmds/netspace_funcs.py +53 -0
  425. chia/cmds/options.py +32 -0
  426. chia/cmds/param_types.py +228 -0
  427. chia/cmds/passphrase.py +130 -0
  428. chia/cmds/passphrase_funcs.py +346 -0
  429. chia/cmds/peer.py +50 -0
  430. chia/cmds/peer_funcs.py +129 -0
  431. chia/cmds/plotnft.py +206 -0
  432. chia/cmds/plotnft_funcs.py +374 -0
  433. chia/cmds/plots.py +222 -0
  434. chia/cmds/plotters.py +17 -0
  435. chia/cmds/rpc.py +188 -0
  436. chia/cmds/show.py +71 -0
  437. chia/cmds/show_funcs.py +214 -0
  438. chia/cmds/signer.py +304 -0
  439. chia/cmds/sim.py +217 -0
  440. chia/cmds/sim_funcs.py +509 -0
  441. chia/cmds/start.py +24 -0
  442. chia/cmds/start_funcs.py +112 -0
  443. chia/cmds/stop.py +61 -0
  444. chia/cmds/units.py +11 -0
  445. chia/cmds/wallet.py +1745 -0
  446. chia/cmds/wallet_funcs.py +1800 -0
  447. chia/consensus/__init__.py +0 -0
  448. chia/consensus/block_body_validation.py +515 -0
  449. chia/consensus/block_creation.py +525 -0
  450. chia/consensus/block_header_validation.py +1064 -0
  451. chia/consensus/block_record.py +32 -0
  452. chia/consensus/block_rewards.py +53 -0
  453. chia/consensus/block_root_validation.py +46 -0
  454. chia/consensus/blockchain.py +1100 -0
  455. chia/consensus/blockchain_interface.py +56 -0
  456. chia/consensus/coinbase.py +30 -0
  457. chia/consensus/condition_costs.py +9 -0
  458. chia/consensus/constants.py +49 -0
  459. chia/consensus/cost_calculator.py +15 -0
  460. chia/consensus/default_constants.py +90 -0
  461. chia/consensus/deficit.py +55 -0
  462. chia/consensus/difficulty_adjustment.py +412 -0
  463. chia/consensus/find_fork_point.py +111 -0
  464. chia/consensus/full_block_to_block_record.py +167 -0
  465. chia/consensus/get_block_challenge.py +106 -0
  466. chia/consensus/get_block_generator.py +26 -0
  467. chia/consensus/make_sub_epoch_summary.py +210 -0
  468. chia/consensus/multiprocess_validation.py +365 -0
  469. chia/consensus/pos_quality.py +19 -0
  470. chia/consensus/pot_iterations.py +67 -0
  471. chia/consensus/puzzles/__init__.py +0 -0
  472. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  473. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  474. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  475. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  476. chia/consensus/vdf_info_computation.py +156 -0
  477. chia/daemon/__init__.py +0 -0
  478. chia/daemon/client.py +233 -0
  479. chia/daemon/keychain_proxy.py +501 -0
  480. chia/daemon/keychain_server.py +365 -0
  481. chia/daemon/server.py +1616 -0
  482. chia/daemon/windows_signal.py +56 -0
  483. chia/data_layer/__init__.py +0 -0
  484. chia/data_layer/data_layer.py +1303 -0
  485. chia/data_layer/data_layer_api.py +25 -0
  486. chia/data_layer/data_layer_errors.py +50 -0
  487. chia/data_layer/data_layer_server.py +170 -0
  488. chia/data_layer/data_layer_util.py +985 -0
  489. chia/data_layer/data_layer_wallet.py +1315 -0
  490. chia/data_layer/data_store.py +2267 -0
  491. chia/data_layer/dl_wallet_store.py +407 -0
  492. chia/data_layer/download_data.py +389 -0
  493. chia/data_layer/puzzles/__init__.py +0 -0
  494. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  495. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  496. chia/data_layer/s3_plugin_config.yml +33 -0
  497. chia/data_layer/s3_plugin_service.py +468 -0
  498. chia/data_layer/util/__init__.py +0 -0
  499. chia/data_layer/util/benchmark.py +108 -0
  500. chia/data_layer/util/plugin.py +41 -0
  501. chia/farmer/__init__.py +0 -0
  502. chia/farmer/farmer.py +920 -0
  503. chia/farmer/farmer_api.py +814 -0
  504. chia/full_node/__init__.py +0 -0
  505. chia/full_node/bitcoin_fee_estimator.py +85 -0
  506. chia/full_node/block_height_map.py +271 -0
  507. chia/full_node/block_store.py +570 -0
  508. chia/full_node/bundle_tools.py +19 -0
  509. chia/full_node/coin_store.py +646 -0
  510. chia/full_node/fee_estimate.py +54 -0
  511. chia/full_node/fee_estimate_store.py +24 -0
  512. chia/full_node/fee_estimation.py +93 -0
  513. chia/full_node/fee_estimator.py +90 -0
  514. chia/full_node/fee_estimator_constants.py +38 -0
  515. chia/full_node/fee_estimator_interface.py +42 -0
  516. chia/full_node/fee_history.py +26 -0
  517. chia/full_node/fee_tracker.py +564 -0
  518. chia/full_node/full_node.py +3052 -0
  519. chia/full_node/full_node_api.py +1974 -0
  520. chia/full_node/full_node_store.py +1033 -0
  521. chia/full_node/hint_management.py +56 -0
  522. chia/full_node/hint_store.py +94 -0
  523. chia/full_node/mempool.py +583 -0
  524. chia/full_node/mempool_check_conditions.py +177 -0
  525. chia/full_node/mempool_manager.py +858 -0
  526. chia/full_node/pending_tx_cache.py +112 -0
  527. chia/full_node/puzzles/__init__.py +0 -0
  528. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  529. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  530. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  531. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  532. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  533. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  534. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  535. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  536. chia/full_node/signage_point.py +16 -0
  537. chia/full_node/subscriptions.py +248 -0
  538. chia/full_node/sync_store.py +145 -0
  539. chia/full_node/tx_processing_queue.py +78 -0
  540. chia/full_node/weight_proof.py +1719 -0
  541. chia/harvester/__init__.py +0 -0
  542. chia/harvester/harvester.py +271 -0
  543. chia/harvester/harvester_api.py +374 -0
  544. chia/introducer/__init__.py +0 -0
  545. chia/introducer/introducer.py +120 -0
  546. chia/introducer/introducer_api.py +64 -0
  547. chia/legacy/__init__.py +0 -0
  548. chia/legacy/keyring.py +154 -0
  549. chia/plot_sync/__init__.py +0 -0
  550. chia/plot_sync/delta.py +61 -0
  551. chia/plot_sync/exceptions.py +56 -0
  552. chia/plot_sync/receiver.py +385 -0
  553. chia/plot_sync/sender.py +337 -0
  554. chia/plot_sync/util.py +43 -0
  555. chia/plotters/__init__.py +0 -0
  556. chia/plotters/bladebit.py +388 -0
  557. chia/plotters/chiapos.py +63 -0
  558. chia/plotters/madmax.py +224 -0
  559. chia/plotters/plotters.py +577 -0
  560. chia/plotters/plotters_util.py +131 -0
  561. chia/plotting/__init__.py +0 -0
  562. chia/plotting/cache.py +212 -0
  563. chia/plotting/check_plots.py +283 -0
  564. chia/plotting/create_plots.py +278 -0
  565. chia/plotting/manager.py +436 -0
  566. chia/plotting/util.py +324 -0
  567. chia/pools/__init__.py +0 -0
  568. chia/pools/pool_config.py +110 -0
  569. chia/pools/pool_puzzles.py +459 -0
  570. chia/pools/pool_wallet.py +926 -0
  571. chia/pools/pool_wallet_info.py +118 -0
  572. chia/pools/puzzles/__init__.py +0 -0
  573. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  574. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  575. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  576. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  577. chia/protocols/__init__.py +0 -0
  578. chia/protocols/farmer_protocol.py +102 -0
  579. chia/protocols/full_node_protocol.py +219 -0
  580. chia/protocols/harvester_protocol.py +216 -0
  581. chia/protocols/introducer_protocol.py +26 -0
  582. chia/protocols/pool_protocol.py +177 -0
  583. chia/protocols/protocol_message_types.py +139 -0
  584. chia/protocols/protocol_state_machine.py +87 -0
  585. chia/protocols/protocol_timing.py +7 -0
  586. chia/protocols/shared_protocol.py +86 -0
  587. chia/protocols/timelord_protocol.py +93 -0
  588. chia/protocols/wallet_protocol.py +401 -0
  589. chia/py.typed +0 -0
  590. chia/rpc/__init__.py +0 -0
  591. chia/rpc/crawler_rpc_api.py +75 -0
  592. chia/rpc/data_layer_rpc_api.py +639 -0
  593. chia/rpc/data_layer_rpc_client.py +188 -0
  594. chia/rpc/data_layer_rpc_util.py +62 -0
  595. chia/rpc/farmer_rpc_api.py +360 -0
  596. chia/rpc/farmer_rpc_client.py +86 -0
  597. chia/rpc/full_node_rpc_api.py +954 -0
  598. chia/rpc/full_node_rpc_client.py +292 -0
  599. chia/rpc/harvester_rpc_api.py +136 -0
  600. chia/rpc/harvester_rpc_client.py +54 -0
  601. chia/rpc/rpc_client.py +144 -0
  602. chia/rpc/rpc_server.py +447 -0
  603. chia/rpc/timelord_rpc_api.py +27 -0
  604. chia/rpc/util.py +293 -0
  605. chia/rpc/wallet_request_types.py +688 -0
  606. chia/rpc/wallet_rpc_api.py +4779 -0
  607. chia/rpc/wallet_rpc_client.py +1844 -0
  608. chia/seeder/__init__.py +0 -0
  609. chia/seeder/crawl_store.py +427 -0
  610. chia/seeder/crawler.py +423 -0
  611. chia/seeder/crawler_api.py +129 -0
  612. chia/seeder/dns_server.py +544 -0
  613. chia/seeder/peer_record.py +146 -0
  614. chia/seeder/start_crawler.py +88 -0
  615. chia/server/__init__.py +0 -0
  616. chia/server/address_manager.py +658 -0
  617. chia/server/address_manager_store.py +237 -0
  618. chia/server/api_protocol.py +11 -0
  619. chia/server/capabilities.py +24 -0
  620. chia/server/chia_policy.py +345 -0
  621. chia/server/introducer_peers.py +76 -0
  622. chia/server/node_discovery.py +718 -0
  623. chia/server/outbound_message.py +33 -0
  624. chia/server/rate_limit_numbers.py +204 -0
  625. chia/server/rate_limits.py +113 -0
  626. chia/server/server.py +720 -0
  627. chia/server/signal_handlers.py +117 -0
  628. chia/server/ssl_context.py +32 -0
  629. chia/server/start_data_layer.py +137 -0
  630. chia/server/start_farmer.py +86 -0
  631. chia/server/start_full_node.py +106 -0
  632. chia/server/start_harvester.py +80 -0
  633. chia/server/start_introducer.py +69 -0
  634. chia/server/start_service.py +328 -0
  635. chia/server/start_timelord.py +82 -0
  636. chia/server/start_wallet.py +109 -0
  637. chia/server/upnp.py +117 -0
  638. chia/server/ws_connection.py +752 -0
  639. chia/simulator/__init__.py +0 -0
  640. chia/simulator/block_tools.py +2053 -0
  641. chia/simulator/full_node_simulator.py +802 -0
  642. chia/simulator/keyring.py +128 -0
  643. chia/simulator/setup_services.py +505 -0
  644. chia/simulator/simulator_constants.py +13 -0
  645. chia/simulator/simulator_full_node_rpc_api.py +101 -0
  646. chia/simulator/simulator_full_node_rpc_client.py +62 -0
  647. chia/simulator/simulator_protocol.py +29 -0
  648. chia/simulator/simulator_test_tools.py +163 -0
  649. chia/simulator/socket.py +27 -0
  650. chia/simulator/ssl_certs.py +114 -0
  651. chia/simulator/ssl_certs_1.py +699 -0
  652. chia/simulator/ssl_certs_10.py +699 -0
  653. chia/simulator/ssl_certs_2.py +699 -0
  654. chia/simulator/ssl_certs_3.py +699 -0
  655. chia/simulator/ssl_certs_4.py +699 -0
  656. chia/simulator/ssl_certs_5.py +699 -0
  657. chia/simulator/ssl_certs_6.py +699 -0
  658. chia/simulator/ssl_certs_7.py +699 -0
  659. chia/simulator/ssl_certs_8.py +699 -0
  660. chia/simulator/ssl_certs_9.py +699 -0
  661. chia/simulator/start_simulator.py +135 -0
  662. chia/simulator/wallet_tools.py +245 -0
  663. chia/ssl/__init__.py +0 -0
  664. chia/ssl/chia_ca.crt +19 -0
  665. chia/ssl/chia_ca.key +28 -0
  666. chia/ssl/create_ssl.py +249 -0
  667. chia/ssl/dst_root_ca.pem +20 -0
  668. chia/timelord/__init__.py +0 -0
  669. chia/timelord/iters_from_block.py +50 -0
  670. chia/timelord/timelord.py +1202 -0
  671. chia/timelord/timelord_api.py +132 -0
  672. chia/timelord/timelord_launcher.py +188 -0
  673. chia/timelord/timelord_state.py +244 -0
  674. chia/timelord/types.py +22 -0
  675. chia/types/__init__.py +0 -0
  676. chia/types/aliases.py +35 -0
  677. chia/types/block_protocol.py +20 -0
  678. chia/types/blockchain_format/__init__.py +0 -0
  679. chia/types/blockchain_format/classgroup.py +5 -0
  680. chia/types/blockchain_format/coin.py +28 -0
  681. chia/types/blockchain_format/foliage.py +8 -0
  682. chia/types/blockchain_format/pool_target.py +5 -0
  683. chia/types/blockchain_format/program.py +270 -0
  684. chia/types/blockchain_format/proof_of_space.py +135 -0
  685. chia/types/blockchain_format/reward_chain_block.py +6 -0
  686. chia/types/blockchain_format/serialized_program.py +5 -0
  687. chia/types/blockchain_format/sized_bytes.py +11 -0
  688. chia/types/blockchain_format/slots.py +9 -0
  689. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  690. chia/types/blockchain_format/tree_hash.py +72 -0
  691. chia/types/blockchain_format/vdf.py +86 -0
  692. chia/types/clvm_cost.py +13 -0
  693. chia/types/coin_record.py +43 -0
  694. chia/types/coin_spend.py +115 -0
  695. chia/types/condition_opcodes.py +73 -0
  696. chia/types/condition_with_args.py +17 -0
  697. chia/types/eligible_coin_spends.py +364 -0
  698. chia/types/end_of_slot_bundle.py +5 -0
  699. chia/types/fee_rate.py +38 -0
  700. chia/types/full_block.py +5 -0
  701. chia/types/generator_types.py +14 -0
  702. chia/types/header_block.py +5 -0
  703. chia/types/internal_mempool_item.py +19 -0
  704. chia/types/mempool_inclusion_status.py +9 -0
  705. chia/types/mempool_item.py +85 -0
  706. chia/types/mempool_submission_status.py +30 -0
  707. chia/types/mojos.py +7 -0
  708. chia/types/peer_info.py +64 -0
  709. chia/types/signing_mode.py +29 -0
  710. chia/types/spend_bundle.py +31 -0
  711. chia/types/spend_bundle_conditions.py +7 -0
  712. chia/types/transaction_queue_entry.py +55 -0
  713. chia/types/unfinished_block.py +5 -0
  714. chia/types/unfinished_header_block.py +37 -0
  715. chia/types/weight_proof.py +50 -0
  716. chia/util/__init__.py +0 -0
  717. chia/util/action_scope.py +168 -0
  718. chia/util/api_decorators.py +89 -0
  719. chia/util/async_pool.py +224 -0
  720. chia/util/augmented_chain.py +130 -0
  721. chia/util/batches.py +39 -0
  722. chia/util/bech32m.py +123 -0
  723. chia/util/beta_metrics.py +118 -0
  724. chia/util/block_cache.py +56 -0
  725. chia/util/byte_types.py +10 -0
  726. chia/util/check_fork_next_block.py +32 -0
  727. chia/util/chia_logging.py +124 -0
  728. chia/util/chia_version.py +33 -0
  729. chia/util/collection.py +17 -0
  730. chia/util/condition_tools.py +201 -0
  731. chia/util/config.py +366 -0
  732. chia/util/cpu.py +20 -0
  733. chia/util/db_synchronous.py +21 -0
  734. chia/util/db_version.py +30 -0
  735. chia/util/db_wrapper.py +427 -0
  736. chia/util/default_root.py +10 -0
  737. chia/util/dump_keyring.py +93 -0
  738. chia/util/english.txt +2048 -0
  739. chia/util/errors.py +351 -0
  740. chia/util/file_keyring.py +480 -0
  741. chia/util/files.py +95 -0
  742. chia/util/full_block_utils.py +321 -0
  743. chia/util/generator_tools.py +62 -0
  744. chia/util/hash.py +29 -0
  745. chia/util/initial-config.yaml +675 -0
  746. chia/util/inline_executor.py +24 -0
  747. chia/util/ints.py +19 -0
  748. chia/util/json_util.py +41 -0
  749. chia/util/keychain.py +673 -0
  750. chia/util/keyring_wrapper.py +266 -0
  751. chia/util/limited_semaphore.py +39 -0
  752. chia/util/lock.py +47 -0
  753. chia/util/log_exceptions.py +29 -0
  754. chia/util/logging.py +34 -0
  755. chia/util/lru_cache.py +29 -0
  756. chia/util/math.py +20 -0
  757. chia/util/network.py +240 -0
  758. chia/util/paginator.py +46 -0
  759. chia/util/path.py +29 -0
  760. chia/util/permissions.py +19 -0
  761. chia/util/pprint.py +40 -0
  762. chia/util/prev_transaction_block.py +23 -0
  763. chia/util/priority_mutex.py +92 -0
  764. chia/util/profiler.py +194 -0
  765. chia/util/recursive_replace.py +22 -0
  766. chia/util/safe_cancel_task.py +14 -0
  767. chia/util/service_groups.py +47 -0
  768. chia/util/setproctitle.py +20 -0
  769. chia/util/significant_bits.py +30 -0
  770. chia/util/ssl_check.py +213 -0
  771. chia/util/streamable.py +654 -0
  772. chia/util/task_timing.py +378 -0
  773. chia/util/timing.py +64 -0
  774. chia/util/vdf_prover.py +31 -0
  775. chia/util/ws_message.py +66 -0
  776. chia/wallet/__init__.py +0 -0
  777. chia/wallet/cat_wallet/__init__.py +0 -0
  778. chia/wallet/cat_wallet/cat_constants.py +75 -0
  779. chia/wallet/cat_wallet/cat_info.py +47 -0
  780. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  781. chia/wallet/cat_wallet/cat_utils.py +163 -0
  782. chia/wallet/cat_wallet/cat_wallet.py +869 -0
  783. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  784. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  785. chia/wallet/cat_wallet/lineage_store.py +74 -0
  786. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  787. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  788. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  789. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  790. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  791. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  792. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  793. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  794. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  795. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  796. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  797. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  798. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  799. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  800. chia/wallet/coin_selection.py +188 -0
  801. chia/wallet/conditions.py +1326 -0
  802. chia/wallet/dao_wallet/__init__.py +0 -0
  803. chia/wallet/dao_wallet/dao_info.py +61 -0
  804. chia/wallet/dao_wallet/dao_utils.py +810 -0
  805. chia/wallet/dao_wallet/dao_wallet.py +2121 -0
  806. chia/wallet/db_wallet/__init__.py +0 -0
  807. chia/wallet/db_wallet/db_wallet_puzzles.py +107 -0
  808. chia/wallet/derivation_record.py +30 -0
  809. chia/wallet/derive_keys.py +146 -0
  810. chia/wallet/did_wallet/__init__.py +0 -0
  811. chia/wallet/did_wallet/did_info.py +39 -0
  812. chia/wallet/did_wallet/did_wallet.py +1485 -0
  813. chia/wallet/did_wallet/did_wallet_puzzles.py +220 -0
  814. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  815. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  816. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  817. chia/wallet/driver_protocol.py +26 -0
  818. chia/wallet/key_val_store.py +55 -0
  819. chia/wallet/lineage_proof.py +58 -0
  820. chia/wallet/nft_wallet/__init__.py +0 -0
  821. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  822. chia/wallet/nft_wallet/nft_info.py +120 -0
  823. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  824. chia/wallet/nft_wallet/nft_wallet.py +1686 -0
  825. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  826. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  827. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  828. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  829. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  830. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  831. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  832. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  833. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  834. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  835. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  836. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  837. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  838. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  839. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  840. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  841. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  842. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  843. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  844. chia/wallet/notification_manager.py +117 -0
  845. chia/wallet/notification_store.py +178 -0
  846. chia/wallet/outer_puzzles.py +84 -0
  847. chia/wallet/payment.py +34 -0
  848. chia/wallet/puzzle_drivers.py +118 -0
  849. chia/wallet/puzzles/__init__.py +0 -0
  850. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  851. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  852. chia/wallet/puzzles/clawback/__init__.py +0 -0
  853. chia/wallet/puzzles/clawback/drivers.py +188 -0
  854. chia/wallet/puzzles/clawback/metadata.py +38 -0
  855. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  856. chia/wallet/puzzles/condition_codes.clib +77 -0
  857. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  858. chia/wallet/puzzles/curry.clib +135 -0
  859. chia/wallet/puzzles/curry_by_index.clib +16 -0
  860. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  861. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  862. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  863. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  864. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  865. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  866. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  867. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  868. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  869. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  870. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  871. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  872. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  873. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  874. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  876. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  877. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  878. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  879. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  880. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  881. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  882. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  883. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  884. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  885. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  886. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  887. chia/wallet/puzzles/json.clib +25 -0
  888. chia/wallet/puzzles/load_clvm.py +162 -0
  889. chia/wallet/puzzles/merkle_utils.clib +18 -0
  890. chia/wallet/puzzles/notification.clsp +7 -0
  891. chia/wallet/puzzles/notification.clsp.hex +1 -0
  892. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  893. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  894. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  895. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  896. chia/wallet/puzzles/p2_conditions.py +27 -0
  897. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  898. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  899. chia/wallet/puzzles/p2_delegated_conditions.py +22 -0
  900. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  901. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  902. chia/wallet/puzzles/p2_delegated_puzzle.py +35 -0
  903. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  904. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +161 -0
  906. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  907. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  908. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +22 -0
  909. chia/wallet/puzzles/p2_parent.clsp +19 -0
  910. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  911. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  912. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  913. chia/wallet/puzzles/p2_puzzle_hash.py +28 -0
  914. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  915. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  916. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  917. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  919. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  920. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  921. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  922. chia/wallet/puzzles/puzzle_utils.py +34 -0
  923. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  924. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  925. chia/wallet/puzzles/sha256tree.clib +11 -0
  926. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  927. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  928. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  929. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  930. chia/wallet/puzzles/singleton_top_layer.py +295 -0
  931. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  932. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  933. chia/wallet/puzzles/singleton_top_layer_v1_1.py +344 -0
  934. chia/wallet/puzzles/singleton_truths.clib +21 -0
  935. chia/wallet/puzzles/tails.py +344 -0
  936. chia/wallet/puzzles/utility_macros.clib +48 -0
  937. chia/wallet/signer_protocol.py +126 -0
  938. chia/wallet/singleton.py +106 -0
  939. chia/wallet/singleton_record.py +30 -0
  940. chia/wallet/trade_manager.py +1088 -0
  941. chia/wallet/trade_record.py +67 -0
  942. chia/wallet/trading/__init__.py +0 -0
  943. chia/wallet/trading/offer.py +703 -0
  944. chia/wallet/trading/trade_status.py +13 -0
  945. chia/wallet/trading/trade_store.py +526 -0
  946. chia/wallet/transaction_record.py +143 -0
  947. chia/wallet/transaction_sorting.py +14 -0
  948. chia/wallet/uncurried_puzzle.py +17 -0
  949. chia/wallet/util/__init__.py +0 -0
  950. chia/wallet/util/address_type.py +55 -0
  951. chia/wallet/util/blind_signer_tl.py +168 -0
  952. chia/wallet/util/clvm_streamable.py +203 -0
  953. chia/wallet/util/compute_hints.py +66 -0
  954. chia/wallet/util/compute_memos.py +45 -0
  955. chia/wallet/util/curry_and_treehash.py +90 -0
  956. chia/wallet/util/debug_spend_bundle.py +234 -0
  957. chia/wallet/util/merkle_tree.py +100 -0
  958. chia/wallet/util/merkle_utils.py +102 -0
  959. chia/wallet/util/new_peak_queue.py +82 -0
  960. chia/wallet/util/notifications.py +12 -0
  961. chia/wallet/util/peer_request_cache.py +174 -0
  962. chia/wallet/util/puzzle_compression.py +96 -0
  963. chia/wallet/util/puzzle_decorator.py +100 -0
  964. chia/wallet/util/puzzle_decorator_type.py +7 -0
  965. chia/wallet/util/query_filter.py +60 -0
  966. chia/wallet/util/transaction_type.py +23 -0
  967. chia/wallet/util/tx_config.py +158 -0
  968. chia/wallet/util/wallet_sync_utils.py +348 -0
  969. chia/wallet/util/wallet_types.py +65 -0
  970. chia/wallet/vc_wallet/__init__.py +0 -0
  971. chia/wallet/vc_wallet/cr_cat_drivers.py +663 -0
  972. chia/wallet/vc_wallet/cr_cat_wallet.py +875 -0
  973. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  974. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  975. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  976. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  977. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  978. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  979. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  980. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  981. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  982. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  983. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  984. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  985. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  986. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  987. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  988. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  989. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  990. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  992. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  994. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  996. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  997. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  998. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_store.py +263 -0
  1002. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1003. chia/wallet/wallet.py +698 -0
  1004. chia/wallet/wallet_action_scope.py +95 -0
  1005. chia/wallet/wallet_blockchain.py +244 -0
  1006. chia/wallet/wallet_coin_record.py +72 -0
  1007. chia/wallet/wallet_coin_store.py +351 -0
  1008. chia/wallet/wallet_info.py +36 -0
  1009. chia/wallet/wallet_interested_store.py +188 -0
  1010. chia/wallet/wallet_nft_store.py +279 -0
  1011. chia/wallet/wallet_node.py +1769 -0
  1012. chia/wallet/wallet_node_api.py +201 -0
  1013. chia/wallet/wallet_pool_store.py +120 -0
  1014. chia/wallet/wallet_protocol.py +90 -0
  1015. chia/wallet/wallet_puzzle_store.py +365 -0
  1016. chia/wallet/wallet_retry_store.py +70 -0
  1017. chia/wallet/wallet_singleton_store.py +258 -0
  1018. chia/wallet/wallet_spend_bundle.py +41 -0
  1019. chia/wallet/wallet_state_manager.py +2820 -0
  1020. chia/wallet/wallet_transaction_store.py +470 -0
  1021. chia/wallet/wallet_user_store.py +110 -0
  1022. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1023. chia_blockchain-2.4.4.dist-info/LICENSE +201 -0
  1024. chia_blockchain-2.4.4.dist-info/METADATA +161 -0
  1025. chia_blockchain-2.4.4.dist-info/RECORD +1028 -0
  1026. chia_blockchain-2.4.4.dist-info/WHEEL +4 -0
  1027. chia_blockchain-2.4.4.dist-info/entry_points.txt +17 -0
  1028. mozilla-ca/cacert.pem +3666 -0
@@ -0,0 +1,703 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Any, BinaryIO, Dict, List, Optional, Set, Tuple, Union
5
+
6
+ from chia_rs import G2Element
7
+ from clvm_tools.binutils import disassemble
8
+
9
+ from chia.consensus.default_constants import DEFAULT_CONSTANTS
10
+ from chia.types.blockchain_format.coin import Coin, coin_as_list
11
+ from chia.types.blockchain_format.program import INFINITE_COST, Program
12
+ from chia.types.blockchain_format.sized_bytes import bytes32
13
+ from chia.types.coin_spend import CoinSpend, make_spend
14
+ from chia.util.bech32m import bech32_decode, bech32_encode, convertbits
15
+ from chia.util.errors import Err, ValidationError
16
+ from chia.util.ints import uint64
17
+ from chia.util.streamable import parse_rust
18
+ from chia.wallet.conditions import (
19
+ AssertCoinAnnouncement,
20
+ AssertPuzzleAnnouncement,
21
+ Condition,
22
+ ConditionValidTimes,
23
+ parse_conditions_non_consensus,
24
+ parse_timelock_info,
25
+ )
26
+ from chia.wallet.outer_puzzles import (
27
+ construct_puzzle,
28
+ create_asset_id,
29
+ get_inner_puzzle,
30
+ get_inner_solution,
31
+ match_puzzle,
32
+ solve_puzzle,
33
+ )
34
+ from chia.wallet.payment import Payment
35
+ from chia.wallet.puzzle_drivers import PuzzleInfo, Solver
36
+ from chia.wallet.puzzles.load_clvm import load_clvm_maybe_recompile
37
+ from chia.wallet.uncurried_puzzle import UncurriedPuzzle, uncurry_puzzle
38
+ from chia.wallet.util.compute_hints import compute_spend_hints_and_additions
39
+ from chia.wallet.util.puzzle_compression import (
40
+ compress_object_with_puzzles,
41
+ decompress_object_with_puzzles,
42
+ lowest_best_version,
43
+ )
44
+ from chia.wallet.wallet_spend_bundle import WalletSpendBundle
45
+
46
+ OFFER_MOD = load_clvm_maybe_recompile("settlement_payments.clsp")
47
+ OFFER_MOD_HASH = OFFER_MOD.get_tree_hash()
48
+ ZERO_32 = bytes32([0] * 32)
49
+
50
+
51
+ def detect_dependent_coin(
52
+ names: List[bytes32], deps: Dict[bytes32, List[bytes32]], announcement_dict: Dict[bytes32, List[bytes32]]
53
+ ) -> Optional[Tuple[bytes32, bytes32]]:
54
+ # First, we check for any dependencies on coins in the same bundle
55
+ for name in names:
56
+ for dependency in deps[name]:
57
+ for coin, announces in announcement_dict.items():
58
+ if dependency in announces and coin != name:
59
+ # We found one, now remove it and anything that depends on it (except the "provider")
60
+ return name, coin
61
+ return None
62
+
63
+
64
+ @dataclass(frozen=True)
65
+ class NotarizedPayment(Payment):
66
+ nonce: bytes32 = ZERO_32
67
+
68
+ @classmethod
69
+ def from_condition_and_nonce(cls, condition: Program, nonce: bytes32) -> NotarizedPayment:
70
+ with_opcode: Program = Program.to((51, condition)) # Gotta do this because the super class is expecting it
71
+ p = Payment.from_condition(with_opcode)
72
+ puzzle_hash, amount, memos = tuple(p.as_condition_args())
73
+ return cls(puzzle_hash, amount, memos, nonce)
74
+
75
+
76
+ @dataclass(frozen=True, eq=False)
77
+ class Offer:
78
+ requested_payments: Dict[
79
+ Optional[bytes32], List[NotarizedPayment]
80
+ ] # The key is the asset id of the asset being requested
81
+ _bundle: WalletSpendBundle
82
+ driver_dict: Dict[bytes32, PuzzleInfo] # asset_id -> asset driver
83
+
84
+ # this is a cache of the coin additions made by the SpendBundle (_bundle)
85
+ # ordered by the coin being spent
86
+ _additions: Dict[Coin, List[Coin]] = field(init=False, repr=False)
87
+ _hints: Dict[bytes32, bytes32] = field(init=False)
88
+ _offered_coins: Dict[Optional[bytes32], List[Coin]] = field(init=False, repr=False)
89
+ _final_spend_bundle: Optional[WalletSpendBundle] = field(init=False, repr=False)
90
+ _conditions: Optional[Dict[Coin, List[Condition]]] = field(init=False)
91
+
92
+ @staticmethod
93
+ def ph() -> bytes32:
94
+ return OFFER_MOD_HASH
95
+
96
+ @staticmethod
97
+ def notarize_payments(
98
+ requested_payments: Dict[Optional[bytes32], List[Payment]], # `None` means you are requesting XCH
99
+ coins: List[Coin],
100
+ ) -> Dict[Optional[bytes32], List[NotarizedPayment]]:
101
+ # This sort should be reproducible in CLVM with `>s`
102
+ sorted_coins: List[Coin] = sorted(coins, key=Coin.name)
103
+ sorted_coin_list: List[List[Union[bytes32, uint64]]] = [coin_as_list(c) for c in sorted_coins]
104
+ nonce: bytes32 = Program.to(sorted_coin_list).get_tree_hash()
105
+
106
+ notarized_payments: Dict[Optional[bytes32], List[NotarizedPayment]] = {}
107
+ for asset_id, payments in requested_payments.items():
108
+ notarized_payments[asset_id] = []
109
+ for p in payments:
110
+ puzzle_hash, amount, memos = tuple(p.as_condition_args())
111
+ notarized_payments[asset_id].append(NotarizedPayment(puzzle_hash, amount, memos, nonce))
112
+
113
+ return notarized_payments
114
+
115
+ # The announcements returned from this function must be asserted in whatever spend bundle is created by the wallet
116
+ @staticmethod
117
+ def calculate_announcements(
118
+ notarized_payments: Dict[Optional[bytes32], List[NotarizedPayment]],
119
+ driver_dict: Dict[bytes32, PuzzleInfo],
120
+ ) -> List[AssertPuzzleAnnouncement]:
121
+ announcements: List[AssertPuzzleAnnouncement] = []
122
+ for asset_id, payments in notarized_payments.items():
123
+ if asset_id is not None:
124
+ if asset_id not in driver_dict:
125
+ raise ValueError("Cannot calculate announcements without driver of requested item")
126
+ settlement_ph: bytes32 = construct_puzzle(driver_dict[asset_id], OFFER_MOD).get_tree_hash()
127
+ else:
128
+ settlement_ph = OFFER_MOD_HASH
129
+
130
+ msg: bytes32 = Program.to((payments[0].nonce, [p.as_condition_args() for p in payments])).get_tree_hash()
131
+ announcements.append(AssertPuzzleAnnouncement(asserted_ph=settlement_ph, asserted_msg=msg))
132
+
133
+ return announcements
134
+
135
+ def __post_init__(self) -> None:
136
+ # Verify that there are no duplicate payments
137
+ for payments in self.requested_payments.values():
138
+ payment_programs: List[bytes32] = [p.name() for p in payments]
139
+ if len(set(payment_programs)) != len(payment_programs):
140
+ raise ValueError("Bundle has duplicate requested payments")
141
+
142
+ # Verify we have a type for every kind of asset
143
+ for asset_id in self.requested_payments:
144
+ if asset_id is not None and asset_id not in self.driver_dict:
145
+ raise ValueError("Offer does not have enough driver information about the requested payments")
146
+
147
+ # populate the _additions cache
148
+ adds: Dict[Coin, List[Coin]] = {}
149
+ hints: Dict[bytes32, bytes32] = {}
150
+ max_cost = int(DEFAULT_CONSTANTS.MAX_BLOCK_COST_CLVM)
151
+ for cs in self._bundle.coin_spends:
152
+ # you can't spend the same coin twice in the same SpendBundle
153
+ assert cs.coin not in adds
154
+ try:
155
+ hinted_coins, cost = compute_spend_hints_and_additions(cs)
156
+ max_cost -= cost
157
+ adds[cs.coin] = [hc.coin for hc in hinted_coins.values()]
158
+ hints = {**hints, **{id: hc.hint for id, hc in hinted_coins.items() if hc.hint is not None}}
159
+ except Exception:
160
+ continue
161
+ if max_cost < 0:
162
+ raise ValidationError(Err.BLOCK_COST_EXCEEDS_MAX, "compute_additions for CoinSpend")
163
+ object.__setattr__(self, "_additions", adds)
164
+ object.__setattr__(self, "_hints", hints)
165
+ object.__setattr__(self, "_conditions", None)
166
+
167
+ def conditions(self) -> Dict[Coin, List[Condition]]:
168
+ if self._conditions is None:
169
+ conditions: Dict[Coin, List[Condition]] = {}
170
+ max_cost = int(DEFAULT_CONSTANTS.MAX_BLOCK_COST_CLVM)
171
+ for cs in self._bundle.coin_spends:
172
+ try:
173
+ cost, conds = cs.puzzle_reveal.run_with_cost(max_cost, cs.solution)
174
+ max_cost -= cost
175
+ conditions[cs.coin] = parse_conditions_non_consensus(conds.as_iter())
176
+ except Exception: # pragma: no cover
177
+ continue
178
+ if max_cost < 0: # pragma: no cover
179
+ raise ValidationError(Err.BLOCK_COST_EXCEEDS_MAX, "computing conditions for CoinSpend")
180
+ object.__setattr__(self, "_conditions", conditions)
181
+ assert self._conditions is not None, "self._conditions is None"
182
+ return self._conditions
183
+
184
+ def valid_times(self) -> Dict[Coin, ConditionValidTimes]:
185
+ return {coin: parse_timelock_info(conditions) for coin, conditions in self.conditions().items()}
186
+
187
+ def absolute_valid_times_ban_relatives(self) -> ConditionValidTimes:
188
+ valid_times: ConditionValidTimes = parse_timelock_info(
189
+ [c for conditions in self.conditions().values() for c in conditions]
190
+ )
191
+ if (
192
+ valid_times.max_secs_after_created is not None
193
+ or valid_times.min_secs_since_created is not None
194
+ or valid_times.max_blocks_after_created is not None
195
+ or valid_times.min_blocks_since_created is not None
196
+ ):
197
+ raise ValueError("Offers with relative timelocks are not currently supported")
198
+ return valid_times
199
+
200
+ def hints(self) -> Dict[bytes32, bytes32]:
201
+ return self._hints
202
+
203
+ def additions(self) -> List[Coin]:
204
+ return [c for additions in self._additions.values() for c in additions]
205
+
206
+ def removals(self) -> List[Coin]:
207
+ return self._bundle.removals()
208
+
209
+ def fees(self) -> int:
210
+ """Unsafe to use for fees validation!!!"""
211
+ amount_in = sum(_.amount for _ in self.removals())
212
+ amount_out = sum(_.amount for _ in self.additions())
213
+ return int(amount_in - amount_out)
214
+
215
+ def coin_spends(self) -> List[CoinSpend]:
216
+ return self._bundle.coin_spends
217
+
218
+ def aggregated_signature(self) -> G2Element:
219
+ return self._bundle.aggregated_signature
220
+
221
+ # This method does not get every coin that is being offered, only the `settlement_payment` children
222
+ # It's also a little heuristic, but it should get most things
223
+ def _get_offered_coins(self) -> Dict[Optional[bytes32], List[Coin]]:
224
+ offered_coins: Dict[Optional[bytes32], List[Coin]] = {}
225
+
226
+ for parent_spend in self._bundle.coin_spends:
227
+ coins_for_this_spend: List[Coin] = []
228
+
229
+ parent_puzzle: UncurriedPuzzle = uncurry_puzzle(parent_spend.puzzle_reveal)
230
+ parent_solution: Program = parent_spend.solution.to_program()
231
+ additions: List[Coin] = self._additions[parent_spend.coin]
232
+
233
+ puzzle_driver = match_puzzle(parent_puzzle)
234
+ if puzzle_driver is not None:
235
+ asset_id = create_asset_id(puzzle_driver)
236
+ inner_puzzle: Optional[Program] = get_inner_puzzle(puzzle_driver, parent_puzzle)
237
+ inner_solution: Optional[Program] = get_inner_solution(puzzle_driver, parent_solution)
238
+ assert inner_puzzle is not None and inner_solution is not None
239
+
240
+ # We're going to look at the conditions created by the inner puzzle
241
+ conditions: Program = inner_puzzle.run(inner_solution)
242
+ expected_num_matches: int = 0
243
+ offered_amounts: List[int] = []
244
+ for condition in conditions.as_iter():
245
+ if condition.first() == 51 and condition.rest().first() == OFFER_MOD_HASH:
246
+ expected_num_matches += 1
247
+ offered_amounts.append(condition.rest().rest().first().as_int())
248
+
249
+ # Start by filtering additions that match the amount
250
+ matching_spend_additions = [a for a in additions if a.amount in offered_amounts]
251
+
252
+ if len(matching_spend_additions) == expected_num_matches:
253
+ coins_for_this_spend.extend(matching_spend_additions)
254
+ # We didn't quite get there so now lets narrow it down by puzzle hash
255
+ else:
256
+ # If we narrowed down too much, we can't trust the amounts so start over with all additions
257
+ if len(matching_spend_additions) < expected_num_matches:
258
+ matching_spend_additions = additions
259
+ matching_spend_additions = [
260
+ a
261
+ for a in matching_spend_additions
262
+ if a.puzzle_hash
263
+ == construct_puzzle(puzzle_driver, OFFER_MOD_HASH).get_tree_hash_precalc( # type: ignore
264
+ OFFER_MOD_HASH
265
+ )
266
+ ]
267
+ if len(matching_spend_additions) == expected_num_matches:
268
+ coins_for_this_spend.extend(matching_spend_additions)
269
+ else:
270
+ raise ValueError("Could not properly guess offered coins from parent spend")
271
+ else:
272
+ # It's much easier if the asset is bare XCH
273
+ asset_id = None
274
+ coins_for_this_spend.extend([a for a in additions if a.puzzle_hash == OFFER_MOD_HASH])
275
+
276
+ # We only care about unspent coins
277
+ coins_for_this_spend = [c for c in coins_for_this_spend if c not in self._bundle.removals()]
278
+
279
+ if coins_for_this_spend != []:
280
+ offered_coins.setdefault(asset_id, [])
281
+ offered_coins[asset_id].extend(coins_for_this_spend)
282
+ return offered_coins
283
+
284
+ def get_offered_coins(self) -> Dict[Optional[bytes32], List[Coin]]:
285
+ try:
286
+ if self._offered_coins is not None:
287
+ return self._offered_coins
288
+ except AttributeError:
289
+ object.__setattr__(self, "_offered_coins", self._get_offered_coins())
290
+ return self._offered_coins
291
+
292
+ def get_offered_amounts(self) -> Dict[Optional[bytes32], int]:
293
+ offered_coins: Dict[Optional[bytes32], List[Coin]] = self.get_offered_coins()
294
+ offered_amounts: Dict[Optional[bytes32], int] = {}
295
+ for asset_id, coins in offered_coins.items():
296
+ offered_amounts[asset_id] = uint64(sum(c.amount for c in coins))
297
+ return offered_amounts
298
+
299
+ def get_requested_payments(self) -> Dict[Optional[bytes32], List[NotarizedPayment]]:
300
+ return self.requested_payments
301
+
302
+ def get_requested_amounts(self) -> Dict[Optional[bytes32], int]:
303
+ requested_amounts: Dict[Optional[bytes32], int] = {}
304
+ for asset_id, coins in self.get_requested_payments().items():
305
+ requested_amounts[asset_id] = uint64(sum(c.amount for c in coins))
306
+ return requested_amounts
307
+
308
+ def arbitrage(self) -> Dict[Optional[bytes32], int]:
309
+ """
310
+ Returns a dictionary of the type of each asset and amount that is involved in the trade
311
+ With the amount being how much their offered amount within the offer
312
+ exceeds/falls short of their requested amount.
313
+ """
314
+ offered_amounts: Dict[Optional[bytes32], int] = self.get_offered_amounts()
315
+ requested_amounts: Dict[Optional[bytes32], int] = self.get_requested_amounts()
316
+
317
+ arbitrage_dict: Dict[Optional[bytes32], int] = {}
318
+ for asset_id in [*requested_amounts.keys(), *offered_amounts.keys()]:
319
+ arbitrage_dict[asset_id] = offered_amounts.get(asset_id, 0) - requested_amounts.get(asset_id, 0)
320
+
321
+ return arbitrage_dict
322
+
323
+ # This is a method mostly for the UI that creates a JSON summary of the offer
324
+ def summary(self) -> Tuple[Dict[str, int], Dict[str, int], Dict[str, Dict[str, Any]], ConditionValidTimes]:
325
+ offered_amounts: Dict[Optional[bytes32], int] = self.get_offered_amounts()
326
+ requested_amounts: Dict[Optional[bytes32], int] = self.get_requested_amounts()
327
+
328
+ def keys_to_strings(dic: Dict[Optional[bytes32], Any]) -> Dict[str, Any]:
329
+ new_dic: Dict[str, Any] = {}
330
+ for key in dic:
331
+ if key is None:
332
+ new_dic["xch"] = dic[key]
333
+ else:
334
+ new_dic[key.hex()] = dic[key]
335
+ return new_dic
336
+
337
+ driver_dict: Dict[str, Any] = {}
338
+ for key, value in self.driver_dict.items():
339
+ driver_dict[key.hex()] = value.info
340
+
341
+ return (
342
+ keys_to_strings(offered_amounts),
343
+ keys_to_strings(requested_amounts),
344
+ driver_dict,
345
+ self.absolute_valid_times_ban_relatives(),
346
+ )
347
+
348
+ # Also mostly for the UI, returns a dictionary of assets and how much of them is pended for this offer
349
+ # This method is also imperfect for sufficiently complex spends
350
+ def get_pending_amounts(self) -> Dict[str, int]:
351
+ all_additions: List[Coin] = self.additions()
352
+ all_removals: List[Coin] = self.removals()
353
+ non_ephemeral_removals: List[Coin] = list(filter(lambda c: c not in all_additions, all_removals))
354
+
355
+ pending_dict: Dict[str, int] = {}
356
+ # First we add up the amounts of all coins that share an ancestor with the offered coins (i.e. a primary coin)
357
+ for asset_id, coins in self.get_offered_coins().items():
358
+ name = "xch" if asset_id is None else asset_id.hex()
359
+ pending_dict[name] = 0
360
+ for coin in coins:
361
+ root_removal: Coin = self.get_root_removal(coin)
362
+
363
+ for addition in filter(lambda c: c.parent_coin_info == root_removal.name(), all_additions):
364
+ pending_dict[name] += addition.amount
365
+
366
+ # Then we gather anything else as unknown
367
+ sum_of_additions_so_far: int = sum(pending_dict.values())
368
+ unknown: int = sum(c.amount for c in non_ephemeral_removals) - sum_of_additions_so_far
369
+ if unknown > 0:
370
+ pending_dict["unknown"] = unknown
371
+
372
+ return pending_dict
373
+
374
+ # This method returns all of the coins that are being used in the offer (without which it would be invalid)
375
+ def get_involved_coins(self) -> List[Coin]:
376
+ additions = self.additions()
377
+ return list(filter(lambda c: c not in additions, self.removals()))
378
+
379
+ # This returns the non-ephemeral removal that is an ancestor of the specified coin
380
+ # This should maybe move to the SpendBundle object at some point
381
+ def get_root_removal(self, coin: Coin) -> Coin:
382
+ all_removals: Set[Coin] = set(self.removals())
383
+ all_removal_ids: Set[bytes32] = {c.name() for c in all_removals}
384
+ non_ephemeral_removals: Set[Coin] = {
385
+ c for c in all_removals if c.parent_coin_info not in {r.name() for r in all_removals}
386
+ }
387
+ if coin.name() not in all_removal_ids and coin.parent_coin_info not in all_removal_ids:
388
+ raise ValueError("The specified coin is not a coin in this bundle")
389
+
390
+ while coin not in non_ephemeral_removals:
391
+ coin = next(c for c in all_removals if c.name() == coin.parent_coin_info)
392
+
393
+ return coin
394
+
395
+ # This will only return coins that are ancestors of settlement payments
396
+ def get_primary_coins(self) -> List[Coin]:
397
+ primary_coins: Set[Coin] = set()
398
+ for _, coins in self.get_offered_coins().items():
399
+ for coin in coins:
400
+ primary_coins.add(self.get_root_removal(coin))
401
+ return list(primary_coins)
402
+
403
+ # This returns the minimum coins that when spent will invalidate the rest of the bundle
404
+ def get_cancellation_coins(self) -> List[Coin]:
405
+ # First, we're going to gather:
406
+ dependencies: Dict[bytes32, List[bytes32]] = {} # all of the hashes that each coin depends on
407
+ announcements: Dict[bytes32, List[bytes32]] = {} # all of the hashes of the announcement that each coin makes
408
+ coin_names: List[bytes32] = [] # The names of all the coins
409
+ additions = self.additions()
410
+ for spend in [cs for cs in self._bundle.coin_spends if cs.coin not in additions]:
411
+ name = bytes32(spend.coin.name())
412
+ coin_names.append(name)
413
+ dependencies[name] = []
414
+ announcements[name] = []
415
+ conditions: Program = spend.puzzle_reveal.run_with_cost(INFINITE_COST, spend.solution)[1]
416
+ for condition in conditions.as_iter():
417
+ if condition.first() == 60: # create coin announcement
418
+ announcements[name].append(
419
+ AssertCoinAnnouncement(asserted_id=name, asserted_msg=condition.at("rf").as_python()).msg_calc
420
+ )
421
+ elif condition.first() == 61: # assert coin announcement
422
+ dependencies[name].append(bytes32(condition.at("rf").as_python()))
423
+
424
+ # We now enter a loop that is attempting to express the following logic:
425
+ # "If I am depending on another coin in the same bundle, you may as well cancel that coin instead of me"
426
+ # By the end of the loop, we should have filtered down the list of coin_names to include only those that will
427
+ # cancel everything else
428
+ while True:
429
+ removed = detect_dependent_coin(coin_names, dependencies, announcements)
430
+ if removed is None:
431
+ break
432
+ removed_coin, provider = removed
433
+ removed_announcements: List[bytes32] = announcements[removed_coin]
434
+ remove_these_keys: List[bytes32] = [removed_coin]
435
+ while True:
436
+ for coin, deps in dependencies.items():
437
+ if set(deps) & set(removed_announcements) and coin != provider:
438
+ remove_these_keys.append(coin)
439
+ removed_announcements = []
440
+ for coin in remove_these_keys:
441
+ dependencies.pop(coin)
442
+ removed_announcements.extend(announcements.pop(coin))
443
+ coin_names = [n for n in coin_names if n not in remove_these_keys]
444
+ if removed_announcements == []:
445
+ break
446
+ else:
447
+ remove_these_keys = []
448
+
449
+ return [cs.coin for cs in self._bundle.coin_spends if cs.coin.name() in coin_names]
450
+
451
+ @classmethod
452
+ def aggregate(cls, offers: List[Offer]) -> Offer:
453
+ total_requested_payments: Dict[Optional[bytes32], List[NotarizedPayment]] = {}
454
+ total_bundle = WalletSpendBundle([], G2Element())
455
+ total_driver_dict: Dict[bytes32, PuzzleInfo] = {}
456
+ for offer in offers:
457
+ # First check for any overlap in inputs
458
+ total_inputs: Set[Coin] = {cs.coin for cs in total_bundle.coin_spends}
459
+ offer_inputs: Set[Coin] = {cs.coin for cs in offer._bundle.coin_spends}
460
+ if total_inputs & offer_inputs:
461
+ raise ValueError("The aggregated offers overlap inputs")
462
+
463
+ # Next, do the aggregation
464
+ for asset_id, payments in offer.requested_payments.items():
465
+ if asset_id in total_requested_payments:
466
+ total_requested_payments[asset_id].extend(payments)
467
+ else:
468
+ total_requested_payments[asset_id] = payments
469
+
470
+ for key, value in offer.driver_dict.items():
471
+ if key in total_driver_dict and total_driver_dict[key] != value:
472
+ raise ValueError(f"The offers to aggregate disagree on the drivers for {key.hex()}")
473
+
474
+ total_bundle = WalletSpendBundle.aggregate([total_bundle, offer._bundle])
475
+ total_driver_dict.update(offer.driver_dict)
476
+
477
+ return cls(total_requested_payments, total_bundle, total_driver_dict)
478
+
479
+ # Validity is defined by having enough funds within the offer to satisfy both sides
480
+ def is_valid(self) -> bool:
481
+ return all([value >= 0 for value in self.arbitrage().values()])
482
+
483
+ # A "valid" spend means that this bundle can be pushed to the network and will succeed
484
+ # This differs from the `to_spend_bundle` method which deliberately creates an invalid SpendBundle
485
+ def to_valid_spend(self, arbitrage_ph: Optional[bytes32] = None, solver: Solver = Solver({})) -> WalletSpendBundle:
486
+ if not self.is_valid():
487
+ raise ValueError("Offer is currently incomplete")
488
+
489
+ completion_spends: List[CoinSpend] = []
490
+ all_offered_coins: Dict[Optional[bytes32], List[Coin]] = self.get_offered_coins()
491
+ total_arbitrage_amount: Dict[Optional[bytes32], int] = self.arbitrage()
492
+ for asset_id, payments in self.requested_payments.items():
493
+ offered_coins: List[Coin] = all_offered_coins[asset_id]
494
+
495
+ # Because of CAT supply laws, we must specify a place for the leftovers to go
496
+ arbitrage_amount: int = total_arbitrage_amount[asset_id]
497
+ all_payments: List[NotarizedPayment] = payments.copy()
498
+ if arbitrage_amount > 0:
499
+ assert arbitrage_amount is not None
500
+ assert arbitrage_ph is not None
501
+ all_payments.append(NotarizedPayment(arbitrage_ph, uint64(arbitrage_amount)))
502
+
503
+ # Some assets need to know about siblings so we need to collect all spends first to be able to use them
504
+ coin_to_spend_dict: Dict[Coin, CoinSpend] = {}
505
+ coin_to_solution_dict: Dict[Coin, Program] = {}
506
+ for coin in offered_coins:
507
+ parent_spend: CoinSpend = list(
508
+ filter(lambda cs: cs.coin.name() == coin.parent_coin_info, self._bundle.coin_spends)
509
+ )[0]
510
+ coin_to_spend_dict[coin] = parent_spend
511
+
512
+ inner_solutions = []
513
+ if coin == offered_coins[0]:
514
+ nonces: List[bytes32] = [p.nonce for p in all_payments]
515
+ for nonce in list(dict.fromkeys(nonces)): # dedup without messing with order
516
+ nonce_payments: List[NotarizedPayment] = list(filter(lambda p: p.nonce == nonce, all_payments))
517
+ inner_solutions.append((nonce, [np.as_condition_args() for np in nonce_payments]))
518
+ coin_to_solution_dict[coin] = Program.to(inner_solutions)
519
+
520
+ for coin in offered_coins:
521
+ if asset_id:
522
+ siblings: str = "("
523
+ sibling_spends: str = "("
524
+ sibling_puzzles: str = "("
525
+ sibling_solutions: str = "("
526
+ disassembled_offer_mod: str = disassemble(OFFER_MOD)
527
+ for sibling_coin in offered_coins:
528
+ if sibling_coin != coin:
529
+ siblings += (
530
+ "0x"
531
+ + sibling_coin.parent_coin_info.hex()
532
+ + sibling_coin.puzzle_hash.hex()
533
+ + uint64(sibling_coin.amount).stream_to_bytes().hex()
534
+ + " "
535
+ )
536
+ sibling_spends += "0x" + bytes(coin_to_spend_dict[sibling_coin]).hex() + " "
537
+ sibling_puzzles += disassembled_offer_mod + " "
538
+ sibling_solutions += disassemble(coin_to_solution_dict[sibling_coin]) + " "
539
+ siblings += ")"
540
+ sibling_spends += ")"
541
+ sibling_puzzles += ")"
542
+ sibling_solutions += ")"
543
+
544
+ solution: Program = solve_puzzle(
545
+ self.driver_dict[asset_id],
546
+ Solver(
547
+ {
548
+ "coin": "0x"
549
+ + coin.parent_coin_info.hex()
550
+ + coin.puzzle_hash.hex()
551
+ + uint64(coin.amount).stream_to_bytes().hex(),
552
+ "parent_spend": "0x" + bytes(coin_to_spend_dict[coin]).hex(),
553
+ "siblings": siblings,
554
+ "sibling_spends": sibling_spends,
555
+ "sibling_puzzles": sibling_puzzles,
556
+ "sibling_solutions": sibling_solutions,
557
+ **solver.info,
558
+ }
559
+ ),
560
+ OFFER_MOD,
561
+ Program.to(coin_to_solution_dict[coin]),
562
+ )
563
+ else:
564
+ solution = Program.to(coin_to_solution_dict[coin])
565
+
566
+ completion_spends.append(
567
+ make_spend(
568
+ coin,
569
+ construct_puzzle(self.driver_dict[asset_id], OFFER_MOD) if asset_id else OFFER_MOD,
570
+ solution,
571
+ )
572
+ )
573
+
574
+ return WalletSpendBundle.aggregate([WalletSpendBundle(completion_spends, G2Element()), self._bundle])
575
+
576
+ def to_spend_bundle(self) -> WalletSpendBundle:
577
+ try:
578
+ if self._final_spend_bundle is not None:
579
+ return self._final_spend_bundle
580
+ except AttributeError:
581
+ pass
582
+ # Before we serialize this as a SpendBundle, we need to serialize the `requested_payments` as dummy CoinSpends
583
+ additional_coin_spends: List[CoinSpend] = []
584
+ for asset_id, payments in self.requested_payments.items():
585
+ puzzle_reveal: Program = construct_puzzle(self.driver_dict[asset_id], OFFER_MOD) if asset_id else OFFER_MOD
586
+ inner_solutions = []
587
+ nonces: List[bytes32] = [p.nonce for p in payments]
588
+ for nonce in list(dict.fromkeys(nonces)): # dedup without messing with order
589
+ nonce_payments: List[NotarizedPayment] = list(filter(lambda p: p.nonce == nonce, payments))
590
+ inner_solutions.append((nonce, [np.as_condition_args() for np in nonce_payments]))
591
+
592
+ additional_coin_spends.append(
593
+ make_spend(
594
+ Coin(
595
+ ZERO_32,
596
+ puzzle_reveal.get_tree_hash(),
597
+ uint64(0),
598
+ ),
599
+ puzzle_reveal,
600
+ Program.to(inner_solutions),
601
+ )
602
+ )
603
+
604
+ sb = WalletSpendBundle.aggregate(
605
+ [
606
+ WalletSpendBundle(additional_coin_spends, G2Element()),
607
+ self._bundle,
608
+ ]
609
+ )
610
+ object.__setattr__(self, "_final_spend_bundle", sb)
611
+ return sb
612
+
613
+ @classmethod
614
+ def from_spend_bundle(cls, bundle: WalletSpendBundle) -> Offer:
615
+ # Because of the `to_spend_bundle` method, we need to parse the dummy CoinSpends as `requested_payments`
616
+ requested_payments: Dict[Optional[bytes32], List[NotarizedPayment]] = {}
617
+ driver_dict: Dict[bytes32, PuzzleInfo] = {}
618
+ leftover_coin_spends: List[CoinSpend] = []
619
+ for coin_spend in bundle.coin_spends:
620
+ driver = match_puzzle(uncurry_puzzle(coin_spend.puzzle_reveal))
621
+ if driver is not None:
622
+ asset_id = create_asset_id(driver)
623
+ assert asset_id is not None
624
+ driver_dict[asset_id] = driver
625
+ else:
626
+ asset_id = None
627
+ if coin_spend.coin.parent_coin_info == ZERO_32:
628
+ notarized_payments: List[NotarizedPayment] = []
629
+ for payment_group in coin_spend.solution.to_program().as_iter():
630
+ nonce = bytes32(payment_group.first().as_atom())
631
+ payment_args_list = payment_group.rest().as_iter()
632
+ notarized_payments.extend(
633
+ [NotarizedPayment.from_condition_and_nonce(condition, nonce) for condition in payment_args_list]
634
+ )
635
+
636
+ requested_payments[asset_id] = notarized_payments
637
+ else:
638
+ leftover_coin_spends.append(coin_spend)
639
+
640
+ return cls(
641
+ requested_payments, WalletSpendBundle(leftover_coin_spends, bundle.aggregated_signature), driver_dict
642
+ )
643
+
644
+ def name(self) -> bytes32:
645
+ return self.to_spend_bundle().name()
646
+
647
+ def __eq__(self, other: object) -> bool:
648
+ if not isinstance(other, Offer):
649
+ return False # don't attempt to compare against unrelated types
650
+ return self.name() == other.name()
651
+
652
+ def compress(self, version: Optional[int] = None) -> bytes:
653
+ as_spend_bundle = self.to_spend_bundle()
654
+ if version is None:
655
+ mods: List[bytes] = [bytes(s.puzzle_reveal.to_program().uncurry()[0]) for s in as_spend_bundle.coin_spends]
656
+ version = max(lowest_best_version(mods), 6) # Clients lower than version 6 should not be able to parse
657
+ return compress_object_with_puzzles(bytes(as_spend_bundle), version)
658
+
659
+ @classmethod
660
+ def from_compressed(cls, compressed_bytes: bytes) -> Offer:
661
+ return Offer.from_bytes(decompress_object_with_puzzles(compressed_bytes))
662
+
663
+ @classmethod
664
+ def try_offer_decompression(cls, offer_bytes: bytes) -> Offer:
665
+ try:
666
+ return cls.from_compressed(offer_bytes)
667
+ except TypeError:
668
+ pass
669
+ return cls.from_bytes(offer_bytes)
670
+
671
+ def to_bech32(self, prefix: str = "offer", compression_version: Optional[int] = None) -> str:
672
+ offer_bytes = self.compress(version=compression_version)
673
+ encoded = bech32_encode(prefix, convertbits(list(offer_bytes), 8, 5))
674
+ return encoded
675
+
676
+ @classmethod
677
+ def from_bech32(cls, offer_bech32: str) -> Offer:
678
+ hrpgot, data = bech32_decode(offer_bech32, max_length=len(offer_bech32))
679
+ if data is None:
680
+ raise ValueError("Invalid Offer")
681
+ decoded = convertbits(list(data), 5, 8, False)
682
+ decoded_bytes = bytes(decoded)
683
+ return cls.try_offer_decompression(decoded_bytes)
684
+
685
+ # Methods to make this a valid Streamable member
686
+ # We basically hijack the SpendBundle versions for most of it
687
+ @classmethod
688
+ def parse(cls, f: BinaryIO) -> Offer:
689
+ parsed_bundle = parse_rust(f, WalletSpendBundle)
690
+ return cls.from_bytes(bytes(parsed_bundle))
691
+
692
+ def stream(self, f: BinaryIO) -> None:
693
+ spend_bundle_bytes = self.to_spend_bundle().to_bytes()
694
+ f.write(spend_bundle_bytes)
695
+
696
+ def __bytes__(self) -> bytes:
697
+ return bytes(self.to_spend_bundle())
698
+
699
+ @classmethod
700
+ def from_bytes(cls, as_bytes: bytes) -> Offer:
701
+ # Because of the __bytes__ method, we need to parse the dummy CoinSpends as `requested_payments`
702
+ bundle = WalletSpendBundle.from_bytes(as_bytes)
703
+ return cls.from_spend_bundle(bundle)