chia-blockchain 2.5.7rc4__py3-none-any.whl → 2.6.0rc2__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 (531) 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_blockchain_transactions.py +5 -2
  6. chia/_tests/blockchain/test_build_chains.py +2 -4
  7. chia/_tests/blockchain/test_get_block_generator.py +2 -3
  8. chia/_tests/clvm/coin_store.py +4 -7
  9. chia/_tests/clvm/test_clvm_step.py +4 -4
  10. chia/_tests/clvm/test_puzzle_compression.py +2 -1
  11. chia/_tests/clvm/test_puzzle_drivers.py +2 -2
  12. chia/_tests/clvm/test_singletons.py +2 -4
  13. chia/_tests/clvm/test_spend_sim.py +2 -2
  14. chia/_tests/cmds/cmd_test_utils.py +27 -45
  15. chia/_tests/cmds/test_cmd_framework.py +6 -6
  16. chia/_tests/cmds/test_daemon.py +3 -3
  17. chia/_tests/cmds/test_show.py +4 -4
  18. chia/_tests/cmds/test_tx_config_args.py +1 -2
  19. chia/_tests/cmds/testing_classes.py +4 -5
  20. chia/_tests/cmds/wallet/test_did.py +24 -27
  21. chia/_tests/cmds/wallet/test_nft.py +12 -10
  22. chia/_tests/cmds/wallet/test_vcs.py +11 -12
  23. chia/_tests/cmds/wallet/test_wallet.py +134 -89
  24. chia/_tests/conftest.py +66 -31
  25. chia/_tests/connection_utils.py +2 -2
  26. chia/_tests/core/cmds/test_beta.py +4 -4
  27. chia/_tests/core/cmds/test_keys.py +2 -3
  28. chia/_tests/core/cmds/test_wallet.py +15 -15
  29. chia/_tests/core/consensus/test_pot_iterations.py +19 -73
  30. chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
  31. chia/_tests/core/daemon/test_daemon.py +11 -11
  32. chia/_tests/core/data_layer/conftest.py +2 -2
  33. chia/_tests/core/data_layer/test_data_rpc.py +28 -14
  34. chia/_tests/core/data_layer/test_data_store.py +10 -10
  35. chia/_tests/core/data_layer/util.py +11 -11
  36. chia/_tests/core/farmer/test_farmer_api.py +2 -4
  37. chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
  38. chia/_tests/core/full_node/stores/test_block_store.py +5 -4
  39. chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
  40. chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
  41. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  42. chia/_tests/core/full_node/test_block_height_map.py +3 -4
  43. chia/_tests/core/full_node/test_conditions.py +21 -23
  44. chia/_tests/core/full_node/test_full_node.py +273 -70
  45. chia/_tests/core/full_node/test_hard_fork_utils.py +92 -0
  46. chia/_tests/core/full_node/test_hint_management.py +2 -4
  47. chia/_tests/core/full_node/test_performance.py +0 -1
  48. chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
  49. chia/_tests/core/full_node/test_transactions.py +1 -2
  50. chia/_tests/core/full_node/test_tx_processing_queue.py +198 -30
  51. chia/_tests/core/mempool/test_mempool.py +54 -50
  52. chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
  53. chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
  54. chia/_tests/core/mempool/test_mempool_manager.py +988 -854
  55. chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
  56. chia/_tests/core/server/serve.py +7 -7
  57. chia/_tests/core/server/test_dos.py +1 -2
  58. chia/_tests/core/server/test_event_loop.py +12 -4
  59. chia/_tests/core/server/test_loop.py +7 -8
  60. chia/_tests/core/server/test_rate_limits.py +9 -8
  61. chia/_tests/core/server/test_server.py +61 -1
  62. chia/_tests/core/services/test_services.py +2 -2
  63. chia/_tests/core/ssl/test_ssl.py +2 -2
  64. chia/_tests/core/test_cost_calculation.py +2 -6
  65. chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
  66. chia/_tests/core/test_filter.py +0 -1
  67. chia/_tests/core/test_full_node_rpc.py +2 -2
  68. chia/_tests/core/test_merkle_set.py +1 -2
  69. chia/_tests/core/test_seeder.py +4 -4
  70. chia/_tests/core/util/test_config.py +4 -4
  71. chia/_tests/core/util/test_jsonify.py +2 -2
  72. chia/_tests/core/util/test_keychain.py +3 -3
  73. chia/_tests/core/util/test_lockfile.py +2 -1
  74. chia/_tests/core/util/test_log_exceptions.py +1 -2
  75. chia/_tests/core/util/test_streamable.py +17 -17
  76. chia/_tests/db/test_db_wrapper.py +3 -2
  77. chia/_tests/environments/wallet.py +14 -14
  78. chia/_tests/ether.py +4 -3
  79. chia/_tests/farmer_harvester/test_farmer.py +41 -24
  80. chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
  81. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
  82. chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
  83. chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
  84. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
  85. chia/_tests/harvester/test_harvester_api.py +11 -4
  86. chia/_tests/plot_sync/test_plot_sync.py +13 -11
  87. chia/_tests/plot_sync/test_receiver.py +11 -10
  88. chia/_tests/plot_sync/test_sync_simulated.py +2 -2
  89. chia/_tests/plot_sync/util.py +1 -2
  90. chia/_tests/plotting/test_plot_manager.py +7 -6
  91. chia/_tests/plotting/test_prover.py +30 -38
  92. chia/_tests/pools/test_pool_cmdline.py +4 -6
  93. chia/_tests/pools/test_pool_rpc.py +203 -61
  94. chia/_tests/pools/test_pool_wallet.py +3 -3
  95. chia/_tests/pools/test_wallet_pool_store.py +1 -4
  96. chia/_tests/process_junit.py +2 -2
  97. chia/_tests/rpc/test_rpc_client.py +4 -4
  98. chia/_tests/rpc/test_rpc_server.py +3 -3
  99. chia/_tests/simulation/test_simulation.py +12 -25
  100. chia/_tests/solver/test_solver_service.py +13 -4
  101. chia/_tests/testconfig.py +2 -2
  102. chia/_tests/timelord/test_new_peak.py +22 -11
  103. chia/_tests/tools/test_run_block.py +0 -2
  104. chia/_tests/tools/test_virtual_project.py +2 -1
  105. chia/_tests/util/benchmarks.py +1 -0
  106. chia/_tests/util/blockchain.py +38 -36
  107. chia/_tests/util/blockchain_mock.py +11 -11
  108. chia/_tests/util/build_network_protocol_files.py +2 -1
  109. chia/_tests/util/coin_store.py +2 -1
  110. chia/_tests/util/config.py +1 -1
  111. chia/_tests/util/db_connection.py +2 -3
  112. chia/_tests/util/full_sync.py +9 -11
  113. chia/_tests/util/gen_ssl_certs.py +4 -5
  114. chia/_tests/util/get_name_puzzle_conditions.py +2 -0
  115. chia/_tests/util/misc.py +24 -24
  116. chia/_tests/util/network_protocol_data.py +20 -3
  117. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  118. chia/_tests/util/protocol_messages_json.py +292 -3
  119. chia/_tests/util/setup_nodes.py +62 -47
  120. chia/_tests/util/spend_sim.py +57 -57
  121. chia/_tests/util/test_async_pool.py +2 -3
  122. chia/_tests/util/test_chia_version.py +1 -3
  123. chia/_tests/util/test_config.py +3 -3
  124. chia/_tests/util/test_full_block_utils.py +6 -3
  125. chia/_tests/util/test_limited_semaphore.py +1 -2
  126. chia/_tests/util/test_misc.py +2 -2
  127. chia/_tests/util/test_network.py +1 -2
  128. chia/_tests/util/test_priority_mutex.py +3 -3
  129. chia/_tests/util/test_recursive_replace.py +5 -6
  130. chia/_tests/util/test_replace_str_to_bytes.py +9 -10
  131. chia/_tests/util/test_testnet_overrides.py +3 -3
  132. chia/_tests/util/time_out_assert.py +2 -2
  133. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
  134. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
  135. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
  136. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
  137. chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
  138. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
  139. chia/_tests/wallet/conftest.py +6 -6
  140. chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
  141. chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
  142. chia/_tests/wallet/did_wallet/test_did.py +16 -6
  143. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
  144. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
  145. chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
  146. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
  147. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
  148. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
  149. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
  150. chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
  151. chia/_tests/wallet/sync/test_wallet_sync.py +63 -60
  152. chia/_tests/wallet/test_clvm_streamable.py +2 -3
  153. chia/_tests/wallet/test_coin_management.py +2 -2
  154. chia/_tests/wallet/test_conditions.py +45 -51
  155. chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
  156. chia/_tests/wallet/test_new_wallet_protocol.py +17 -17
  157. chia/_tests/wallet/test_notifications.py +14 -14
  158. chia/_tests/wallet/test_signer_protocol.py +5 -5
  159. chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
  160. chia/_tests/wallet/test_transaction_store.py +20 -20
  161. chia/_tests/wallet/test_util.py +2 -2
  162. chia/_tests/wallet/test_wallet.py +380 -228
  163. chia/_tests/wallet/test_wallet_action_scope.py +4 -4
  164. chia/_tests/wallet/test_wallet_blockchain.py +12 -12
  165. chia/_tests/wallet/test_wallet_coin_store.py +3 -4
  166. chia/_tests/wallet/test_wallet_node.py +16 -15
  167. chia/_tests/wallet/test_wallet_test_framework.py +2 -1
  168. chia/_tests/wallet/test_wallet_utils.py +2 -3
  169. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
  170. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
  171. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
  172. chia/_tests/wallet/wallet_block_tools.py +12 -11
  173. chia/_tests/weight_proof/config.py +1 -0
  174. chia/_tests/weight_proof/test_weight_proof.py +5 -4
  175. chia/apis/__init__.py +21 -0
  176. chia/apis/farmer_stub.py +102 -0
  177. chia/apis/full_node_stub.py +374 -0
  178. chia/apis/harvester_stub.py +57 -0
  179. chia/apis/introducer_stub.py +35 -0
  180. chia/apis/solver_stub.py +30 -0
  181. chia/apis/stub_protocol_registry.py +21 -0
  182. chia/apis/timelord_stub.py +39 -0
  183. chia/apis/wallet_stub.py +161 -0
  184. chia/cmds/beta.py +3 -4
  185. chia/cmds/beta_funcs.py +4 -3
  186. chia/cmds/check_wallet_db.py +4 -4
  187. chia/cmds/chia.py +1 -2
  188. chia/cmds/cmd_classes.py +11 -13
  189. chia/cmds/cmd_helpers.py +11 -11
  190. chia/cmds/cmds_util.py +15 -15
  191. chia/cmds/coin_funcs.py +6 -7
  192. chia/cmds/coins.py +2 -3
  193. chia/cmds/configure.py +1 -2
  194. chia/cmds/data.py +42 -42
  195. chia/cmds/data_funcs.py +81 -81
  196. chia/cmds/db.py +4 -5
  197. chia/cmds/db_backup_func.py +2 -2
  198. chia/cmds/db_upgrade_func.py +3 -3
  199. chia/cmds/db_validate_func.py +2 -2
  200. chia/cmds/dev/data.py +4 -4
  201. chia/cmds/dev/gh.py +5 -5
  202. chia/cmds/dev/installers.py +2 -3
  203. chia/cmds/dev/mempool.py +3 -4
  204. chia/cmds/dev/mempool_funcs.py +4 -4
  205. chia/cmds/dev/sim.py +8 -8
  206. chia/cmds/dump_keyring.py +3 -3
  207. chia/cmds/farm.py +6 -8
  208. chia/cmds/farm_funcs.py +25 -24
  209. chia/cmds/init_funcs.py +4 -4
  210. chia/cmds/keys.py +16 -18
  211. chia/cmds/keys_funcs.py +36 -36
  212. chia/cmds/netspace.py +1 -3
  213. chia/cmds/netspace_funcs.py +1 -2
  214. chia/cmds/options.py +3 -2
  215. chia/cmds/param_types.py +17 -16
  216. chia/cmds/passphrase.py +6 -7
  217. chia/cmds/passphrase_funcs.py +11 -13
  218. chia/cmds/peer.py +1 -3
  219. chia/cmds/peer_funcs.py +3 -3
  220. chia/cmds/plotnft.py +6 -7
  221. chia/cmds/plotnft_funcs.py +37 -26
  222. chia/cmds/rpc.py +3 -3
  223. chia/cmds/show.py +3 -5
  224. chia/cmds/show_funcs.py +9 -9
  225. chia/cmds/sim_funcs.py +25 -26
  226. chia/cmds/solver.py +1 -3
  227. chia/cmds/solver_funcs.py +1 -2
  228. chia/cmds/start_funcs.py +2 -2
  229. chia/cmds/wallet.py +76 -81
  230. chia/cmds/wallet_funcs.py +206 -177
  231. chia/consensus/augmented_chain.py +6 -6
  232. chia/consensus/block_body_validation.py +19 -15
  233. chia/consensus/block_creation.py +25 -21
  234. chia/consensus/block_header_validation.py +27 -13
  235. chia/consensus/block_height_map.py +3 -6
  236. chia/consensus/block_height_map_protocol.py +2 -2
  237. chia/consensus/block_record.py +2 -4
  238. chia/consensus/blockchain.py +58 -40
  239. chia/consensus/blockchain_interface.py +7 -7
  240. chia/consensus/coin_store_protocol.py +5 -6
  241. chia/consensus/condition_tools.py +4 -4
  242. chia/consensus/cost_calculator.py +2 -3
  243. chia/consensus/default_constants.py +19 -13
  244. chia/consensus/deficit.py +1 -3
  245. chia/consensus/difficulty_adjustment.py +3 -5
  246. chia/consensus/find_fork_point.py +2 -4
  247. chia/consensus/full_block_to_block_record.py +11 -13
  248. chia/consensus/generator_tools.py +2 -3
  249. chia/consensus/get_block_challenge.py +50 -26
  250. chia/consensus/get_block_generator.py +2 -3
  251. chia/consensus/make_sub_epoch_summary.py +8 -7
  252. chia/consensus/multiprocess_validation.py +31 -20
  253. chia/consensus/pos_quality.py +6 -23
  254. chia/consensus/pot_iterations.py +17 -44
  255. chia/consensus/signage_point.py +4 -5
  256. chia/consensus/vdf_info_computation.py +2 -4
  257. chia/daemon/client.py +8 -8
  258. chia/daemon/keychain_proxy.py +31 -37
  259. chia/daemon/server.py +32 -33
  260. chia/daemon/windows_signal.py +4 -3
  261. chia/data_layer/data_layer.py +86 -77
  262. chia/data_layer/data_layer_rpc_api.py +9 -9
  263. chia/data_layer/data_layer_rpc_client.py +13 -15
  264. chia/data_layer/data_layer_server.py +3 -3
  265. chia/data_layer/data_layer_util.py +14 -14
  266. chia/data_layer/data_layer_wallet.py +94 -101
  267. chia/data_layer/data_store.py +50 -50
  268. chia/data_layer/dl_wallet_store.py +9 -12
  269. chia/data_layer/download_data.py +8 -9
  270. chia/data_layer/s3_plugin_service.py +5 -9
  271. chia/data_layer/start_data_layer.py +5 -5
  272. chia/farmer/farmer.py +31 -31
  273. chia/farmer/farmer_api.py +45 -33
  274. chia/farmer/farmer_rpc_api.py +5 -4
  275. chia/farmer/farmer_rpc_client.py +6 -6
  276. chia/farmer/start_farmer.py +6 -6
  277. chia/full_node/block_store.py +13 -16
  278. chia/full_node/check_fork_next_block.py +1 -2
  279. chia/full_node/coin_store.py +15 -16
  280. chia/full_node/eligible_coin_spends.py +3 -3
  281. chia/full_node/fee_estimate_store.py +2 -3
  282. chia/full_node/fee_tracker.py +1 -2
  283. chia/full_node/full_block_utils.py +4 -4
  284. chia/full_node/full_node.py +239 -223
  285. chia/full_node/full_node_api.py +197 -152
  286. chia/full_node/full_node_rpc_api.py +34 -32
  287. chia/full_node/full_node_rpc_client.py +18 -19
  288. chia/full_node/full_node_store.py +45 -43
  289. chia/full_node/hard_fork_utils.py +44 -0
  290. chia/full_node/hint_management.py +2 -2
  291. chia/full_node/mempool.py +17 -19
  292. chia/full_node/mempool_manager.py +89 -42
  293. chia/full_node/pending_tx_cache.py +2 -3
  294. chia/full_node/start_full_node.py +5 -5
  295. chia/full_node/sync_store.py +3 -4
  296. chia/full_node/tx_processing_queue.py +120 -36
  297. chia/full_node/weight_proof.py +61 -48
  298. chia/harvester/harvester.py +25 -24
  299. chia/harvester/harvester_api.py +61 -38
  300. chia/harvester/harvester_rpc_api.py +10 -10
  301. chia/harvester/start_harvester.py +4 -4
  302. chia/introducer/introducer.py +3 -3
  303. chia/introducer/introducer_api.py +6 -4
  304. chia/introducer/start_introducer.py +4 -4
  305. chia/legacy/keyring.py +3 -3
  306. chia/plot_sync/delta.py +1 -2
  307. chia/plot_sync/receiver.py +20 -17
  308. chia/plot_sync/sender.py +15 -10
  309. chia/plotters/bladebit.py +7 -7
  310. chia/plotters/chiapos.py +2 -2
  311. chia/plotters/madmax.py +4 -4
  312. chia/plotters/plotters.py +4 -4
  313. chia/plotters/plotters_util.py +3 -3
  314. chia/plotting/cache.py +20 -14
  315. chia/plotting/check_plots.py +26 -35
  316. chia/plotting/create_plots.py +22 -23
  317. chia/plotting/manager.py +21 -14
  318. chia/plotting/prover.py +59 -42
  319. chia/plotting/util.py +16 -16
  320. chia/pools/pool_config.py +2 -1
  321. chia/pools/pool_puzzles.py +11 -12
  322. chia/pools/pool_wallet.py +34 -57
  323. chia/pools/pool_wallet_info.py +39 -10
  324. chia/protocols/farmer_protocol.py +8 -9
  325. chia/protocols/fee_estimate.py +3 -4
  326. chia/protocols/full_node_protocol.py +3 -4
  327. chia/protocols/harvester_protocol.py +27 -15
  328. chia/protocols/outbound_message.py +3 -3
  329. chia/protocols/pool_protocol.py +8 -9
  330. chia/protocols/shared_protocol.py +1 -2
  331. chia/protocols/solver_protocol.py +9 -2
  332. chia/protocols/timelord_protocol.py +4 -7
  333. chia/protocols/wallet_protocol.py +11 -12
  334. chia/rpc/rpc_client.py +9 -9
  335. chia/rpc/rpc_server.py +17 -17
  336. chia/rpc/util.py +2 -2
  337. chia/seeder/crawler.py +8 -8
  338. chia/seeder/crawler_api.py +21 -27
  339. chia/seeder/crawler_rpc_api.py +2 -2
  340. chia/seeder/dns_server.py +21 -21
  341. chia/seeder/start_crawler.py +4 -4
  342. chia/server/address_manager.py +15 -16
  343. chia/server/api_protocol.py +11 -11
  344. chia/server/chia_policy.py +46 -26
  345. chia/server/introducer_peers.py +2 -3
  346. chia/server/node_discovery.py +19 -19
  347. chia/server/rate_limit_numbers.py +4 -5
  348. chia/server/rate_limits.py +4 -4
  349. chia/server/resolve_peer_info.py +4 -4
  350. chia/server/server.py +49 -52
  351. chia/server/signal_handlers.py +6 -6
  352. chia/server/start_service.py +17 -17
  353. chia/server/upnp.py +4 -6
  354. chia/server/ws_connection.py +52 -37
  355. chia/simulator/add_blocks_in_batches.py +1 -3
  356. chia/simulator/block_tools.py +312 -200
  357. chia/simulator/full_node_simulator.py +56 -35
  358. chia/simulator/keyring.py +2 -3
  359. chia/simulator/setup_services.py +15 -15
  360. chia/simulator/simulator_full_node_rpc_api.py +1 -2
  361. chia/simulator/simulator_full_node_rpc_client.py +1 -2
  362. chia/simulator/simulator_protocol.py +1 -2
  363. chia/simulator/simulator_test_tools.py +3 -3
  364. chia/simulator/start_simulator.py +7 -7
  365. chia/simulator/wallet_tools.py +10 -10
  366. chia/solver/solver.py +10 -10
  367. chia/solver/solver_api.py +10 -8
  368. chia/solver/solver_rpc_api.py +2 -2
  369. chia/solver/start_solver.py +4 -4
  370. chia/ssl/cacert.pem +148 -90
  371. chia/ssl/chia_ca.crt +14 -10
  372. chia/ssl/chia_ca_old.crt +19 -0
  373. chia/ssl/create_ssl.py +4 -4
  374. chia/ssl/renewedselfsignedca.conf +4 -0
  375. chia/ssl/ssl_check.py +1 -2
  376. chia/timelord/iters_from_block.py +1 -4
  377. chia/timelord/start_timelord.py +4 -4
  378. chia/timelord/timelord.py +44 -40
  379. chia/timelord/timelord_api.py +6 -4
  380. chia/timelord/timelord_launcher.py +2 -2
  381. chia/timelord/timelord_rpc_api.py +2 -2
  382. chia/timelord/timelord_state.py +11 -12
  383. chia/types/block_protocol.py +1 -3
  384. chia/types/blockchain_format/coin.py +1 -3
  385. chia/types/blockchain_format/program.py +11 -8
  386. chia/types/blockchain_format/proof_of_space.py +123 -76
  387. chia/types/blockchain_format/tree_hash.py +3 -3
  388. chia/types/blockchain_format/vdf.py +1 -2
  389. chia/types/coin_spend.py +3 -3
  390. chia/types/mempool_item.py +5 -5
  391. chia/types/mempool_submission_status.py +2 -3
  392. chia/types/peer_info.py +1 -2
  393. chia/types/unfinished_header_block.py +3 -4
  394. chia/types/validation_state.py +1 -2
  395. chia/util/action_scope.py +8 -8
  396. chia/util/async_pool.py +5 -5
  397. chia/util/bech32m.py +1 -2
  398. chia/util/beta_metrics.py +2 -2
  399. chia/util/block_cache.py +4 -4
  400. chia/util/chia_logging.py +2 -2
  401. chia/util/chia_version.py +1 -2
  402. chia/util/config.py +15 -16
  403. chia/util/db_wrapper.py +26 -27
  404. chia/util/default_root.py +1 -2
  405. chia/util/errors.py +3 -3
  406. chia/util/file_keyring.py +14 -14
  407. chia/util/files.py +2 -3
  408. chia/util/hash.py +4 -4
  409. chia/util/initial-config.yaml +4 -5
  410. chia/util/inline_executor.py +2 -1
  411. chia/util/ip_address.py +1 -2
  412. chia/util/keychain.py +25 -27
  413. chia/util/keyring_wrapper.py +18 -19
  414. chia/util/lock.py +3 -4
  415. chia/util/log_exceptions.py +1 -2
  416. chia/util/lru_cache.py +2 -2
  417. chia/util/network.py +6 -6
  418. chia/util/path.py +2 -3
  419. chia/util/priority_mutex.py +2 -2
  420. chia/util/profiler.py +1 -2
  421. chia/util/safe_cancel_task.py +1 -2
  422. chia/util/streamable.py +24 -10
  423. chia/util/task_referencer.py +1 -1
  424. chia/util/timing.py +3 -3
  425. chia/util/virtual_project_analysis.py +6 -5
  426. chia/util/ws_message.py +2 -2
  427. chia/wallet/cat_wallet/cat_info.py +3 -4
  428. chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
  429. chia/wallet/cat_wallet/cat_utils.py +3 -4
  430. chia/wallet/cat_wallet/cat_wallet.py +61 -83
  431. chia/wallet/cat_wallet/lineage_store.py +3 -4
  432. chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
  433. chia/wallet/coin_selection.py +9 -10
  434. chia/wallet/conditions.py +142 -106
  435. chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
  436. chia/wallet/derivation_record.py +1 -2
  437. chia/wallet/derive_keys.py +2 -4
  438. chia/wallet/did_wallet/did_info.py +10 -11
  439. chia/wallet/did_wallet/did_wallet.py +36 -82
  440. chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
  441. chia/wallet/driver_protocol.py +5 -7
  442. chia/wallet/lineage_proof.py +4 -4
  443. chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
  444. chia/wallet/nft_wallet/nft_info.py +8 -9
  445. chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
  446. chia/wallet/nft_wallet/nft_wallet.py +79 -116
  447. chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
  448. chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
  449. chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
  450. chia/wallet/nft_wallet/uncurry_nft.py +10 -11
  451. chia/wallet/notification_manager.py +3 -3
  452. chia/wallet/notification_store.py +44 -61
  453. chia/wallet/outer_puzzles.py +6 -7
  454. chia/wallet/puzzle_drivers.py +34 -6
  455. chia/wallet/puzzles/clawback/drivers.py +6 -6
  456. chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
  457. chia/wallet/puzzles/load_clvm.py +1 -1
  458. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
  459. chia/wallet/puzzles/singleton_top_layer.py +2 -3
  460. chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
  461. chia/wallet/puzzles/tails.py +3 -3
  462. chia/wallet/singleton.py +5 -7
  463. chia/wallet/singleton_record.py +3 -3
  464. chia/wallet/start_wallet.py +5 -5
  465. chia/wallet/trade_manager.py +37 -58
  466. chia/wallet/trade_record.py +4 -4
  467. chia/wallet/trading/offer.py +59 -46
  468. chia/wallet/trading/trade_store.py +8 -9
  469. chia/wallet/transaction_record.py +8 -8
  470. chia/wallet/uncurried_puzzle.py +1 -2
  471. chia/wallet/util/clvm_streamable.py +12 -12
  472. chia/wallet/util/compute_hints.py +4 -5
  473. chia/wallet/util/curry_and_treehash.py +1 -2
  474. chia/wallet/util/merkle_tree.py +2 -3
  475. chia/wallet/util/peer_request_cache.py +8 -8
  476. chia/wallet/util/signing.py +85 -0
  477. chia/wallet/util/tx_config.py +15 -6
  478. chia/wallet/util/wallet_sync_utils.py +14 -16
  479. chia/wallet/util/wallet_types.py +2 -2
  480. chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
  481. chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
  482. chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
  483. chia/wallet/vc_wallet/vc_drivers.py +27 -27
  484. chia/wallet/vc_wallet/vc_store.py +5 -6
  485. chia/wallet/vc_wallet/vc_wallet.py +33 -61
  486. chia/wallet/wallet.py +50 -78
  487. chia/wallet/wallet_action_scope.py +11 -11
  488. chia/wallet/wallet_blockchain.py +12 -12
  489. chia/wallet/wallet_coin_record.py +12 -6
  490. chia/wallet/wallet_coin_store.py +24 -25
  491. chia/wallet/wallet_interested_store.py +3 -5
  492. chia/wallet/wallet_nft_store.py +10 -11
  493. chia/wallet/wallet_node.py +53 -61
  494. chia/wallet/wallet_node_api.py +5 -3
  495. chia/wallet/wallet_protocol.py +23 -23
  496. chia/wallet/wallet_puzzle_store.py +15 -18
  497. chia/wallet/wallet_request_types.py +778 -114
  498. chia/wallet/wallet_retry_store.py +1 -3
  499. chia/wallet/wallet_rpc_api.py +572 -909
  500. chia/wallet/wallet_rpc_client.py +87 -279
  501. chia/wallet/wallet_singleton_store.py +3 -4
  502. chia/wallet/wallet_state_manager.py +332 -106
  503. chia/wallet/wallet_transaction_store.py +11 -14
  504. chia/wallet/wallet_user_store.py +4 -6
  505. chia/wallet/wallet_weight_proof_handler.py +4 -4
  506. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/METADATA +6 -5
  507. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/RECORD +510 -517
  508. chia/apis.py +0 -21
  509. chia/consensus/check_time_locks.py +0 -57
  510. chia/data_layer/puzzles/__init__.py +0 -0
  511. chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
  512. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
  513. chia/types/coin_record.py +0 -44
  514. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  515. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
  516. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
  517. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
  518. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
  519. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
  520. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
  521. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
  522. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
  523. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
  524. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
  525. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
  526. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
  527. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
  528. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
  529. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/WHEEL +0 -0
  530. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/entry_points.txt +0 -0
  531. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/licenses/LICENSE +0 -0
@@ -1,23 +1,34 @@
1
1
  from __future__ import annotations
2
2
 
3
- from dataclasses import dataclass, field
4
- from typing import Any, BinaryIO, Optional, final
3
+ from dataclasses import dataclass, field, fields
4
+ from enum import Enum
5
+ from functools import cached_property
6
+ from typing import Any, BinaryIO, TypeVar, final
5
7
 
6
- from chia_rs import Coin, G1Element, G2Element, PrivateKey
8
+ from chia_rs import Coin, CoinRecord, G1Element, G2Element, PrivateKey
7
9
  from chia_rs.sized_bytes import bytes32
8
10
  from chia_rs.sized_ints import uint8, uint16, uint32, uint64
9
11
  from typing_extensions import Self
10
12
 
11
- from chia.data_layer.data_layer_wallet import Mirror
13
+ from chia.data_layer.data_layer_wallet import DataLayerSummary, Mirror
12
14
  from chia.data_layer.singleton_record import SingletonRecord
13
- from chia.pools.pool_wallet_info import PoolWalletInfo
15
+ from chia.pools.pool_wallet_info import NewPoolWalletInitialTargetState, PoolWalletInfo
16
+ from chia.types.blockchain_format.coin import coin_as_list
14
17
  from chia.types.blockchain_format.program import Program
15
- from chia.types.coin_record import CoinRecord
18
+ from chia.types.signing_mode import SigningMode
16
19
  from chia.util.byte_types import hexstr_to_bytes
17
- from chia.util.streamable import Streamable, streamable
18
- from chia.wallet.conditions import Condition, ConditionValidTimes, conditions_to_json_dicts
20
+ from chia.util.hash import std_hash
21
+ from chia.util.streamable import Streamable, streamable, streamable_enum
22
+ from chia.wallet.conditions import (
23
+ AssertCoinAnnouncement,
24
+ AssertPuzzleAnnouncement,
25
+ Condition,
26
+ ConditionValidTimes,
27
+ conditions_to_json_dicts,
28
+ )
19
29
  from chia.wallet.nft_wallet.nft_info import NFTInfo
20
30
  from chia.wallet.notification_store import Notification
31
+ from chia.wallet.puzzle_drivers import PuzzleInfo, Solver
21
32
  from chia.wallet.signer_protocol import (
22
33
  SignedTransaction,
23
34
  SigningInstructions,
@@ -26,13 +37,18 @@ from chia.wallet.signer_protocol import (
26
37
  UnsignedTransaction,
27
38
  )
28
39
  from chia.wallet.trade_record import TradeRecord
29
- from chia.wallet.trading.offer import Offer
40
+ from chia.wallet.trading.offer import Offer, OfferSummary
30
41
  from chia.wallet.transaction_record import TransactionRecord
31
42
  from chia.wallet.transaction_sorting import SortKey
32
43
  from chia.wallet.util.clvm_streamable import json_deserialize_with_clvm_streamable
33
44
  from chia.wallet.util.puzzle_decorator_type import PuzzleDecoratorType
34
45
  from chia.wallet.util.query_filter import TransactionTypeFilter
35
- from chia.wallet.util.tx_config import CoinSelectionConfig, CoinSelectionConfigLoader, TXConfig
46
+ from chia.wallet.util.tx_config import (
47
+ CoinSelectionConfig,
48
+ CoinSelectionConfigLoader,
49
+ TXConfig,
50
+ )
51
+ from chia.wallet.util.wallet_types import WalletType
36
52
  from chia.wallet.vc_wallet.vc_store import VCProofs, VCRecord
37
53
  from chia.wallet.wallet_info import WalletInfo
38
54
  from chia.wallet.wallet_node import Balance
@@ -64,14 +80,14 @@ class LogInResponse(Streamable):
64
80
  @streamable
65
81
  @dataclass(frozen=True)
66
82
  class GetLoggedInFingerprintResponse(Streamable):
67
- fingerprint: Optional[uint32]
83
+ fingerprint: uint32 | None
68
84
 
69
85
 
70
86
  @streamable
71
87
  @dataclass(frozen=True)
72
88
  class GetPublicKeysResponse(Streamable):
73
89
  keyring_is_locked: bool
74
- public_key_fingerprints: Optional[list[uint32]] = None
90
+ public_key_fingerprints: list[uint32] | None = None
75
91
 
76
92
  @property
77
93
  def pk_fingerprints(self) -> list[uint32]:
@@ -97,7 +113,7 @@ class GetPrivateKeyFormat(Streamable):
97
113
  pk: G1Element
98
114
  farmer_pk: G1Element
99
115
  pool_pk: G1Element
100
- seed: Optional[str]
116
+ seed: str | None
101
117
 
102
118
 
103
119
  @streamable
@@ -116,7 +132,7 @@ class GenerateMnemonicResponse(Streamable):
116
132
  @dataclass(frozen=True)
117
133
  class AddKey(Streamable):
118
134
  mnemonic: list[str]
119
- label: Optional[str] = None
135
+ label: str | None = None
120
136
 
121
137
 
122
138
  @streamable
@@ -199,7 +215,7 @@ class GetTimestampForHeightResponse(Streamable):
199
215
  @streamable
200
216
  @dataclass(frozen=True)
201
217
  class GetWallets(Streamable):
202
- type: Optional[uint16] = None
218
+ type: uint16 | None = None
203
219
  include_data: bool = True
204
220
 
205
221
 
@@ -215,7 +231,7 @@ class WalletInfoResponse(WalletInfo):
215
231
  @dataclass(frozen=True)
216
232
  class GetWalletsResponse(Streamable):
217
233
  wallets: list[WalletInfoResponse]
218
- fingerprint: Optional[uint32] = None
234
+ fingerprint: uint32 | None = None
219
235
 
220
236
 
221
237
  @streamable
@@ -227,7 +243,7 @@ class GetWalletBalance(Streamable):
227
243
  @streamable
228
244
  @dataclass(frozen=True)
229
245
  class GetWalletBalances(Streamable):
230
- wallet_ids: Optional[list[uint32]] = None
246
+ wallet_ids: list[uint32] | None = None
231
247
 
232
248
 
233
249
  # utility for GetWalletBalanceResponse(s)
@@ -236,9 +252,9 @@ class GetWalletBalances(Streamable):
236
252
  class BalanceResponse(Balance):
237
253
  wallet_id: uint32 = field(default_factory=default_raise)
238
254
  wallet_type: uint8 = field(default_factory=default_raise)
239
- fingerprint: Optional[uint32] = None
240
- asset_id: Optional[bytes32] = None
241
- pending_approval_balance: Optional[uint64] = None
255
+ fingerprint: uint32 | None = None
256
+ asset_id: bytes32 | None = None
257
+ pending_approval_balance: uint64 | None = None
242
258
 
243
259
 
244
260
  @streamable
@@ -270,13 +286,13 @@ class GetTransactionResponse(Streamable):
270
286
  @dataclass(frozen=True)
271
287
  class GetTransactions(Streamable):
272
288
  wallet_id: uint32
273
- start: Optional[uint16] = None
274
- end: Optional[uint16] = None
275
- sort_key: Optional[str] = None
289
+ start: uint32 | None = None
290
+ end: uint32 | None = None
291
+ sort_key: str | None = None
276
292
  reverse: bool = False
277
- to_address: Optional[str] = None
278
- type_filter: Optional[TransactionTypeFilter] = None
279
- confirmed: Optional[bool] = None
293
+ to_address: str | None = None
294
+ type_filter: TransactionTypeFilter | None = None
295
+ confirmed: bool | None = None
280
296
 
281
297
  def __post_init__(self) -> None:
282
298
  if self.sort_key is not None and not hasattr(SortKey, self.sort_key):
@@ -323,7 +339,7 @@ class TransactionRecordMetadata:
323
339
  @streamable
324
340
  @dataclass(frozen=True)
325
341
  class TransactionRecordWithMetadata(TransactionRecord):
326
- metadata: Optional[TransactionRecordMetadata] = None
342
+ metadata: TransactionRecordMetadata | None = None
327
343
 
328
344
 
329
345
  @streamable
@@ -336,9 +352,9 @@ class GetTransactionsResponse(Streamable):
336
352
  @streamable
337
353
  @dataclass(frozen=True)
338
354
  class GetNotifications(Streamable):
339
- ids: Optional[list[bytes32]] = None
340
- start: Optional[uint32] = None
341
- end: Optional[uint32] = None
355
+ ids: list[bytes32] | None = None
356
+ start: uint32 | None = None
357
+ end: uint32 | None = None
342
358
 
343
359
 
344
360
  @streamable
@@ -350,7 +366,7 @@ class GetNotificationsResponse(Streamable):
350
366
  @streamable
351
367
  @dataclass(frozen=True)
352
368
  class DeleteNotifications(Streamable):
353
- ids: Optional[list[bytes32]] = None
369
+ ids: list[bytes32] | None = None
354
370
 
355
371
 
356
372
  @streamable
@@ -359,15 +375,38 @@ class VerifySignature(Streamable):
359
375
  message: str
360
376
  pubkey: G1Element
361
377
  signature: G2Element
362
- signing_mode: Optional[str] = None
363
- address: Optional[str] = None
378
+ signing_mode: str | None = None
379
+ address: str | None = None
380
+
381
+ @property
382
+ def signing_mode_enum(self) -> SigningMode:
383
+ # Default to BLS_MESSAGE_AUGMENTATION_HEX_INPUT as this RPC was originally designed to verify
384
+ # signatures made by `chia keys sign`, which uses BLS_MESSAGE_AUGMENTATION_HEX_INPUT
385
+ if self.signing_mode is None:
386
+ return SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT
387
+ else:
388
+ try:
389
+ return SigningMode(self.signing_mode)
390
+ except ValueError:
391
+ raise ValueError(f"Invalid signing mode: {self.signing_mode!r}")
364
392
 
365
393
 
366
394
  @streamable
367
395
  @dataclass(frozen=True)
368
396
  class VerifySignatureResponse(Streamable):
369
397
  isValid: bool
370
- error: Optional[str] = None
398
+ error: str | None = None
399
+
400
+
401
+ def signing_mode_enum(request: SignMessageByAddress | SignMessageByID) -> SigningMode:
402
+ if request.is_hex and request.safe_mode:
403
+ return SigningMode.CHIP_0002_HEX_INPUT
404
+ elif not request.is_hex and not request.safe_mode:
405
+ return SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT
406
+ elif request.is_hex and not request.safe_mode:
407
+ return SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT
408
+
409
+ return SigningMode.CHIP_0002
371
410
 
372
411
 
373
412
  @streamable
@@ -378,6 +417,10 @@ class SignMessageByAddress(Streamable):
378
417
  is_hex: bool = False
379
418
  safe_mode: bool = True
380
419
 
420
+ @property
421
+ def signing_mode_enum(self) -> SigningMode:
422
+ return signing_mode_enum(self)
423
+
381
424
 
382
425
  @streamable
383
426
  @dataclass(frozen=True)
@@ -395,6 +438,10 @@ class SignMessageByID(Streamable):
395
438
  is_hex: bool = False
396
439
  safe_mode: bool = True
397
440
 
441
+ @property
442
+ def signing_mode_enum(self) -> SigningMode:
443
+ return signing_mode_enum(self)
444
+
398
445
 
399
446
  @streamable
400
447
  @dataclass(frozen=True)
@@ -441,8 +488,8 @@ class GetTransactionMemoResponse(Streamable):
441
488
  @dataclass(frozen=True)
442
489
  class GetTransactionCount(Streamable):
443
490
  wallet_id: uint32
444
- confirmed: Optional[bool] = None
445
- type_filter: Optional[TransactionTypeFilter] = None
491
+ confirmed: bool | None = None
492
+ type_filter: TransactionTypeFilter | None = None
446
493
 
447
494
 
448
495
  @streamable
@@ -478,7 +525,7 @@ class DeleteUnconfirmedTransactions(Streamable):
478
525
  class SelectCoins(CoinSelectionConfigLoader):
479
526
  wallet_id: uint32 = field(default_factory=default_raise)
480
527
  amount: uint64 = field(default_factory=default_raise)
481
- exclude_coins: Optional[list[Coin]] = None # for backwards compatibility
528
+ exclude_coins: list[Coin] | None = None # for backwards compatibility
482
529
 
483
530
  def __post_init__(self) -> None:
484
531
  if self.excluded_coin_ids is not None and self.exclude_coins is not None:
@@ -489,7 +536,10 @@ class SelectCoins(CoinSelectionConfigLoader):
489
536
 
490
537
  @classmethod
491
538
  def from_coin_selection_config(
492
- cls, wallet_id: uint32, amount: uint64, coin_selection_config: CoinSelectionConfig
539
+ cls,
540
+ wallet_id: uint32,
541
+ amount: uint64,
542
+ coin_selection_config: CoinSelectionConfig,
493
543
  ) -> Self:
494
544
  return cls(
495
545
  wallet_id=wallet_id,
@@ -535,8 +585,8 @@ class GetSpendableCoinsResponse(Streamable):
535
585
  @dataclass(frozen=True)
536
586
  class GetCoinRecordsByNames(Streamable):
537
587
  names: list[bytes32]
538
- start_height: Optional[uint32] = None
539
- end_height: Optional[uint32] = None
588
+ start_height: uint32 | None = None
589
+ end_height: uint32 | None = None
540
590
  include_spent_coins: bool = True
541
591
 
542
592
 
@@ -549,7 +599,7 @@ class GetCoinRecordsByNamesResponse(Streamable):
549
599
  @streamable
550
600
  @dataclass(frozen=True)
551
601
  class GetCurrentDerivationIndexResponse(Streamable):
552
- index: Optional[uint32]
602
+ index: uint32 | None
553
603
 
554
604
 
555
605
  @streamable
@@ -561,7 +611,7 @@ class ExtendDerivationIndex(Streamable):
561
611
  @streamable
562
612
  @dataclass(frozen=True)
563
613
  class ExtendDerivationIndexResponse(Streamable):
564
- index: Optional[uint32]
614
+ index: uint32 | None
565
615
 
566
616
 
567
617
  @streamable
@@ -649,8 +699,53 @@ class CATAssetIDToName(Streamable):
649
699
  @streamable
650
700
  @dataclass(frozen=True)
651
701
  class CATAssetIDToNameResponse(Streamable):
652
- wallet_id: Optional[uint32]
653
- name: Optional[str]
702
+ wallet_id: uint32 | None
703
+ name: str | None
704
+
705
+
706
+ @streamable
707
+ @dataclass(frozen=True)
708
+ class GetOfferSummary(Streamable):
709
+ offer: str
710
+ advanced: bool = False
711
+
712
+ @cached_property
713
+ def parsed_offer(self) -> Offer:
714
+ return Offer.from_bech32(self.offer)
715
+
716
+
717
+ @streamable
718
+ @dataclass(frozen=True)
719
+ class GetOfferSummaryResponse(Streamable):
720
+ id: bytes32
721
+ summary: OfferSummary | None = None
722
+ data_layer_summary: DataLayerSummary | None = None
723
+
724
+ def __post_init__(self) -> None:
725
+ if self.summary is not None and self.data_layer_summary is not None:
726
+ raise ValueError("Cannot have both summary and data_layer_summary")
727
+ elif self.summary is None and self.data_layer_summary is None:
728
+ raise ValueError("Must have either summary or data_layer_summary")
729
+ super().__post_init__()
730
+
731
+ def to_json_dict(self) -> dict[str, Any]:
732
+ serialized = super().to_json_dict()
733
+ if self.data_layer_summary is not None:
734
+ serialized["summary"] = serialized["data_layer_summary"]
735
+ del serialized["data_layer_summary"]
736
+ return serialized
737
+
738
+ @classmethod
739
+ def from_json_dict(cls, json_dict: dict[str, Any]) -> Self:
740
+ if isinstance(json_dict["summary"]["offered"], dict):
741
+ summary: OfferSummary | DataLayerSummary = OfferSummary.from_json_dict(json_dict["summary"])
742
+ else:
743
+ summary = DataLayerSummary.from_json_dict(json_dict["summary"])
744
+ return cls(
745
+ id=bytes32.from_hexstr(json_dict["id"]),
746
+ summary=summary if isinstance(summary, OfferSummary) else None,
747
+ data_layer_summary=summary if isinstance(summary, DataLayerSummary) else None,
748
+ )
654
749
 
655
750
 
656
751
  @streamable
@@ -706,7 +801,7 @@ class DIDGetInfoResponse(Streamable):
706
801
  latest_coin: bytes32
707
802
  p2_address: str
708
803
  public_key: bytes
709
- recovery_list_hash: Optional[bytes32]
804
+ recovery_list_hash: bytes32 | None
710
805
  num_verification: uint16
711
806
  metadata: dict[str, str]
712
807
  launcher_id: bytes32
@@ -719,9 +814,9 @@ class DIDGetInfoResponse(Streamable):
719
814
  @dataclass(frozen=True)
720
815
  class DIDFindLostDID(Streamable):
721
816
  coin_id: str
722
- recovery_list_hash: Optional[bytes32] = None
723
- num_verification: Optional[uint16] = None
724
- metadata: Optional[dict[str, str]] = None
817
+ recovery_list_hash: bytes32 | None = None
818
+ num_verification: uint16 | None = None
819
+ metadata: dict[str, str] | None = None
725
820
 
726
821
 
727
822
  @streamable
@@ -782,7 +877,7 @@ class DIDGetDID(Streamable):
782
877
  class DIDGetDIDResponse(Streamable):
783
878
  wallet_id: uint32
784
879
  my_did: str
785
- coin_id: Optional[bytes32] = None
880
+ coin_id: bytes32 | None = None
786
881
 
787
882
 
788
883
  @streamable
@@ -801,20 +896,20 @@ class DIDGetMetadataResponse(Streamable):
801
896
  @streamable
802
897
  @dataclass(frozen=True)
803
898
  class NFTCountNFTs(Streamable):
804
- wallet_id: Optional[uint32] = None
899
+ wallet_id: uint32 | None = None
805
900
 
806
901
 
807
902
  @streamable
808
903
  @dataclass(frozen=True)
809
904
  class NFTCountNFTsResponse(Streamable):
810
- wallet_id: Optional[uint32]
905
+ wallet_id: uint32 | None
811
906
  count: uint64
812
907
 
813
908
 
814
909
  @streamable
815
910
  @dataclass(frozen=True)
816
911
  class NFTGetNFTs(Streamable):
817
- wallet_id: Optional[uint32] = None
912
+ wallet_id: uint32 | None = None
818
913
  start_index: uint32 = uint32(0)
819
914
  num: uint32 = uint32(50)
820
915
 
@@ -822,14 +917,14 @@ class NFTGetNFTs(Streamable):
822
917
  @streamable
823
918
  @dataclass(frozen=True)
824
919
  class NFTGetNFTsResponse(Streamable):
825
- wallet_id: Optional[uint32]
920
+ wallet_id: uint32 | None
826
921
  nft_list: list[NFTInfo]
827
922
 
828
923
 
829
924
  @streamable
830
925
  @dataclass(frozen=True)
831
926
  class NFTGetByDID(Streamable):
832
- did_id: Optional[str] = None
927
+ did_id: str | None = None
833
928
 
834
929
 
835
930
  @streamable
@@ -847,7 +942,7 @@ class NFTGetWalletDID(Streamable):
847
942
  @streamable
848
943
  @dataclass(frozen=True)
849
944
  class NFTGetWalletDIDResponse(Streamable):
850
- did_id: Optional[str]
945
+ did_id: str | None
851
946
 
852
947
 
853
948
  @streamable
@@ -899,7 +994,7 @@ class RoyaltyAsset(Streamable):
899
994
  @streamable
900
995
  @dataclass(frozen=True)
901
996
  class FungibleAsset(Streamable):
902
- asset: Optional[str]
997
+ asset: str | None
903
998
  amount: uint64
904
999
 
905
1000
 
@@ -921,7 +1016,7 @@ class NFTCalculateRoyalties(Streamable):
921
1016
  @dataclass(frozen=True)
922
1017
  class RoyaltySummary(Streamable):
923
1018
  royalty_asset: str
924
- fungible_asset: Optional[str]
1019
+ fungible_asset: str | None
925
1020
  royalty_address: str
926
1021
  royalty_amount: uint64
927
1022
 
@@ -1013,7 +1108,7 @@ class DLLatestSingleton(Streamable):
1013
1108
  @streamable
1014
1109
  @dataclass(frozen=True)
1015
1110
  class DLLatestSingletonResponse(Streamable):
1016
- singleton: Optional[SingletonRecord]
1111
+ singleton: SingletonRecord | None
1017
1112
 
1018
1113
 
1019
1114
  @streamable
@@ -1033,9 +1128,9 @@ class DLSingletonsByRootResponse(Streamable):
1033
1128
  @dataclass(frozen=True)
1034
1129
  class DLHistory(Streamable):
1035
1130
  launcher_id: bytes32
1036
- min_generation: Optional[uint32] = None
1037
- max_generation: Optional[uint32] = None
1038
- num_results: Optional[uint32] = None
1131
+ min_generation: uint32 | None = None
1132
+ max_generation: uint32 | None = None
1133
+ num_results: uint32 | None = None
1039
1134
 
1040
1135
 
1041
1136
  @streamable
@@ -1073,7 +1168,7 @@ class VCGet(Streamable):
1073
1168
  @streamable
1074
1169
  @dataclass(frozen=True)
1075
1170
  class VCGetResponse(Streamable):
1076
- vc_record: Optional[VCRecord]
1171
+ vc_record: VCRecord | None
1077
1172
 
1078
1173
 
1079
1174
  @streamable
@@ -1102,7 +1197,7 @@ class VCProofsRPC(Streamable):
1102
1197
  @dataclass(frozen=True)
1103
1198
  class VCProofWithHash(Streamable):
1104
1199
  hash: bytes32
1105
- proof: Optional[VCProofsRPC]
1200
+ proof: VCProofsRPC | None
1106
1201
 
1107
1202
 
1108
1203
  # utility for VCGetListResponse
@@ -1124,7 +1219,7 @@ class VCGetListResponse(Streamable):
1124
1219
  proofs: list[VCProofWithHash]
1125
1220
 
1126
1221
  @property
1127
- def proof_dict(self) -> dict[bytes32, Optional[dict[str, str]]]:
1222
+ def proof_dict(self) -> dict[bytes32, dict[str, str] | None]:
1128
1223
  return {
1129
1224
  pwh.hash: None if pwh.proof is None else {key: value for key, value in pwh.proof.key_value_pairs}
1130
1225
  for pwh in self.proofs
@@ -1230,8 +1325,8 @@ class ExecuteSigningInstructionsResponse(Streamable):
1230
1325
  @dataclass(frozen=True, kw_only=True)
1231
1326
  class TransactionEndpointRequest(Streamable):
1232
1327
  fee: uint64 = uint64(0)
1233
- push: Optional[bool] = None
1234
- sign: Optional[bool] = None
1328
+ push: bool | None = None
1329
+ sign: bool | None = None
1235
1330
 
1236
1331
  def to_json_dict(self, _avoid_ban: bool = False) -> dict[str, Any]:
1237
1332
  if not _avoid_ban:
@@ -1242,7 +1337,10 @@ class TransactionEndpointRequest(Streamable):
1242
1337
  return super().to_json_dict()
1243
1338
 
1244
1339
  def json_serialize_for_transport(
1245
- self, tx_config: TXConfig, extra_conditions: tuple[Condition, ...], timelock_info: ConditionValidTimes
1340
+ self,
1341
+ tx_config: TXConfig,
1342
+ extra_conditions: tuple[Condition, ...],
1343
+ timelock_info: ConditionValidTimes,
1246
1344
  ) -> dict[str, Any]:
1247
1345
  return {
1248
1346
  **tx_config.to_json_dict(),
@@ -1282,7 +1380,7 @@ class SendTransaction(TransactionEndpointRequest):
1282
1380
  # Technically this value was meant to support many types here
1283
1381
  # However, only one is supported right now and there are no plans to extend
1284
1382
  # So, as a slight hack, we'll specify that only Clawback is supported
1285
- puzzle_decorator: Optional[list[ClawbackPuzzleDecoratorOverride]] = None
1383
+ puzzle_decorator: list[ClawbackPuzzleDecoratorOverride] | None = None
1286
1384
 
1287
1385
 
1288
1386
  @streamable
@@ -1296,7 +1394,7 @@ class SendTransactionResponse(TransactionEndpointResponse):
1296
1394
  @dataclass(frozen=True)
1297
1395
  class SpendClawbackCoins(TransactionEndpointRequest):
1298
1396
  coin_ids: list[bytes32] = field(default_factory=default_raise)
1299
- batch_size: Optional[uint16] = None
1397
+ batch_size: uint16 | None = None
1300
1398
  force: bool = False
1301
1399
 
1302
1400
 
@@ -1324,7 +1422,7 @@ class SendNotificationResponse(TransactionEndpointResponse):
1324
1422
  @dataclass(frozen=True)
1325
1423
  class PushTransactions(TransactionEndpointRequest):
1326
1424
  transactions: list[TransactionRecord] = field(default_factory=default_raise)
1327
- push: Optional[bool] = True
1425
+ push: bool | None = True
1328
1426
 
1329
1427
  # We allow for flexibility in transaction parsing here so we need to override
1330
1428
  @classmethod
@@ -1355,6 +1453,12 @@ class SplitCoins(TransactionEndpointRequest):
1355
1453
  amount_per_coin: uint64 = field(default_factory=default_raise)
1356
1454
  target_coin_id: bytes32 = field(default_factory=default_raise)
1357
1455
 
1456
+ def __post_init__(self) -> None:
1457
+ if self.number_of_coins > 500:
1458
+ raise ValueError(f"{self.number_of_coins} coins is greater then the maximum limit of 500 coins.")
1459
+ if self.number_of_coins == 0:
1460
+ raise ValueError("Cannot split into 0 new coins")
1461
+
1358
1462
 
1359
1463
  @streamable
1360
1464
  @dataclass(frozen=True)
@@ -1369,9 +1473,19 @@ class CombineCoins(TransactionEndpointRequest):
1369
1473
  number_of_coins: uint16 = uint16(500)
1370
1474
  largest_first: bool = False
1371
1475
  target_coin_ids: list[bytes32] = field(default_factory=list)
1372
- target_coin_amount: Optional[uint64] = None
1476
+ target_coin_amount: uint64 | None = None
1373
1477
  coin_num_limit: uint16 = uint16(500)
1374
1478
 
1479
+ def __post_init__(self) -> None:
1480
+ if self.number_of_coins > self.coin_num_limit:
1481
+ raise ValueError(
1482
+ f"{self.number_of_coins} coins is greater then the maximum limit of {self.coin_num_limit} coins."
1483
+ )
1484
+ if self.number_of_coins < 2:
1485
+ raise ValueError("You need at least two coins to combine")
1486
+ if len(self.target_coin_ids) > self.number_of_coins:
1487
+ raise ValueError("More coin IDs specified than desired number of coins to combine")
1488
+
1375
1489
 
1376
1490
  @streamable
1377
1491
  @dataclass(frozen=True)
@@ -1379,28 +1493,28 @@ class CombineCoinsResponse(TransactionEndpointResponse):
1379
1493
  pass
1380
1494
 
1381
1495
 
1382
- # utility for CATSpend
1496
+ # utility for CATSpend/CreateSignedTransaction
1383
1497
  # unfortunate that we can't use CreateCoin but the memos are taken as strings not bytes
1384
1498
  @streamable
1385
1499
  @dataclass(frozen=True)
1386
1500
  class Addition(Streamable):
1387
1501
  amount: uint64
1388
1502
  puzzle_hash: bytes32
1389
- memos: Optional[list[str]] = None
1503
+ memos: list[str] | None = None
1390
1504
 
1391
1505
 
1392
1506
  @streamable
1393
1507
  @dataclass(frozen=True, kw_only=True)
1394
1508
  class CATSpend(TransactionEndpointRequest):
1395
1509
  wallet_id: uint32 = field(default_factory=default_raise)
1396
- additions: Optional[list[Addition]] = None
1397
- amount: Optional[uint64] = None
1398
- inner_address: Optional[str] = None
1399
- memos: Optional[list[str]] = None
1400
- coins: Optional[list[Coin]] = None
1401
- extra_delta: Optional[str] = None # str to support negative ints :(
1402
- tail_reveal: Optional[bytes] = None
1403
- tail_solution: Optional[bytes] = None
1510
+ additions: list[Addition] | None = None
1511
+ amount: uint64 | None = None
1512
+ inner_address: str | None = None
1513
+ memos: list[str] | None = None
1514
+ coins: list[Coin] | None = None
1515
+ extra_delta: str | None = None # str to support negative ints :(
1516
+ tail_reveal: bytes | None = None
1517
+ tail_solution: bytes | None = None
1404
1518
 
1405
1519
  def __post_init__(self) -> None:
1406
1520
  if (
@@ -1413,7 +1527,7 @@ class CATSpend(TransactionEndpointRequest):
1413
1527
  super().__post_init__()
1414
1528
 
1415
1529
  @property
1416
- def cat_discrepancy(self) -> Optional[tuple[int, Program, Program]]:
1530
+ def cat_discrepancy(self) -> tuple[int, Program, Program] | None:
1417
1531
  if self.extra_delta is None and self.tail_reveal is None and self.tail_solution is None:
1418
1532
  return None
1419
1533
  elif None in {self.extra_delta, self.tail_reveal, self.tail_solution}:
@@ -1486,8 +1600,8 @@ class DIDTransferDIDResponse(TransactionEndpointResponse):
1486
1600
  @dataclass(frozen=True, kw_only=True)
1487
1601
  class NFTMintNFTRequest(TransactionEndpointRequest):
1488
1602
  wallet_id: uint32 = field(default_factory=default_raise)
1489
- royalty_address: Optional[str] = field(default_factory=default_raise)
1490
- target_address: Optional[str] = field(default_factory=default_raise)
1603
+ royalty_address: str | None = field(default_factory=default_raise)
1604
+ target_address: str | None = field(default_factory=default_raise)
1491
1605
  uris: list[str] = field(default_factory=default_raise)
1492
1606
  hash: bytes32 = field(default_factory=default_raise)
1493
1607
  royalty_amount: uint16 = uint16(0)
@@ -1495,9 +1609,9 @@ class NFTMintNFTRequest(TransactionEndpointRequest):
1495
1609
  license_uris: list[str] = field(default_factory=list)
1496
1610
  edition_number: uint64 = uint64(1)
1497
1611
  edition_total: uint64 = uint64(1)
1498
- meta_hash: Optional[bytes32] = None
1499
- license_hash: Optional[bytes32] = None
1500
- did_id: Optional[str] = None
1612
+ meta_hash: bytes32 | None = None
1613
+ license_hash: bytes32 | None = None
1614
+ did_id: str | None = None
1501
1615
 
1502
1616
 
1503
1617
  @streamable
@@ -1513,7 +1627,7 @@ class NFTMintNFTResponse(TransactionEndpointResponse):
1513
1627
  class NFTSetNFTDID(TransactionEndpointRequest):
1514
1628
  wallet_id: uint32 = field(default_factory=default_raise)
1515
1629
  nft_coin_id: bytes32 = field(default_factory=default_raise)
1516
- did_id: Optional[str] = None
1630
+ did_id: str | None = None
1517
1631
 
1518
1632
 
1519
1633
  @streamable
@@ -1527,7 +1641,7 @@ class NFTSetNFTDIDResponse(TransactionEndpointResponse):
1527
1641
  @dataclass(frozen=True, kw_only=True)
1528
1642
  class NFTSetDIDBulk(TransactionEndpointRequest):
1529
1643
  nft_coin_list: list[NFTCoin] = field(default_factory=default_raise)
1530
- did_id: Optional[str] = None
1644
+ did_id: str | None = None
1531
1645
 
1532
1646
 
1533
1647
  @streamable
@@ -1692,8 +1806,8 @@ class NFTMintMetadata(Streamable):
1692
1806
  license_uris: list[str] = field(default_factory=list)
1693
1807
  edition_number: uint64 = uint64(1)
1694
1808
  edition_total: uint64 = uint64(1)
1695
- meta_hash: Optional[bytes32] = None
1696
- license_hash: Optional[bytes32] = None
1809
+ meta_hash: bytes32 | None = None
1810
+ license_hash: bytes32 | None = None
1697
1811
 
1698
1812
 
1699
1813
  @streamable
@@ -1701,17 +1815,17 @@ class NFTMintMetadata(Streamable):
1701
1815
  class NFTMintBulk(TransactionEndpointRequest):
1702
1816
  wallet_id: uint32 = field(default_factory=default_raise)
1703
1817
  metadata_list: list[NFTMintMetadata] = field(default_factory=default_raise)
1704
- royalty_address: Optional[str] = None
1705
- royalty_percentage: Optional[uint16] = None
1818
+ royalty_address: str | None = None
1819
+ royalty_percentage: uint16 | None = None
1706
1820
  target_list: list[str] = field(default_factory=list)
1707
1821
  mint_number_start: uint16 = uint16(1)
1708
- mint_total: Optional[uint16] = None
1709
- xch_coins: Optional[list[Coin]] = None
1710
- xch_change_target: Optional[str] = None
1711
- new_innerpuzhash: Optional[bytes32] = None
1712
- new_p2_puzhash: Optional[bytes32] = None
1713
- did_coin: Optional[Coin] = None
1714
- did_lineage_parent: Optional[bytes32] = None
1822
+ mint_total: uint16 | None = None
1823
+ xch_coins: list[Coin] | None = None
1824
+ xch_change_target: str | None = None
1825
+ new_innerpuzhash: bytes32 | None = None
1826
+ new_p2_puzhash: bytes32 | None = None
1827
+ did_coin: Coin | None = None
1828
+ did_lineage_parent: bytes32 | None = None
1715
1829
  mint_from_did: bool = False
1716
1830
 
1717
1831
 
@@ -1736,7 +1850,7 @@ class PWJoinPool(TransactionEndpointRequest):
1736
1850
  class PWJoinPoolResponse(TransactionEndpointResponse):
1737
1851
  total_fee: uint64
1738
1852
  transaction: TransactionRecord
1739
- fee_transaction: Optional[TransactionRecord]
1853
+ fee_transaction: TransactionRecord | None
1740
1854
 
1741
1855
 
1742
1856
  @streamable
@@ -1750,14 +1864,14 @@ class PWSelfPool(TransactionEndpointRequest):
1750
1864
  class PWSelfPoolResponse(TransactionEndpointResponse):
1751
1865
  total_fee: uint64
1752
1866
  transaction: TransactionRecord
1753
- fee_transaction: Optional[TransactionRecord]
1867
+ fee_transaction: TransactionRecord | None
1754
1868
 
1755
1869
 
1756
1870
  @streamable
1757
1871
  @dataclass(frozen=True)
1758
1872
  class PWAbsorbRewards(TransactionEndpointRequest):
1759
1873
  wallet_id: uint32 = field(default_factory=default_raise)
1760
- max_spends_in_tx: Optional[uint16] = None
1874
+ max_spends_in_tx: uint16 | None = None
1761
1875
 
1762
1876
 
1763
1877
  @streamable
@@ -1765,14 +1879,14 @@ class PWAbsorbRewards(TransactionEndpointRequest):
1765
1879
  class PWAbsorbRewardsResponse(TransactionEndpointResponse):
1766
1880
  state: PoolWalletInfo
1767
1881
  transaction: TransactionRecord
1768
- fee_transaction: Optional[TransactionRecord]
1882
+ fee_transaction: TransactionRecord | None
1769
1883
 
1770
1884
 
1771
1885
  @streamable
1772
1886
  @dataclass(frozen=True)
1773
1887
  class VCMint(TransactionEndpointRequest):
1774
1888
  did_id: str = field(default_factory=default_raise)
1775
- target_address: Optional[str] = None
1889
+ target_address: str | None = None
1776
1890
 
1777
1891
 
1778
1892
  @streamable
@@ -1785,9 +1899,9 @@ class VCMintResponse(TransactionEndpointResponse):
1785
1899
  @dataclass(frozen=True)
1786
1900
  class VCSpend(TransactionEndpointRequest):
1787
1901
  vc_id: bytes32 = field(default_factory=default_raise)
1788
- new_puzhash: Optional[bytes32] = None
1789
- new_proof_hash: Optional[bytes32] = None
1790
- provider_inner_puzhash: Optional[bytes32] = None
1902
+ new_puzhash: bytes32 | None = None
1903
+ new_proof_hash: bytes32 | None = None
1904
+ provider_inner_puzhash: bytes32 | None = None
1791
1905
 
1792
1906
 
1793
1907
  @streamable
@@ -1808,15 +1922,61 @@ class VCRevokeResponse(TransactionEndpointResponse):
1808
1922
  pass
1809
1923
 
1810
1924
 
1811
- # TODO: The section below needs corresponding request types
1812
- # TODO: The section below should be added to the API (currently only for client)
1925
+ @streamable
1926
+ @dataclass(frozen=True)
1927
+ class CSTCoinAnnouncement(Streamable):
1928
+ coin_id: bytes32
1929
+ message: bytes
1813
1930
 
1814
1931
 
1815
1932
  @streamable
1816
1933
  @dataclass(frozen=True)
1817
- class SendTransactionMultiResponse(TransactionEndpointResponse):
1818
- transaction: TransactionRecord
1819
- transaction_id: bytes32
1934
+ class CSTPuzzleAnnouncement(Streamable):
1935
+ puzzle_hash: bytes32
1936
+ message: bytes
1937
+
1938
+
1939
+ @streamable
1940
+ @dataclass(frozen=True)
1941
+ class CreateSignedTransaction(TransactionEndpointRequest):
1942
+ additions: list[Addition] = field(default_factory=default_raise)
1943
+ wallet_id: uint32 | None = None
1944
+ coins: list[Coin] | None = None
1945
+ morph_bytes: bytes | None = None
1946
+ coin_announcements: list[CSTCoinAnnouncement] = field(default_factory=list)
1947
+ puzzle_announcements: list[CSTPuzzleAnnouncement] = field(default_factory=list)
1948
+
1949
+ def __post_init__(self) -> None:
1950
+ if len(self.additions) < 1:
1951
+ raise ValueError("Must have at least one addition")
1952
+ super().__post_init__()
1953
+
1954
+ @property
1955
+ def coin_set(self) -> set[Coin] | None:
1956
+ if self.coins is None:
1957
+ return None
1958
+ else:
1959
+ return set(self.coins)
1960
+
1961
+ @property
1962
+ def asserted_coin_announcements(self) -> tuple[AssertCoinAnnouncement, ...]:
1963
+ return tuple(
1964
+ AssertCoinAnnouncement(
1965
+ asserted_id=ca.coin_id,
1966
+ asserted_msg=(ca.message if self.morph_bytes is None else std_hash(self.morph_bytes + ca.message)),
1967
+ )
1968
+ for ca in self.coin_announcements
1969
+ )
1970
+
1971
+ @property
1972
+ def asserted_puzzle_announcements(self) -> tuple[AssertPuzzleAnnouncement, ...]:
1973
+ return tuple(
1974
+ AssertPuzzleAnnouncement(
1975
+ asserted_ph=pa.puzzle_hash,
1976
+ asserted_msg=(pa.message if self.morph_bytes is None else std_hash(self.morph_bytes + pa.message)),
1977
+ )
1978
+ for pa in self.puzzle_announcements
1979
+ )
1820
1980
 
1821
1981
 
1822
1982
  @streamable
@@ -1826,12 +1986,113 @@ class CreateSignedTransactionsResponse(TransactionEndpointResponse):
1826
1986
  signed_tx: TransactionRecord
1827
1987
 
1828
1988
 
1989
+ _T_SendTransactionMultiProxy = TypeVar("_T_SendTransactionMultiProxy", CATSpend, CreateSignedTransaction)
1990
+
1991
+
1992
+ @streamable
1993
+ @dataclass(frozen=True)
1994
+ class SendTransactionMulti(TransactionEndpointRequest):
1995
+ # primarily for cat_spend
1996
+ wallet_id: uint32 = field(default_factory=default_raise)
1997
+ additions: list[Addition] | None = None # for both
1998
+ amount: uint64 | None = None
1999
+ inner_address: str | None = None
2000
+ memos: list[str] | None = None
2001
+ coins: list[Coin] | None = None # for both
2002
+ extra_delta: str | None = None # str to support negative ints :(
2003
+ tail_reveal: bytes | None = None
2004
+ tail_solution: bytes | None = None
2005
+ # for create_signed_transaction
2006
+ morph_bytes: bytes | None = None
2007
+ coin_announcements: list[CSTCoinAnnouncement] | None = None
2008
+ puzzle_announcements: list[CSTPuzzleAnnouncement] | None = None
2009
+
2010
+ def convert_to_proxy(self, proxy_type: type[_T_SendTransactionMultiProxy]) -> _T_SendTransactionMultiProxy:
2011
+ if proxy_type is CATSpend:
2012
+ if self.morph_bytes is not None:
2013
+ raise ValueError(
2014
+ 'Specified "morph_bytes" for a CAT-type wallet. Maybe you meant to specify an XCH wallet?'
2015
+ )
2016
+ elif self.coin_announcements is not None or self.puzzle_announcements is not None:
2017
+ raise ValueError(
2018
+ 'Specified "coin/puzzle_announcements" for a CAT-type wallet.'
2019
+ "Maybe you meant to specify an XCH wallet?"
2020
+ )
2021
+
2022
+ # not sure why mypy hasn't understood this is purely a CATSpend
2023
+ return proxy_type(
2024
+ wallet_id=self.wallet_id,
2025
+ additions=self.additions, # type: ignore[arg-type]
2026
+ amount=self.amount, # type: ignore[call-arg]
2027
+ inner_address=self.inner_address,
2028
+ memos=self.memos,
2029
+ coins=self.coins,
2030
+ extra_delta=self.extra_delta,
2031
+ tail_reveal=self.tail_reveal,
2032
+ tail_solution=self.tail_solution,
2033
+ fee=self.fee,
2034
+ push=self.push,
2035
+ sign=self.sign,
2036
+ )
2037
+ elif proxy_type is CreateSignedTransaction:
2038
+ if self.amount is not None:
2039
+ raise ValueError('Specified "amount" for an XCH wallet. Maybe you meant to specify a CAT-type wallet?')
2040
+ elif self.inner_address is not None:
2041
+ raise ValueError(
2042
+ 'Specified "inner_address" for an XCH wallet. Maybe you meant to specify a CAT-type wallet?'
2043
+ )
2044
+ elif self.memos is not None:
2045
+ raise ValueError('Specified "memos" for an XCH wallet. Maybe you meant to specify a CAT-type wallet?')
2046
+ elif self.extra_delta is not None or self.tail_reveal is not None or self.tail_solution is not None:
2047
+ raise ValueError(
2048
+ 'Specified "extra_delta", "tail_reveal", or "tail_solution" for an XCH wallet.'
2049
+ "Maybe you meant to specify a CAT-type wallet?"
2050
+ )
2051
+ elif self.additions is None:
2052
+ raise ValueError('"additions" are required for XCH wallets.')
2053
+
2054
+ # not sure why mypy hasn't understood this is purely a CreateSignedTransaction
2055
+ return proxy_type(
2056
+ additions=self.additions,
2057
+ wallet_id=self.wallet_id,
2058
+ coins=self.coins,
2059
+ morph_bytes=self.morph_bytes, # type: ignore[call-arg]
2060
+ coin_announcements=self.coin_announcements if self.coin_announcements is not None else [],
2061
+ puzzle_announcements=self.puzzle_announcements if self.puzzle_announcements is not None else [],
2062
+ fee=self.fee,
2063
+ push=self.push,
2064
+ sign=self.sign,
2065
+ )
2066
+ else:
2067
+ raise ValueError("An unsupported wallet type was selected for `send_transaction_multi`")
2068
+
2069
+
2070
+ @streamable
2071
+ @dataclass(frozen=True)
2072
+ class SendTransactionMultiResponse(TransactionEndpointResponse):
2073
+ transaction: TransactionRecord
2074
+ transaction_id: bytes32
2075
+
2076
+
1829
2077
  @streamable
1830
2078
  @dataclass(frozen=True)
1831
2079
  class _OfferEndpointResponse(TransactionEndpointResponse):
1832
- offer: Offer
2080
+ offer: Offer # gotta figure out how to ignore this in streamable
1833
2081
  trade_record: TradeRecord
1834
2082
 
2083
+ def to_json_dict(self) -> dict[str, Any]:
2084
+ old_offer_override = getattr(self.offer, "json_serialization_override", None)
2085
+ object.__setattr__(self.offer, "json_serialization_override", lambda o: o.to_bech32())
2086
+ try:
2087
+ response = {
2088
+ **super().to_json_dict(),
2089
+ "trade_record": self.trade_record.to_json_dict_convenience(),
2090
+ }
2091
+ except Exception:
2092
+ object.__setattr__(self.offer, "json_serialization_override", old_offer_override)
2093
+ raise
2094
+ return response
2095
+
1835
2096
  @classmethod
1836
2097
  def from_json_dict(cls, json_dict: dict[str, Any]) -> Self:
1837
2098
  tx_endpoint: TransactionEndpointResponse = json_deserialize_with_clvm_streamable(
@@ -1846,25 +2107,428 @@ class _OfferEndpointResponse(TransactionEndpointResponse):
1846
2107
  )
1847
2108
 
1848
2109
 
2110
+ @streamable
2111
+ @dataclass(frozen=True)
2112
+ class CreateOfferForIDs(TransactionEndpointRequest):
2113
+ # a hack for dict[str, int] because streamable doesn't support negative ints
2114
+ offer: dict[str, str] = field(default_factory=default_raise)
2115
+ driver_dict: dict[bytes32, PuzzleInfo] | None = None
2116
+ solver: Solver | None = None
2117
+ validate_only: bool = False
2118
+
2119
+ @property
2120
+ def offer_spec(self) -> dict[int | bytes32, int]:
2121
+ modified_offer: dict[int | bytes32, int] = {}
2122
+ for wallet_identifier, change in self.offer.items():
2123
+ if len(wallet_identifier) > 16: # wallet IDs are uint32 therefore no longer than 8 bytes :P
2124
+ modified_offer[bytes32.from_hexstr(wallet_identifier)] = int(change)
2125
+ else:
2126
+ modified_offer[int(wallet_identifier)] = int(change)
2127
+
2128
+ return modified_offer
2129
+
2130
+
1849
2131
  @streamable
1850
2132
  @dataclass(frozen=True)
1851
2133
  class CreateOfferForIDsResponse(_OfferEndpointResponse):
1852
2134
  pass
1853
2135
 
1854
2136
 
2137
+ @streamable
2138
+ @dataclass(frozen=True)
2139
+ class TakeOffer(TransactionEndpointRequest):
2140
+ offer: str = field(default_factory=default_raise)
2141
+ solver: Solver | None = None
2142
+
2143
+ @cached_property
2144
+ def parsed_offer(self) -> Offer:
2145
+ return Offer.from_bech32(self.offer)
2146
+
2147
+
1855
2148
  @streamable
1856
2149
  @dataclass(frozen=True)
1857
2150
  class TakeOfferResponse(_OfferEndpointResponse): # Inheriting for de-dup sake
1858
2151
  pass
1859
2152
 
1860
2153
 
2154
+ @streamable
2155
+ @dataclass(frozen=True)
2156
+ class GetOffer(Streamable):
2157
+ trade_id: bytes32
2158
+ file_contents: bool = False
2159
+
2160
+
2161
+ @streamable
2162
+ @dataclass(frozen=True)
2163
+ class GetOfferResponse(Streamable):
2164
+ offer: str | None
2165
+ trade_record: TradeRecord
2166
+
2167
+ def to_json_dict(self) -> dict[str, Any]:
2168
+ return {
2169
+ **super().to_json_dict(),
2170
+ "trade_record": self.trade_record.to_json_dict_convenience(),
2171
+ }
2172
+
2173
+ @classmethod
2174
+ def from_json_dict(cls, json_dict: dict[str, Any]) -> Self:
2175
+ return cls(
2176
+ offer=json_dict["offer"],
2177
+ trade_record=TradeRecord.from_json_dict_convenience(
2178
+ json_dict["trade_record"],
2179
+ bytes(Offer.from_bech32(json_dict["offer"])).hex() if json_dict["offer"] is not None else "",
2180
+ ),
2181
+ )
2182
+
2183
+
2184
+ @streamable
2185
+ @dataclass(frozen=True)
2186
+ class GetAllOffers(Streamable):
2187
+ start: uint16 = uint16(0)
2188
+ end: uint16 = uint16(10)
2189
+ exclude_my_offers: bool = False
2190
+ exclude_taken_offers: bool = False
2191
+ include_completed: bool = False
2192
+ sort_key: str | None = None
2193
+ reverse: bool = False
2194
+ file_contents: bool = False
2195
+
2196
+
2197
+ @streamable
2198
+ @dataclass(frozen=True)
2199
+ class GetAllOffersResponse(Streamable):
2200
+ offers: list[str] | None
2201
+ trade_records: list[TradeRecord]
2202
+
2203
+ def to_json_dict(self) -> dict[str, Any]:
2204
+ return {
2205
+ **super().to_json_dict(),
2206
+ "trade_records": [tr.to_json_dict_convenience() for tr in self.trade_records],
2207
+ }
2208
+
2209
+ @classmethod
2210
+ def from_json_dict(cls, json_dict: dict[str, Any]) -> Self:
2211
+ return cls(
2212
+ offers=json_dict["offers"],
2213
+ trade_records=[
2214
+ TradeRecord.from_json_dict_convenience(
2215
+ json_tr,
2216
+ bytes(Offer.from_bech32(json_dict["offers"][i])).hex() if json_dict["offers"] is not None else "",
2217
+ )
2218
+ for i, json_tr in enumerate(json_dict["trade_records"])
2219
+ ],
2220
+ )
2221
+
2222
+
2223
+ @streamable
2224
+ @dataclass(frozen=True)
2225
+ class CancelOffer(TransactionEndpointRequest):
2226
+ trade_id: bytes32 = field(default_factory=default_raise)
2227
+ secure: bool = field(default_factory=default_raise)
2228
+
2229
+
1861
2230
  @streamable
1862
2231
  @dataclass(frozen=True)
1863
2232
  class CancelOfferResponse(TransactionEndpointResponse):
1864
2233
  pass
1865
2234
 
1866
2235
 
2236
+ @streamable
2237
+ @dataclass(frozen=True)
2238
+ class CancelOffers(TransactionEndpointRequest):
2239
+ secure: bool = field(default_factory=default_raise)
2240
+ batch_fee: uint64 = uint64(0)
2241
+ batch_size: uint16 = uint16(5)
2242
+ cancel_all: bool = False
2243
+ asset_id: str = "xch"
2244
+
2245
+ @property
2246
+ def query_key(self) -> bytes32 | None:
2247
+ if self.cancel_all:
2248
+ return None
2249
+ if self.asset_id != "xch":
2250
+ return bytes32.from_hexstr(self.asset_id)
2251
+ return None
2252
+
2253
+
1867
2254
  @streamable
1868
2255
  @dataclass(frozen=True)
1869
2256
  class CancelOffersResponse(TransactionEndpointResponse):
1870
2257
  pass
2258
+
2259
+
2260
+ # utilities for CreateNewWallet
2261
+ @streamable_enum(str)
2262
+ class CreateNewWalletType(Enum):
2263
+ CAT_WALLET = "cat_wallet"
2264
+ DID_WALLET = "did_wallet"
2265
+ NFT_WALLET = "nft_wallet"
2266
+ POOL_WALLET = "pool_wallet"
2267
+
2268
+
2269
+ @streamable_enum(str)
2270
+ class WalletCreationMode(Enum):
2271
+ NEW = "new"
2272
+ EXISTING = "existing"
2273
+
2274
+
2275
+ @streamable_enum(str)
2276
+ class DIDType(Enum):
2277
+ NEW = "new"
2278
+ RECOVERY = "recovery"
2279
+
2280
+
2281
+ @streamable
2282
+ @dataclass(frozen=True)
2283
+ class CreateNewWallet(TransactionEndpointRequest):
2284
+ wallet_type: CreateNewWalletType = field(default_factory=default_raise)
2285
+ # CAT_WALLET
2286
+ mode: WalletCreationMode | None = None # required
2287
+ amount: uint64 | None = None # required in "new"
2288
+ name: str | None = None # If not provided, the name will be autogenerated based on the tail hash
2289
+ test: bool = False # must be True in "new"
2290
+ asset_id: bytes32 | None = None # required in "existing"
2291
+
2292
+ # DID_WALLET
2293
+ did_type: DIDType | None = None # required
2294
+ # only in "new"
2295
+ # amount: uint64 # already defined, required
2296
+ backup_dids: list[str] = field(default_factory=list) # must error if not []
2297
+ metadata: dict[str, str] = field(default_factory=dict)
2298
+ wallet_name: str | None = None
2299
+ # only in "recovery"
2300
+ backup_data: str | None = None # required
2301
+
2302
+ # NFT_WALLET
2303
+ did_id: str | None = None
2304
+ # name: Optional[str] = None # already defined
2305
+
2306
+ # POOL_WALLET
2307
+ # mode: WalletCreationMode # already defined, required, must be "new"
2308
+ initial_target_state: NewPoolWalletInitialTargetState | None = None # required
2309
+ p2_singleton_delayed_ph: bytes32 | None = None
2310
+ p2_singleton_delay_time: uint64 | None = None
2311
+
2312
+ def __post_init__(self) -> None:
2313
+ if self.wallet_type == CreateNewWalletType.CAT_WALLET:
2314
+ if self.mode is None:
2315
+ raise ValueError('Must specify a "mode" when creating a new CAT wallet')
2316
+ if self.mode == WalletCreationMode.NEW:
2317
+ if not self.test:
2318
+ raise ValueError(
2319
+ "Support for this RPC mode has been dropped."
2320
+ " Please use the CAT Admin Tool @ https://github.com/Chia-Network/CAT-admin-tool instead."
2321
+ )
2322
+ if self.amount is None:
2323
+ raise ValueError('Must specify an "amount" of CATs to generate')
2324
+ if self.asset_id is not None:
2325
+ raise ValueError('"asset_id" is not an argument for new CAT wallets. Maybe you meant existing?')
2326
+ if self.mode == WalletCreationMode.EXISTING:
2327
+ if self.asset_id is None:
2328
+ raise ValueError('Must specify an "asset_id" when creating an existing CAT wallet')
2329
+ if self.amount is not None:
2330
+ raise ValueError('"amount" is not an argument for existing CAT wallets')
2331
+ elif self.test:
2332
+ raise ValueError('"test" mode is not supported except for new CAT wallets')
2333
+ else:
2334
+ if self.asset_id is not None:
2335
+ raise ValueError(
2336
+ '"asset_id" is not a valid argument. Maybe you meant to create an existing CAT wallet?'
2337
+ )
2338
+ if self.mode is not None and self.mode != WalletCreationMode.NEW:
2339
+ raise ValueError('"mode": "existing" is only valid for CAT wallets')
2340
+
2341
+ if self.wallet_type == CreateNewWalletType.DID_WALLET:
2342
+ if self.did_type is None:
2343
+ raise ValueError('Must specify "did_type": "new/recovery"')
2344
+ if self.did_type == DIDType.NEW:
2345
+ if self.amount is None:
2346
+ raise ValueError('Must specify an "amount" when creating a new DID')
2347
+ if self.backup_dids != []:
2348
+ raise ValueError('Recovery options are no longer supported. "backup_dids" cannot be set.')
2349
+ if self.backup_data is not None:
2350
+ raise ValueError('"backup_data" is only an option in "did_type": "recovery"')
2351
+ if self.did_type == DIDType.RECOVERY:
2352
+ if self.amount is not None:
2353
+ raise ValueError('Cannot specify an "amount" when recovering a DID')
2354
+ if self.backup_dids != []:
2355
+ raise ValueError('Cannot specify "backup_dids" when recovering a DID')
2356
+ if self.metadata != {}:
2357
+ raise ValueError('Cannot specify "metadata" when recovering a DID')
2358
+ if self.backup_data is None:
2359
+ raise ValueError('Must specify "backup_data" when recovering a DID')
2360
+ else:
2361
+ if self.did_type is not None:
2362
+ raise ValueError('"did_type" is only a valid argument for DID wallets')
2363
+ if self.backup_dids != []:
2364
+ raise ValueError('"backup_dids" is only a valid argument for DID wallets')
2365
+ if self.metadata != {}:
2366
+ raise ValueError('"metadata" is only a valid argument for DID wallets')
2367
+ if self.wallet_name is not None:
2368
+ raise ValueError('"wallet_name" is only a valid argument for DID wallets')
2369
+ if self.backup_data is not None:
2370
+ raise ValueError('"backup_data" is only a valid argument for DID wallets')
2371
+
2372
+ if self.wallet_type != CreateNewWalletType.NFT_WALLET and self.did_id is not None:
2373
+ raise ValueError('"did_id" is only a valid argument for NFT wallets')
2374
+
2375
+ if self.wallet_type == CreateNewWalletType.POOL_WALLET:
2376
+ if self.initial_target_state is None:
2377
+ raise ValueError('"initial_target_state" is required for new pool wallets')
2378
+ else:
2379
+ if self.initial_target_state is not None:
2380
+ raise ValueError('"initial_target_state" is only a valid argument for pool wallets')
2381
+ if self.p2_singleton_delayed_ph is not None:
2382
+ raise ValueError('"p2_singleton_delayed_ph" is only a valid argument for pool wallets')
2383
+ if self.p2_singleton_delay_time is not None:
2384
+ raise ValueError('"p2_singleton_delay_time" is only a valid argument for pool wallets')
2385
+
2386
+ super().__post_init__()
2387
+
2388
+
2389
+ @streamable
2390
+ @dataclass(frozen=True)
2391
+ class CreateNewWalletResponse(TransactionEndpointResponse):
2392
+ type: str # Alias for WalletType which is IntEnum and therefore incompatible
2393
+ wallet_id: uint32
2394
+ # Nothing below is truly optional when that type is being returned
2395
+ # CAT_WALLET (TXEndpoint)
2396
+ asset_id: bytes32 | None = None
2397
+ # DID_WALLET - NEW (TXEndpoint) / RECOVERY
2398
+ my_did: str | None = None
2399
+ # DID_WALLET - RECOVERY
2400
+ coin_name: bytes32 | None = None
2401
+ coin_list: Coin | None = None
2402
+ newpuzhash: bytes32 | None = None
2403
+ pubkey: G1Element | None = None
2404
+ backup_dids: list[bytes32] | None = None
2405
+ num_verifications_required: uint64 | None = None
2406
+ # NFT_WALLET
2407
+ # ...
2408
+ # POOL_WALLET (TXEndpoint)
2409
+ total_fee: uint64 | None = None
2410
+ transaction: TransactionRecord | None = None
2411
+ launcher_id: bytes32 | None = None
2412
+ p2_singleton_puzzle_hash: bytes32 | None = None
2413
+
2414
+ def __post_init__(self) -> None:
2415
+ if self.type not in {member.name for member in WalletType}:
2416
+ raise ValueError(f"Invalid wallet type: {self.type}")
2417
+ super().__post_init__()
2418
+
2419
+ def to_json_dict(self) -> dict[str, Any]:
2420
+ field_names = {"type", "wallet_id"}
2421
+ tx_endpoint_field_names = set(field.name for field in fields(TransactionEndpointResponse))
2422
+ serialization_updates: dict[str, Any] = {}
2423
+ wallet_type = next(member for member in WalletType if member.name == self.type)
2424
+ if wallet_type == WalletType.CAT:
2425
+ if self.asset_id is None:
2426
+ raise ValueError("`asset_id` is required for CAT wallets")
2427
+ field_names |= {"asset_id"}
2428
+ field_names |= tx_endpoint_field_names
2429
+ elif wallet_type == WalletType.DECENTRALIZED_ID:
2430
+ if self.my_did is None:
2431
+ raise ValueError("`my_did` is required for DID wallets")
2432
+ field_names |= {"my_did"}
2433
+ if (
2434
+ self.coin_name is not None
2435
+ and self.coin_list is not None
2436
+ and self.newpuzhash is not None
2437
+ and self.pubkey is not None
2438
+ and self.backup_dids is not None
2439
+ and self.num_verifications_required is not None
2440
+ ):
2441
+ field_names |= {
2442
+ "coin_name",
2443
+ "coin_list",
2444
+ "newpuzhash",
2445
+ "pubkey",
2446
+ "backup_dids",
2447
+ "num_verifications_required",
2448
+ }
2449
+ serialization_updates["coin_list"] = coin_as_list(self.coin_list)
2450
+ elif not (
2451
+ self.coin_name is None
2452
+ and self.coin_list is None
2453
+ and self.newpuzhash is None
2454
+ and self.pubkey is None
2455
+ and self.backup_dids is None
2456
+ and self.num_verifications_required is None
2457
+ ):
2458
+ raise ValueError("Must specify all recovery options or none of them")
2459
+ else:
2460
+ field_names |= tx_endpoint_field_names
2461
+ elif wallet_type == WalletType.POOLING_WALLET:
2462
+ if not (
2463
+ (
2464
+ self.total_fee is None
2465
+ and self.transaction is None
2466
+ and self.launcher_id is None
2467
+ and self.p2_singleton_puzzle_hash is None
2468
+ )
2469
+ or (
2470
+ self.total_fee is not None
2471
+ and self.transaction is not None
2472
+ and self.launcher_id is not None
2473
+ and self.p2_singleton_puzzle_hash is not None
2474
+ )
2475
+ ):
2476
+ raise ValueError("Must specify all pooling options or none of them")
2477
+ else:
2478
+ field_names = { # leaves out wallet_id
2479
+ "type",
2480
+ "total_fee",
2481
+ "transaction",
2482
+ "launcher_id",
2483
+ "p2_singleton_puzzle_hash",
2484
+ }
2485
+ field_names |= tx_endpoint_field_names
2486
+
2487
+ return {**{k: v for k, v in super().to_json_dict().items() if k in field_names}, **serialization_updates}
2488
+
2489
+ @classmethod
2490
+ def from_json_dict(cls, json_dict: dict[str, Any]) -> Self:
2491
+ if "wallet_id" not in json_dict:
2492
+ json_dict["wallet_id"] = uint32(0)
2493
+ if "transactions" not in json_dict:
2494
+ json_dict["transactions"] = []
2495
+ if "unsigned_transactions" not in json_dict:
2496
+ json_dict["unsigned_transactions"] = []
2497
+ if "coin_list" in json_dict:
2498
+ parent_hex, ph_hex, amt = json_dict["coin_list"]
2499
+ json_dict["coin_list"] = Coin(
2500
+ bytes32.from_hexstr(parent_hex), bytes32.from_hexstr(ph_hex), uint64(amt)
2501
+ ).to_json_dict()
2502
+
2503
+ return super().from_json_dict(json_dict)
2504
+
2505
+
2506
+ @streamable
2507
+ @dataclass(frozen=True)
2508
+ class CRCATApprovePending(TransactionEndpointRequest):
2509
+ wallet_id: uint32 = field(default_factory=default_raise)
2510
+ min_amount_to_claim: uint64 = field(default_factory=default_raise)
2511
+
2512
+
2513
+ @streamable
2514
+ @dataclass(frozen=True)
2515
+ class CRCATApprovePendingResponse(TransactionEndpointResponse):
2516
+ pass
2517
+
2518
+
2519
+ @streamable
2520
+ @dataclass(frozen=True)
2521
+ class GetFarmedAmount(Streamable):
2522
+ include_pool_rewards: bool = False
2523
+
2524
+
2525
+ @streamable
2526
+ @dataclass(frozen=True)
2527
+ class GetFarmedAmountResponse(Streamable):
2528
+ farmed_amount: uint64
2529
+ pool_reward_amount: uint64
2530
+ farmer_reward_amount: uint64
2531
+ fee_amount: uint64
2532
+ last_height_farmed: uint32
2533
+ last_time_farmed: uint64
2534
+ blocks_won: uint32