chia-blockchain 2.5.7rc3__py3-none-any.whl → 2.5.8rc1__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 (528) hide show
  1. chia/__init__.py +8 -4
  2. chia/_tests/blockchain/blockchain_test_utils.py +6 -8
  3. chia/_tests/blockchain/test_augmented_chain.py +4 -4
  4. chia/_tests/blockchain/test_blockchain.py +165 -190
  5. chia/_tests/blockchain/test_build_chains.py +2 -4
  6. chia/_tests/blockchain/test_get_block_generator.py +2 -3
  7. chia/_tests/clvm/coin_store.py +4 -7
  8. chia/_tests/clvm/test_clvm_step.py +4 -4
  9. chia/_tests/clvm/test_puzzle_compression.py +2 -1
  10. chia/_tests/clvm/test_puzzle_drivers.py +2 -2
  11. chia/_tests/clvm/test_singletons.py +2 -4
  12. chia/_tests/clvm/test_spend_sim.py +2 -2
  13. chia/_tests/cmds/cmd_test_utils.py +27 -45
  14. chia/_tests/cmds/test_cmd_framework.py +6 -6
  15. chia/_tests/cmds/test_daemon.py +3 -3
  16. chia/_tests/cmds/test_show.py +4 -4
  17. chia/_tests/cmds/test_tx_config_args.py +1 -2
  18. chia/_tests/cmds/testing_classes.py +4 -5
  19. chia/_tests/cmds/wallet/test_did.py +24 -27
  20. chia/_tests/cmds/wallet/test_nft.py +12 -10
  21. chia/_tests/cmds/wallet/test_vcs.py +11 -12
  22. chia/_tests/cmds/wallet/test_wallet.py +134 -89
  23. chia/_tests/conftest.py +59 -30
  24. chia/_tests/connection_utils.py +2 -2
  25. chia/_tests/core/cmds/test_beta.py +4 -4
  26. chia/_tests/core/cmds/test_keys.py +2 -3
  27. chia/_tests/core/cmds/test_wallet.py +15 -15
  28. chia/_tests/core/consensus/test_pot_iterations.py +19 -73
  29. chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
  30. chia/_tests/core/daemon/test_daemon.py +11 -11
  31. chia/_tests/core/data_layer/conftest.py +2 -2
  32. chia/_tests/core/data_layer/test_data_rpc.py +28 -14
  33. chia/_tests/core/data_layer/test_data_store.py +10 -10
  34. chia/_tests/core/data_layer/util.py +11 -11
  35. chia/_tests/core/farmer/test_farmer_api.py +2 -4
  36. chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
  37. chia/_tests/core/full_node/stores/test_block_store.py +5 -4
  38. chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
  39. chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
  40. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  41. chia/_tests/core/full_node/test_block_height_map.py +3 -4
  42. chia/_tests/core/full_node/test_conditions.py +21 -23
  43. chia/_tests/core/full_node/test_full_node.py +225 -62
  44. chia/_tests/core/full_node/test_hint_management.py +2 -4
  45. chia/_tests/core/full_node/test_performance.py +0 -1
  46. chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
  47. chia/_tests/core/full_node/test_transactions.py +1 -2
  48. chia/_tests/core/full_node/test_tx_processing_queue.py +109 -25
  49. chia/_tests/core/mempool/test_mempool.py +29 -37
  50. chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
  51. chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
  52. chia/_tests/core/mempool/test_mempool_manager.py +963 -839
  53. chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
  54. chia/_tests/core/server/serve.py +7 -7
  55. chia/_tests/core/server/test_dos.py +1 -2
  56. chia/_tests/core/server/test_event_loop.py +12 -4
  57. chia/_tests/core/server/test_loop.py +7 -8
  58. chia/_tests/core/server/test_rate_limits.py +9 -8
  59. chia/_tests/core/server/test_server.py +61 -1
  60. chia/_tests/core/services/test_services.py +2 -2
  61. chia/_tests/core/ssl/test_ssl.py +2 -2
  62. chia/_tests/core/test_cost_calculation.py +2 -6
  63. chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
  64. chia/_tests/core/test_filter.py +0 -1
  65. chia/_tests/core/test_full_node_rpc.py +2 -2
  66. chia/_tests/core/test_merkle_set.py +1 -2
  67. chia/_tests/core/test_seeder.py +4 -4
  68. chia/_tests/core/util/test_config.py +4 -4
  69. chia/_tests/core/util/test_jsonify.py +2 -2
  70. chia/_tests/core/util/test_keychain.py +3 -3
  71. chia/_tests/core/util/test_lockfile.py +2 -1
  72. chia/_tests/core/util/test_log_exceptions.py +1 -2
  73. chia/_tests/core/util/test_streamable.py +17 -17
  74. chia/_tests/db/test_db_wrapper.py +3 -2
  75. chia/_tests/environments/wallet.py +14 -14
  76. chia/_tests/ether.py +4 -3
  77. chia/_tests/farmer_harvester/test_farmer.py +41 -24
  78. chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
  79. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
  80. chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
  81. chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
  82. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
  83. chia/_tests/harvester/test_harvester_api.py +11 -4
  84. chia/_tests/plot_sync/test_plot_sync.py +13 -11
  85. chia/_tests/plot_sync/test_receiver.py +11 -10
  86. chia/_tests/plot_sync/test_sync_simulated.py +2 -2
  87. chia/_tests/plot_sync/util.py +1 -2
  88. chia/_tests/plotting/test_plot_manager.py +7 -6
  89. chia/_tests/plotting/test_prover.py +30 -38
  90. chia/_tests/pools/test_pool_cmdline.py +4 -6
  91. chia/_tests/pools/test_pool_rpc.py +203 -61
  92. chia/_tests/pools/test_pool_wallet.py +3 -3
  93. chia/_tests/pools/test_wallet_pool_store.py +1 -4
  94. chia/_tests/process_junit.py +2 -2
  95. chia/_tests/rpc/test_rpc_client.py +4 -4
  96. chia/_tests/rpc/test_rpc_server.py +3 -3
  97. chia/_tests/simulation/test_simulation.py +12 -25
  98. chia/_tests/solver/test_solver_service.py +13 -4
  99. chia/_tests/testconfig.py +2 -2
  100. chia/_tests/timelord/test_new_peak.py +22 -11
  101. chia/_tests/tools/test_run_block.py +0 -2
  102. chia/_tests/tools/test_virtual_project.py +2 -1
  103. chia/_tests/util/benchmarks.py +1 -0
  104. chia/_tests/util/blockchain.py +38 -36
  105. chia/_tests/util/blockchain_mock.py +11 -11
  106. chia/_tests/util/build_network_protocol_files.py +2 -1
  107. chia/_tests/util/coin_store.py +2 -1
  108. chia/_tests/util/config.py +1 -1
  109. chia/_tests/util/db_connection.py +2 -3
  110. chia/_tests/util/full_sync.py +9 -11
  111. chia/_tests/util/gen_ssl_certs.py +4 -5
  112. chia/_tests/util/get_name_puzzle_conditions.py +2 -0
  113. chia/_tests/util/misc.py +24 -24
  114. chia/_tests/util/network_protocol_data.py +20 -3
  115. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  116. chia/_tests/util/protocol_messages_json.py +292 -3
  117. chia/_tests/util/setup_nodes.py +62 -47
  118. chia/_tests/util/spend_sim.py +57 -57
  119. chia/_tests/util/test_async_pool.py +2 -3
  120. chia/_tests/util/test_chia_version.py +1 -3
  121. chia/_tests/util/test_config.py +3 -3
  122. chia/_tests/util/test_full_block_utils.py +6 -3
  123. chia/_tests/util/test_limited_semaphore.py +1 -2
  124. chia/_tests/util/test_misc.py +2 -2
  125. chia/_tests/util/test_network.py +1 -2
  126. chia/_tests/util/test_priority_mutex.py +3 -3
  127. chia/_tests/util/test_recursive_replace.py +5 -6
  128. chia/_tests/util/test_replace_str_to_bytes.py +8 -10
  129. chia/_tests/util/test_testnet_overrides.py +3 -3
  130. chia/_tests/util/time_out_assert.py +2 -2
  131. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
  132. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
  133. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
  134. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
  135. chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
  136. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
  137. chia/_tests/wallet/conftest.py +6 -6
  138. chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
  139. chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
  140. chia/_tests/wallet/did_wallet/test_did.py +16 -6
  141. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
  142. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
  143. chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
  144. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
  145. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
  146. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
  147. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
  148. chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
  149. chia/_tests/wallet/sync/test_wallet_sync.py +43 -47
  150. chia/_tests/wallet/test_clvm_streamable.py +2 -3
  151. chia/_tests/wallet/test_coin_management.py +2 -2
  152. chia/_tests/wallet/test_conditions.py +45 -51
  153. chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
  154. chia/_tests/wallet/test_new_wallet_protocol.py +4 -6
  155. chia/_tests/wallet/test_notifications.py +14 -14
  156. chia/_tests/wallet/test_signer_protocol.py +5 -5
  157. chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
  158. chia/_tests/wallet/test_transaction_store.py +20 -20
  159. chia/_tests/wallet/test_util.py +2 -2
  160. chia/_tests/wallet/test_wallet.py +380 -228
  161. chia/_tests/wallet/test_wallet_action_scope.py +4 -4
  162. chia/_tests/wallet/test_wallet_blockchain.py +12 -12
  163. chia/_tests/wallet/test_wallet_coin_store.py +3 -4
  164. chia/_tests/wallet/test_wallet_node.py +14 -14
  165. chia/_tests/wallet/test_wallet_test_framework.py +2 -1
  166. chia/_tests/wallet/test_wallet_utils.py +2 -3
  167. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
  168. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
  169. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
  170. chia/_tests/wallet/wallet_block_tools.py +12 -11
  171. chia/_tests/weight_proof/config.py +1 -0
  172. chia/_tests/weight_proof/test_weight_proof.py +5 -4
  173. chia/apis/__init__.py +21 -0
  174. chia/apis/farmer_stub.py +102 -0
  175. chia/apis/full_node_stub.py +372 -0
  176. chia/apis/harvester_stub.py +57 -0
  177. chia/apis/introducer_stub.py +35 -0
  178. chia/apis/solver_stub.py +30 -0
  179. chia/apis/stub_protocol_registry.py +21 -0
  180. chia/apis/timelord_stub.py +39 -0
  181. chia/apis/wallet_stub.py +161 -0
  182. chia/cmds/beta.py +3 -4
  183. chia/cmds/beta_funcs.py +4 -3
  184. chia/cmds/check_wallet_db.py +4 -4
  185. chia/cmds/chia.py +1 -2
  186. chia/cmds/cmd_classes.py +11 -13
  187. chia/cmds/cmd_helpers.py +11 -11
  188. chia/cmds/cmds_util.py +15 -15
  189. chia/cmds/coin_funcs.py +6 -7
  190. chia/cmds/coins.py +2 -3
  191. chia/cmds/configure.py +1 -2
  192. chia/cmds/data.py +42 -42
  193. chia/cmds/data_funcs.py +81 -81
  194. chia/cmds/db.py +4 -5
  195. chia/cmds/db_backup_func.py +2 -2
  196. chia/cmds/db_upgrade_func.py +3 -3
  197. chia/cmds/db_validate_func.py +2 -2
  198. chia/cmds/dev/data.py +4 -4
  199. chia/cmds/dev/gh.py +5 -5
  200. chia/cmds/dev/installers.py +2 -3
  201. chia/cmds/dev/mempool.py +3 -4
  202. chia/cmds/dev/mempool_funcs.py +4 -4
  203. chia/cmds/dev/sim.py +8 -8
  204. chia/cmds/dump_keyring.py +3 -3
  205. chia/cmds/farm.py +6 -8
  206. chia/cmds/farm_funcs.py +25 -24
  207. chia/cmds/init_funcs.py +4 -4
  208. chia/cmds/keys.py +16 -18
  209. chia/cmds/keys_funcs.py +36 -36
  210. chia/cmds/netspace.py +1 -3
  211. chia/cmds/netspace_funcs.py +1 -2
  212. chia/cmds/options.py +3 -2
  213. chia/cmds/param_types.py +17 -16
  214. chia/cmds/passphrase.py +6 -7
  215. chia/cmds/passphrase_funcs.py +11 -13
  216. chia/cmds/peer.py +1 -3
  217. chia/cmds/peer_funcs.py +3 -3
  218. chia/cmds/plotnft.py +6 -7
  219. chia/cmds/plotnft_funcs.py +37 -26
  220. chia/cmds/rpc.py +3 -3
  221. chia/cmds/show.py +3 -5
  222. chia/cmds/show_funcs.py +9 -9
  223. chia/cmds/sim_funcs.py +25 -26
  224. chia/cmds/solver.py +1 -3
  225. chia/cmds/solver_funcs.py +1 -2
  226. chia/cmds/start_funcs.py +2 -2
  227. chia/cmds/wallet.py +76 -81
  228. chia/cmds/wallet_funcs.py +206 -177
  229. chia/consensus/augmented_chain.py +6 -6
  230. chia/consensus/block_body_validation.py +19 -15
  231. chia/consensus/block_creation.py +25 -21
  232. chia/consensus/block_header_validation.py +27 -13
  233. chia/consensus/block_height_map.py +3 -6
  234. chia/consensus/block_height_map_protocol.py +2 -2
  235. chia/consensus/block_record.py +2 -4
  236. chia/consensus/blockchain.py +58 -40
  237. chia/consensus/blockchain_interface.py +7 -7
  238. chia/consensus/coin_store_protocol.py +5 -6
  239. chia/consensus/condition_tools.py +4 -4
  240. chia/consensus/cost_calculator.py +2 -3
  241. chia/consensus/default_constants.py +16 -13
  242. chia/consensus/deficit.py +1 -3
  243. chia/consensus/difficulty_adjustment.py +3 -5
  244. chia/consensus/find_fork_point.py +2 -4
  245. chia/consensus/full_block_to_block_record.py +11 -13
  246. chia/consensus/generator_tools.py +2 -3
  247. chia/consensus/get_block_challenge.py +42 -26
  248. chia/consensus/get_block_generator.py +2 -3
  249. chia/consensus/make_sub_epoch_summary.py +8 -7
  250. chia/consensus/multiprocess_validation.py +31 -20
  251. chia/consensus/pos_quality.py +6 -23
  252. chia/consensus/pot_iterations.py +17 -44
  253. chia/consensus/signage_point.py +4 -5
  254. chia/consensus/vdf_info_computation.py +2 -4
  255. chia/daemon/client.py +8 -8
  256. chia/daemon/keychain_proxy.py +31 -37
  257. chia/daemon/server.py +32 -33
  258. chia/daemon/windows_signal.py +4 -3
  259. chia/data_layer/data_layer.py +86 -77
  260. chia/data_layer/data_layer_rpc_api.py +9 -9
  261. chia/data_layer/data_layer_rpc_client.py +13 -15
  262. chia/data_layer/data_layer_server.py +3 -3
  263. chia/data_layer/data_layer_util.py +14 -14
  264. chia/data_layer/data_layer_wallet.py +94 -101
  265. chia/data_layer/data_store.py +50 -50
  266. chia/data_layer/dl_wallet_store.py +9 -12
  267. chia/data_layer/download_data.py +8 -9
  268. chia/data_layer/s3_plugin_service.py +5 -9
  269. chia/data_layer/start_data_layer.py +5 -5
  270. chia/farmer/farmer.py +31 -31
  271. chia/farmer/farmer_api.py +45 -33
  272. chia/farmer/farmer_rpc_api.py +5 -4
  273. chia/farmer/farmer_rpc_client.py +6 -6
  274. chia/farmer/start_farmer.py +12 -7
  275. chia/full_node/block_store.py +13 -16
  276. chia/full_node/check_fork_next_block.py +1 -2
  277. chia/full_node/coin_store.py +15 -16
  278. chia/full_node/eligible_coin_spends.py +3 -3
  279. chia/full_node/fee_estimate_store.py +2 -3
  280. chia/full_node/fee_tracker.py +1 -2
  281. chia/full_node/full_block_utils.py +4 -4
  282. chia/full_node/full_node.py +238 -224
  283. chia/full_node/full_node_api.py +193 -150
  284. chia/full_node/full_node_rpc_api.py +53 -31
  285. chia/full_node/full_node_rpc_client.py +18 -19
  286. chia/full_node/full_node_store.py +45 -43
  287. chia/full_node/hint_management.py +2 -2
  288. chia/full_node/mempool.py +17 -19
  289. chia/full_node/mempool_manager.py +89 -42
  290. chia/full_node/pending_tx_cache.py +2 -3
  291. chia/full_node/start_full_node.py +5 -5
  292. chia/full_node/sync_store.py +3 -4
  293. chia/full_node/tx_processing_queue.py +34 -13
  294. chia/full_node/weight_proof.py +61 -48
  295. chia/harvester/harvester.py +25 -24
  296. chia/harvester/harvester_api.py +61 -38
  297. chia/harvester/harvester_rpc_api.py +10 -10
  298. chia/harvester/start_harvester.py +4 -4
  299. chia/introducer/introducer.py +3 -3
  300. chia/introducer/introducer_api.py +6 -4
  301. chia/introducer/start_introducer.py +4 -4
  302. chia/legacy/keyring.py +3 -3
  303. chia/plot_sync/delta.py +1 -2
  304. chia/plot_sync/receiver.py +20 -17
  305. chia/plot_sync/sender.py +15 -10
  306. chia/plotters/bladebit.py +7 -7
  307. chia/plotters/chiapos.py +2 -2
  308. chia/plotters/madmax.py +4 -4
  309. chia/plotters/plotters.py +4 -4
  310. chia/plotters/plotters_util.py +3 -3
  311. chia/plotting/cache.py +20 -14
  312. chia/plotting/check_plots.py +26 -35
  313. chia/plotting/create_plots.py +22 -23
  314. chia/plotting/manager.py +21 -14
  315. chia/plotting/prover.py +59 -42
  316. chia/plotting/util.py +16 -16
  317. chia/pools/pool_config.py +2 -1
  318. chia/pools/pool_puzzles.py +11 -12
  319. chia/pools/pool_wallet.py +34 -57
  320. chia/pools/pool_wallet_info.py +39 -10
  321. chia/protocols/farmer_protocol.py +8 -9
  322. chia/protocols/fee_estimate.py +3 -4
  323. chia/protocols/full_node_protocol.py +3 -4
  324. chia/protocols/harvester_protocol.py +27 -15
  325. chia/protocols/outbound_message.py +3 -3
  326. chia/protocols/pool_protocol.py +8 -9
  327. chia/protocols/shared_protocol.py +1 -2
  328. chia/protocols/solver_protocol.py +9 -2
  329. chia/protocols/timelord_protocol.py +4 -7
  330. chia/protocols/wallet_protocol.py +11 -12
  331. chia/rpc/rpc_client.py +9 -9
  332. chia/rpc/rpc_server.py +17 -17
  333. chia/rpc/util.py +2 -2
  334. chia/seeder/crawler.py +8 -8
  335. chia/seeder/crawler_api.py +21 -27
  336. chia/seeder/crawler_rpc_api.py +2 -2
  337. chia/seeder/dns_server.py +21 -21
  338. chia/seeder/start_crawler.py +4 -4
  339. chia/server/address_manager.py +15 -16
  340. chia/server/api_protocol.py +11 -11
  341. chia/server/chia_policy.py +46 -26
  342. chia/server/introducer_peers.py +2 -3
  343. chia/server/node_discovery.py +19 -19
  344. chia/server/rate_limit_numbers.py +4 -5
  345. chia/server/rate_limits.py +4 -4
  346. chia/server/resolve_peer_info.py +4 -4
  347. chia/server/server.py +49 -52
  348. chia/server/signal_handlers.py +6 -6
  349. chia/server/start_service.py +17 -17
  350. chia/server/upnp.py +4 -6
  351. chia/server/ws_connection.py +52 -37
  352. chia/simulator/add_blocks_in_batches.py +1 -3
  353. chia/simulator/block_tools.py +312 -200
  354. chia/simulator/full_node_simulator.py +56 -35
  355. chia/simulator/keyring.py +2 -3
  356. chia/simulator/setup_services.py +16 -15
  357. chia/simulator/simulator_full_node_rpc_api.py +1 -2
  358. chia/simulator/simulator_full_node_rpc_client.py +1 -2
  359. chia/simulator/simulator_protocol.py +1 -2
  360. chia/simulator/simulator_test_tools.py +3 -3
  361. chia/simulator/start_simulator.py +7 -7
  362. chia/simulator/wallet_tools.py +10 -10
  363. chia/solver/solver.py +10 -10
  364. chia/solver/solver_api.py +10 -8
  365. chia/solver/solver_rpc_api.py +2 -2
  366. chia/solver/start_solver.py +4 -4
  367. chia/ssl/cacert.pem +148 -90
  368. chia/ssl/chia_ca.crt +14 -10
  369. chia/ssl/chia_ca_old.crt +19 -0
  370. chia/ssl/create_ssl.py +4 -4
  371. chia/ssl/renewedselfsignedca.conf +4 -0
  372. chia/ssl/ssl_check.py +1 -2
  373. chia/timelord/iters_from_block.py +1 -4
  374. chia/timelord/start_timelord.py +4 -4
  375. chia/timelord/timelord.py +44 -40
  376. chia/timelord/timelord_api.py +6 -4
  377. chia/timelord/timelord_launcher.py +2 -2
  378. chia/timelord/timelord_rpc_api.py +2 -2
  379. chia/timelord/timelord_state.py +11 -12
  380. chia/types/block_protocol.py +1 -3
  381. chia/types/blockchain_format/coin.py +1 -3
  382. chia/types/blockchain_format/program.py +11 -8
  383. chia/types/blockchain_format/proof_of_space.py +123 -76
  384. chia/types/blockchain_format/tree_hash.py +3 -3
  385. chia/types/blockchain_format/vdf.py +1 -2
  386. chia/types/coin_spend.py +3 -3
  387. chia/types/mempool_item.py +5 -5
  388. chia/types/mempool_submission_status.py +2 -3
  389. chia/types/peer_info.py +1 -2
  390. chia/types/unfinished_header_block.py +3 -4
  391. chia/types/validation_state.py +1 -2
  392. chia/util/action_scope.py +8 -8
  393. chia/util/async_pool.py +5 -5
  394. chia/util/bech32m.py +1 -2
  395. chia/util/beta_metrics.py +2 -2
  396. chia/util/block_cache.py +4 -4
  397. chia/util/chia_logging.py +2 -2
  398. chia/util/chia_version.py +1 -2
  399. chia/util/config.py +15 -16
  400. chia/util/db_wrapper.py +26 -27
  401. chia/util/default_root.py +1 -2
  402. chia/util/errors.py +3 -3
  403. chia/util/file_keyring.py +14 -14
  404. chia/util/files.py +2 -3
  405. chia/util/hash.py +4 -4
  406. chia/util/initial-config.yaml +3 -5
  407. chia/util/inline_executor.py +2 -1
  408. chia/util/ip_address.py +1 -2
  409. chia/util/keychain.py +25 -27
  410. chia/util/keyring_wrapper.py +18 -19
  411. chia/util/lock.py +3 -4
  412. chia/util/log_exceptions.py +1 -2
  413. chia/util/lru_cache.py +2 -2
  414. chia/util/network.py +6 -6
  415. chia/util/path.py +2 -3
  416. chia/util/priority_mutex.py +2 -2
  417. chia/util/profiler.py +1 -2
  418. chia/util/safe_cancel_task.py +1 -2
  419. chia/util/streamable.py +22 -8
  420. chia/util/task_referencer.py +1 -1
  421. chia/util/timing.py +3 -3
  422. chia/util/virtual_project_analysis.py +6 -5
  423. chia/util/ws_message.py +2 -2
  424. chia/wallet/cat_wallet/cat_info.py +3 -4
  425. chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
  426. chia/wallet/cat_wallet/cat_utils.py +3 -4
  427. chia/wallet/cat_wallet/cat_wallet.py +61 -83
  428. chia/wallet/cat_wallet/lineage_store.py +3 -4
  429. chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
  430. chia/wallet/coin_selection.py +9 -10
  431. chia/wallet/conditions.py +120 -105
  432. chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
  433. chia/wallet/derivation_record.py +1 -2
  434. chia/wallet/derive_keys.py +2 -4
  435. chia/wallet/did_wallet/did_info.py +10 -11
  436. chia/wallet/did_wallet/did_wallet.py +36 -82
  437. chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
  438. chia/wallet/driver_protocol.py +5 -7
  439. chia/wallet/lineage_proof.py +4 -4
  440. chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
  441. chia/wallet/nft_wallet/nft_info.py +8 -9
  442. chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
  443. chia/wallet/nft_wallet/nft_wallet.py +79 -116
  444. chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
  445. chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
  446. chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
  447. chia/wallet/nft_wallet/uncurry_nft.py +10 -11
  448. chia/wallet/notification_manager.py +3 -3
  449. chia/wallet/notification_store.py +44 -61
  450. chia/wallet/outer_puzzles.py +6 -7
  451. chia/wallet/puzzle_drivers.py +34 -6
  452. chia/wallet/puzzles/clawback/drivers.py +6 -6
  453. chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
  454. chia/wallet/puzzles/load_clvm.py +1 -1
  455. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
  456. chia/wallet/puzzles/singleton_top_layer.py +2 -3
  457. chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
  458. chia/wallet/puzzles/tails.py +3 -3
  459. chia/wallet/singleton.py +5 -7
  460. chia/wallet/singleton_record.py +3 -3
  461. chia/wallet/start_wallet.py +5 -5
  462. chia/wallet/trade_manager.py +37 -58
  463. chia/wallet/trade_record.py +4 -4
  464. chia/wallet/trading/offer.py +59 -46
  465. chia/wallet/trading/trade_store.py +8 -9
  466. chia/wallet/transaction_record.py +8 -8
  467. chia/wallet/uncurried_puzzle.py +1 -2
  468. chia/wallet/util/clvm_streamable.py +12 -12
  469. chia/wallet/util/compute_hints.py +4 -5
  470. chia/wallet/util/curry_and_treehash.py +1 -2
  471. chia/wallet/util/merkle_tree.py +2 -3
  472. chia/wallet/util/peer_request_cache.py +8 -8
  473. chia/wallet/util/signing.py +85 -0
  474. chia/wallet/util/tx_config.py +15 -6
  475. chia/wallet/util/wallet_sync_utils.py +14 -16
  476. chia/wallet/util/wallet_types.py +2 -2
  477. chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
  478. chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
  479. chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
  480. chia/wallet/vc_wallet/vc_drivers.py +27 -27
  481. chia/wallet/vc_wallet/vc_store.py +5 -6
  482. chia/wallet/vc_wallet/vc_wallet.py +33 -61
  483. chia/wallet/wallet.py +50 -78
  484. chia/wallet/wallet_action_scope.py +11 -11
  485. chia/wallet/wallet_blockchain.py +12 -12
  486. chia/wallet/wallet_coin_record.py +12 -6
  487. chia/wallet/wallet_coin_store.py +24 -25
  488. chia/wallet/wallet_interested_store.py +3 -5
  489. chia/wallet/wallet_nft_store.py +10 -11
  490. chia/wallet/wallet_node.py +53 -61
  491. chia/wallet/wallet_node_api.py +5 -3
  492. chia/wallet/wallet_protocol.py +23 -23
  493. chia/wallet/wallet_puzzle_store.py +15 -18
  494. chia/wallet/wallet_request_types.py +778 -114
  495. chia/wallet/wallet_retry_store.py +1 -3
  496. chia/wallet/wallet_rpc_api.py +572 -909
  497. chia/wallet/wallet_rpc_client.py +87 -279
  498. chia/wallet/wallet_singleton_store.py +3 -4
  499. chia/wallet/wallet_state_manager.py +332 -106
  500. chia/wallet/wallet_transaction_store.py +11 -14
  501. chia/wallet/wallet_user_store.py +4 -6
  502. chia/wallet/wallet_weight_proof_handler.py +4 -4
  503. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/METADATA +6 -5
  504. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/RECORD +507 -516
  505. chia/apis.py +0 -21
  506. chia/consensus/check_time_locks.py +0 -57
  507. chia/data_layer/puzzles/__init__.py +0 -0
  508. chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
  509. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
  510. chia/types/coin_record.py +0 -44
  511. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  512. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
  513. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
  514. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
  515. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
  516. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
  517. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
  518. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
  519. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
  520. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
  521. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
  522. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
  523. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
  524. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
  525. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
  526. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/WHEEL +0 -0
  527. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/entry_points.txt +0 -0
  528. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,85 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+ from chia_rs import AugSchemeMPL, G1Element, G2Element, PrivateKey
6
+ from chia_rs.sized_bytes import bytes32
7
+
8
+ from chia.types.blockchain_format.program import Program
9
+ from chia.types.signing_mode import CHIP_0002_SIGN_MESSAGE_PREFIX, SigningMode
10
+ from chia.util.bech32m import decode_puzzle_hash
11
+ from chia.util.byte_types import hexstr_to_bytes
12
+ from chia.wallet.puzzles import p2_delegated_conditions
13
+ from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_hash_for_synthetic_public_key
14
+ from chia.wallet.wallet_request_types import VerifySignatureResponse
15
+
16
+ # CHIP-0002 message signing as documented at:
17
+ # https://github.com/Chia-Network/chips/blob/80e4611fe52b174bf1a0382b9dff73805b18b8c6/CHIPs/chip-0002.md
18
+
19
+
20
+ def verify_signature(
21
+ *, signing_mode: SigningMode, public_key: G1Element, message: str, signature: G2Element, address: str | None
22
+ ) -> VerifySignatureResponse:
23
+ """
24
+ Given a public key, message and signature, verify if it is valid.
25
+ :param request:
26
+ :return:
27
+ """
28
+ if signing_mode in {SigningMode.CHIP_0002, SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS}:
29
+ # CHIP-0002 message signatures are made over the tree hash of:
30
+ # ("Chia Signed Message", message)
31
+ message_to_verify: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message)).get_tree_hash()
32
+ elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT:
33
+ # Message is expected to be a hex string
34
+ message_to_verify = hexstr_to_bytes(message)
35
+ elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT:
36
+ # Message is expected to be a UTF-8 string
37
+ message_to_verify = bytes(message, "utf-8")
38
+ else:
39
+ raise ValueError(f"Unsupported signing mode: {signing_mode!r}")
40
+
41
+ # Verify using the BLS message augmentation scheme
42
+ is_valid = AugSchemeMPL.verify(
43
+ public_key,
44
+ message_to_verify,
45
+ signature,
46
+ )
47
+ if address is not None:
48
+ # For signatures made by the sign_message_by_address/sign_message_by_id
49
+ # endpoints, the "address" field should contain the p2_address of the NFT/DID
50
+ # that was used to sign the message.
51
+ puzzle_hash: bytes32 = decode_puzzle_hash(address)
52
+ expected_puzzle_hash: bytes32 | None = None
53
+ if signing_mode == SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS:
54
+ puzzle = p2_delegated_conditions.puzzle_for_pk(Program.to(public_key))
55
+ expected_puzzle_hash = bytes32(puzzle.get_tree_hash())
56
+ else:
57
+ expected_puzzle_hash = puzzle_hash_for_synthetic_public_key(public_key)
58
+ if puzzle_hash != expected_puzzle_hash:
59
+ return VerifySignatureResponse(isValid=False, error="Public key doesn't match the address")
60
+ if is_valid:
61
+ return VerifySignatureResponse(isValid=is_valid)
62
+ else:
63
+ return VerifySignatureResponse(isValid=False, error="Signature is invalid.")
64
+
65
+
66
+ @dataclass(kw_only=True, frozen=True)
67
+ class SignMessageResponse:
68
+ pubkey: G1Element
69
+ signature: G2Element
70
+
71
+
72
+ def sign_message(secret_key: PrivateKey, message: str, mode: SigningMode) -> SignMessageResponse:
73
+ public_key = secret_key.get_g1()
74
+ if mode == SigningMode.CHIP_0002_HEX_INPUT:
75
+ hex_message: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, bytes.fromhex(message))).get_tree_hash()
76
+ elif mode == SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT:
77
+ hex_message = bytes(message, "utf-8")
78
+ elif mode == SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT:
79
+ hex_message = bytes.fromhex(message)
80
+ else:
81
+ hex_message = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message)).get_tree_hash()
82
+ return SignMessageResponse(
83
+ pubkey=public_key,
84
+ signature=AugSchemeMPL.sign(secret_key, hex_message),
85
+ )
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
- from typing import Any, Optional
4
+ from typing import Any
5
5
 
6
6
  from chia_rs import ConsensusConstants
7
7
  from chia_rs.sized_bytes import bytes32
@@ -32,6 +32,15 @@ class CoinSelectionConfig:
32
32
  def override(self, **kwargs: Any) -> CoinSelectionConfig:
33
33
  return dataclasses.replace(self, **kwargs)
34
34
 
35
+ def filter_coins(self, coins: set[Coin]) -> set[Coin]:
36
+ return {
37
+ coin
38
+ for coin in coins
39
+ if self.min_coin_amount <= coin.amount <= self.max_coin_amount
40
+ and coin.amount not in self.excluded_coin_amounts
41
+ and coin.name() not in self.excluded_coin_ids
42
+ }
43
+
35
44
 
36
45
  @dataclasses.dataclass(frozen=True)
37
46
  class TXConfig(CoinSelectionConfig):
@@ -69,10 +78,10 @@ class AutofillArgs(TypedDict):
69
78
  @streamable
70
79
  @dataclasses.dataclass(frozen=True)
71
80
  class CoinSelectionConfigLoader(Streamable):
72
- min_coin_amount: Optional[uint64] = None
73
- max_coin_amount: Optional[uint64] = None
74
- excluded_coin_amounts: Optional[list[uint64]] = None
75
- excluded_coin_ids: Optional[list[bytes32]] = None
81
+ min_coin_amount: uint64 | None = None
82
+ max_coin_amount: uint64 | None = None
83
+ excluded_coin_amounts: list[uint64] | None = None
84
+ excluded_coin_ids: list[bytes32] | None = None
76
85
 
77
86
  def autofill(
78
87
  self,
@@ -106,7 +115,7 @@ class CoinSelectionConfigLoader(Streamable):
106
115
  @streamable
107
116
  @dataclasses.dataclass(frozen=True)
108
117
  class TXConfigLoader(CoinSelectionConfigLoader):
109
- reuse_puzhash: Optional[bool] = None
118
+ reuse_puzhash: bool | None = None
110
119
 
111
120
  def autofill(
112
121
  self,
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import logging
5
5
  import random
6
- from typing import Any, Optional, Union
6
+ from typing import Any
7
7
 
8
8
  from chia_rs import (
9
9
  CoinSpend,
@@ -60,7 +60,7 @@ async def subscribe_to_phs(
60
60
  Tells full nodes that we are interested in puzzle hashes, and returns the response.
61
61
  """
62
62
  msg = RegisterForPhUpdates(puzzle_hashes, uint32(max(min_height, uint32(0))))
63
- all_coins_state: Optional[RespondToPhUpdates] = await peer.call_api(
63
+ all_coins_state: RespondToPhUpdates | None = await peer.call_api(
64
64
  FullNodeAPI.register_for_ph_updates, msg, timeout=300
65
65
  )
66
66
  if all_coins_state is None:
@@ -77,7 +77,7 @@ async def subscribe_to_coin_updates(
77
77
  Tells full nodes that we are interested in coin ids, and returns the response.
78
78
  """
79
79
  msg = RegisterForCoinUpdates(coin_names, uint32(max(0, min_height)))
80
- all_coins_state: Optional[RespondToCoinUpdates] = await peer.call_api(
80
+ all_coins_state: RespondToCoinUpdates | None = await peer.call_api(
81
81
  FullNodeAPI.register_for_coin_updates, msg, timeout=300
82
82
  )
83
83
 
@@ -88,7 +88,7 @@ async def subscribe_to_coin_updates(
88
88
 
89
89
  def validate_additions(
90
90
  coins: list[tuple[bytes32, list[Coin]]],
91
- proofs: Optional[list[tuple[bytes32, bytes, Optional[bytes]]]],
91
+ proofs: list[tuple[bytes32, bytes, bytes | None]] | None,
92
92
  root: bytes32,
93
93
  ) -> bool:
94
94
  if proofs is None:
@@ -107,8 +107,8 @@ def validate_additions(
107
107
  for i in range(len(coins)):
108
108
  assert coins[i][0] == proofs[i][0]
109
109
  coin_list_1: list[Coin] = coins[i][1]
110
- puzzle_hash_proof: Optional[bytes] = proofs[i][1]
111
- coin_list_proof: Optional[bytes] = proofs[i][2]
110
+ puzzle_hash_proof: bytes | None = proofs[i][1]
111
+ coin_list_proof: bytes | None = proofs[i][2]
112
112
  if len(coin_list_1) == 0:
113
113
  # Verify exclusion proof for puzzle hash
114
114
  assert puzzle_hash_proof is not None
@@ -149,7 +149,7 @@ def validate_additions(
149
149
 
150
150
 
151
151
  def validate_removals(
152
- coins: list[tuple[bytes32, Optional[Coin]]], proofs: Optional[list[tuple[bytes32, bytes]]], root: bytes32
152
+ coins: list[tuple[bytes32, Coin | None]], proofs: list[tuple[bytes32, bytes]] | None, root: bytes32
153
153
  ) -> bool:
154
154
  if proofs is None:
155
155
  # If there are no proofs, it means all removals were returned in the response.
@@ -198,7 +198,7 @@ async def request_and_validate_removals(
198
198
  ) -> bool:
199
199
  removals_request = RequestRemovals(height, header_hash, [coin_name])
200
200
 
201
- removals_res: Optional[Union[RespondRemovals, RejectRemovalsRequest]] = await peer.call_api(
201
+ removals_res: RespondRemovals | RejectRemovalsRequest | None = await peer.call_api(
202
202
  FullNodeAPI.request_removals, removals_request
203
203
  )
204
204
  if removals_res is None or isinstance(removals_res, RejectRemovalsRequest):
@@ -217,7 +217,7 @@ async def request_and_validate_additions(
217
217
  if peer_request_cache.in_additions_in_block(header_hash, puzzle_hash):
218
218
  return True
219
219
  additions_request = RequestAdditions(height, header_hash, [puzzle_hash])
220
- additions_res: Optional[Union[RespondAdditions, RejectAdditionsRequest]] = await peer.call_api(
220
+ additions_res: RespondAdditions | RejectAdditionsRequest | None = await peer.call_api(
221
221
  FullNodeAPI.request_additions, additions_request
222
222
  )
223
223
  if additions_res is None or isinstance(additions_res, RejectAdditionsRequest):
@@ -254,7 +254,7 @@ def sort_coin_states(coin_states: set[CoinState]) -> list[CoinState]:
254
254
 
255
255
  async def request_header_blocks(
256
256
  peer: WSChiaConnection, start_height: uint32, end_height: uint32
257
- ) -> Optional[list[HeaderBlock]]:
257
+ ) -> list[HeaderBlock] | None:
258
258
  if Capability.BLOCK_HEADERS in peer.peer_capabilities:
259
259
  response = await peer.call_api(
260
260
  FullNodeAPI.request_block_headers, RequestBlockHeaders(start_height, end_height, False)
@@ -271,7 +271,7 @@ async def _fetch_header_blocks_inner(
271
271
  all_peers: list[tuple[WSChiaConnection, bool]],
272
272
  request_start: uint32,
273
273
  request_end: uint32,
274
- ) -> Optional[Union[RespondHeaderBlocks, RespondBlockHeaders]]:
274
+ ) -> RespondHeaderBlocks | RespondBlockHeaders | None:
275
275
  # We will modify this list, don't modify passed parameters.
276
276
  bytes_api_peers = [peer for peer in all_peers if Capability.BLOCK_HEADERS in peer[0].peer_capabilities]
277
277
  other_peers = [peer for peer in all_peers if Capability.BLOCK_HEADERS not in peer[0].peer_capabilities]
@@ -305,19 +305,17 @@ async def fetch_header_blocks_in_range(
305
305
  end: uint32,
306
306
  peer_request_cache: PeerRequestCache,
307
307
  all_peers: list[tuple[WSChiaConnection, bool]],
308
- ) -> Optional[list[HeaderBlock]]:
308
+ ) -> list[HeaderBlock] | None:
309
309
  blocks: list[HeaderBlock] = []
310
310
  for i in range(start - (start % 32), end + 1, 32):
311
311
  request_start = min(uint32(i), end)
312
312
  request_end = min(uint32(i + 31), end)
313
- res_h_blocks_task: Optional[asyncio.Task[Any]] = peer_request_cache.get_block_request(
314
- request_start, request_end
315
- )
313
+ res_h_blocks_task: asyncio.Task[Any] | None = peer_request_cache.get_block_request(request_start, request_end)
316
314
 
317
315
  if res_h_blocks_task is not None:
318
316
  log.debug(f"Using cache for: {start}-{end}")
319
317
  if res_h_blocks_task.done():
320
- res_h_blocks: Optional[Union[RespondBlockHeaders, RespondHeaderBlocks]] = res_h_blocks_task.result()
318
+ res_h_blocks: RespondBlockHeaders | RespondHeaderBlocks | None = res_h_blocks_task.result()
321
319
  else:
322
320
  res_h_blocks = await res_h_blocks_task
323
321
  else:
@@ -33,8 +33,8 @@ class WalletType(IntEnum):
33
33
  def to_json_dict(self) -> str:
34
34
  # yes, this isn't a `dict`, but it is json and
35
35
  # unfortunately the magic method name is misleading
36
- # not sure this code is used
37
- # TODO: determine if this code is used and if not, remove it
36
+
37
+ # This gets called with EnhancedJSONEncoder in the RPC
38
38
  return self.name
39
39
 
40
40
 
@@ -4,7 +4,6 @@ import functools
4
4
  from collections.abc import Iterable
5
5
  from dataclasses import dataclass, replace
6
6
  from enum import IntEnum
7
- from typing import Optional
8
7
 
9
8
  from chia_puzzles_py.programs import (
10
9
  CONDITIONS_W_FEE_ANNOUNCE,
@@ -65,7 +64,7 @@ CREDENTIAL_STRUCT: Program = Program.to(
65
64
  curry_and_treehash(
66
65
  Program.to((1, EXTIGENT_METADATA_LAYER_HASH)).get_tree_hash_precalc(EXTIGENT_METADATA_LAYER_HASH),
67
66
  Program.to(EXTIGENT_METADATA_LAYER_HASH).get_tree_hash(),
68
- Program.to(None).get_tree_hash(),
67
+ Program.NIL.get_tree_hash(),
69
68
  GUARANTEED_NIL_TP_HASH,
70
69
  Program.to(GUARANTEED_NIL_TP_HASH).get_tree_hash(),
71
70
  P2_ANNOUNCED_DELEGATED_PUZZLE_HASH,
@@ -127,7 +126,7 @@ def construct_cr_layer_hash(
127
126
 
128
127
  def match_cr_layer(
129
128
  uncurried_puzzle: UncurriedPuzzle,
130
- ) -> Optional[tuple[list[bytes32], Program, Program]]:
129
+ ) -> tuple[list[bytes32], Program, Program] | None:
131
130
  extra_uncurried_puzzle = uncurry_puzzle(uncurried_puzzle.mod)
132
131
  if extra_uncurried_puzzle.mod == CREDENTIAL_RESTRICTION:
133
132
  return (
@@ -188,7 +187,7 @@ class CRCAT:
188
187
  authorized_providers: list[bytes32],
189
188
  proofs_checker: Program,
190
189
  # Probably never need this but some tail might
191
- optional_lineage_proof: Optional[LineageProof] = None,
190
+ optional_lineage_proof: LineageProof | None = None,
192
191
  ) -> tuple[Program, CoinSpend, CRCAT]:
193
192
  """
194
193
  Launch a new CR-CAT from XCH.
@@ -327,7 +326,7 @@ class CRCAT:
327
326
  def get_next_from_coin_spend(
328
327
  cls,
329
328
  parent_spend: CoinSpend,
330
- conditions: Optional[Program] = None, # For optimization purposes, the conditions may already have been run
329
+ conditions: Program | None = None, # For optimization purposes, the conditions may already have been run
331
330
  ) -> list[CRCAT]:
332
331
  """
333
332
  Given a coin spend, this will return the next CR-CATs that were created as an output of that spend.
@@ -342,7 +341,7 @@ class CRCAT:
342
341
 
343
342
  # Get info by uncurrying
344
343
  _, tail_hash_as_prog, potential_cr_layer = puzzle.uncurry()[1].as_iter()
345
- new_inner_puzzle_hash: Optional[bytes32] = None
344
+ new_inner_puzzle_hash: bytes32 | None = None
346
345
  if potential_cr_layer.uncurry()[0].uncurry()[0] != CREDENTIAL_RESTRICTION:
347
346
  # If the previous spend is not a CR-CAT:
348
347
  # we look for a remark condition that tells us the authorized_providers and proofs_checker
@@ -428,12 +427,12 @@ class CRCAT:
428
427
  proof_checker_solution: Program,
429
428
  provider_id: bytes32,
430
429
  vc_launcher_id: bytes32,
431
- vc_inner_puzhash: Optional[bytes32], # Optional for incomplete spends
430
+ vc_inner_puzhash: bytes32 | None, # Optional for incomplete spends
432
431
  # Inner puzzle and solution
433
432
  inner_puzzle: Program,
434
433
  inner_solution: Program,
435
434
  # For optimization purposes the conditions may already have been run
436
- conditions: Optional[Iterable[Program]] = None,
435
+ conditions: Iterable[Program] | None = None,
437
436
  ) -> tuple[list[AssertCoinAnnouncement], CoinSpend, list[CRCAT]]:
438
437
  """
439
438
  Spend a CR-CAT.
@@ -521,7 +520,7 @@ class CRCAT:
521
520
  proof_checker_solution: Program,
522
521
  provider_id: bytes32,
523
522
  vc_launcher_id: bytes32,
524
- vc_inner_puzhash: Optional[bytes32], # Optional for incomplete spends
523
+ vc_inner_puzhash: bytes32 | None, # Optional for incomplete spends
525
524
  ) -> tuple[list[AssertCoinAnnouncement], list[CoinSpend], list[CRCAT]]:
526
525
  """
527
526
  Spend a multiple CR-CATs.
@@ -615,7 +614,7 @@ class CRCATSpend:
615
614
  inner_puzzle,
616
615
  inner_solution,
617
616
  CRCAT.get_next_from_coin_spend(spend, conditions=inner_conditions),
618
- Program.from_serialized(spend.solution).at("f").at("rrrrf") == Program.to(None),
617
+ Program.from_serialized(spend.solution).at("f").at("rrrrf") == Program.NIL,
619
618
  list(inner_conditions.as_iter()),
620
619
  Program.from_serialized(spend.solution).at("f").at("f"),
621
620
  )
@@ -628,7 +627,7 @@ class ProofsChecker(Streamable):
628
627
 
629
628
  def as_program(self) -> Program:
630
629
  def byte_sort_flags(f1: str, f2: str) -> int:
631
- return 1 if Program.to([10, (1, f1), (1, f2)]).run([]) == Program.to(None) else -1
630
+ return 1 if Program.to([10, (1, f1), (1, f2)]).run([]) == Program.NIL else -1
632
631
 
633
632
  return PROOF_FLAGS_CHECKER.curry(
634
633
  [
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  import time
5
5
  import traceback
6
- from typing import TYPE_CHECKING, Any, ClassVar, Optional
6
+ from typing import TYPE_CHECKING, Any, ClassVar
7
7
 
8
8
  from chia_rs import CoinSpend, G1Element, G2Element
9
9
  from chia_rs.sized_bytes import bytes32
@@ -72,8 +72,8 @@ class CRCATWallet(CATWallet):
72
72
  wallet_info_type: ClassVar[type[CRCATInfo]] = CRCATInfo
73
73
 
74
74
  @staticmethod
75
- def default_wallet_name_for_unknown_cat(limitations_program_hash_hex: str) -> str:
76
- return f"CAT {limitations_program_hash_hex[:16]}..."
75
+ def default_wallet_name_for_unknown_cat(limitations_program_hash: bytes32) -> str:
76
+ return f"CAT {limitations_program_hash.hex()[:16]}..."
77
77
 
78
78
  @property
79
79
  def cost_of_single_tx(self) -> int:
@@ -87,7 +87,7 @@ class CRCATWallet(CATWallet):
87
87
  amount: uint64,
88
88
  action_scope: WalletActionScope,
89
89
  fee: uint64 = uint64(0),
90
- name: Optional[str] = None,
90
+ name: str | None = None,
91
91
  push: bool = False,
92
92
  ) -> CATWallet: # pragma: no cover
93
93
  raise NotImplementedError("create_new_cat_wallet is a legacy method and is not available on CR-CAT wallets")
@@ -97,31 +97,29 @@ class CRCATWallet(CATWallet):
97
97
  cls,
98
98
  wallet_state_manager: WalletStateManager,
99
99
  wallet: Wallet,
100
- limitations_program_hash_hex: str,
101
- name: Optional[str] = None,
102
- authorized_providers: Optional[list[bytes32]] = None,
103
- proofs_checker: Optional[ProofsChecker] = None,
100
+ limitations_program_hash: bytes32,
101
+ name: str | None = None,
102
+ authorized_providers: list[bytes32] | None = None,
103
+ proofs_checker: ProofsChecker | None = None,
104
104
  ) -> Self:
105
105
  if authorized_providers is None or proofs_checker is None: # pragma: no cover
106
106
  raise ValueError("get_or_create_wallet_for_cat was call on CRCATWallet without proper arguments")
107
107
  self = cls()
108
108
  self.standard_wallet = wallet
109
109
  if name is None:
110
- name = self.default_wallet_name_for_unknown_cat(limitations_program_hash_hex)
110
+ name = self.default_wallet_name_for_unknown_cat(limitations_program_hash)
111
111
  self.log = logging.getLogger(name)
112
112
 
113
- tail_hash = bytes32.from_hexstr(limitations_program_hash_hex)
114
-
115
113
  for id, w in wallet_state_manager.wallets.items():
116
114
  if w.type() == cls.type():
117
115
  assert isinstance(w, cls)
118
- if w.get_asset_id() == limitations_program_hash_hex:
116
+ if w.get_asset_id() == limitations_program_hash:
119
117
  self.log.warning("Not creating wallet for already existing CR-CAT wallet")
120
118
  return w
121
119
 
122
120
  self.wallet_state_manager = wallet_state_manager
123
121
 
124
- self.info = cls.wallet_info_type(tail_hash, None, authorized_providers, proofs_checker)
122
+ self.info = cls.wallet_info_type(limitations_program_hash, None, authorized_providers, proofs_checker)
125
123
  info_as_string = bytes(self.info).hex()
126
124
  self.wallet_info = await wallet_state_manager.user_store.create_wallet(name, WalletType.CRCAT, info_as_string)
127
125
 
@@ -134,20 +132,20 @@ class CRCATWallet(CATWallet):
134
132
  wallet_state_manager: WalletStateManager,
135
133
  wallet: Wallet,
136
134
  puzzle_driver: PuzzleInfo,
137
- name: Optional[str] = None,
135
+ name: str | None = None,
138
136
  # We're hinting this as Any for mypy by should explore adding this to the wallet protocol and hinting properly
139
- potential_subclasses: Optional[dict[AssetType, Any]] = None,
137
+ potential_subclasses: dict[AssetType, Any] | None = None,
140
138
  ) -> Any:
141
139
  if potential_subclasses is None:
142
140
  potential_subclasses = {}
143
141
 
144
- cr_layer: Optional[PuzzleInfo] = puzzle_driver.also()
142
+ cr_layer: PuzzleInfo | None = puzzle_driver.also()
145
143
  if cr_layer is None: # pragma: no cover
146
144
  raise ValueError("create_from_puzzle_info called on CRCATWallet with a non CR-CAT puzzle driver")
147
145
  return await cls.get_or_create_wallet_for_cat(
148
146
  wallet_state_manager,
149
147
  wallet,
150
- puzzle_driver["tail"].hex(),
148
+ puzzle_driver["tail"],
151
149
  name,
152
150
  [bytes32(provider) for provider in cr_layer["authorized_providers"]],
153
151
  ProofsChecker.from_program(uncurry_puzzle(cr_layer["proofs_checker"])),
@@ -201,14 +199,14 @@ class CRCATWallet(CATWallet):
201
199
  def id(self) -> uint32:
202
200
  return self.wallet_info.id
203
201
 
204
- def get_asset_id(self) -> str:
205
- return bytes(self.info.limitations_program_hash).hex()
202
+ def get_asset_id(self) -> bytes32:
203
+ return self.info.limitations_program_hash
206
204
 
207
205
  async def set_tail_program(self, tail_program: str) -> None: # pragma: no cover
208
206
  raise NotImplementedError("set_tail_program is a legacy method and is not available on CR-CAT wallets")
209
207
 
210
208
  async def coin_added(
211
- self, coin: Coin, height: uint32, peer: WSChiaConnection, coin_data: Optional[CATCoinData]
209
+ self, coin: Coin, height: uint32, peer: WSChiaConnection, coin_data: CATCoinData | None
212
210
  ) -> None:
213
211
  """Notification from wallet state manager that wallet has been received."""
214
212
  self.log.info(f"CR-CAT wallet has been notified that {coin.name().hex()} was added")
@@ -322,21 +320,13 @@ class CRCATWallet(CATWallet):
322
320
  "inner_puzzle_for_cat_puzhash is a legacy method and is not available on CR-CAT wallets"
323
321
  )
324
322
 
325
- async def get_cat_spendable_coins(self, records: Optional[set[WalletCoinRecord]] = None) -> list[WalletCoinRecord]:
326
- result: list[WalletCoinRecord] = []
327
-
328
- record_list: set[WalletCoinRecord] = await self.wallet_state_manager.get_spendable_coins_for_wallet(
329
- self.id(), records
330
- )
331
-
332
- for record in record_list:
333
- crcat: CRCAT = self.coin_record_to_crcat(record)
334
- if crcat.lineage_proof is not None and not crcat.lineage_proof.is_none():
335
- result.append(record)
336
-
337
- return result
323
+ async def is_coin_spendable(self, record: WalletCoinRecord) -> bool:
324
+ crcat: CRCAT = self.coin_record_to_crcat(record)
325
+ if crcat.lineage_proof is not None and not crcat.lineage_proof.is_none():
326
+ return True
327
+ return False
338
328
 
339
- async def get_confirmed_balance(self, record_list: Optional[set[WalletCoinRecord]] = None) -> uint128:
329
+ async def get_confirmed_balance(self, record_list: set[WalletCoinRecord] | None = None) -> uint128:
340
330
  if record_list is None:
341
331
  record_list = await self.wallet_state_manager.coin_store.get_unspent_coins_for_wallet(
342
332
  self.id(), CoinType.CRCAT
@@ -350,7 +340,7 @@ class CRCATWallet(CATWallet):
350
340
  self.log.info(f"Confirmed balance for cat wallet {self.id()} is {amount}")
351
341
  return uint128(amount)
352
342
 
353
- async def get_pending_approval_balance(self, record_list: Optional[set[WalletCoinRecord]] = None) -> uint128:
343
+ async def get_pending_approval_balance(self, record_list: set[WalletCoinRecord] | None = None) -> uint128:
354
344
  if record_list is None:
355
345
  record_list = await self.wallet_state_manager.coin_store.get_unspent_coins_for_wallet(
356
346
  self.id(), CoinType.CRCAT_PENDING
@@ -398,7 +388,7 @@ class CRCATWallet(CATWallet):
398
388
  except Exception as e: # pragma: no cover
399
389
  raise ValueError(f"Error parsing CRCAT metadata: {e}")
400
390
 
401
- async def get_lineage_proof_for_coin(self, coin: Coin) -> Optional[LineageProof]: # pragma: no cover
391
+ async def get_lineage_proof_for_coin(self, coin: Coin) -> LineageProof | None: # pragma: no cover
402
392
  raise RuntimeError("get_lineage_proof_for_coin is a legacy method and is not available on CR-CAT wallets")
403
393
 
404
394
  async def _generate_unsigned_spendbundle(
@@ -406,8 +396,8 @@ class CRCATWallet(CATWallet):
406
396
  payments: list[CreateCoin],
407
397
  action_scope: WalletActionScope,
408
398
  fee: uint64 = uint64(0),
409
- cat_discrepancy: Optional[tuple[int, Program, Program]] = None, # (extra_delta, tail_reveal, tail_solution)
410
- coins: Optional[set[Coin]] = None,
399
+ cat_discrepancy: tuple[int, Program, Program] | None = None, # (extra_delta, tail_reveal, tail_solution)
400
+ coins: set[Coin] | None = None,
411
401
  extra_conditions: tuple[Condition, ...] = tuple(),
412
402
  add_authorizations_to_cr_cats: bool = True,
413
403
  ) -> WalletSpendBundle:
@@ -480,7 +470,7 @@ class CRCATWallet(CATWallet):
480
470
  raise RuntimeError("CR-CATs cannot be spent without an appropriate VC") # pragma: no cover
481
471
 
482
472
  # Loop through the coins we've selected and gather the information we need to spend them
483
- vc: Optional[VerifiedCredential] = None
473
+ vc: VerifiedCredential | None = None
484
474
  vc_announcements_to_make: list[bytes] = []
485
475
  inner_spends: list[tuple[CRCAT, int, Program, Program]] = []
486
476
  first = True
@@ -502,7 +492,7 @@ class CRCATWallet(CATWallet):
502
492
  cat_condition = UnknownCondition(
503
493
  opcode=Program.to(51),
504
494
  args=[
505
- Program.to(None),
495
+ Program.NIL,
506
496
  Program.to(-113),
507
497
  tail_reveal,
508
498
  tail_solution,
@@ -583,7 +573,7 @@ class CRCATWallet(CATWallet):
583
573
  expected_announcements, coin_spends, _ = CRCAT.spend_many(
584
574
  inner_spends,
585
575
  proof_of_inclusions,
586
- Program.to(None), # TODO: With more proofs checkers, this may need to be flexible. For now, it's hardcoded.
576
+ Program.NIL, # TODO: With more proofs checkers, this may need to be flexible. For now, it's hardcoded.
587
577
  vc.proof_provider,
588
578
  vc.launcher_id,
589
579
  vc.wrap_inner_with_backdoor().get_tree_hash() if add_authorizations_to_cr_cats else None,
@@ -609,13 +599,13 @@ class CRCATWallet(CATWallet):
609
599
  puzzle_hashes: list[bytes32],
610
600
  action_scope: WalletActionScope,
611
601
  fee: uint64 = uint64(0),
612
- coins: Optional[set[Coin]] = None,
613
- memos: Optional[list[list[bytes]]] = None,
602
+ coins: set[Coin] | None = None,
603
+ memos: list[list[bytes]] | None = None,
614
604
  extra_conditions: tuple[Condition, ...] = tuple(),
615
605
  **kwargs: Unpack[GSTOptionalArgs],
616
606
  ) -> None:
617
607
  # (extra_delta, tail_reveal, tail_solution)
618
- cat_discrepancy: Optional[tuple[int, Program, Program]] = kwargs.get("cat_discrepancy", None)
608
+ cat_discrepancy: tuple[int, Program, Program] | None = kwargs.get("cat_discrepancy", None)
619
609
  add_authorizations_to_cr_cats: bool = kwargs.get("add_authorizations_to_cr_cats", True)
620
610
  if memos is None:
621
611
  memos = [[] for _ in range(len(puzzle_hashes))]
@@ -659,25 +649,17 @@ class CRCATWallet(CATWallet):
659
649
  addition for tx in interface.side_effects.transactions for addition in tx.additions
660
650
  }
661
651
  tx_list = [
662
- TransactionRecord(
663
- confirmed_at_height=uint32(0),
664
- created_at_time=uint64(time.time()),
665
- to_puzzle_hash=payment.puzzle_hash,
666
- to_address=self.wallet_state_manager.encode_puzzle_hash(payment.puzzle_hash),
667
- amount=payment.amount,
668
- fee_amount=fee,
669
- confirmed=False,
670
- sent=uint32(0),
671
- spend_bundle=spend_bundle if i == 0 else None,
652
+ self.wallet_state_manager.new_outgoing_transaction(
653
+ wallet_id=self.id(),
654
+ puzzle_hash=payment.puzzle_hash,
655
+ amount=uint64(payment.amount),
656
+ fee=fee,
657
+ # semantics guarantee not None here
658
+ spend_bundle=spend_bundle if i == 0 else None, # type: ignore[arg-type]
672
659
  additions=list(set(spend_bundle.additions()) - other_tx_additions) if i == 0 else [],
673
660
  removals=list(set(spend_bundle.removals()) - other_tx_removals) if i == 0 else [],
674
- wallet_id=self.id(),
675
- sent_to=[],
676
- trade_id=None,
677
- type=uint32(TransactionType.OUTGOING_TX.value),
678
661
  name=spend_bundle.name() if i == 0 else payment.to_program().get_tree_hash(),
679
- memos=compute_memos(spend_bundle),
680
- valid_times=parse_timelock_info(extra_conditions),
662
+ extra_conditions=extra_conditions,
681
663
  )
682
664
  for i, payment in enumerate(payments)
683
665
  ]
@@ -689,11 +671,11 @@ class CRCATWallet(CATWallet):
689
671
  min_amount_to_claim: uint64,
690
672
  action_scope: WalletActionScope,
691
673
  fee: uint64 = uint64(0),
692
- coins: Optional[set[Coin]] = None,
693
- min_coin_amount: Optional[uint64] = None,
694
- max_coin_amount: Optional[uint64] = None,
695
- excluded_coin_amounts: Optional[list[uint64]] = None,
696
- reuse_puzhash: Optional[bool] = None,
674
+ coins: set[Coin] | None = None,
675
+ min_coin_amount: uint64 | None = None,
676
+ max_coin_amount: uint64 | None = None,
677
+ excluded_coin_amounts: list[uint64] | None = None,
678
+ reuse_puzhash: bool | None = None,
697
679
  extra_conditions: tuple[Condition, ...] = tuple(),
698
680
  ) -> None:
699
681
  # Select the relevant CR-CAT coins
@@ -723,7 +705,7 @@ class CRCATWallet(CATWallet):
723
705
 
724
706
  # Select the relevant VC coin
725
707
  vc_wallet: VCWallet = await self.wallet_state_manager.get_or_create_vc_wallet()
726
- vc: Optional[VerifiedCredential] = await vc_wallet.get_vc_with_provider_in_and_proofs(
708
+ vc: VerifiedCredential | None = await vc_wallet.get_vc_with_provider_in_and_proofs(
727
709
  self.info.authorized_providers, self.info.proofs_checker.flags
728
710
  )
729
711
  if vc is None: # pragma: no cover
@@ -756,7 +738,7 @@ class CRCATWallet(CATWallet):
756
738
  for crcat, inner_puzhash in crcats_and_puzhashes
757
739
  ],
758
740
  proof_of_inclusions,
759
- Program.to(None), # TODO: With more proofs checkers, this may need to be flexible. For now, it's hardcoded.
741
+ Program.NIL, # TODO: With more proofs checkers, this may need to be flexible. For now, it's hardcoded.
760
742
  vc.proof_provider,
761
743
  vc.launcher_id,
762
744
  vc.wrap_inner_with_backdoor().get_tree_hash(),
@@ -818,7 +800,7 @@ class CRCATWallet(CATWallet):
818
800
  AssetType(puzzle_driver.type()) == AssetType.CAT
819
801
  and puzzle_driver["tail"] == self.info.limitations_program_hash
820
802
  ):
821
- inner_puzzle_driver: Optional[PuzzleInfo] = puzzle_driver.also()
803
+ inner_puzzle_driver: PuzzleInfo | None = puzzle_driver.also()
822
804
  if inner_puzzle_driver is None:
823
805
  raise ValueError("Malformed puzzle driver passed to CRCATWallet.match_puzzle_info") # pragma: no cover
824
806
  return (