chia-blockchain 2.5.4rc1__py3-none-any.whl → 2.5.5__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 (453) hide show
  1. chia/_tests/blockchain/blockchain_test_utils.py +2 -3
  2. chia/_tests/blockchain/test_augmented_chain.py +2 -3
  3. chia/_tests/blockchain/test_blockchain.py +261 -44
  4. chia/_tests/blockchain/test_blockchain_transactions.py +4 -3
  5. chia/_tests/blockchain/test_build_chains.py +197 -1
  6. chia/_tests/blockchain/test_get_block_generator.py +1 -1
  7. chia/_tests/blockchain/test_lookup_fork_chain.py +1 -1
  8. chia/_tests/clvm/benchmark_costs.py +1 -1
  9. chia/_tests/clvm/coin_store.py +3 -4
  10. chia/_tests/clvm/test_message_conditions.py +2 -2
  11. chia/_tests/clvm/test_puzzle_compression.py +2 -3
  12. chia/_tests/clvm/test_puzzles.py +1 -2
  13. chia/_tests/clvm/test_singletons.py +2 -3
  14. chia/_tests/clvm/test_spend_sim.py +7 -7
  15. chia/_tests/cmds/cmd_test_utils.py +30 -25
  16. chia/_tests/cmds/test_dev_gh.py +1 -1
  17. chia/_tests/cmds/test_farm_cmd.py +1 -1
  18. chia/_tests/cmds/test_show.py +1 -2
  19. chia/_tests/cmds/wallet/test_did.py +101 -56
  20. chia/_tests/cmds/wallet/test_nft.py +109 -84
  21. chia/_tests/cmds/wallet/test_notifications.py +1 -1
  22. chia/_tests/cmds/wallet/test_offer.toffer +1 -1
  23. chia/_tests/cmds/wallet/test_vcs.py +8 -8
  24. chia/_tests/cmds/wallet/test_wallet.py +100 -46
  25. chia/_tests/conftest.py +31 -20
  26. chia/_tests/connection_utils.py +1 -1
  27. chia/_tests/core/consensus/stores/__init__.py +0 -0
  28. chia/_tests/core/consensus/stores/test_coin_store_protocol.py +40 -0
  29. chia/_tests/core/consensus/test_block_creation.py +2 -31
  30. chia/_tests/core/consensus/test_pot_iterations.py +38 -3
  31. chia/_tests/core/custom_types/test_proof_of_space.py +154 -26
  32. chia/_tests/core/custom_types/test_spend_bundle.py +2 -3
  33. chia/_tests/core/daemon/test_daemon.py +80 -0
  34. chia/_tests/core/data_layer/test_data_layer.py +1 -1
  35. chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
  36. chia/_tests/core/data_layer/test_data_rpc.py +14 -10
  37. chia/_tests/core/data_layer/test_data_store.py +5 -5
  38. chia/_tests/core/farmer/test_farmer_api.py +2 -2
  39. chia/_tests/core/full_node/full_sync/test_full_sync.py +446 -406
  40. chia/_tests/core/full_node/ram_db.py +3 -1
  41. chia/_tests/core/full_node/stores/test_block_store.py +28 -16
  42. chia/_tests/core/full_node/stores/test_coin_store.py +277 -185
  43. chia/_tests/core/full_node/stores/test_full_node_store.py +11 -4
  44. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  45. chia/_tests/core/full_node/test_address_manager.py +200 -27
  46. chia/_tests/core/full_node/test_block_height_map.py +2 -2
  47. chia/_tests/core/full_node/test_conditions.py +7 -6
  48. chia/_tests/core/full_node/test_full_node.py +456 -40
  49. chia/_tests/core/full_node/test_generator_tools.py +32 -2
  50. chia/_tests/core/full_node/test_hint_management.py +1 -1
  51. chia/_tests/core/full_node/test_node_load.py +20 -21
  52. chia/_tests/core/full_node/test_performance.py +3 -4
  53. chia/_tests/core/full_node/test_prev_tx_block.py +43 -0
  54. chia/_tests/core/full_node/test_subscriptions.py +1 -2
  55. chia/_tests/core/full_node/test_transactions.py +9 -5
  56. chia/_tests/core/full_node/test_tx_processing_queue.py +1 -2
  57. chia/_tests/core/large_block.py +1 -2
  58. chia/_tests/core/make_block_generator.py +3 -4
  59. chia/_tests/core/mempool/test_mempool.py +36 -86
  60. chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
  61. chia/_tests/core/mempool/test_mempool_item_queries.py +1 -3
  62. chia/_tests/core/mempool/test_mempool_manager.py +529 -69
  63. chia/_tests/core/mempool/test_mempool_performance.py +3 -2
  64. chia/_tests/core/mempool/test_singleton_fast_forward.py +61 -132
  65. chia/_tests/core/server/flood.py +1 -1
  66. chia/_tests/core/server/test_dos.py +1 -1
  67. chia/_tests/core/server/test_node_discovery.py +41 -27
  68. chia/_tests/core/server/test_rate_limits.py +1 -1
  69. chia/_tests/core/server/test_server.py +1 -1
  70. chia/_tests/core/services/test_services.py +5 -5
  71. chia/_tests/core/ssl/test_ssl.py +1 -1
  72. chia/_tests/core/test_cost_calculation.py +6 -6
  73. chia/_tests/core/test_crawler.py +2 -2
  74. chia/_tests/core/test_crawler_rpc.py +1 -1
  75. chia/_tests/core/test_db_conversion.py +3 -1
  76. chia/_tests/core/test_db_validation.py +5 -3
  77. chia/_tests/core/test_farmer_harvester_rpc.py +15 -15
  78. chia/_tests/core/test_filter.py +4 -1
  79. chia/_tests/core/test_full_node_rpc.py +99 -82
  80. chia/_tests/core/test_program.py +2 -2
  81. chia/_tests/core/util/test_block_cache.py +1 -1
  82. chia/_tests/core/util/test_keychain.py +2 -2
  83. chia/_tests/core/util/test_lockfile.py +1 -1
  84. chia/_tests/core/util/test_log_exceptions.py +5 -5
  85. chia/_tests/core/util/test_streamable.py +81 -22
  86. chia/_tests/db/test_db_wrapper.py +1 -3
  87. chia/_tests/environments/wallet.py +5 -5
  88. chia/_tests/farmer_harvester/test_farmer.py +9 -7
  89. chia/_tests/farmer_harvester/test_farmer_harvester.py +11 -4
  90. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
  91. chia/_tests/farmer_harvester/test_third_party_harvesters.py +15 -9
  92. chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -2
  93. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +7 -5
  94. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
  95. chia/_tests/generator/test_compression.py +1 -2
  96. chia/_tests/generator/test_rom.py +8 -4
  97. chia/_tests/plot_sync/test_plot_sync.py +3 -3
  98. chia/_tests/plot_sync/test_receiver.py +3 -3
  99. chia/_tests/plot_sync/test_sender.py +1 -1
  100. chia/_tests/plot_sync/test_sync_simulated.py +3 -3
  101. chia/_tests/plot_sync/util.py +2 -2
  102. chia/_tests/pools/test_pool_cmdline.py +48 -21
  103. chia/_tests/pools/test_pool_puzzles_lifecycle.py +2 -3
  104. chia/_tests/pools/test_pool_rpc.py +237 -105
  105. chia/_tests/pools/test_pool_wallet.py +11 -2
  106. chia/_tests/pools/test_wallet_pool_store.py +5 -4
  107. chia/_tests/rpc/test_rpc_client.py +1 -1
  108. chia/_tests/simulation/test_simulation.py +13 -8
  109. chia/_tests/simulation/test_simulator.py +2 -2
  110. chia/_tests/timelord/test_new_peak.py +191 -47
  111. chia/_tests/timelord/test_timelord.py +1 -1
  112. chia/_tests/tools/test_full_sync.py +0 -2
  113. chia/_tests/tools/test_run_block.py +3 -1
  114. chia/_tests/util/benchmark_cost.py +3 -3
  115. chia/_tests/util/benchmarks.py +2 -2
  116. chia/_tests/util/blockchain.py +11 -5
  117. chia/_tests/util/blockchain_mock.py +1 -4
  118. chia/_tests/util/coin_store.py +29 -0
  119. chia/_tests/util/constants.py +2 -18
  120. chia/_tests/util/full_sync.py +3 -3
  121. chia/_tests/util/generator_tools_testing.py +2 -3
  122. chia/_tests/util/key_tool.py +2 -3
  123. chia/_tests/util/misc.py +33 -31
  124. chia/_tests/util/network_protocol_data.py +19 -17
  125. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  126. chia/_tests/util/protocol_messages_json.py +3 -1
  127. chia/_tests/util/run_block.py +2 -2
  128. chia/_tests/util/setup_nodes.py +7 -7
  129. chia/_tests/util/spend_sim.py +47 -55
  130. chia/_tests/util/test_condition_tools.py +5 -4
  131. chia/_tests/util/test_config.py +2 -2
  132. chia/_tests/util/test_dump_keyring.py +1 -1
  133. chia/_tests/util/test_full_block_utils.py +12 -14
  134. chia/_tests/util/test_misc.py +2 -2
  135. chia/_tests/util/test_paginator.py +4 -4
  136. chia/_tests/util/test_priority_mutex.py +2 -2
  137. chia/_tests/util/test_replace_str_to_bytes.py +15 -5
  138. chia/_tests/util/test_ssl_check.py +1 -1
  139. chia/_tests/util/test_testnet_overrides.py +13 -3
  140. chia/_tests/util/time_out_assert.py +4 -2
  141. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
  142. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -2
  143. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +352 -432
  144. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +3 -6
  145. chia/_tests/wallet/cat_wallet/test_trades.py +53 -77
  146. chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -1
  147. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +3 -3
  148. chia/_tests/wallet/clawback/test_clawback_metadata.py +4 -2
  149. chia/_tests/wallet/conftest.py +11 -12
  150. chia/_tests/wallet/db_wallet/test_db_graftroot.py +11 -4
  151. chia/_tests/wallet/db_wallet/test_dl_offers.py +433 -130
  152. chia/_tests/wallet/db_wallet/test_dl_wallet.py +3 -3
  153. chia/_tests/wallet/did_wallet/test_did.py +2132 -2000
  154. chia/_tests/wallet/nft_wallet/config.py +1 -1
  155. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1610 -742
  156. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +486 -907
  157. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +4 -4
  158. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +517 -294
  159. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +133 -62
  160. chia/_tests/wallet/rpc/test_wallet_rpc.py +495 -265
  161. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +10 -6
  162. chia/_tests/wallet/sync/test_wallet_sync.py +89 -60
  163. chia/_tests/wallet/test_clvm_casts.py +88 -0
  164. chia/_tests/wallet/test_coin_management.py +1 -1
  165. chia/_tests/wallet/test_coin_selection.py +1 -1
  166. chia/_tests/wallet/test_conditions.py +1 -1
  167. chia/_tests/wallet/test_new_wallet_protocol.py +13 -11
  168. chia/_tests/wallet/test_notifications.py +5 -3
  169. chia/_tests/wallet/test_sign_coin_spends.py +6 -6
  170. chia/_tests/wallet/test_signer_protocol.py +13 -12
  171. chia/_tests/wallet/test_singleton.py +1 -1
  172. chia/_tests/wallet/test_singleton_lifecycle_fast.py +5 -7
  173. chia/_tests/wallet/test_util.py +2 -2
  174. chia/_tests/wallet/test_wallet.py +108 -29
  175. chia/_tests/wallet/test_wallet_action_scope.py +9 -2
  176. chia/_tests/wallet/test_wallet_blockchain.py +2 -3
  177. chia/_tests/wallet/test_wallet_key_val_store.py +1 -2
  178. chia/_tests/wallet/test_wallet_node.py +2 -4
  179. chia/_tests/wallet/test_wallet_retry.py +4 -2
  180. chia/_tests/wallet/test_wallet_state_manager.py +191 -5
  181. chia/_tests/wallet/test_wallet_test_framework.py +1 -1
  182. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +8 -8
  183. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -12
  184. chia/_tests/wallet/wallet_block_tools.py +6 -6
  185. chia/_tests/weight_proof/test_weight_proof.py +10 -48
  186. chia/apis.py +1 -1
  187. chia/cmds/beta.py +1 -1
  188. chia/cmds/chia.py +9 -9
  189. chia/cmds/cmd_classes.py +12 -11
  190. chia/cmds/cmd_helpers.py +1 -1
  191. chia/cmds/cmds_util.py +12 -9
  192. chia/cmds/coin_funcs.py +2 -2
  193. chia/cmds/configure.py +2 -2
  194. chia/cmds/data.py +0 -2
  195. chia/cmds/data_funcs.py +1 -1
  196. chia/cmds/db_validate_func.py +1 -2
  197. chia/cmds/dev/__init__.py +0 -0
  198. chia/cmds/dev/data.py +273 -0
  199. chia/cmds/{gh.py → dev/gh.py} +5 -5
  200. chia/cmds/dev/main.py +22 -0
  201. chia/cmds/dev/mempool.py +78 -0
  202. chia/cmds/dev/mempool_funcs.py +63 -0
  203. chia/cmds/farm_funcs.py +5 -4
  204. chia/cmds/init_funcs.py +11 -11
  205. chia/cmds/keys.py +2 -2
  206. chia/cmds/keys_funcs.py +4 -4
  207. chia/cmds/netspace_funcs.py +1 -1
  208. chia/cmds/peer_funcs.py +2 -2
  209. chia/cmds/plotnft_funcs.py +72 -26
  210. chia/cmds/rpc.py +1 -1
  211. chia/cmds/show_funcs.py +5 -5
  212. chia/cmds/signer.py +8 -7
  213. chia/cmds/sim_funcs.py +8 -9
  214. chia/cmds/wallet.py +2 -2
  215. chia/cmds/wallet_funcs.py +165 -131
  216. chia/{util → consensus}/augmented_chain.py +1 -2
  217. chia/consensus/block_body_validation.py +54 -40
  218. chia/consensus/block_creation.py +42 -76
  219. chia/consensus/block_header_validation.py +32 -26
  220. chia/consensus/block_record.py +0 -3
  221. chia/consensus/blockchain.py +23 -32
  222. chia/consensus/blockchain_interface.py +1 -5
  223. chia/consensus/check_time_locks.py +57 -0
  224. chia/consensus/coin_store_protocol.py +151 -0
  225. chia/consensus/coinbase.py +0 -6
  226. chia/consensus/condition_costs.py +4 -0
  227. chia/{util → consensus}/condition_tools.py +4 -5
  228. chia/consensus/cost_calculator.py +1 -1
  229. chia/consensus/default_constants.py +32 -9
  230. chia/consensus/deficit.py +1 -3
  231. chia/consensus/difficulty_adjustment.py +1 -2
  232. chia/consensus/find_fork_point.py +1 -3
  233. chia/consensus/full_block_to_block_record.py +1 -6
  234. chia/{util → consensus}/generator_tools.py +1 -3
  235. chia/consensus/get_block_challenge.py +30 -7
  236. chia/consensus/make_sub_epoch_summary.py +1 -5
  237. chia/consensus/multiprocess_validation.py +21 -20
  238. chia/consensus/pot_iterations.py +74 -13
  239. chia/{util → consensus}/prev_transaction_block.py +1 -1
  240. chia/consensus/vdf_info_computation.py +1 -3
  241. chia/daemon/keychain_proxy.py +5 -5
  242. chia/daemon/server.py +22 -5
  243. chia/data_layer/data_layer.py +92 -51
  244. chia/{rpc → data_layer}/data_layer_rpc_api.py +1 -1
  245. chia/{rpc → data_layer}/data_layer_rpc_util.py +3 -6
  246. chia/data_layer/data_layer_util.py +4 -6
  247. chia/data_layer/data_layer_wallet.py +42 -69
  248. chia/data_layer/dl_wallet_store.py +12 -6
  249. chia/data_layer/download_data.py +3 -3
  250. chia/data_layer/s3_plugin_service.py +0 -1
  251. chia/farmer/farmer.py +3 -4
  252. chia/farmer/farmer_api.py +11 -7
  253. chia/{rpc → farmer}/farmer_rpc_client.py +1 -1
  254. chia/full_node/block_height_map.py +7 -6
  255. chia/full_node/block_store.py +5 -7
  256. chia/full_node/bundle_tools.py +1 -2
  257. chia/full_node/coin_store.py +153 -124
  258. chia/{types → full_node}/eligible_coin_spends.py +39 -70
  259. chia/full_node/fee_estimator.py +1 -1
  260. chia/full_node/fee_estimator_interface.py +0 -8
  261. chia/full_node/fee_tracker.py +25 -25
  262. chia/full_node/full_node.py +70 -53
  263. chia/full_node/full_node_api.py +57 -40
  264. chia/{rpc → full_node}/full_node_rpc_api.py +87 -8
  265. chia/{rpc → full_node}/full_node_rpc_client.py +7 -6
  266. chia/full_node/full_node_store.py +23 -8
  267. chia/full_node/mempool.py +206 -53
  268. chia/full_node/mempool_check_conditions.py +20 -63
  269. chia/full_node/mempool_manager.py +53 -47
  270. chia/full_node/subscriptions.py +1 -3
  271. chia/full_node/tx_processing_queue.py +50 -3
  272. chia/full_node/weight_proof.py +46 -37
  273. chia/harvester/harvester.py +1 -1
  274. chia/harvester/harvester_api.py +22 -7
  275. chia/introducer/introducer.py +1 -1
  276. chia/introducer/introducer_api.py +1 -1
  277. chia/plot_sync/exceptions.py +1 -1
  278. chia/plot_sync/receiver.py +1 -1
  279. chia/plot_sync/sender.py +2 -2
  280. chia/pools/pool_puzzles.py +13 -18
  281. chia/pools/pool_wallet.py +23 -46
  282. chia/protocols/farmer_protocol.py +11 -3
  283. chia/protocols/full_node_protocol.py +1 -4
  284. chia/protocols/harvester_protocol.py +3 -3
  285. chia/protocols/pool_protocol.py +1 -2
  286. chia/protocols/shared_protocol.py +3 -3
  287. chia/protocols/timelord_protocol.py +1 -3
  288. chia/protocols/wallet_protocol.py +3 -3
  289. chia/rpc/rpc_client.py +7 -8
  290. chia/rpc/rpc_server.py +3 -3
  291. chia/rpc/util.py +3 -1
  292. chia/seeder/crawler.py +1 -1
  293. chia/seeder/crawler_api.py +1 -1
  294. chia/seeder/dns_server.py +2 -0
  295. chia/seeder/start_crawler.py +3 -3
  296. chia/server/address_manager.py +286 -38
  297. chia/server/address_manager_store.py +0 -215
  298. chia/{types → server}/aliases.py +7 -7
  299. chia/server/api_protocol.py +1 -1
  300. chia/server/chia_policy.py +1 -1
  301. chia/server/node_discovery.py +76 -113
  302. chia/server/rate_limits.py +1 -1
  303. chia/server/resolve_peer_info.py +43 -0
  304. chia/server/server.py +5 -5
  305. chia/server/start_data_layer.py +4 -4
  306. chia/server/start_farmer.py +5 -4
  307. chia/server/start_full_node.py +5 -4
  308. chia/server/start_harvester.py +7 -5
  309. chia/server/start_introducer.py +2 -2
  310. chia/server/start_service.py +1 -1
  311. chia/server/start_timelord.py +7 -5
  312. chia/server/start_wallet.py +7 -5
  313. chia/server/ws_connection.py +1 -1
  314. chia/simulator/add_blocks_in_batches.py +2 -2
  315. chia/simulator/block_tools.py +245 -201
  316. chia/simulator/full_node_simulator.py +38 -10
  317. chia/simulator/setup_services.py +12 -12
  318. chia/simulator/simulator_full_node_rpc_api.py +2 -2
  319. chia/simulator/simulator_full_node_rpc_client.py +2 -2
  320. chia/simulator/simulator_test_tools.py +2 -2
  321. chia/simulator/start_simulator.py +1 -1
  322. chia/simulator/wallet_tools.py +10 -18
  323. chia/ssl/create_ssl.py +1 -1
  324. chia/timelord/iters_from_block.py +14 -14
  325. chia/timelord/timelord.py +15 -11
  326. chia/timelord/timelord_api.py +14 -2
  327. chia/timelord/timelord_state.py +20 -14
  328. chia/types/blockchain_format/program.py +53 -10
  329. chia/types/blockchain_format/proof_of_space.py +73 -19
  330. chia/types/coin_spend.py +3 -56
  331. chia/types/generator_types.py +28 -0
  332. chia/types/internal_mempool_item.py +1 -2
  333. chia/types/mempool_item.py +12 -7
  334. chia/types/unfinished_header_block.py +1 -2
  335. chia/types/validation_state.py +1 -2
  336. chia/types/weight_proof.py +1 -3
  337. chia/util/action_scope.py +3 -3
  338. chia/util/block_cache.py +1 -2
  339. chia/util/byte_types.py +1 -1
  340. chia/util/casts.py +21 -0
  341. chia/util/config.py +0 -37
  342. chia/util/db_wrapper.py +8 -1
  343. chia/util/errors.py +3 -2
  344. chia/util/initial-config.yaml +21 -5
  345. chia/util/keychain.py +6 -7
  346. chia/util/keyring_wrapper.py +5 -5
  347. chia/util/limited_semaphore.py +1 -1
  348. chia/util/priority_mutex.py +1 -1
  349. chia/util/streamable.py +63 -5
  350. chia/util/task_timing.py +1 -1
  351. chia/util/virtual_project_analysis.py +1 -1
  352. chia/wallet/cat_wallet/cat_info.py +7 -3
  353. chia/wallet/cat_wallet/cat_outer_puzzle.py +9 -5
  354. chia/wallet/cat_wallet/cat_utils.py +1 -1
  355. chia/wallet/cat_wallet/cat_wallet.py +44 -36
  356. chia/wallet/cat_wallet/lineage_store.py +7 -0
  357. chia/wallet/cat_wallet/r_cat_wallet.py +274 -0
  358. chia/wallet/conditions.py +5 -10
  359. chia/wallet/db_wallet/db_wallet_puzzles.py +4 -4
  360. chia/wallet/derivation_record.py +33 -0
  361. chia/wallet/derive_keys.py +3 -3
  362. chia/wallet/did_wallet/did_info.py +12 -3
  363. chia/wallet/did_wallet/did_wallet.py +132 -101
  364. chia/wallet/did_wallet/did_wallet_puzzles.py +9 -9
  365. chia/wallet/driver_protocol.py +3 -1
  366. chia/{types/spend_bundle.py → wallet/estimate_fees.py} +2 -7
  367. chia/wallet/nft_wallet/metadata_outer_puzzle.py +5 -3
  368. chia/wallet/nft_wallet/nft_puzzle_utils.py +1 -1
  369. chia/wallet/nft_wallet/nft_wallet.py +69 -112
  370. chia/wallet/nft_wallet/ownership_outer_puzzle.py +5 -3
  371. chia/wallet/nft_wallet/singleton_outer_puzzle.py +6 -4
  372. chia/wallet/nft_wallet/transfer_program_puzzle.py +4 -2
  373. chia/wallet/nft_wallet/uncurry_nft.py +4 -6
  374. chia/wallet/notification_manager.py +2 -3
  375. chia/wallet/outer_puzzles.py +7 -2
  376. chia/wallet/puzzle_drivers.py +1 -1
  377. chia/wallet/puzzles/clawback/drivers.py +5 -4
  378. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -1
  379. chia/wallet/puzzles/singleton_top_layer.py +2 -1
  380. chia/wallet/puzzles/singleton_top_layer_v1_1.py +2 -1
  381. chia/wallet/puzzles/tails.py +1 -3
  382. chia/wallet/signer_protocol.py +5 -6
  383. chia/wallet/singleton.py +5 -4
  384. chia/wallet/singleton_record.py +1 -1
  385. chia/wallet/trade_manager.py +18 -20
  386. chia/wallet/trade_record.py +3 -6
  387. chia/wallet/trading/offer.py +12 -13
  388. chia/wallet/uncurried_puzzle.py +2 -2
  389. chia/wallet/util/compute_additions.py +58 -0
  390. chia/wallet/util/compute_hints.py +3 -3
  391. chia/wallet/util/compute_memos.py +4 -4
  392. chia/wallet/util/curry_and_treehash.py +2 -1
  393. chia/wallet/util/debug_spend_bundle.py +1 -1
  394. chia/wallet/util/merkle_tree.py +1 -1
  395. chia/wallet/util/peer_request_cache.py +1 -2
  396. chia/wallet/util/tx_config.py +3 -8
  397. chia/wallet/util/wallet_sync_utils.py +10 -5
  398. chia/wallet/util/wallet_types.py +1 -0
  399. chia/wallet/vc_wallet/cr_cat_drivers.py +17 -18
  400. chia/wallet/vc_wallet/cr_cat_wallet.py +30 -28
  401. chia/wallet/vc_wallet/cr_outer_puzzle.py +5 -3
  402. chia/wallet/vc_wallet/vc_drivers.py +50 -8
  403. chia/wallet/vc_wallet/vc_store.py +3 -5
  404. chia/wallet/vc_wallet/vc_wallet.py +15 -22
  405. chia/wallet/wallet.py +36 -46
  406. chia/wallet/wallet_action_scope.py +73 -4
  407. chia/wallet/wallet_blockchain.py +1 -3
  408. chia/wallet/wallet_interested_store.py +1 -1
  409. chia/wallet/wallet_nft_store.py +3 -3
  410. chia/wallet/wallet_node.py +17 -16
  411. chia/wallet/wallet_node_api.py +4 -5
  412. chia/wallet/wallet_pool_store.py +1 -1
  413. chia/wallet/wallet_protocol.py +2 -0
  414. chia/wallet/wallet_puzzle_store.py +1 -1
  415. chia/{rpc → wallet}/wallet_request_types.py +670 -81
  416. chia/{rpc → wallet}/wallet_rpc_api.py +735 -766
  417. chia/{rpc → wallet}/wallet_rpc_client.py +268 -420
  418. chia/wallet/wallet_singleton_store.py +8 -7
  419. chia/wallet/wallet_spend_bundle.py +4 -3
  420. chia/wallet/wallet_state_manager.py +320 -191
  421. chia/wallet/wallet_weight_proof_handler.py +1 -2
  422. chia/wallet/wsm_apis.py +98 -0
  423. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/METADATA +7 -7
  424. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/RECORD +443 -436
  425. mozilla-ca/cacert.pem +3 -165
  426. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +0 -145
  427. chia/cmds/dev.py +0 -18
  428. chia/types/blockchain_format/slots.py +0 -9
  429. chia/types/blockchain_format/sub_epoch_summary.py +0 -5
  430. chia/types/end_of_slot_bundle.py +0 -5
  431. chia/types/full_block.py +0 -5
  432. chia/types/header_block.py +0 -5
  433. chia/types/spend_bundle_conditions.py +0 -7
  434. chia/types/transaction_queue_entry.py +0 -56
  435. chia/types/unfinished_block.py +0 -5
  436. /chia/cmds/{installers.py → dev/installers.py} +0 -0
  437. /chia/cmds/{sim.py → dev/sim.py} +0 -0
  438. /chia/{util → cmds}/dump_keyring.py +0 -0
  439. /chia/{full_node → consensus}/signage_point.py +0 -0
  440. /chia/{rpc → data_layer}/data_layer_rpc_client.py +0 -0
  441. /chia/{rpc → farmer}/farmer_rpc_api.py +0 -0
  442. /chia/{util → full_node}/full_block_utils.py +0 -0
  443. /chia/{rpc → harvester}/harvester_rpc_api.py +0 -0
  444. /chia/{rpc → harvester}/harvester_rpc_client.py +0 -0
  445. /chia/{full_node → protocols}/fee_estimate.py +0 -0
  446. /chia/{server → protocols}/outbound_message.py +0 -0
  447. /chia/{rpc → seeder}/crawler_rpc_api.py +0 -0
  448. /chia/{util → simulator}/vdf_prover.py +0 -0
  449. /chia/{util → ssl}/ssl_check.py +0 -0
  450. /chia/{rpc → timelord}/timelord_rpc_api.py +0 -0
  451. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/LICENSE +0 -0
  452. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/WHEEL +0 -0
  453. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/entry_points.txt +0 -0
@@ -6,18 +6,21 @@ import io
6
6
  import json
7
7
  import logging
8
8
  import random
9
+ from collections.abc import AsyncIterator
9
10
  from operator import attrgetter
10
11
  from typing import Any, Optional, cast
11
12
  from unittest.mock import patch
12
13
 
13
14
  import aiosqlite
14
15
  import pytest
15
- from chia_rs import G1Element, G2Element
16
+ from chia_rs import CoinSpend, G1Element, G2Element
16
17
  from chia_rs.sized_bytes import bytes32
17
- from chia_rs.sized_ints import uint16, uint32, uint64
18
+ from chia_rs.sized_ints import uint16, uint32, uint64, uint128
18
19
 
19
20
  from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework
21
+ from chia._tests.util.setup_nodes import SimulatorsAndWalletsServices
20
22
  from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_not_none
23
+ from chia._tests.wallet.cat_wallet.test_cat_wallet import mint_cat
21
24
  from chia._tests.wallet.test_wallet_coin_store import (
22
25
  get_coin_records_amount_filter_tests,
23
26
  get_coin_records_amount_range_tests,
@@ -47,39 +50,16 @@ from chia._tests.wallet.test_wallet_coin_store import (
47
50
  from chia.cmds.coins import CombineCMD, SplitCMD
48
51
  from chia.cmds.param_types import CliAmount
49
52
  from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
50
- from chia.consensus.coinbase import create_puzzlehash_for_pk
51
- from chia.rpc.full_node_rpc_client import FullNodeRpcClient
53
+ from chia.full_node.full_node_rpc_client import FullNodeRpcClient
52
54
  from chia.rpc.rpc_client import ResponseFailureError
53
- from chia.rpc.rpc_server import RpcServer
54
- from chia.rpc.wallet_request_types import (
55
- AddKey,
56
- CheckDeleteKey,
57
- CombineCoins,
58
- DefaultCAT,
59
- DeleteKey,
60
- DIDGetPubkey,
61
- GetNotifications,
62
- GetPrivateKey,
63
- GetSyncStatusResponse,
64
- GetTimestampForHeight,
65
- LogIn,
66
- PushTransactions,
67
- PushTX,
68
- SetWalletResyncOnStartup,
69
- SplitCoins,
70
- VerifySignature,
71
- VerifySignatureResponse,
72
- )
73
- from chia.rpc.wallet_rpc_api import WalletRpcApi
74
- from chia.rpc.wallet_rpc_client import WalletRpcClient
55
+ from chia.server.aliases import WalletService
75
56
  from chia.server.server import ChiaServer
76
- from chia.server.start_service import Service
77
57
  from chia.simulator.full_node_simulator import FullNodeSimulator
78
58
  from chia.simulator.simulator_protocol import FarmNewBlockProtocol
79
59
  from chia.types.blockchain_format.coin import Coin, coin_as_list
80
60
  from chia.types.blockchain_format.program import Program
81
61
  from chia.types.coin_record import CoinRecord
82
- from chia.types.coin_spend import CoinSpend, make_spend
62
+ from chia.types.coin_spend import make_spend
83
63
  from chia.types.peer_info import PeerInfo
84
64
  from chia.types.signing_mode import SigningMode
85
65
  from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
@@ -90,6 +70,7 @@ from chia.util.streamable import ConversionError, InvalidTypeError
90
70
  from chia.wallet.cat_wallet.cat_constants import DEFAULT_CATS
91
71
  from chia.wallet.cat_wallet.cat_utils import CAT_MOD, construct_cat_puzzle
92
72
  from chia.wallet.cat_wallet.cat_wallet import CATWallet
73
+ from chia.wallet.cat_wallet.r_cat_wallet import RCATWallet
93
74
  from chia.wallet.conditions import (
94
75
  ConditionValidTimes,
95
76
  CreateCoinAnnouncement,
@@ -101,7 +82,10 @@ from chia.wallet.derive_keys import master_sk_to_wallet_sk, master_sk_to_wallet_
101
82
  from chia.wallet.did_wallet.did_wallet import DIDWallet
102
83
  from chia.wallet.nft_wallet.nft_wallet import NFTWallet
103
84
  from chia.wallet.puzzles.clawback.metadata import AutoClaimSettings
85
+ from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_hash_for_pk
104
86
  from chia.wallet.signer_protocol import UnsignedTransaction
87
+ from chia.wallet.trade_record import TradeRecord
88
+ from chia.wallet.trading.offer import Offer
105
89
  from chia.wallet.trading.trade_status import TradeStatus
106
90
  from chia.wallet.transaction_record import TransactionRecord
107
91
  from chia.wallet.transaction_sorting import SortKey
@@ -119,6 +103,44 @@ from chia.wallet.wallet_coin_record import WalletCoinRecord
119
103
  from chia.wallet.wallet_coin_store import GetCoinRecords
120
104
  from chia.wallet.wallet_node import WalletNode
121
105
  from chia.wallet.wallet_protocol import WalletProtocol
106
+ from chia.wallet.wallet_request_types import (
107
+ AddKey,
108
+ CheckDeleteKey,
109
+ CombineCoins,
110
+ DefaultCAT,
111
+ DeleteKey,
112
+ DIDCreateBackupFile,
113
+ DIDGetDID,
114
+ DIDGetMetadata,
115
+ DIDGetPubkey,
116
+ DIDGetRecoveryList,
117
+ DIDGetWalletName,
118
+ DIDMessageSpend,
119
+ DIDSetWalletName,
120
+ DIDTransferDID,
121
+ DIDUpdateMetadata,
122
+ DIDUpdateRecoveryIDs,
123
+ FungibleAsset,
124
+ GetNotifications,
125
+ GetPrivateKey,
126
+ GetSyncStatusResponse,
127
+ GetTimestampForHeight,
128
+ LogIn,
129
+ NFTCalculateRoyalties,
130
+ NFTGetInfo,
131
+ NFTGetNFTs,
132
+ NFTMintNFTRequest,
133
+ NFTTransferNFT,
134
+ PushTransactions,
135
+ PushTX,
136
+ RoyaltyAsset,
137
+ SetWalletResyncOnStartup,
138
+ SplitCoins,
139
+ VerifySignature,
140
+ VerifySignatureResponse,
141
+ )
142
+ from chia.wallet.wallet_rpc_api import WalletRpcApi
143
+ from chia.wallet.wallet_rpc_client import WalletRpcClient
122
144
  from chia.wallet.wallet_spend_bundle import WalletSpendBundle
123
145
 
124
146
  log = logging.getLogger(__name__)
@@ -126,7 +148,7 @@ log = logging.getLogger(__name__)
126
148
 
127
149
  @dataclasses.dataclass
128
150
  class WalletBundle:
129
- service: Service
151
+ service: WalletService
130
152
  node: WalletNode
131
153
  rpc_client: WalletRpcClient
132
154
  wallet: Wallet
@@ -150,29 +172,30 @@ async def check_client_synced(wallet_client: WalletRpcClient) -> bool:
150
172
  return (await wallet_client.get_sync_status()).synced
151
173
 
152
174
 
153
- async def farm_transaction_block(full_node_api: FullNodeSimulator, wallet_node: WalletNode):
175
+ async def farm_transaction_block(full_node_api: FullNodeSimulator, wallet_node: WalletNode) -> None:
154
176
  await full_node_api.farm_blocks_to_puzzlehash(count=1)
155
177
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
156
178
 
157
179
 
158
- def check_mempool_spend_count(full_node_api: FullNodeSimulator, num_of_spends):
180
+ def check_mempool_spend_count(full_node_api: FullNodeSimulator, num_of_spends: int) -> bool:
159
181
  return full_node_api.full_node.mempool_manager.mempool.size() == num_of_spends
160
182
 
161
183
 
162
- async def farm_transaction(full_node_api: FullNodeSimulator, wallet_node: WalletNode, spend_bundle: WalletSpendBundle):
163
- await time_out_assert(
164
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, spend_bundle, spend_bundle.name()
165
- )
184
+ async def farm_transaction(
185
+ full_node_api: FullNodeSimulator, wallet_node: WalletNode, spend_bundle: WalletSpendBundle
186
+ ) -> None:
187
+ spend_bundle_name = spend_bundle.name()
188
+ await time_out_assert(20, full_node_api.full_node.mempool_manager.get_spendbundle, spend_bundle, spend_bundle_name)
166
189
  await farm_transaction_block(full_node_api, wallet_node)
167
- assert full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle.name()) is None
190
+ assert full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle_name) is None
168
191
 
169
192
 
170
- async def generate_funds(full_node_api: FullNodeSimulator, wallet_bundle: WalletBundle, num_blocks: int = 1):
193
+ async def generate_funds(full_node_api: FullNodeSimulator, wallet_bundle: WalletBundle, num_blocks: int = 1) -> int:
171
194
  wallet_id = 1
172
195
  initial_balances = await wallet_bundle.rpc_client.get_wallet_balance(wallet_id)
173
196
  ph: bytes32 = decode_puzzle_hash(await wallet_bundle.rpc_client.get_next_address(wallet_id, True))
174
197
  generated_funds = 0
175
- for i in range(0, num_blocks):
198
+ for _ in range(num_blocks):
176
199
  await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
177
200
  peak_height = full_node_api.full_node.blockchain.get_peak_height()
178
201
  assert peak_height is not None
@@ -191,7 +214,9 @@ async def generate_funds(full_node_api: FullNodeSimulator, wallet_bundle: Wallet
191
214
 
192
215
 
193
216
  @pytest.fixture(scope="function", params=[True, False])
194
- async def wallet_rpc_environment(two_wallet_nodes_services, request, self_hostname):
217
+ async def wallet_rpc_environment(
218
+ two_wallet_nodes_services: SimulatorsAndWalletsServices, request: pytest.FixtureRequest, self_hostname: str
219
+ ) -> AsyncIterator[WalletRpcTestEnvironment]:
195
220
  full_node, wallets, bt = two_wallet_nodes_services
196
221
  full_node_service = full_node[0]
197
222
  full_node_api = full_node_service._api
@@ -216,33 +241,42 @@ async def wallet_rpc_environment(two_wallet_nodes_services, request, self_hostna
216
241
  await wallet_node.server.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
217
242
  await wallet_node_2.server.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
218
243
 
244
+ assert wallet_service.rpc_server is not None
219
245
  async with WalletRpcClient.create_as_context(
220
246
  hostname, wallet_service.rpc_server.listen_port, wallet_service.root_path, wallet_service.config
221
247
  ) as client:
248
+ assert wallet_service_2.rpc_server is not None
222
249
  async with WalletRpcClient.create_as_context(
223
250
  hostname, wallet_service_2.rpc_server.listen_port, wallet_service_2.root_path, wallet_service_2.config
224
251
  ) as client_2:
252
+ assert full_node_service.rpc_server is not None
225
253
  async with FullNodeRpcClient.create_as_context(
226
254
  hostname,
227
255
  full_node_service.rpc_server.listen_port,
228
256
  full_node_service.root_path,
229
257
  full_node_service.config,
230
258
  ) as client_node:
231
- wallet_bundle_1: WalletBundle = WalletBundle(wallet_service, wallet_node, client, wallet)
232
- wallet_bundle_2: WalletBundle = WalletBundle(wallet_service_2, wallet_node_2, client_2, wallet_2)
233
- node_bundle: FullNodeBundle = FullNodeBundle(full_node_server, full_node_api, client_node)
259
+ wallet_bundle_1 = WalletBundle(wallet_service, wallet_node, client, wallet)
260
+ wallet_bundle_2 = WalletBundle(wallet_service_2, wallet_node_2, client_2, wallet_2)
261
+ node_bundle = FullNodeBundle(full_node_server, full_node_api, client_node)
234
262
 
235
263
  yield WalletRpcTestEnvironment(wallet_bundle_1, wallet_bundle_2, node_bundle)
236
264
 
237
265
 
238
266
  async def create_tx_outputs(wallet: Wallet, output_args: list[tuple[int, Optional[list[str]]]]) -> list[dict[str, Any]]:
239
267
  outputs = []
240
- for args in output_args:
241
- output = {"amount": uint64(args[0]), "puzzle_hash": await wallet.get_new_puzzlehash()}
242
- if args[1] is not None:
243
- assert len(args[1]) > 0
244
- output["memos"] = args[1]
245
- outputs.append(output)
268
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
269
+ for args in output_args:
270
+ output = {
271
+ "amount": uint64(args[0]),
272
+ "puzzle_hash": await action_scope.get_puzzle_hash(
273
+ wallet.wallet_state_manager, override_reuse_puzhash_with=False
274
+ ),
275
+ }
276
+ if args[1] is not None:
277
+ assert len(args[1]) > 0
278
+ output["memos"] = args[1]
279
+ outputs.append(output)
246
280
  return outputs
247
281
 
248
282
 
@@ -278,7 +312,7 @@ def assert_tx_amounts(
278
312
  assert (sum(removal_amounts) - sum(addition_amounts)) == amount_fee
279
313
 
280
314
 
281
- async def assert_push_tx_error(node_rpc: FullNodeRpcClient, tx: TransactionRecord):
315
+ async def assert_push_tx_error(node_rpc: FullNodeRpcClient, tx: TransactionRecord) -> None:
282
316
  spend_bundle = tx.spend_bundle
283
317
  assert spend_bundle is not None
284
318
  # check error for a ASSERT_ANNOUNCE_CONSUMED_FAILED and if the error is not there throw a value error
@@ -290,7 +324,7 @@ async def assert_push_tx_error(node_rpc: FullNodeRpcClient, tx: TransactionRecor
290
324
  raise ValueError from error
291
325
 
292
326
 
293
- async def assert_get_balance(rpc_client: WalletRpcClient, wallet_node: WalletNode, wallet: WalletProtocol) -> None:
327
+ async def assert_get_balance(rpc_client: WalletRpcClient, wallet_node: WalletNode, wallet: WalletProtocol[Any]) -> None:
294
328
  expected_balance = await wallet_node.get_balance(wallet.id())
295
329
  expected_balance_dict = expected_balance.to_json_dict()
296
330
  expected_balance_dict["wallet_id"] = wallet.id()
@@ -302,21 +336,25 @@ async def assert_get_balance(rpc_client: WalletRpcClient, wallet_node: WalletNod
302
336
  assert await rpc_client.get_wallet_balance(wallet.id()) == expected_balance_dict
303
337
 
304
338
 
305
- async def tx_in_mempool(client: WalletRpcClient, transaction_id: bytes32):
339
+ async def tx_in_mempool(client: WalletRpcClient, transaction_id: bytes32) -> bool:
306
340
  tx = await client.get_transaction(transaction_id)
307
341
  return tx.is_in_mempool()
308
342
 
309
343
 
310
- async def get_confirmed_balance(client: WalletRpcClient, wallet_id: int):
311
- return (await client.get_wallet_balance(wallet_id))["confirmed_wallet_balance"]
344
+ async def get_confirmed_balance(client: WalletRpcClient, wallet_id: int) -> uint128:
345
+ balance = await client.get_wallet_balance(wallet_id)
346
+ # TODO: casting due to lack of type checked deserialization
347
+ return cast(uint128, balance["confirmed_wallet_balance"])
312
348
 
313
349
 
314
- async def get_unconfirmed_balance(client: WalletRpcClient, wallet_id: int):
315
- return (await client.get_wallet_balance(wallet_id))["unconfirmed_wallet_balance"]
350
+ async def get_unconfirmed_balance(client: WalletRpcClient, wallet_id: int) -> uint128:
351
+ balance = await client.get_wallet_balance(wallet_id)
352
+ # TODO: casting due to lack of type checked deserialization
353
+ return cast(uint128, balance["unconfirmed_wallet_balance"])
316
354
 
317
355
 
318
356
  @pytest.mark.anyio
319
- async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment):
357
+ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
320
358
  env: WalletRpcTestEnvironment = wallet_rpc_environment
321
359
 
322
360
  wallet_2: Wallet = env.wallet_2.wallet
@@ -326,7 +364,8 @@ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment
326
364
 
327
365
  generated_funds = await generate_funds(full_node_api, env.wallet_1)
328
366
 
329
- addr = encode_puzzle_hash(await wallet_2.get_new_puzzlehash(), "txch")
367
+ async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
368
+ addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
330
369
  tx_amount = uint64(15600000)
331
370
  with pytest.raises(ValueError):
332
371
  await client.send_transaction(1, uint64(100000000000000001), addr, DEFAULT_TX_CONFIG)
@@ -396,7 +435,7 @@ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment
396
435
 
397
436
 
398
437
  @pytest.mark.anyio
399
- async def test_push_transactions(wallet_rpc_environment: WalletRpcTestEnvironment):
438
+ async def test_push_transactions(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
400
439
  env: WalletRpcTestEnvironment = wallet_rpc_environment
401
440
 
402
441
  wallet: Wallet = env.wallet_1.wallet
@@ -443,7 +482,7 @@ async def test_push_transactions(wallet_rpc_environment: WalletRpcTestEnvironmen
443
482
 
444
483
 
445
484
  @pytest.mark.anyio
446
- async def test_get_balance(wallet_rpc_environment: WalletRpcTestEnvironment):
485
+ async def test_get_balance(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
447
486
  env = wallet_rpc_environment
448
487
  wallet: Wallet = env.wallet_1.wallet
449
488
  wallet_node: WalletNode = env.wallet_1.node
@@ -465,7 +504,7 @@ async def test_get_balance(wallet_rpc_environment: WalletRpcTestEnvironment):
465
504
 
466
505
 
467
506
  @pytest.mark.anyio
468
- async def test_get_farmed_amount(wallet_rpc_environment: WalletRpcTestEnvironment):
507
+ async def test_get_farmed_amount(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
469
508
  env = wallet_rpc_environment
470
509
  wallet: Wallet = env.wallet_1.wallet
471
510
  full_node_api: FullNodeSimulator = env.full_node.api
@@ -491,7 +530,7 @@ async def test_get_farmed_amount(wallet_rpc_environment: WalletRpcTestEnvironmen
491
530
 
492
531
 
493
532
  @pytest.mark.anyio
494
- async def test_get_farmed_amount_with_fee(wallet_rpc_environment: WalletRpcTestEnvironment):
533
+ async def test_get_farmed_amount_with_fee(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
495
534
  env = wallet_rpc_environment
496
535
  wallet: Wallet = env.wallet_1.wallet
497
536
  full_node_api: FullNodeSimulator = env.full_node.api
@@ -508,8 +547,8 @@ async def test_get_farmed_amount_with_fee(wallet_rpc_environment: WalletRpcTestE
508
547
  action_scope=action_scope,
509
548
  fee=uint64(fee_amount),
510
549
  )
550
+ our_ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
511
551
 
512
- our_ph = await wallet.get_new_puzzlehash()
513
552
  await full_node_api.wait_transaction_records_entered_mempool(records=action_scope.side_effects.transactions)
514
553
  await full_node_api.farm_blocks_to_puzzlehash(count=2, farm_to=our_ph, guarantee_transaction_blocks=True)
515
554
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
@@ -519,7 +558,7 @@ async def test_get_farmed_amount_with_fee(wallet_rpc_environment: WalletRpcTestE
519
558
 
520
559
 
521
560
  @pytest.mark.anyio
522
- async def test_get_timestamp_for_height(wallet_rpc_environment: WalletRpcTestEnvironment):
561
+ async def test_get_timestamp_for_height(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
523
562
  env: WalletRpcTestEnvironment = wallet_rpc_environment
524
563
 
525
564
  full_node_api: FullNodeSimulator = env.full_node.api
@@ -554,7 +593,7 @@ async def test_create_signed_transaction(
554
593
  fee: int,
555
594
  select_coin: bool,
556
595
  is_cat: bool,
557
- ):
596
+ ) -> None:
558
597
  env: WalletRpcTestEnvironment = wallet_rpc_environment
559
598
 
560
599
  wallet_2: Wallet = env.wallet_2.wallet
@@ -574,7 +613,7 @@ async def test_create_signed_transaction(
574
613
  wallet_id = res["wallet_id"]
575
614
 
576
615
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
577
- for i in range(5):
616
+ for _ in range(5):
578
617
  if check_mempool_spend_count(full_node_api, 0):
579
618
  break
580
619
  await farm_transaction_block(full_node_api, wallet_1_node)
@@ -652,7 +691,9 @@ async def test_create_signed_transaction(
652
691
 
653
692
 
654
693
  @pytest.mark.anyio
655
- async def test_create_signed_transaction_with_coin_announcement(wallet_rpc_environment: WalletRpcTestEnvironment):
694
+ async def test_create_signed_transaction_with_coin_announcement(
695
+ wallet_rpc_environment: WalletRpcTestEnvironment,
696
+ ) -> None:
656
697
  env: WalletRpcTestEnvironment = wallet_rpc_environment
657
698
 
658
699
  wallet_2: Wallet = env.wallet_2.wallet
@@ -684,7 +725,9 @@ async def test_create_signed_transaction_with_coin_announcement(wallet_rpc_envir
684
725
 
685
726
 
686
727
  @pytest.mark.anyio
687
- async def test_create_signed_transaction_with_puzzle_announcement(wallet_rpc_environment: WalletRpcTestEnvironment):
728
+ async def test_create_signed_transaction_with_puzzle_announcement(
729
+ wallet_rpc_environment: WalletRpcTestEnvironment,
730
+ ) -> None:
688
731
  env: WalletRpcTestEnvironment = wallet_rpc_environment
689
732
 
690
733
  wallet_2: Wallet = env.wallet_2.wallet
@@ -765,7 +808,7 @@ async def test_create_signed_transaction_with_excluded_coins(wallet_rpc_environm
765
808
 
766
809
 
767
810
  @pytest.mark.anyio
768
- async def test_spend_clawback_coins(wallet_rpc_environment: WalletRpcTestEnvironment):
811
+ async def test_spend_clawback_coins(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
769
812
  env: WalletRpcTestEnvironment = wallet_rpc_environment
770
813
 
771
814
  wallet_1_node: WalletNode = env.wallet_1.node
@@ -779,9 +822,11 @@ async def test_spend_clawback_coins(wallet_rpc_environment: WalletRpcTestEnviron
779
822
 
780
823
  generated_funds = await generate_funds(full_node_api, env.wallet_1, 1)
781
824
  await generate_funds(full_node_api, env.wallet_2, 1)
782
- wallet_1_puzhash = await wallet_1.get_new_puzzlehash()
825
+ async with wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
826
+ wallet_1_puzhash = await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager)
783
827
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_1_node, timeout=20)
784
- wallet_2_puzhash = await wallet_2.get_new_puzzlehash()
828
+ async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
829
+ wallet_2_puzhash = await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)
785
830
  tx = (
786
831
  await wallet_1_rpc.send_transaction(
787
832
  wallet_id=1,
@@ -884,7 +929,7 @@ async def test_spend_clawback_coins(wallet_rpc_environment: WalletRpcTestEnviron
884
929
 
885
930
 
886
931
  @pytest.mark.anyio
887
- async def test_send_transaction_multi(wallet_rpc_environment: WalletRpcTestEnvironment):
932
+ async def test_send_transaction_multi(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
888
933
  env: WalletRpcTestEnvironment = wallet_rpc_environment
889
934
 
890
935
  wallet_2: Wallet = env.wallet_2.wallet
@@ -935,7 +980,7 @@ async def test_send_transaction_multi(wallet_rpc_environment: WalletRpcTestEnvir
935
980
 
936
981
 
937
982
  @pytest.mark.anyio
938
- async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment):
983
+ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
939
984
  env: WalletRpcTestEnvironment = wallet_rpc_environment
940
985
 
941
986
  wallet: Wallet = env.wallet_1.wallet
@@ -960,7 +1005,8 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
960
1005
  assert all_transactions == sorted(all_transactions, key=attrgetter("confirmed_at_height"), reverse=True)
961
1006
 
962
1007
  # Test RELEVANCE
963
- puzhash = await wallet.get_new_puzzlehash()
1008
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1009
+ puzhash = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
964
1010
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
965
1011
  await client.send_transaction(
966
1012
  1, uint64(1), encode_puzzle_hash(puzhash, "txch"), DEFAULT_TX_CONFIG
@@ -979,7 +1025,8 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
979
1025
  assert all_transactions == sorted_transactions
980
1026
 
981
1027
  # Test get_transactions to address
982
- ph_by_addr = await wallet.get_new_puzzlehash()
1028
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1029
+ ph_by_addr = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
983
1030
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
984
1031
  await client.send_transaction(1, uint64(1), encode_puzzle_hash(ph_by_addr, "txch"), DEFAULT_TX_CONFIG)
985
1032
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
@@ -992,7 +1039,7 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
992
1039
  1, type_filter=TransactionTypeFilter.include([TransactionType.COINBASE_REWARD])
993
1040
  )
994
1041
  assert len(all_transactions) == 5
995
- assert all(transaction.type == TransactionType.COINBASE_REWARD for transaction in all_transactions)
1042
+ assert all(transaction.type == TransactionType.COINBASE_REWARD.value for transaction in all_transactions)
996
1043
  # Test confirmed filter
997
1044
  all_transactions = await client.get_transactions(1, confirmed=True)
998
1045
  assert len(all_transactions) == 10
@@ -1012,7 +1059,7 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
1012
1059
 
1013
1060
 
1014
1061
  @pytest.mark.anyio
1015
- async def test_get_transaction_count(wallet_rpc_environment: WalletRpcTestEnvironment):
1062
+ async def test_get_transaction_count(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
1016
1063
  env: WalletRpcTestEnvironment = wallet_rpc_environment
1017
1064
 
1018
1065
  full_node_api: FullNodeSimulator = env.full_node.api
@@ -1032,23 +1079,34 @@ async def test_get_transaction_count(wallet_rpc_environment: WalletRpcTestEnviro
1032
1079
  assert transaction_count == 0
1033
1080
 
1034
1081
 
1082
+ @pytest.mark.parametrize(
1083
+ "wallet_environments",
1084
+ [
1085
+ {
1086
+ "num_environments": 2,
1087
+ "blocks_needed": [1, 1],
1088
+ }
1089
+ ],
1090
+ indirect=True,
1091
+ )
1092
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
1093
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
1035
1094
  @pytest.mark.anyio
1036
- async def test_cat_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1037
- env: WalletRpcTestEnvironment = wallet_rpc_environment
1038
-
1039
- wallet_node: WalletNode = env.wallet_1.node
1040
-
1041
- client: WalletRpcClient = env.wallet_1.rpc_client
1042
- client_2: WalletRpcClient = env.wallet_2.rpc_client
1043
-
1044
- full_node_api: FullNodeSimulator = env.full_node.api
1045
-
1046
- await generate_funds(full_node_api, env.wallet_1, 1)
1047
- await generate_funds(full_node_api, env.wallet_2, 1)
1048
-
1095
+ async def test_cat_endpoints(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
1096
+ env_0 = wallet_environments.environments[0]
1097
+ env_1 = wallet_environments.environments[1]
1098
+ env_0.wallet_aliases = {
1099
+ "xch": 1,
1100
+ "cat0": 2,
1101
+ "cat1": 3,
1102
+ }
1103
+ env_1.wallet_aliases = {
1104
+ "xch": 1,
1105
+ "cat0": 2,
1106
+ }
1049
1107
  # Test a deprecated path
1050
1108
  with pytest.raises(ValueError, match="dropped"):
1051
- await client.fetch(
1109
+ await env_0.rpc_client.fetch(
1052
1110
  "create_new_wallet",
1053
1111
  {
1054
1112
  "wallet_type": "cat_wallet",
@@ -1057,82 +1115,85 @@ async def test_cat_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1057
1115
  )
1058
1116
 
1059
1117
  # Creates a CAT wallet with 100 mojos and a CAT with 20 mojos and fee=10
1060
- await client.create_new_cat_and_wallet(uint64(100), fee=uint64(10), test=True)
1061
- await time_out_assert(20, check_client_synced, True, client)
1118
+ await mint_cat(
1119
+ wallet_environments,
1120
+ env_0,
1121
+ "xch",
1122
+ "cat0",
1123
+ uint64(100),
1124
+ wallet_type,
1125
+ "cat0",
1126
+ )
1127
+ await mint_cat(
1128
+ wallet_environments,
1129
+ env_0,
1130
+ "xch",
1131
+ "cat1",
1132
+ uint64(20),
1133
+ wallet_type,
1134
+ "cat1",
1135
+ )
1062
1136
 
1063
- res = await client.create_new_cat_and_wallet(uint64(20), test=True)
1064
- assert res["success"]
1065
- cat_0_id = res["wallet_id"]
1066
- asset_id = bytes32.fromhex(res["asset_id"])
1067
- assert len(asset_id) > 0
1068
-
1069
- await assert_wallet_types(client, {WalletType.STANDARD_WALLET: 1, WalletType.CAT: 2})
1070
- await assert_wallet_types(client_2, {WalletType.STANDARD_WALLET: 1})
1071
-
1072
- bal_0 = await client.get_wallet_balance(cat_0_id)
1073
- assert bal_0["confirmed_wallet_balance"] == 0
1074
- assert bal_0["pending_coin_removal_count"] == 1
1075
- col = await client.get_cat_asset_id(cat_0_id)
1076
- assert col == asset_id
1077
- assert (await client.get_cat_name(cat_0_id)) == CATWallet.default_wallet_name_for_unknown_cat(asset_id.hex())
1078
- await client.set_cat_name(cat_0_id, "My cat")
1079
- assert (await client.get_cat_name(cat_0_id)) == "My cat"
1080
- result = await client.cat_asset_id_to_name(col)
1137
+ cat_0_id = env_0.wallet_aliases["cat0"]
1138
+ # The RPC response contains more than just the balance info but all the
1139
+ # balance info should match. We're leveraging the `<=` operator to check
1140
+ # for subset on `dict` `.items()`.
1141
+ assert (
1142
+ env_0.wallet_states[uint32(env_0.wallet_aliases["cat0"])].balance.to_json_dict().items()
1143
+ <= (await env_0.rpc_client.get_wallet_balance(cat_0_id)).items()
1144
+ )
1145
+ asset_id = await env_0.rpc_client.get_cat_asset_id(cat_0_id)
1146
+ assert (await env_0.rpc_client.get_cat_name(cat_0_id)) == wallet_type.default_wallet_name_for_unknown_cat(
1147
+ asset_id.hex()
1148
+ )
1149
+ await env_0.rpc_client.set_cat_name(cat_0_id, "My cat")
1150
+ assert (await env_0.rpc_client.get_cat_name(cat_0_id)) == "My cat"
1151
+ result = await env_0.rpc_client.cat_asset_id_to_name(asset_id)
1081
1152
  assert result is not None
1082
1153
  wid, name = result
1083
1154
  assert wid == cat_0_id
1084
1155
  assert name == "My cat"
1085
- result = await client.cat_asset_id_to_name(bytes32.zeros)
1156
+ result = await env_0.rpc_client.cat_asset_id_to_name(bytes32.zeros)
1086
1157
  assert result is None
1087
1158
  verified_asset_id = next(iter(DEFAULT_CATS.items()))[1]["asset_id"]
1088
- result = await client.cat_asset_id_to_name(bytes32.from_hexstr(verified_asset_id))
1159
+ result = await env_0.rpc_client.cat_asset_id_to_name(bytes32.from_hexstr(verified_asset_id))
1089
1160
  assert result is not None
1090
1161
  should_be_none, name = result
1091
1162
  assert should_be_none is None
1092
1163
  assert name == next(iter(DEFAULT_CATS.items()))[1]["name"]
1093
1164
 
1094
- # make sure spend is in mempool before farming tx block
1095
- await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 2)
1096
- for i in range(5):
1097
- if check_mempool_spend_count(full_node_api, 0):
1098
- break
1099
- await farm_transaction_block(full_node_api, wallet_node)
1100
-
1101
- # check that we farmed the transaction
1102
- assert check_mempool_spend_count(full_node_api, 0)
1103
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=5)
1104
-
1105
- await time_out_assert(5, get_confirmed_balance, 20, client, cat_0_id)
1106
- bal_0 = await client.get_wallet_balance(cat_0_id)
1107
- assert bal_0["pending_coin_removal_count"] == 0
1108
- assert bal_0["unspent_coin_count"] == 1
1109
-
1110
1165
  # Creates a second wallet with the same CAT
1111
- res = await client_2.create_wallet_for_existing_cat(asset_id)
1166
+ res = await env_1.rpc_client.create_wallet_for_existing_cat(asset_id)
1112
1167
  assert res["success"]
1113
1168
  cat_1_id = res["wallet_id"]
1114
1169
  cat_1_asset_id = bytes.fromhex(res["asset_id"])
1115
1170
  assert cat_1_asset_id == asset_id
1116
1171
 
1117
- await assert_wallet_types(client, {WalletType.STANDARD_WALLET: 1, WalletType.CAT: 2})
1118
- await assert_wallet_types(client_2, {WalletType.STANDARD_WALLET: 1, WalletType.CAT: 1})
1119
-
1120
- await farm_transaction_block(full_node_api, wallet_node)
1121
-
1122
- bal_1 = await client_2.get_wallet_balance(cat_1_id)
1123
- assert bal_1["confirmed_wallet_balance"] == 0
1172
+ await wallet_environments.process_pending_states(
1173
+ [
1174
+ WalletStateTransition(),
1175
+ WalletStateTransition(
1176
+ pre_block_balance_updates={
1177
+ "cat0": {
1178
+ "init": True,
1179
+ }
1180
+ },
1181
+ post_block_balance_updates={},
1182
+ ),
1183
+ ]
1184
+ )
1124
1185
 
1125
- addr_0 = await client.get_next_address(cat_0_id, False)
1126
- addr_1 = await client_2.get_next_address(cat_1_id, False)
1186
+ addr_0 = await env_0.rpc_client.get_next_address(cat_0_id, False)
1187
+ addr_1 = await env_1.rpc_client.get_next_address(cat_1_id, False)
1127
1188
 
1128
1189
  assert addr_0 != addr_1
1129
1190
 
1130
1191
  # Test CAT spend without a fee
1131
1192
  with pytest.raises(ValueError):
1132
- await client.cat_spend(
1193
+ await env_0.rpc_client.cat_spend(
1133
1194
  cat_0_id,
1134
1195
  DEFAULT_TX_CONFIG.override(
1135
- excluded_coin_amounts=[uint64(20)],
1196
+ excluded_coin_amounts=[uint64(100)],
1136
1197
  excluded_coin_ids=[bytes32.zeros],
1137
1198
  ),
1138
1199
  uint64(4),
@@ -1140,53 +1201,146 @@ async def test_cat_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1140
1201
  uint64(0),
1141
1202
  ["the cat memo"],
1142
1203
  )
1143
- tx_res = await client.cat_spend(cat_0_id, DEFAULT_TX_CONFIG, uint64(4), addr_1, uint64(0), ["the cat memo"])
1204
+ tx_res = await env_0.rpc_client.cat_spend(
1205
+ cat_0_id, wallet_environments.tx_config, uint64(4), addr_1, uint64(0), ["the cat memo"]
1206
+ )
1144
1207
 
1145
1208
  spend_bundle = tx_res.transaction.spend_bundle
1146
1209
  assert spend_bundle is not None
1147
1210
  assert uncurry_puzzle(spend_bundle.coin_spends[0].puzzle_reveal).mod == CAT_MOD
1148
- await farm_transaction(full_node_api, wallet_node, spend_bundle)
1149
1211
 
1150
- await farm_transaction_block(full_node_api, wallet_node)
1212
+ await wallet_environments.process_pending_states(
1213
+ [
1214
+ WalletStateTransition(
1215
+ pre_block_balance_updates={
1216
+ "cat0": {
1217
+ "unconfirmed_wallet_balance": -4,
1218
+ "spendable_balance": -100,
1219
+ "max_send_amount": -100,
1220
+ "pending_change": 96,
1221
+ "pending_coin_removal_count": 1,
1222
+ }
1223
+ },
1224
+ post_block_balance_updates={
1225
+ "cat0": {
1226
+ "confirmed_wallet_balance": -4,
1227
+ "spendable_balance": 96,
1228
+ "max_send_amount": 96,
1229
+ "pending_change": -96,
1230
+ "pending_coin_removal_count": -1,
1231
+ }
1232
+ },
1233
+ ),
1234
+ WalletStateTransition(
1235
+ pre_block_balance_updates={},
1236
+ post_block_balance_updates={
1237
+ "cat0": {
1238
+ "confirmed_wallet_balance": 4,
1239
+ "unconfirmed_wallet_balance": 4,
1240
+ "spendable_balance": 4,
1241
+ "max_send_amount": 4,
1242
+ "unspent_coin_count": 1,
1243
+ }
1244
+ },
1245
+ ),
1246
+ ]
1247
+ )
1151
1248
 
1152
1249
  # Test CAT spend with a fee
1153
- tx_res = await client.cat_spend(cat_0_id, DEFAULT_TX_CONFIG, uint64(1), addr_1, uint64(5_000_000), ["the cat memo"])
1250
+ tx_res = await env_0.rpc_client.cat_spend(
1251
+ cat_0_id, wallet_environments.tx_config, uint64(1), addr_1, uint64(5_000_000), ["the cat memo"]
1252
+ )
1154
1253
 
1155
1254
  spend_bundle = tx_res.transaction.spend_bundle
1156
1255
  assert spend_bundle is not None
1157
- await farm_transaction(full_node_api, wallet_node, spend_bundle)
1256
+
1257
+ cat_spend_changes = [
1258
+ WalletStateTransition(
1259
+ pre_block_balance_updates={
1260
+ "xch": {
1261
+ "unconfirmed_wallet_balance": -5_000_000,
1262
+ "<=#spendable_balance": -5_000_000,
1263
+ "<=#max_send_amount": -5_000_000,
1264
+ ">=#pending_change": 1, # any amount increase
1265
+ "unspent_coin_count": 0,
1266
+ "pending_coin_removal_count": 1,
1267
+ },
1268
+ "cat0": {
1269
+ "unconfirmed_wallet_balance": -1,
1270
+ "<=#spendable_balance": -1,
1271
+ "<=#max_send_amount": -1,
1272
+ ">=#pending_change": 1,
1273
+ "pending_coin_removal_count": 1,
1274
+ },
1275
+ },
1276
+ post_block_balance_updates={
1277
+ "xch": {
1278
+ "confirmed_wallet_balance": -5_000_000,
1279
+ ">=#spendable_balance": 1, # any amount increase
1280
+ ">=#max_send_amount": 1, # any amount increase
1281
+ "<=#pending_change": -1, # any amount decrease
1282
+ "unspent_coin_count": 0,
1283
+ "pending_coin_removal_count": -1,
1284
+ },
1285
+ "cat0": {
1286
+ "confirmed_wallet_balance": -1,
1287
+ ">=#spendable_balance": 1, # any amount increase
1288
+ ">=#max_send_amount": 1, # any amount increase
1289
+ "<=#pending_change": -1, # any amount decrease
1290
+ "pending_coin_removal_count": -1,
1291
+ },
1292
+ },
1293
+ ),
1294
+ WalletStateTransition(
1295
+ pre_block_balance_updates={},
1296
+ post_block_balance_updates={
1297
+ "cat0": {
1298
+ "confirmed_wallet_balance": 1,
1299
+ "unconfirmed_wallet_balance": 1,
1300
+ "spendable_balance": 1,
1301
+ "max_send_amount": 1,
1302
+ "unspent_coin_count": 1,
1303
+ },
1304
+ },
1305
+ ),
1306
+ ]
1307
+ await wallet_environments.process_pending_states(cat_spend_changes)
1158
1308
 
1159
1309
  # Test CAT spend with a fee and pre-specified removals / coins
1160
- removals = await client.select_coins(
1161
- amount=uint64(2), wallet_id=cat_0_id, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG
1310
+ removals = await env_0.rpc_client.select_coins(
1311
+ amount=uint64(2), wallet_id=cat_0_id, coin_selection_config=wallet_environments.tx_config.coin_selection_config
1162
1312
  )
1163
- tx_res = await client.cat_spend(
1164
- cat_0_id, DEFAULT_TX_CONFIG, uint64(1), addr_1, uint64(5_000_000), ["the cat memo"], removals=removals
1313
+ tx_res = await env_0.rpc_client.cat_spend(
1314
+ cat_0_id,
1315
+ wallet_environments.tx_config,
1316
+ uint64(1),
1317
+ addr_1,
1318
+ uint64(5_000_000),
1319
+ ["the cat memo"],
1320
+ removals=removals,
1165
1321
  )
1166
1322
 
1167
1323
  spend_bundle = tx_res.transaction.spend_bundle
1168
1324
  assert spend_bundle is not None
1169
1325
  assert removals[0] in {removal for tx in tx_res.transactions for removal in tx.removals}
1170
- await farm_transaction(full_node_api, wallet_node, spend_bundle)
1326
+
1327
+ await wallet_environments.process_pending_states(cat_spend_changes)
1171
1328
 
1172
1329
  # Test unacknowledged CAT
1173
- await wallet_node.wallet_state_manager.interested_store.add_unacknowledged_token(
1330
+ await env_0.wallet_state_manager.interested_store.add_unacknowledged_token(
1174
1331
  asset_id, "Unknown", uint32(10000), bytes32(b"\00" * 32)
1175
1332
  )
1176
- cats = await client.get_stray_cats()
1333
+ cats = await env_0.rpc_client.get_stray_cats()
1177
1334
  assert len(cats) == 1
1178
1335
 
1179
- await time_out_assert(20, get_confirmed_balance, 14, client, cat_0_id)
1180
- await time_out_assert(20, get_confirmed_balance, 6, client_2, cat_1_id)
1181
-
1182
1336
  # Test CAT coin selection
1183
- selected_coins = await client.select_coins(
1184
- amount=1, wallet_id=cat_0_id, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG
1337
+ selected_coins = await env_0.rpc_client.select_coins(
1338
+ amount=1, wallet_id=cat_0_id, coin_selection_config=wallet_environments.tx_config.coin_selection_config
1185
1339
  )
1186
1340
  assert len(selected_coins) > 0
1187
1341
 
1188
1342
  # Test get_cat_list
1189
- cat_list = (await client.get_cat_list()).cat_list
1343
+ cat_list = (await env_0.rpc_client.get_cat_list()).cat_list
1190
1344
  assert len(DEFAULT_CATS) == len(cat_list)
1191
1345
  default_cats_set = {
1192
1346
  DefaultCAT(asset_id=bytes32.from_hexstr(cat["asset_id"]), name=cat["name"], symbol=cat["symbol"])
@@ -1196,7 +1350,7 @@ async def test_cat_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1196
1350
 
1197
1351
 
1198
1352
  @pytest.mark.anyio
1199
- async def test_offer_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1353
+ async def test_offer_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
1200
1354
  env: WalletRpcTestEnvironment = wallet_rpc_environment
1201
1355
 
1202
1356
  wallet_node: WalletNode = env.wallet_1.node
@@ -1315,14 +1469,14 @@ async def test_offer_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment)
1315
1469
 
1316
1470
  await farm_transaction_block(full_node_api, wallet_node)
1317
1471
 
1318
- async def is_trade_confirmed(client, trade) -> bool:
1319
- trade_record = await client.get_offer(trade.name())
1472
+ async def is_trade_confirmed(client: WalletRpcClient, offer: Offer) -> bool:
1473
+ trade_record = await client.get_offer(offer.name())
1320
1474
  return TradeStatus(trade_record.status) == TradeStatus.CONFIRMED
1321
1475
 
1322
1476
  await time_out_assert(15, is_trade_confirmed, True, wallet_1_rpc, offer)
1323
1477
 
1324
1478
  # Test trade sorting
1325
- def only_ids(trades):
1479
+ def only_ids(trades: list[TradeRecord]) -> list[bytes32]:
1326
1480
  return [t.trade_id for t in trades]
1327
1481
 
1328
1482
  trade_record = await wallet_1_rpc.get_offer(offer.name())
@@ -1403,7 +1557,10 @@ async def test_get_coin_records_by_names(wallet_rpc_environment: WalletRpcTestEn
1403
1557
  full_node_api = env.full_node.api
1404
1558
  # Generate some funds
1405
1559
  generated_funds = await generate_funds(full_node_api, env.wallet_1, 5)
1406
- address = encode_puzzle_hash(await env.wallet_1.wallet.get_new_puzzlehash(), "txch")
1560
+ async with env.wallet_1.wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1561
+ address = encode_puzzle_hash(
1562
+ await action_scope.get_puzzle_hash(env.wallet_1.wallet.wallet_state_manager), "txch"
1563
+ )
1407
1564
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
1408
1565
 
1409
1566
  # Spend half of it back to the same wallet get some spent coins in the wallet
@@ -1448,7 +1605,7 @@ async def test_get_coin_records_by_names(wallet_rpc_environment: WalletRpcTestEn
1448
1605
 
1449
1606
 
1450
1607
  @pytest.mark.anyio
1451
- async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1608
+ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
1452
1609
  env: WalletRpcTestEnvironment = wallet_rpc_environment
1453
1610
 
1454
1611
  wallet_1: Wallet = env.wallet_1.wallet
@@ -1469,57 +1626,67 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1469
1626
  did_id_0 = res["my_did"]
1470
1627
 
1471
1628
  # Get wallet name
1472
- res = await wallet_1_rpc.did_get_wallet_name(did_wallet_id_0)
1473
- assert res["success"]
1474
- assert res["name"] == "Profile 1"
1475
- nft_wallet: WalletProtocol = wallet_1_node.wallet_state_manager.wallets[did_wallet_id_0 + 1]
1629
+ get_name_res = await wallet_1_rpc.did_get_wallet_name(DIDGetWalletName(did_wallet_id_0))
1630
+ assert get_name_res.name == "Profile 1"
1631
+ nft_wallet = wallet_1_node.wallet_state_manager.wallets[did_wallet_id_0 + 1]
1476
1632
  assert isinstance(nft_wallet, NFTWallet)
1477
1633
  assert nft_wallet.get_name() == "Profile 1 NFT Wallet"
1478
1634
 
1479
1635
  # Set wallet name
1480
1636
  new_wallet_name = "test name"
1481
- res = await wallet_1_rpc.did_set_wallet_name(did_wallet_id_0, new_wallet_name)
1482
- assert res["success"]
1483
- res = await wallet_1_rpc.did_get_wallet_name(did_wallet_id_0)
1484
- assert res["success"]
1485
- assert res["name"] == new_wallet_name
1637
+ await wallet_1_rpc.did_set_wallet_name(DIDSetWalletName(did_wallet_id_0, new_wallet_name))
1638
+ get_name_res = await wallet_1_rpc.did_get_wallet_name(DIDGetWalletName(did_wallet_id_0))
1639
+ assert get_name_res.name == new_wallet_name
1486
1640
  with pytest.raises(ValueError, match="wallet id 1 is of type Wallet but type DIDWallet is required"):
1487
- await wallet_1_rpc.did_set_wallet_name(wallet_1_id, new_wallet_name)
1641
+ await wallet_1_rpc.did_set_wallet_name(DIDSetWalletName(wallet_1_id, new_wallet_name))
1488
1642
 
1489
1643
  # Check DID ID
1490
- res = await wallet_1_rpc.get_did_id(did_wallet_id_0)
1491
- assert res["success"]
1492
- assert did_id_0 == res["my_did"]
1644
+ did_id_res = await wallet_1_rpc.get_did_id(DIDGetDID(did_wallet_id_0))
1645
+ assert did_id_0 == did_id_res.my_did
1493
1646
  # Create backup file
1494
- res = await wallet_1_rpc.create_did_backup_file(did_wallet_id_0, "backup.did")
1495
- assert res["success"]
1647
+ await wallet_1_rpc.create_did_backup_file(DIDCreateBackupFile(did_wallet_id_0))
1496
1648
 
1497
1649
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
1498
1650
  await farm_transaction_block(full_node_api, wallet_1_node)
1499
1651
  # Update recovery list
1500
- update_res = await wallet_1_rpc.update_did_recovery_list(did_wallet_id_0, [did_id_0], 1, DEFAULT_TX_CONFIG)
1652
+ update_res = await wallet_1_rpc.update_did_recovery_list(
1653
+ DIDUpdateRecoveryIDs(
1654
+ wallet_id=uint32(did_wallet_id_0), new_list=[did_id_0], num_verifications_required=uint64(1), push=True
1655
+ ),
1656
+ DEFAULT_TX_CONFIG,
1657
+ )
1501
1658
  assert len(update_res.transactions) > 0
1502
- res = await wallet_1_rpc.get_did_recovery_list(did_wallet_id_0)
1503
- assert res["num_required"] == 1
1504
- assert res["recovery_list"][0] == did_id_0
1659
+ recovery_list_res = await wallet_1_rpc.get_did_recovery_list(DIDGetRecoveryList(did_wallet_id_0))
1660
+ assert recovery_list_res.num_required == 1
1661
+ assert recovery_list_res.recovery_list[0] == did_id_0
1505
1662
 
1506
1663
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
1507
1664
  await farm_transaction_block(full_node_api, wallet_1_node)
1508
1665
 
1509
1666
  # Update metadata
1510
1667
  with pytest.raises(ValueError, match="wallet id 1 is of type Wallet but type DIDWallet is required"):
1511
- await wallet_1_rpc.update_did_metadata(wallet_1_id, {"Twitter": "Https://test"}, DEFAULT_TX_CONFIG)
1512
- await wallet_1_rpc.update_did_metadata(did_wallet_id_0, {"Twitter": "Https://test"}, DEFAULT_TX_CONFIG)
1668
+ await wallet_1_rpc.update_did_metadata(
1669
+ DIDUpdateMetadata(wallet_id=wallet_1_id, metadata={"Twitter": "Https://test"}, push=True), DEFAULT_TX_CONFIG
1670
+ )
1671
+ await wallet_1_rpc.update_did_metadata(
1672
+ DIDUpdateMetadata(wallet_id=did_wallet_id_0, metadata={"Twitter": "Https://test"}, push=True), DEFAULT_TX_CONFIG
1673
+ )
1513
1674
 
1514
- res = await wallet_1_rpc.get_did_metadata(did_wallet_id_0)
1515
- assert res["metadata"]["Twitter"] == "Https://test"
1675
+ get_metadata_res = await wallet_1_rpc.get_did_metadata(DIDGetMetadata(did_wallet_id_0))
1676
+ assert get_metadata_res.metadata["Twitter"] == "Https://test"
1516
1677
 
1517
1678
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
1518
1679
  await farm_transaction_block(full_node_api, wallet_1_node)
1519
1680
 
1520
1681
  # Transfer DID
1521
- addr = encode_puzzle_hash(await wallet_2.get_new_puzzlehash(), "txch")
1522
- await wallet_1_rpc.did_transfer_did(did_wallet_id_0, addr, 0, True, DEFAULT_TX_CONFIG)
1682
+ async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1683
+ addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
1684
+ await wallet_1_rpc.did_transfer_did(
1685
+ DIDTransferDID(
1686
+ wallet_id=did_wallet_id_0, inner_address=addr, fee=uint64(0), with_recovery_info=True, push=True
1687
+ ),
1688
+ DEFAULT_TX_CONFIG,
1689
+ )
1523
1690
 
1524
1691
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
1525
1692
  await farm_transaction_block(full_node_api, wallet_1_node)
@@ -1531,11 +1698,11 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1531
1698
 
1532
1699
  did_wallets = list(
1533
1700
  filter(
1534
- lambda w: (w.type == WalletType.DECENTRALIZED_ID),
1701
+ lambda w: (w.type == WalletType.DECENTRALIZED_ID.value),
1535
1702
  await wallet_2_node.wallet_state_manager.get_all_wallet_info_entries(),
1536
1703
  )
1537
1704
  )
1538
- did_wallet_2: WalletProtocol = wallet_2_node.wallet_state_manager.wallets[did_wallets[0].id]
1705
+ did_wallet_2 = wallet_2_node.wallet_state_manager.wallets[did_wallets[0].id]
1539
1706
  assert isinstance(did_wallet_2, DIDWallet)
1540
1707
  assert (
1541
1708
  encode_puzzle_hash(bytes32.from_hexstr(did_wallet_2.get_my_DID()), AddressType.DID.hrp(wallet_2_node.config))
@@ -1545,7 +1712,7 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1545
1712
  assert metadata["Twitter"] == "Https://test"
1546
1713
 
1547
1714
  last_did_coin = await did_wallet_2.get_coin()
1548
- await wallet_2_rpc.did_message_spend(did_wallet_2.id(), DEFAULT_TX_CONFIG, push=True)
1715
+ await wallet_2_rpc.did_message_spend(DIDMessageSpend(wallet_id=did_wallet_2.id(), push=True), DEFAULT_TX_CONFIG)
1549
1716
  await wallet_2_node.wallet_state_manager.add_interested_coin_ids([last_did_coin.name()])
1550
1717
 
1551
1718
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
@@ -1555,7 +1722,9 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1555
1722
  assert next_did_coin.parent_coin_info == last_did_coin.name()
1556
1723
  last_did_coin = next_did_coin
1557
1724
 
1558
- await wallet_2_rpc.did_message_spend(did_wallet_2.id(), DEFAULT_TX_CONFIG.override(reuse_puzhash=True), push=True)
1725
+ await wallet_2_rpc.did_message_spend(
1726
+ DIDMessageSpend(wallet_id=did_wallet_2.id(), push=True), DEFAULT_TX_CONFIG.override(reuse_puzhash=True)
1727
+ )
1559
1728
  await wallet_2_node.wallet_state_manager.add_interested_coin_ids([last_did_coin.name()])
1560
1729
 
1561
1730
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
@@ -1571,7 +1740,7 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1571
1740
 
1572
1741
 
1573
1742
  @pytest.mark.anyio
1574
- async def test_nft_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1743
+ async def test_nft_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
1575
1744
  env: WalletRpcTestEnvironment = wallet_rpc_environment
1576
1745
  wallet_1_node: WalletNode = env.wallet_1.node
1577
1746
  wallet_1_rpc: WalletRpcClient = env.wallet_1.rpc_client
@@ -1585,12 +1754,15 @@ async def test_nft_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1585
1754
  res = await wallet_1_rpc.create_new_nft_wallet(None)
1586
1755
  nft_wallet_id = res["wallet_id"]
1587
1756
  mint_res = await wallet_1_rpc.mint_nft(
1588
- nft_wallet_id,
1589
- None,
1590
- None,
1591
- "0xD4584AD463139FA8C0D9F68F4B59F185",
1592
- ["https://www.chia.net/img/branding/chia-logo.svg"],
1593
- DEFAULT_TX_CONFIG,
1757
+ request=NFTMintNFTRequest(
1758
+ wallet_id=nft_wallet_id,
1759
+ royalty_address=None,
1760
+ target_address=None,
1761
+ hash=bytes32.from_hexstr("0xD4584AD463139FA8C0D9F68F4B59F185D4584AD463139FA8C0D9F68F4B59F185"),
1762
+ uris=["https://www.chia.net/img/branding/chia-logo.svg"],
1763
+ push=True,
1764
+ ),
1765
+ tx_config=DEFAULT_TX_CONFIG,
1594
1766
  )
1595
1767
 
1596
1768
  spend_bundle = mint_res.spend_bundle
@@ -1599,27 +1771,32 @@ async def test_nft_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1599
1771
 
1600
1772
  await full_node_api.wait_for_wallet_synced(wallet_node=wallet_1_node, timeout=15)
1601
1773
 
1602
- nft_wallet: WalletProtocol = wallet_1_node.wallet_state_manager.wallets[nft_wallet_id]
1774
+ nft_wallet = wallet_1_node.wallet_state_manager.wallets[nft_wallet_id]
1603
1775
  assert isinstance(nft_wallet, NFTWallet)
1604
1776
 
1605
- async def have_nfts():
1777
+ async def have_nfts() -> bool:
1606
1778
  return await nft_wallet.get_nft_count() > 0
1607
1779
 
1608
1780
  await time_out_assert(15, have_nfts, True)
1609
1781
 
1610
1782
  # Test with the hex version of nft_id
1611
1783
  nft_id = (await nft_wallet.get_current_nfts())[0].coin.name().hex()
1612
- nft_info = (await wallet_1_rpc.get_nft_info(nft_id))["nft_info"]
1613
- assert nft_info["nft_coin_id"][2:] == (await nft_wallet.get_current_nfts())[0].coin.name().hex()
1784
+ with pytest.raises(ResponseFailureError, match="Invalid Coin ID format for 'coin_id'"):
1785
+ await wallet_1_rpc.get_nft_info(NFTGetInfo("error"))
1786
+ nft_info = (await wallet_1_rpc.get_nft_info(NFTGetInfo(nft_id))).nft_info
1787
+ assert nft_info.nft_coin_id == (await nft_wallet.get_current_nfts())[0].coin.name()
1614
1788
  # Test with the bech32m version of nft_id
1615
1789
  hmr_nft_id = encode_puzzle_hash(
1616
1790
  (await nft_wallet.get_current_nfts())[0].coin.name(), AddressType.NFT.hrp(wallet_1_node.config)
1617
1791
  )
1618
- nft_info = (await wallet_1_rpc.get_nft_info(hmr_nft_id))["nft_info"]
1619
- assert nft_info["nft_coin_id"][2:] == (await nft_wallet.get_current_nfts())[0].coin.name().hex()
1792
+ nft_info = (await wallet_1_rpc.get_nft_info(NFTGetInfo(hmr_nft_id))).nft_info
1793
+ assert nft_info.nft_coin_id == (await nft_wallet.get_current_nfts())[0].coin.name()
1620
1794
 
1621
- addr = encode_puzzle_hash(await wallet_2.get_new_puzzlehash(), "txch")
1622
- await wallet_1_rpc.transfer_nft(nft_wallet_id, nft_id, addr, 0, DEFAULT_TX_CONFIG)
1795
+ async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1796
+ addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
1797
+ await wallet_1_rpc.transfer_nft(
1798
+ NFTTransferNFT(wallet_id=nft_wallet_id, nft_coin_id=nft_id, target_address=addr, push=True), DEFAULT_TX_CONFIG
1799
+ )
1623
1800
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
1624
1801
  await farm_transaction_block(full_node_api, wallet_1_node)
1625
1802
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 0)
@@ -1630,26 +1807,71 @@ async def test_nft_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1630
1807
  nft_wallet_id_1 = (
1631
1808
  await wallet_2_node.wallet_state_manager.get_all_wallet_info_entries(wallet_type=WalletType.NFT)
1632
1809
  )[0].id
1633
- nft_wallet_1: WalletProtocol = wallet_2_node.wallet_state_manager.wallets[nft_wallet_id_1]
1810
+ nft_wallet_1 = wallet_2_node.wallet_state_manager.wallets[nft_wallet_id_1]
1634
1811
  assert isinstance(nft_wallet_1, NFTWallet)
1635
- nft_info_1 = (await wallet_1_rpc.get_nft_info(nft_id, False))["nft_info"]
1812
+ nft_info_1 = (await wallet_1_rpc.get_nft_info(NFTGetInfo(nft_id, False))).nft_info
1636
1813
  assert nft_info_1 == nft_info
1637
- nft_info_1 = (await wallet_1_rpc.get_nft_info(nft_id))["nft_info"]
1638
- assert nft_info_1["nft_coin_id"][2:] == (await nft_wallet_1.get_current_nfts())[0].coin.name().hex()
1814
+ nft_info_1 = (await wallet_1_rpc.get_nft_info(NFTGetInfo(nft_id))).nft_info
1815
+ assert nft_info_1.nft_coin_id == (await nft_wallet_1.get_current_nfts())[0].coin.name()
1639
1816
  # Cross-check NFT
1640
- nft_info_2 = (await wallet_2_rpc.list_nfts(nft_wallet_id_1))["nft_list"][0]
1817
+ nft_info_2 = (await wallet_2_rpc.list_nfts(NFTGetNFTs(nft_wallet_id_1))).nft_list[0]
1818
+ assert nft_info_1 == nft_info_2
1819
+ nft_info_2 = (await wallet_2_rpc.list_nfts(NFTGetNFTs())).nft_list[0]
1641
1820
  assert nft_info_1 == nft_info_2
1642
1821
 
1643
1822
  # Test royalty endpoint
1823
+ with pytest.raises(ValueError, match="Multiple royalty assets with same name specified"):
1824
+ await wallet_1_rpc.nft_calculate_royalties(
1825
+ NFTCalculateRoyalties(
1826
+ [
1827
+ RoyaltyAsset(
1828
+ "my asset",
1829
+ "my address",
1830
+ uint16(10000),
1831
+ ),
1832
+ RoyaltyAsset(
1833
+ "my asset",
1834
+ "some other address",
1835
+ uint16(11111),
1836
+ ),
1837
+ ],
1838
+ [],
1839
+ )
1840
+ )
1841
+ with pytest.raises(ValueError, match="Multiple fungible assets with same name specified"):
1842
+ await wallet_1_rpc.nft_calculate_royalties(
1843
+ NFTCalculateRoyalties(
1844
+ [],
1845
+ [
1846
+ FungibleAsset(
1847
+ None,
1848
+ uint64(10000),
1849
+ ),
1850
+ FungibleAsset(
1851
+ None,
1852
+ uint64(11111),
1853
+ ),
1854
+ ],
1855
+ )
1856
+ )
1644
1857
  royalty_summary = await wallet_1_rpc.nft_calculate_royalties(
1645
- {
1646
- "my asset": ("my address", uint16(10000)),
1647
- },
1648
- {
1649
- None: uint64(10000),
1650
- },
1858
+ NFTCalculateRoyalties(
1859
+ [
1860
+ RoyaltyAsset(
1861
+ "my asset",
1862
+ "my address",
1863
+ uint16(10000),
1864
+ )
1865
+ ],
1866
+ [
1867
+ FungibleAsset(
1868
+ None,
1869
+ uint64(10000),
1870
+ )
1871
+ ],
1872
+ )
1651
1873
  )
1652
- assert royalty_summary == {
1874
+ assert royalty_summary.to_json_dict() == {
1653
1875
  "my asset": [
1654
1876
  {
1655
1877
  "asset": None,
@@ -1669,11 +1891,11 @@ async def _check_delete_key(
1669
1891
 
1670
1892
  sk = await wallet_node.get_key_for_fingerprint(farmer_fp, private=True)
1671
1893
  assert sk is not None
1672
- farmer_ph = create_puzzlehash_for_pk(create_sk(sk, uint32(0)).get_g1())
1894
+ farmer_ph = puzzle_hash_for_pk(create_sk(sk, uint32(0)).get_g1())
1673
1895
 
1674
1896
  sk = await wallet_node.get_key_for_fingerprint(pool_fp, private=True)
1675
1897
  assert sk is not None
1676
- pool_ph = create_puzzlehash_for_pk(create_sk(sk, uint32(0)).get_g1())
1898
+ pool_ph = puzzle_hash_for_pk(create_sk(sk, uint32(0)).get_g1())
1677
1899
 
1678
1900
  with lock_and_load_config(wallet_node.root_path, "config.yaml") as test_config:
1679
1901
  test_config["farmer"]["xch_target_address"] = encode_puzzle_hash(farmer_ph, "txch")
@@ -1700,7 +1922,7 @@ async def _check_delete_key(
1700
1922
 
1701
1923
 
1702
1924
  @pytest.mark.anyio
1703
- async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):
1925
+ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
1704
1926
  env: WalletRpcTestEnvironment = wallet_rpc_environment
1705
1927
 
1706
1928
  wallet: Wallet = env.wallet_1.wallet
@@ -1717,7 +1939,8 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
1717
1939
 
1718
1940
  assert (await client.get_height_info()).height > 0
1719
1941
 
1720
- ph = await wallet.get_new_puzzlehash()
1942
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1943
+ ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
1721
1944
  addr = encode_puzzle_hash(ph, "txch")
1722
1945
  tx_amount = uint64(15600000)
1723
1946
  await env.full_node.api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
@@ -1792,7 +2015,7 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
1792
2015
 
1793
2016
 
1794
2017
  @pytest.mark.anyio
1795
- async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment):
2018
+ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
1796
2019
  env: WalletRpcTestEnvironment = wallet_rpc_environment
1797
2020
 
1798
2021
  wallet_2: Wallet = env.wallet_2.wallet
@@ -1803,7 +2026,8 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
1803
2026
 
1804
2027
  funds = await generate_funds(full_node_api, env.wallet_1)
1805
2028
 
1806
- addr = encode_puzzle_hash(await wallet_2.get_new_puzzlehash(), "txch")
2029
+ async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
2030
+ addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
1807
2031
  coin_300: list[Coin]
1808
2032
  tx_amounts: list[uint64] = [uint64(1000), uint64(300), uint64(1000), uint64(1000), uint64(10000)]
1809
2033
  for tx_amount in tx_amounts:
@@ -1923,7 +2147,7 @@ async def test_get_coin_records_rpc(wallet_rpc_environment: WalletRpcTestEnviron
1923
2147
  test_request: GetCoinRecords,
1924
2148
  test_total_count: Optional[int],
1925
2149
  test_records: list[WalletCoinRecord],
1926
- ):
2150
+ ) -> None:
1927
2151
  response = await client.get_coin_records(test_request)
1928
2152
  assert response["coin_records"] == [coin.to_json_dict_parsed_metadata() for coin in test_records], test_case
1929
2153
  assert response["total_count"] == test_total_count, test_case
@@ -1962,9 +2186,9 @@ async def test_get_coin_records_rpc_limits(
1962
2186
  env: WalletRpcTestEnvironment = wallet_rpc_environment
1963
2187
  wallet_node: WalletNode = env.wallet_1.node
1964
2188
  client: WalletRpcClient = env.wallet_1.rpc_client
1965
- rpc_server: Optional[RpcServer] = wallet_rpc_environment.wallet_1.service.rpc_server
2189
+ rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
1966
2190
  assert rpc_server is not None
1967
- api: WalletRpcApi = cast(WalletRpcApi, rpc_server.rpc_api)
2191
+ api: WalletRpcApi = rpc_server.rpc_api
1968
2192
  store = wallet_node.wallet_state_manager.coin_store
1969
2193
 
1970
2194
  # Adjust the limits for faster testing
@@ -2034,9 +2258,9 @@ async def test_get_coin_records_rpc_failures(
2034
2258
  ) -> None:
2035
2259
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2036
2260
  client: WalletRpcClient = env.wallet_1.rpc_client
2037
- rpc_server: Optional[RpcServer] = wallet_rpc_environment.wallet_1.service.rpc_server
2261
+ rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
2038
2262
  assert rpc_server is not None
2039
- api = cast(WalletRpcApi, rpc_server.rpc_api)
2263
+ api = rpc_server.rpc_api
2040
2264
 
2041
2265
  too_many_hashes = [bytes32.random(seeded_random) for _ in range(api.max_get_coin_records_filter_items + 1)]
2042
2266
  too_many_amounts = [
@@ -2076,7 +2300,7 @@ async def test_get_coin_records_rpc_failures(
2076
2300
 
2077
2301
 
2078
2302
  @pytest.mark.anyio
2079
- async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironment):
2303
+ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2080
2304
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2081
2305
 
2082
2306
  wallet_2: Wallet = env.wallet_2.wallet
@@ -2089,12 +2313,13 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
2089
2313
 
2090
2314
  env.wallet_2.node.config["enable_notifications"] = True
2091
2315
  env.wallet_2.node.config["required_notification_amount"] = 100000000000
2092
- tx = await client.send_notification(
2093
- await wallet_2.get_new_puzzlehash(),
2094
- b"hello",
2095
- uint64(100000000000),
2096
- fee=uint64(100000000000),
2097
- )
2316
+ async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
2317
+ tx = await client.send_notification(
2318
+ await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager),
2319
+ b"hello",
2320
+ uint64(100000000000),
2321
+ fee=uint64(100000000000),
2322
+ )
2098
2323
 
2099
2324
  assert tx.spend_bundle is not None
2100
2325
  await time_out_assert(
@@ -2115,12 +2340,13 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
2115
2340
  assert await client_2.delete_notifications()
2116
2341
  assert [] == (await client_2.get_notifications(GetNotifications([notification.id]))).notifications
2117
2342
 
2118
- tx = await client.send_notification(
2119
- await wallet_2.get_new_puzzlehash(),
2120
- b"hello",
2121
- uint64(100000000000),
2122
- fee=uint64(100000000000),
2123
- )
2343
+ async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
2344
+ tx = await client.send_notification(
2345
+ await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager),
2346
+ b"hello",
2347
+ uint64(100000000000),
2348
+ fee=uint64(100000000000),
2349
+ )
2124
2350
 
2125
2351
  assert tx.spend_bundle is not None
2126
2352
  await time_out_assert(
@@ -2277,10 +2503,10 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
2277
2503
  async def test_verify_signature(
2278
2504
  wallet_rpc_environment: WalletRpcTestEnvironment,
2279
2505
  rpc_request: dict[str, Any],
2280
- rpc_response: dict[str, Any],
2506
+ rpc_response: VerifySignatureResponse,
2281
2507
  prefix_hex_strings: bool,
2282
- ):
2283
- rpc_server: Optional[RpcServer] = wallet_rpc_environment.wallet_1.service.rpc_server
2508
+ ) -> None:
2509
+ rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
2284
2510
  assert rpc_server is not None
2285
2511
  updated_request = rpc_request.copy()
2286
2512
  updated_request["pubkey"] = ("0x" if prefix_hex_strings else "") + updated_request["pubkey"]
@@ -2293,13 +2519,13 @@ async def test_verify_signature(
2293
2519
 
2294
2520
  @pytest.mark.anyio
2295
2521
  @pytest.mark.limit_consensus_modes(reason="irrelevant")
2296
- async def test_set_auto_claim(wallet_rpc_environment: WalletRpcTestEnvironment):
2522
+ async def test_set_auto_claim(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2297
2523
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2298
2524
  full_node_api: FullNodeSimulator = env.full_node.api
2299
- rpc_server: Optional[RpcServer] = wallet_rpc_environment.wallet_1.service.rpc_server
2525
+ rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
2300
2526
  await generate_funds(full_node_api, env.wallet_1)
2301
2527
  assert rpc_server is not None
2302
- api: WalletRpcApi = cast(WalletRpcApi, rpc_server.rpc_api)
2528
+ api: WalletRpcApi = rpc_server.rpc_api
2303
2529
  req = {"enabled": False, "tx_fee": -1, "min_amount": 100}
2304
2530
  has_exception = False
2305
2531
  try:
@@ -2320,10 +2546,10 @@ async def test_set_auto_claim(wallet_rpc_environment: WalletRpcTestEnvironment):
2320
2546
 
2321
2547
  @pytest.mark.anyio
2322
2548
  @pytest.mark.limit_consensus_modes(reason="irrelevant")
2323
- async def test_get_auto_claim(wallet_rpc_environment: WalletRpcTestEnvironment):
2549
+ async def test_get_auto_claim(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2324
2550
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2325
2551
  full_node_api: FullNodeSimulator = env.full_node.api
2326
- rpc_server: Optional[RpcServer] = wallet_rpc_environment.wallet_1.service.rpc_server
2552
+ rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
2327
2553
  await generate_funds(full_node_api, env.wallet_1)
2328
2554
  assert rpc_server is not None
2329
2555
  res = await env.wallet_1.rpc_client.get_auto_claim()
@@ -2334,7 +2560,7 @@ async def test_get_auto_claim(wallet_rpc_environment: WalletRpcTestEnvironment):
2334
2560
 
2335
2561
 
2336
2562
  @pytest.mark.anyio
2337
- async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTestEnvironment):
2563
+ async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2338
2564
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2339
2565
  full_node_api: FullNodeSimulator = env.full_node.api
2340
2566
  client: WalletRpcClient = env.wallet_1.rpc_client
@@ -2349,12 +2575,15 @@ async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTes
2349
2575
  nft_wallet_id = nft_wallet["wallet_id"]
2350
2576
  address = await wc.get_next_address(env.wallet_1.wallet.id(), True)
2351
2577
  await wc.mint_nft(
2352
- nft_wallet_id,
2578
+ request=NFTMintNFTRequest(
2579
+ wallet_id=nft_wallet_id,
2580
+ royalty_address=address,
2581
+ target_address=address,
2582
+ hash=bytes32.from_hexstr("0xD4584AD463139FA8C0D9F68F4B59F185D4584AD463139FA8C0D9F68F4B59F185"),
2583
+ uris=["http://test.nft"],
2584
+ push=True,
2585
+ ),
2353
2586
  tx_config=DEFAULT_TX_CONFIG,
2354
- royalty_address=address,
2355
- target_address=address,
2356
- hash="deadbeef",
2357
- uris=["http://test.nft"],
2358
2587
  )
2359
2588
  await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
2360
2589
  await farm_transaction_block(full_node_api, env.wallet_1.node)
@@ -2431,7 +2660,7 @@ async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTes
2431
2660
 
2432
2661
 
2433
2662
  @pytest.mark.anyio
2434
- async def test_set_wallet_resync_on_startup_disable(wallet_rpc_environment: WalletRpcTestEnvironment):
2663
+ async def test_set_wallet_resync_on_startup_disable(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2435
2664
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2436
2665
  full_node_api: FullNodeSimulator = env.full_node.api
2437
2666
  client: WalletRpcClient = env.wallet_1.rpc_client
@@ -2471,13 +2700,13 @@ async def test_set_wallet_resync_on_startup_disable(wallet_rpc_environment: Wall
2471
2700
 
2472
2701
  @pytest.mark.anyio
2473
2702
  @pytest.mark.limit_consensus_modes(reason="irrelevant")
2474
- async def test_set_wallet_resync_schema(wallet_rpc_environment: WalletRpcTestEnvironment):
2703
+ async def test_set_wallet_resync_schema(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2475
2704
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2476
2705
  full_node_api: FullNodeSimulator = env.full_node.api
2477
2706
  await generate_funds(full_node_api, env.wallet_1)
2478
2707
  wallet_node: WalletNode = env.wallet_1.node
2479
2708
  fingerprint = wallet_node.logged_in_fingerprint
2480
- assert fingerprint
2709
+ assert fingerprint is not None
2481
2710
  db_path = wallet_node.wallet_state_manager.db_path
2482
2711
  assert await wallet_node.reset_sync_db(db_path, fingerprint), (
2483
2712
  "Schema has been changed, reset sync db won't work, please update WalletNode.reset_sync_db function"
@@ -2493,7 +2722,7 @@ async def test_set_wallet_resync_schema(wallet_rpc_environment: WalletRpcTestEnv
2493
2722
 
2494
2723
 
2495
2724
  @pytest.mark.anyio
2496
- async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironment):
2725
+ async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2497
2726
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2498
2727
 
2499
2728
  wallet_node: WalletNode = env.wallet_1.node
@@ -2504,7 +2733,8 @@ async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironme
2504
2733
  await generate_funds(full_node_api, env.wallet_1, 1)
2505
2734
 
2506
2735
  # Send to a CAT with an anyone can spend TAIL
2507
- our_ph: bytes32 = await env.wallet_1.wallet.get_new_puzzlehash()
2736
+ async with env.wallet_1.wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
2737
+ our_ph = await action_scope.get_puzzle_hash(env.wallet_1.wallet.wallet_state_manager)
2508
2738
  cat_puzzle: Program = construct_cat_puzzle(CAT_MOD, Program.to(None).get_tree_hash(), Program.to(1))
2509
2739
  addr = encode_puzzle_hash(
2510
2740
  cat_puzzle.get_tree_hash(),
@@ -2572,7 +2802,7 @@ async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironme
2572
2802
 
2573
2803
 
2574
2804
  @pytest.mark.anyio
2575
- async def test_get_balances(wallet_rpc_environment: WalletRpcTestEnvironment):
2805
+ async def test_get_balances(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
2576
2806
  env: WalletRpcTestEnvironment = wallet_rpc_environment
2577
2807
 
2578
2808
  client: WalletRpcClient = env.wallet_1.rpc_client
@@ -2930,7 +3160,7 @@ async def test_combine_coins(wallet_environments: WalletTestFramework, capsys: p
2930
3160
  async with env.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
2931
3161
  await cat_wallet.generate_signed_transaction(
2932
3162
  [BIG_COIN_AMOUNT, SMALL_COIN_AMOUNT, REALLY_SMALL_COIN_AMOUNT],
2933
- [await env.xch_wallet.get_puzzle_hash(new=not action_scope.config.tx_config.reuse_puzhash)] * 3,
3163
+ [await action_scope.get_puzzle_hash(env.wallet_state_manager)] * 3,
2934
3164
  action_scope,
2935
3165
  )
2936
3166