chia-blockchain 2.5.4rc2__py3-none-any.whl → 2.5.5rc2__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 +421 -69
  63. chia/_tests/core/mempool/test_mempool_performance.py +3 -2
  64. chia/_tests/core/mempool/test_singleton_fast_forward.py +60 -131
  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 +143 -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 +26 -40
  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.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/METADATA +7 -7
  424. {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.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.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/LICENSE +0 -0
  452. {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/WHEEL +0 -0
  453. {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/entry_points.txt +0 -0
@@ -1,104 +1,105 @@
1
1
  from __future__ import annotations
2
2
 
3
- import contextlib
4
- import random
5
- from typing import Any
3
+ from typing import Optional, cast
6
4
 
7
5
  import pytest
8
6
  from chia_rs.sized_bytes import bytes32
9
7
  from chia_rs.sized_ints import uint16, uint32, uint64
10
8
 
11
- from chia._tests.util.setup_nodes import SimulatorsAndWalletsServices
12
- from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_not_none
13
- from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
14
- from chia.rpc.full_node_rpc_client import FullNodeRpcClient
15
- from chia.rpc.wallet_rpc_api import WalletRpcApi
16
- from chia.rpc.wallet_rpc_client import WalletRpcClient
17
- from chia.simulator.full_node_simulator import FullNodeSimulator
18
- from chia.simulator.simulator_protocol import FarmNewBlockProtocol
9
+ from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework
10
+ from chia._tests.util.time_out_assert import time_out_assert
19
11
  from chia.types.blockchain_format.program import Program
20
- from chia.types.peer_info import PeerInfo
21
12
  from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
22
13
  from chia.wallet.did_wallet.did_wallet import DIDWallet
23
14
  from chia.wallet.nft_wallet.nft_wallet import NFTWallet
24
15
  from chia.wallet.nft_wallet.uncurry_nft import UncurriedNFT
16
+ from chia.wallet.transaction_record import TransactionRecord
25
17
  from chia.wallet.util.address_type import AddressType
26
- from chia.wallet.util.tx_config import DEFAULT_COIN_SELECTION_CONFIG, DEFAULT_TX_CONFIG
18
+ from chia.wallet.wallet_request_types import NFTGetNFTs, NFTMintBulk, NFTMintMetadata, PushTransactions
27
19
 
28
20
 
29
21
  async def nft_count(wallet: NFTWallet) -> int:
30
22
  return await wallet.get_nft_count()
31
23
 
32
24
 
33
- @pytest.mark.parametrize(
34
- "trusted",
35
- [True, False],
36
- )
25
+ @pytest.mark.limit_consensus_modes
26
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
27
+ @pytest.mark.parametrize("with_did", [True, False])
37
28
  @pytest.mark.anyio
38
- async def test_nft_mint_from_did(
39
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
40
- ) -> None:
41
- full_nodes, wallets, _ = two_wallet_nodes
42
- full_node_api: FullNodeSimulator = full_nodes[0]
43
- full_node_server = full_node_api.server
44
- wallet_node_0, server_0 = wallets[0]
45
- wallet_node_1, server_1 = wallets[1]
46
- wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
47
- wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
48
- ph_maker = await wallet_0.get_new_puzzlehash()
49
- ph_token = bytes32.random(seeded_random)
50
-
51
- if trusted:
52
- wallet_node_0.config["trusted_peers"] = {
53
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
54
- }
55
- wallet_node_1.config["trusted_peers"] = {
56
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
57
- }
58
- else:
59
- wallet_node_0.config["trusted_peers"] = {}
60
- wallet_node_1.config["trusted_peers"] = {}
61
-
62
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
63
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
64
-
65
- # for _ in range(1, num_blocks):
66
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
67
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
68
- funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
69
-
70
- await time_out_assert(30, wallet_0.get_unconfirmed_balance, funds)
71
- await time_out_assert(30, wallet_0.get_confirmed_balance, funds)
72
-
73
- async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
29
+ async def test_nft_mint(wallet_environments: WalletTestFramework, with_did: bool) -> None:
30
+ env_0 = wallet_environments.environments[0]
31
+ env_1 = wallet_environments.environments[1]
32
+ wallet_0 = env_0.xch_wallet
33
+ wallet_1 = env_1.xch_wallet
34
+ env_0.wallet_aliases = {
35
+ "xch": 1,
36
+ "did": 2,
37
+ "nft": 3,
38
+ }
39
+ env_1.wallet_aliases = {
40
+ "xch": 1,
41
+ "nft": 2,
42
+ }
43
+
44
+ async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
45
+ ph_0 = await action_scope.get_puzzle_hash(env_0.wallet_state_manager)
74
46
  did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
75
- wallet_node_0.wallet_state_manager, wallet_0, uint64(1), action_scope
47
+ env_0.wallet_state_manager, wallet_0, uint64(1), action_scope
76
48
  )
77
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
78
- await time_out_assert(30, wallet_0.get_pending_change_balance, 0)
79
49
 
80
50
  hex_did_id = did_wallet.get_my_DID()
81
51
  did_id = bytes32.fromhex(hex_did_id)
82
52
 
83
- await time_out_assert(5, did_wallet.get_confirmed_balance, 1)
84
-
85
- nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
86
- wallet_node_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
53
+ nft_wallet_0 = await NFTWallet.create_new_nft_wallet(
54
+ env_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
87
55
  )
88
56
 
89
- nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
90
- wallet_node_1.wallet_state_manager, wallet_1, name="NFT WALLET 2"
57
+ nft_wallet_1 = await NFTWallet.create_new_nft_wallet(env_1.wallet_state_manager, wallet_1, name="NFT WALLET 2")
58
+
59
+ await wallet_environments.process_pending_states(
60
+ [
61
+ WalletStateTransition(
62
+ pre_block_balance_updates={
63
+ "xch": {
64
+ "set_remainder": True,
65
+ },
66
+ "did": {
67
+ "init": True,
68
+ "set_remainder": True,
69
+ },
70
+ "nft": {
71
+ "init": True,
72
+ },
73
+ },
74
+ post_block_balance_updates={
75
+ "xch": {
76
+ "set_remainder": True,
77
+ },
78
+ "did": {
79
+ "set_remainder": True,
80
+ },
81
+ },
82
+ ),
83
+ WalletStateTransition(
84
+ pre_block_balance_updates={
85
+ "nft": {
86
+ "init": True,
87
+ }
88
+ },
89
+ post_block_balance_updates={},
90
+ ),
91
+ ]
91
92
  )
92
93
 
93
94
  royalty_pc = uint16(300)
94
- royalty_addr = ph_maker
95
+ royalty_addr = ph_0
95
96
 
96
97
  mint_total = 10
97
98
  fee = uint64(100)
98
99
  metadata_list = [
99
100
  {
100
101
  "program": Program.to(
101
- [("u", ["https://www.chia.net/img/branding/chia-logo.svg"]), ("h", bytes32.random(seeded_random).hex())]
102
+ [("u", ["https://www.chia.net/img/branding/chia-logo.svg"]), ("h", bytes32.zeros.hex())]
102
103
  ),
103
104
  "royalty_pc": royalty_pc,
104
105
  "royalty_ph": royalty_addr,
@@ -106,31 +107,87 @@ async def test_nft_mint_from_did(
106
107
  for x in range(mint_total)
107
108
  ]
108
109
 
109
- target_list = [(await wallet_1.get_new_puzzlehash()) for x in range(mint_total)]
110
-
111
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
112
- await nft_wallet_maker.mint_from_did(
113
- metadata_list,
114
- action_scope,
115
- target_list=target_list,
116
- mint_number_start=1,
117
- mint_total=mint_total,
118
- fee=fee,
119
- )
120
- for record in action_scope.side_effects.transactions:
121
- if record.spend_bundle is not None:
122
- await time_out_assert_not_none(
123
- 5, full_node_api.full_node.mempool_manager.get_spendbundle, record.spend_bundle.name()
110
+ async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
111
+ target_list = [await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager) for x in range(mint_total)]
112
+
113
+ async with nft_wallet_0.wallet_state_manager.new_action_scope(
114
+ wallet_environments.tx_config, push=True
115
+ ) as action_scope:
116
+ if with_did:
117
+ await nft_wallet_0.mint_from_did(
118
+ metadata_list,
119
+ action_scope,
120
+ target_list=target_list,
121
+ mint_number_start=1,
122
+ mint_total=mint_total,
123
+ fee=fee,
124
+ )
125
+ else:
126
+ await nft_wallet_0.mint_from_xch(
127
+ metadata_list,
128
+ action_scope,
129
+ target_list=target_list,
130
+ mint_number_start=1,
131
+ mint_total=mint_total,
132
+ fee=fee,
124
133
  )
125
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
126
-
127
- await time_out_assert(30, nft_count, mint_total, nft_wallet_taker)
128
- await time_out_assert(30, nft_count, 0, nft_wallet_maker)
129
134
 
130
- expected_xch_bal = funds - fee - mint_total - 1
131
- await time_out_assert(30, wallet_0.get_confirmed_balance, expected_xch_bal)
135
+ await wallet_environments.process_pending_states(
136
+ [
137
+ WalletStateTransition(
138
+ pre_block_balance_updates={
139
+ "xch": {
140
+ "unconfirmed_wallet_balance": -fee - mint_total,
141
+ "<=#spendable_balance": -fee - mint_total,
142
+ "<=#max_send_amount": -fee - mint_total,
143
+ ">=#pending_change": 1,
144
+ "pending_coin_removal_count": 1,
145
+ },
146
+ "did": {
147
+ "spendable_balance": -1,
148
+ "max_send_amount": -1,
149
+ "pending_change": 1,
150
+ "pending_coin_removal_count": 1,
151
+ }
152
+ if with_did
153
+ else {},
154
+ "nft": {
155
+ "pending_coin_removal_count": mint_total,
156
+ },
157
+ },
158
+ post_block_balance_updates={
159
+ "xch": {
160
+ "confirmed_wallet_balance": -fee - mint_total,
161
+ ">=#spendable_balance": 1,
162
+ ">=#max_send_amount": 1,
163
+ "<=#pending_change": -1,
164
+ "pending_coin_removal_count": -1,
165
+ },
166
+ "did": {
167
+ "spendable_balance": 1,
168
+ "max_send_amount": 1,
169
+ "pending_change": -1,
170
+ "pending_coin_removal_count": -1,
171
+ }
172
+ if with_did
173
+ else {},
174
+ "nft": {
175
+ "pending_coin_removal_count": -mint_total,
176
+ },
177
+ },
178
+ ),
179
+ WalletStateTransition(
180
+ pre_block_balance_updates={},
181
+ post_block_balance_updates={
182
+ "nft": {
183
+ "unspent_coin_count": mint_total,
184
+ }
185
+ },
186
+ ),
187
+ ]
188
+ )
132
189
 
133
- nfts = await nft_wallet_taker.get_current_nfts()
190
+ nfts = await nft_wallet_1.get_current_nfts()
134
191
  matched_data = dict(zip(target_list, metadata_list))
135
192
 
136
193
  # Check targets and metadata entries match in the final nfts
@@ -142,839 +199,303 @@ async def test_nft_mint_from_did(
142
199
  inner_ph = inner_args.at("rrrf").get_tree_hash()
143
200
  meta = unft.metadata.at("rfr").as_atom()
144
201
  # check that the target puzzle hashes of transferred nfts matches the metadata entry
145
- assert matched_data[inner_ph]["program"].at("rfr").as_atom() == meta
146
- # Check the did is set for each nft
147
- assert nft.minter_did == did_id
148
-
149
-
150
- @pytest.mark.parametrize(
151
- "trusted",
152
- [True, False],
153
- )
202
+ prog: Program = cast(Program, matched_data[inner_ph]["program"])
203
+ assert prog.at("rfr").as_atom() == meta
204
+ if with_did:
205
+ # Check the did is set for each nft
206
+ assert nft.minter_did == did_id
207
+ else:
208
+ assert nft.minter_did is None
209
+
210
+
211
+ @pytest.mark.limit_consensus_modes
212
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
213
+ @pytest.mark.parametrize("zero_royalties", [True, False])
214
+ @pytest.mark.parametrize("with_did", [True, False])
154
215
  @pytest.mark.anyio
155
- async def test_nft_mint_from_did_rpc(
156
- two_wallet_nodes_services: SimulatorsAndWalletsServices,
157
- trusted: Any,
158
- self_hostname: str,
159
- seeded_random: random.Random,
160
- ) -> None:
161
- [full_node_service], wallet_services, bt = two_wallet_nodes_services
162
- full_node_api: FullNodeSimulator = full_node_service._api
163
- full_node_server = full_node_api.server
164
- wallet_node_maker = wallet_services[0]._node
165
- wallet_node_taker = wallet_services[1]._node
166
- server_0 = wallet_node_maker.server
167
- server_1 = wallet_node_taker.server
168
- wallet_maker = wallet_node_maker.wallet_state_manager.main_wallet
169
- wallet_taker = wallet_node_taker.wallet_state_manager.main_wallet
170
-
171
- ph_maker = await wallet_maker.get_new_puzzlehash()
172
- ph_taker = await wallet_taker.get_new_puzzlehash()
173
- ph_token = bytes32.random(seeded_random)
174
-
175
- if trusted:
176
- wallet_node_maker.config["trusted_peers"] = {
177
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
178
- }
179
- wallet_node_taker.config["trusted_peers"] = {
180
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
181
- }
182
- else:
183
- wallet_node_maker.config["trusted_peers"] = {}
184
- wallet_node_taker.config["trusted_peers"] = {}
185
-
186
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
187
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
188
-
189
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
190
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_taker))
191
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
192
-
193
- funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
194
-
195
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
196
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
197
- await time_out_assert(30, wallet_taker.get_unconfirmed_balance, funds)
198
- await time_out_assert(30, wallet_taker.get_confirmed_balance, funds)
199
-
200
- api_maker = WalletRpcApi(wallet_node_maker)
201
- api_taker = WalletRpcApi(wallet_node_taker)
202
- config = bt.config
203
-
204
- assert wallet_services[0].rpc_server is not None
205
- assert full_node_service.rpc_server is not None
206
-
207
- async with contextlib.AsyncExitStack() as exit_stack:
208
- client = await exit_stack.enter_async_context(
209
- WalletRpcClient.create_as_context(
210
- self_hostname,
211
- wallet_services[0].rpc_server.listen_port,
212
- wallet_services[0].root_path,
213
- wallet_services[0].config,
214
- )
216
+ async def test_nft_mint_rpc(wallet_environments: WalletTestFramework, zero_royalties: bool, with_did: bool) -> None:
217
+ env_0 = wallet_environments.environments[0]
218
+ env_1 = wallet_environments.environments[1]
219
+ wallet_0 = env_0.xch_wallet
220
+ env_0.wallet_aliases = {
221
+ "xch": 1,
222
+ "did": 2,
223
+ "nft": 3,
224
+ }
225
+ env_1.wallet_aliases = {
226
+ "xch": 1,
227
+ "nft": 2,
228
+ }
229
+
230
+ async with env_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
231
+ ph_1 = await action_scope.get_puzzle_hash(env_1.wallet_state_manager)
232
+
233
+ async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
234
+ did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
235
+ env_0.wallet_state_manager, wallet_0, uint64(1), action_scope
215
236
  )
216
- client_node = await exit_stack.enter_async_context(
217
- FullNodeRpcClient.create_as_context(
218
- self_hostname,
219
- full_node_service.rpc_server.listen_port,
220
- full_node_service.root_path,
221
- full_node_service.config,
222
- )
223
- )
224
-
225
- async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
226
- did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
227
- wallet_node_maker.wallet_state_manager, wallet_maker, uint64(1), action_scope
228
- )
229
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
230
237
 
231
- await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
232
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds - 1)
233
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds - 1)
234
-
235
- hex_did_id = did_wallet_maker.get_my_DID()
236
- hmr_did_id = encode_puzzle_hash(bytes32.from_hexstr(hex_did_id), AddressType.DID.hrp(config))
237
-
238
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
239
-
240
- nft_wallet_maker = await api_maker.create_new_wallet(
241
- dict(wallet_type="nft_wallet", name="NFT WALLET 1", did_id=hmr_did_id)
242
- )
243
- assert isinstance(nft_wallet_maker, dict)
244
- assert nft_wallet_maker.get("success")
245
-
246
- nft_wallet_taker = await api_taker.create_new_wallet(dict(wallet_type="nft_wallet", name="NFT WALLET 2"))
247
-
248
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
249
-
250
- n = 10
251
- metadata_list = [
252
- {
253
- "hash": bytes32.random(seeded_random).hex(),
254
- "uris": [f"https://data.com/{i}"],
255
- "meta_hash": bytes32.random(seeded_random).hex(),
256
- "meta_uris": [f"https://meatadata.com/{i}"],
257
- "license_hash": bytes32.random(seeded_random).hex(),
258
- "license_uris": [f"https://license.com/{i}"],
259
- "edition_number": i + 1,
260
- "edition_total": n,
261
- }
262
- for i in range(n)
238
+ await wallet_environments.process_pending_states(
239
+ [
240
+ WalletStateTransition(
241
+ pre_block_balance_updates={
242
+ "xch": {
243
+ "set_remainder": True,
244
+ },
245
+ "did": {
246
+ "init": True,
247
+ "set_remainder": True,
248
+ },
249
+ },
250
+ post_block_balance_updates={
251
+ "xch": {
252
+ "set_remainder": True,
253
+ },
254
+ "did": {
255
+ "set_remainder": True,
256
+ },
257
+ },
258
+ ),
259
+ WalletStateTransition(),
263
260
  ]
264
- target_list = [encode_puzzle_hash((ph_taker), "xch") for x in range(n)]
265
- royalty_address = encode_puzzle_hash(bytes32.random(seeded_random), "xch")
266
- royalty_percentage = 300
267
- fee = 100
268
- required_amount = n + (fee * n)
269
- xch_coins = await client.select_coins(
270
- amount=required_amount, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=wallet_maker.id()
271
- )
272
- funding_coin = xch_coins[0]
273
- assert funding_coin.amount >= required_amount
274
- funding_coin_dict = xch_coins[0].to_json_dict()
275
- chunk = 5
276
- next_coin = funding_coin
277
- did_coin = (
278
- await client.select_coins(amount=1, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=2)
279
- )[0]
280
- did_lineage_parent = None
281
- spends = []
282
- nft_ids = set()
283
- for i in range(0, n, chunk):
284
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
285
- resp = await client.nft_mint_bulk(
286
- wallet_id=nft_wallet_maker["wallet_id"],
287
- metadata_list=metadata_list[i : i + chunk],
288
- target_list=target_list[i : i + chunk],
289
- royalty_percentage=royalty_percentage,
290
- royalty_address=royalty_address,
291
- mint_number_start=i + 1,
292
- mint_total=n,
293
- xch_coins=[next_coin.to_json_dict()],
294
- xch_change_target=funding_coin_dict["puzzle_hash"],
295
- did_coin=did_coin.to_json_dict(),
296
- did_lineage_parent=did_lineage_parent,
297
- mint_from_did=True,
298
- fee=fee,
299
- tx_config=DEFAULT_TX_CONFIG,
300
- )
301
- sb = resp.spend_bundle
302
- did_lineage_parent = next(cn for cn in sb.removals() if cn.name() == did_coin.name()).parent_coin_info.hex()
303
- did_coin = next(
304
- cn for cn in sb.additions() if (cn.parent_coin_info == did_coin.name()) and (cn.amount == 1)
305
- )
306
- spends.append(sb)
307
- xch_adds = [c for c in sb.additions() if c.puzzle_hash == funding_coin.puzzle_hash]
308
- assert len(xch_adds) == 1
309
- next_coin = xch_adds[0]
310
- for nft_id in resp.nft_id_list:
311
- nft_ids.add(decode_puzzle_hash(nft_id))
312
- for sb in spends:
313
- push_resp = await client_node.push_tx(sb)
314
- assert push_resp["success"]
315
- await full_node_api.process_spend_bundles([sb])
316
-
317
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
318
-
319
- async def get_taker_nfts() -> int:
320
- return int((await api_taker.nft_count_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["count"])
321
-
322
- # We are using a long time out here because it can take a long time for the NFTs to show up
323
- # Even with only 10 NFTs it regularly takes longer than 30-40s for them to be found
324
- await time_out_assert(60, get_taker_nfts, n)
261
+ )
325
262
 
326
- # check NFT edition numbers
327
- nfts = (await api_taker.nft_get_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["nft_list"]
328
- for nft in nfts:
329
- edition_num = nft.edition_number
330
- meta_dict = metadata_list[edition_num - 1]
331
- assert meta_dict["hash"] == nft.data_hash.hex()
332
- assert meta_dict["uris"] == nft.data_uris
333
- assert meta_dict["meta_hash"] == nft.metadata_hash.hex()
334
- assert meta_dict["meta_uris"] == nft.metadata_uris
335
- assert meta_dict["license_hash"] == nft.license_hash.hex()
336
- assert meta_dict["license_uris"] == nft.license_uris
337
- assert meta_dict["edition_number"] == nft.edition_number
338
- assert meta_dict["edition_total"] == nft.edition_total
339
- assert nft.launcher_id in nft_ids
263
+ hex_did_id = did_wallet_maker.get_my_DID()
264
+ hmr_did_id = encode_puzzle_hash(bytes32.from_hexstr(hex_did_id), AddressType.DID.hrp(env_0.node.config))
340
265
 
266
+ nft_wallet_maker = await env_0.rpc_client.create_new_nft_wallet(name="NFT WALLET 1", did_id=hmr_did_id)
341
267
 
342
- @pytest.mark.parametrize(
343
- "trusted",
344
- [True, False],
345
- )
346
- @pytest.mark.anyio
347
- async def test_nft_mint_from_did_rpc_no_royalties(
348
- two_wallet_nodes_services: SimulatorsAndWalletsServices,
349
- trusted: Any,
350
- self_hostname: str,
351
- seeded_random: random.Random,
352
- ) -> None:
353
- [full_node_service], wallet_services, bt = two_wallet_nodes_services
354
- full_node_api: FullNodeSimulator = full_node_service._api
355
- full_node_server = full_node_api.server
356
- wallet_node_maker = wallet_services[0]._node
357
- wallet_node_taker = wallet_services[1]._node
358
- server_0 = wallet_node_maker.server
359
- server_1 = wallet_node_taker.server
360
- wallet_maker = wallet_node_maker.wallet_state_manager.main_wallet
361
- wallet_taker = wallet_node_taker.wallet_state_manager.main_wallet
268
+ await env_1.rpc_client.create_new_nft_wallet(name="NFT WALLET 2", did_id=None)
362
269
 
363
- ph_maker = await wallet_maker.get_new_puzzlehash()
364
- ph_taker = await wallet_taker.get_new_puzzlehash()
365
- ph_token = bytes32.random(seeded_random)
270
+ await env_0.change_balances({"nft": {"init": True}})
271
+ await env_1.change_balances({"nft": {"init": True}})
366
272
 
367
- if trusted:
368
- wallet_node_maker.config["trusted_peers"] = {
369
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
370
- }
371
- wallet_node_taker.config["trusted_peers"] = {
372
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
273
+ n = 10
274
+ chunk = 5
275
+ metadata_list = [
276
+ {
277
+ "hash": bytes([i] * 32).hex(),
278
+ "uris": [f"https://data.com/{i}"],
279
+ "meta_hash": bytes([i] * 32).hex(),
280
+ "meta_uris": [f"https://meatadata.com/{i}"],
281
+ "license_hash": bytes([i] * 32).hex(),
282
+ "license_uris": [f"https://license.com/{i}"],
283
+ "edition_number": i + 1,
284
+ "edition_total": n,
373
285
  }
374
- else:
375
- wallet_node_maker.config["trusted_peers"] = {}
376
- wallet_node_taker.config["trusted_peers"] = {}
377
-
378
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
379
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
380
-
381
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
382
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_taker))
383
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
384
-
385
- funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
386
-
387
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
388
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
389
- await time_out_assert(30, wallet_taker.get_unconfirmed_balance, funds)
390
- await time_out_assert(30, wallet_taker.get_confirmed_balance, funds)
391
-
392
- api_maker = WalletRpcApi(wallet_node_maker)
393
- api_taker = WalletRpcApi(wallet_node_taker)
394
- config = bt.config
395
-
396
- assert wallet_services[0].rpc_server is not None
397
- assert full_node_service.rpc_server is not None
398
-
399
- async with contextlib.AsyncExitStack() as exit_stack:
400
- client = await exit_stack.enter_async_context(
401
- WalletRpcClient.create_as_context(
402
- self_hostname,
403
- wallet_services[0].rpc_server.listen_port,
404
- wallet_services[0].root_path,
405
- wallet_services[0].config,
406
- )
407
- )
408
- client_node = await exit_stack.enter_async_context(
409
- FullNodeRpcClient.create_as_context(
410
- self_hostname,
411
- full_node_service.rpc_server.listen_port,
412
- full_node_service.root_path,
413
- full_node_service.config,
414
- )
415
- )
416
-
417
- async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
418
- did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
419
- wallet_node_maker.wallet_state_manager, wallet_maker, uint64(1), action_scope
420
- )
421
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
422
-
423
- await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
424
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds - 1)
425
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds - 1)
426
-
427
- hex_did_id = did_wallet_maker.get_my_DID()
428
- hmr_did_id = encode_puzzle_hash(bytes32.from_hexstr(hex_did_id), AddressType.DID.hrp(config))
429
-
430
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
431
-
432
- nft_wallet_maker = await api_maker.create_new_wallet(
433
- dict(wallet_type="nft_wallet", name="NFT WALLET 1", did_id=hmr_did_id)
434
- )
435
- assert isinstance(nft_wallet_maker, dict)
436
- assert nft_wallet_maker.get("success")
437
-
438
- nft_wallet_taker = await api_taker.create_new_wallet(dict(wallet_type="nft_wallet", name="NFT WALLET 2"))
439
-
440
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
441
-
442
- n = 10
443
- metadata_list = [
444
- {
445
- "hash": bytes32.random(seeded_random).hex(),
446
- "uris": [f"https://data.com/{i}"],
447
- "meta_hash": bytes32.random(seeded_random).hex(),
448
- "meta_uris": [f"https://meatadata.com/{i}"],
449
- "license_hash": bytes32.random(seeded_random).hex(),
450
- "license_uris": [f"https://license.com/{i}"],
451
- "edition_number": i + 1,
452
- "edition_total": n,
453
- }
454
- for i in range(n)
455
- ]
456
- target_list = [encode_puzzle_hash((ph_taker), "xch") for x in range(n)]
457
- royalty_address = None
458
- royalty_percentage = None
459
- required_amount = n
460
- xch_coins = await client.select_coins(
461
- amount=required_amount, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=wallet_maker.id()
286
+ for i in range(n)
287
+ ]
288
+ target_list = [encode_puzzle_hash(ph_1, "xch") for x in range(n)]
289
+ royalty_address = None if zero_royalties else encode_puzzle_hash(bytes32.zeros, "xch")
290
+ royalty_percentage = None if zero_royalties else 300
291
+ fee = 100
292
+ num_chunks = int(n / chunk) + (1 if n % chunk > 0 else 0)
293
+ required_amount = n + (fee * num_chunks)
294
+ xch_coins = await env_0.rpc_client.select_coins(
295
+ amount=required_amount,
296
+ coin_selection_config=wallet_environments.tx_config.coin_selection_config,
297
+ wallet_id=wallet_0.id(),
298
+ )
299
+ funding_coin = xch_coins[0]
300
+ assert funding_coin.amount >= required_amount
301
+ funding_coin_dict = xch_coins[0].to_json_dict()
302
+ next_coin = funding_coin
303
+ did_coin = (
304
+ await env_0.rpc_client.select_coins(
305
+ amount=1,
306
+ coin_selection_config=wallet_environments.tx_config.coin_selection_config,
307
+ wallet_id=env_0.wallet_aliases["did"],
462
308
  )
463
- funding_coin = xch_coins[0]
464
- assert funding_coin.amount >= required_amount
465
- funding_coin_dict = xch_coins[0].to_json_dict()
466
- chunk = 5
467
- next_coin = funding_coin
468
- did_coin = (
469
- await client.select_coins(amount=1, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=2)
470
- )[0]
471
- did_lineage_parent = None
472
- spends = []
473
-
474
- for i in range(0, n, chunk):
475
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
476
- resp = await client.nft_mint_bulk(
309
+ )[0]
310
+ did_lineage_parent: Optional[bytes32] = None
311
+ txs: list[TransactionRecord] = []
312
+ nft_ids = set()
313
+ for i in range(0, n, chunk):
314
+ resp = await env_0.rpc_client.nft_mint_bulk(
315
+ NFTMintBulk(
477
316
  wallet_id=nft_wallet_maker["wallet_id"],
478
- metadata_list=metadata_list[i : i + chunk],
317
+ metadata_list=[NFTMintMetadata.from_json_dict(metadata) for metadata in metadata_list[i : i + chunk]],
479
318
  target_list=target_list[i : i + chunk],
480
- royalty_percentage=royalty_percentage,
319
+ royalty_percentage=uint16.construct_optional(royalty_percentage),
481
320
  royalty_address=royalty_address,
482
- mint_number_start=i + 1,
483
- mint_total=n,
484
- xch_coins=[next_coin.to_json_dict()],
321
+ mint_number_start=uint16(i + 1),
322
+ mint_total=uint16(n),
323
+ xch_coins=[next_coin],
485
324
  xch_change_target=funding_coin_dict["puzzle_hash"],
486
- did_coin=did_coin.to_json_dict(),
487
- did_lineage_parent=did_lineage_parent,
488
- mint_from_did=True,
489
- tx_config=DEFAULT_TX_CONFIG,
490
- )
491
- sb = resp.spend_bundle
492
- did_lineage_parent = next(cn for cn in sb.removals() if cn.name() == did_coin.name()).parent_coin_info.hex()
325
+ did_coin=did_coin if with_did else None,
326
+ did_lineage_parent=did_lineage_parent if with_did else None,
327
+ mint_from_did=with_did,
328
+ fee=uint64(fee),
329
+ ),
330
+ tx_config=wallet_environments.tx_config,
331
+ )
332
+ if with_did:
333
+ did_lineage_parent = next(
334
+ cn
335
+ for tx in resp.transactions
336
+ if tx.spend_bundle is not None
337
+ for cn in tx.spend_bundle.removals()
338
+ if cn.name() == did_coin.name()
339
+ ).parent_coin_info
493
340
  did_coin = next(
494
- cn for cn in sb.additions() if (cn.parent_coin_info == did_coin.name()) and (cn.amount == 1)
341
+ cn
342
+ for tx in resp.transactions
343
+ if tx.spend_bundle is not None
344
+ for cn in tx.spend_bundle.additions()
345
+ if (cn.parent_coin_info == did_coin.name()) and (cn.amount == 1)
495
346
  )
496
- spends.append(sb)
497
- xch_adds = [c for c in sb.additions() if c.puzzle_hash == funding_coin.puzzle_hash]
498
- assert len(xch_adds) == 1
499
- next_coin = xch_adds[0]
500
-
501
- for sb in spends:
502
- push_resp = await client_node.push_tx(sb)
503
- assert push_resp["success"]
504
- await full_node_api.process_spend_bundles([sb])
505
-
506
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
507
-
508
- async def get_taker_nfts() -> int:
509
- return int((await api_taker.nft_count_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["count"])
510
-
511
- await time_out_assert(60, get_taker_nfts, n)
512
-
513
-
514
- @pytest.mark.parametrize(
515
- "trusted",
516
- [True, False],
517
- )
518
- @pytest.mark.anyio
519
- async def test_nft_mint_from_did_multiple_xch(
520
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
521
- ) -> None:
522
- full_nodes, wallets, _ = two_wallet_nodes
523
- full_node_api: FullNodeSimulator = full_nodes[0]
524
- full_node_server = full_node_api.server
525
- wallet_node_0, server_0 = wallets[0]
526
- wallet_node_1, server_1 = wallets[1]
527
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
528
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
529
- ph_maker = await wallet_maker.get_new_puzzlehash()
530
- ph_taker = await wallet_taker.get_new_puzzlehash()
531
- ph_token = bytes32.random(seeded_random)
532
-
533
- if trusted:
534
- wallet_node_0.config["trusted_peers"] = {
535
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
536
- }
537
- wallet_node_1.config["trusted_peers"] = {
538
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
539
- }
540
- else:
541
- wallet_node_0.config["trusted_peers"] = {}
542
- wallet_node_1.config["trusted_peers"] = {}
543
-
544
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
545
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
546
-
547
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
548
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
549
-
550
- funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
551
-
552
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
553
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
554
-
555
- async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
556
- did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
557
- wallet_node_0.wallet_state_manager, wallet_maker, uint64(1), action_scope
558
- )
559
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
560
- await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
561
-
562
- hex_did_id = did_wallet.get_my_DID()
563
- did_id = bytes32.fromhex(hex_did_id)
564
-
565
- await time_out_assert(5, did_wallet.get_confirmed_balance, 1)
566
-
567
- nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
568
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1", did_id=did_id
569
- )
347
+ txs.extend(resp.transactions)
348
+ xch_adds = [
349
+ c
350
+ for tx in resp.transactions
351
+ if tx.spend_bundle is not None
352
+ for c in tx.spend_bundle.additions()
353
+ if c.puzzle_hash == funding_coin.puzzle_hash
354
+ ]
355
+ assert len(xch_adds) == 1
356
+ next_coin = xch_adds[0]
357
+ for nft_id in resp.nft_id_list:
358
+ nft_ids.add(decode_puzzle_hash(nft_id))
570
359
 
571
- nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
572
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
573
- )
360
+ await env_0.rpc_client.push_transactions(PushTransactions(transactions=txs), wallet_environments.tx_config)
574
361
 
575
- # construct sample metadata
576
- metadata = Program.to(
362
+ await wallet_environments.process_pending_states(
577
363
  [
578
- ("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
579
- ("h", "0xD4584AD463139FA8C0D9F68F4B59F185"),
364
+ WalletStateTransition(
365
+ pre_block_balance_updates={
366
+ "xch": {
367
+ "unconfirmed_wallet_balance": -(fee * num_chunks) - n,
368
+ "<=#spendable_balance": -(fee * num_chunks) - n,
369
+ "<=#max_send_amount": -(fee * num_chunks) - n,
370
+ ">=#pending_change": 1,
371
+ "pending_coin_removal_count": num_chunks,
372
+ },
373
+ "did": {
374
+ "spendable_balance": -1,
375
+ "max_send_amount": -1,
376
+ # 2 here feels a bit weird but I'm not sure it's necessarily incorrect
377
+ "pending_change": 2,
378
+ "pending_coin_removal_count": 2,
379
+ }
380
+ if with_did
381
+ else {},
382
+ "nft": {
383
+ "pending_coin_removal_count": n,
384
+ },
385
+ },
386
+ post_block_balance_updates={
387
+ "xch": {
388
+ "confirmed_wallet_balance": -(fee * num_chunks) - n,
389
+ ">=#spendable_balance": 1,
390
+ ">=#max_send_amount": 1,
391
+ "<=#pending_change": -1,
392
+ "pending_coin_removal_count": -num_chunks,
393
+ },
394
+ "did": {
395
+ "spendable_balance": 1,
396
+ "max_send_amount": 1,
397
+ "pending_change": -2,
398
+ "pending_coin_removal_count": -2,
399
+ }
400
+ if with_did
401
+ else {},
402
+ "nft": {
403
+ "pending_coin_removal_count": -n,
404
+ },
405
+ },
406
+ ),
407
+ WalletStateTransition(
408
+ pre_block_balance_updates={},
409
+ post_block_balance_updates={
410
+ "nft": {
411
+ "unspent_coin_count": n,
412
+ }
413
+ },
414
+ ),
580
415
  ]
581
416
  )
582
- royalty_pc = uint16(300)
583
- royalty_addr = ph_maker
584
-
585
- mint_total = 1
586
- fee = uint64(100)
587
- metadata_list = [
588
- {"program": metadata, "royalty_pc": royalty_pc, "royalty_ph": royalty_addr} for x in range(mint_total)
589
- ]
590
-
591
- # Grab two coins for testing that we can create a bulk minting with more than 1 xch coin
592
- async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
593
- xch_coins_1 = await wallet_maker.select_coins(amount=10000, action_scope=action_scope)
594
- xch_coins_2 = await wallet_maker.select_coins(
595
- amount=10000,
596
- action_scope=action_scope,
597
- )
598
- xch_coins = xch_coins_1.union(xch_coins_2)
599
-
600
- target_list = [ph_taker for x in range(mint_total)]
601
417
 
602
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
603
- await nft_wallet_maker.mint_from_did(
604
- metadata_list,
605
- action_scope,
606
- target_list=target_list,
607
- mint_number_start=1,
608
- mint_total=mint_total,
609
- xch_coins=xch_coins,
610
- fee=fee,
611
- )
612
- sb = action_scope.side_effects.transactions[0].spend_bundle
613
- assert sb is not None
614
-
615
- await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, sb.name())
616
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
617
-
618
- await time_out_assert(30, nft_count, mint_total, nft_wallet_taker)
619
- await time_out_assert(30, nft_count, 0, nft_wallet_maker)
620
-
621
- # confirm that the spend uses the right amount of xch
622
- expected_xch_bal = funds - fee - mint_total - 1
623
- await time_out_assert(30, wallet_maker.get_confirmed_balance, expected_xch_bal)
624
-
625
-
626
- @pytest.mark.parametrize(
627
- "trusted",
628
- [True, False],
629
- )
418
+ # check NFT edition numbers
419
+ nfts = [nft for nft in (await env_1.rpc_client.list_nfts(NFTGetNFTs(uint32(env_1.wallet_aliases["nft"])))).nft_list]
420
+ for nft in nfts:
421
+ edition_num = nft.edition_number
422
+ meta_dict = metadata_list[edition_num - 1]
423
+ assert meta_dict["hash"] == nft.data_hash.hex()
424
+ assert meta_dict["uris"] == nft.data_uris
425
+ assert meta_dict["meta_hash"] == nft.metadata_hash.hex()
426
+ assert meta_dict["meta_uris"] == nft.metadata_uris
427
+ assert meta_dict["license_hash"] == nft.license_hash.hex()
428
+ assert meta_dict["license_uris"] == nft.license_uris
429
+ assert meta_dict["edition_number"] == nft.edition_number
430
+ assert meta_dict["edition_total"] == nft.edition_total
431
+ assert nft.launcher_id in nft_ids
432
+
433
+
434
+ @pytest.mark.limit_consensus_modes
435
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
436
+ @pytest.mark.parametrize("with_did", [True, False])
630
437
  @pytest.mark.anyio
631
- async def test_nft_mint_from_xch(
632
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
633
- ) -> None:
634
- full_nodes, wallets, _ = two_wallet_nodes
635
- full_node_api: FullNodeSimulator = full_nodes[0]
636
- full_node_server = full_node_api.server
637
- wallet_node_0, server_0 = wallets[0]
638
- wallet_node_1, server_1 = wallets[1]
639
- wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
640
- wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
641
- ph_maker = await wallet_0.get_new_puzzlehash()
642
- ph_token = bytes32.random(seeded_random)
643
-
644
- if trusted:
645
- wallet_node_0.config["trusted_peers"] = {
646
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
647
- }
648
- wallet_node_1.config["trusted_peers"] = {
649
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
650
- }
651
- else:
652
- wallet_node_0.config["trusted_peers"] = {}
653
- wallet_node_1.config["trusted_peers"] = {}
654
-
655
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
656
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
657
-
658
- # for _ in range(1, num_blocks):
659
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
660
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
661
- funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
662
-
663
- await time_out_assert(30, wallet_0.get_unconfirmed_balance, funds)
664
- await time_out_assert(30, wallet_0.get_confirmed_balance, funds)
665
-
666
- async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
438
+ async def test_nft_mint_multiple_xch(wallet_environments: WalletTestFramework, with_did: bool) -> None:
439
+ env_0 = wallet_environments.environments[0]
440
+ env_1 = wallet_environments.environments[1]
441
+ wallet_0 = env_0.xch_wallet
442
+ wallet_1 = env_1.xch_wallet
443
+ env_0.wallet_aliases = {
444
+ "xch": 1,
445
+ "did": 2,
446
+ "nft": 3,
447
+ }
448
+ env_1.wallet_aliases = {
449
+ "xch": 1,
450
+ "nft": 2,
451
+ }
452
+
453
+ async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
454
+ ph_0 = await action_scope.get_puzzle_hash(env_0.wallet_state_manager)
667
455
  did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
668
- wallet_node_0.wallet_state_manager, wallet_0, uint64(1), action_scope
456
+ env_0.wallet_state_manager, wallet_0, uint64(1), action_scope
669
457
  )
670
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
671
- await time_out_assert(30, wallet_0.get_pending_change_balance, 0)
672
-
673
- hex_did_id = did_wallet.get_my_DID()
674
- did_id = bytes32.fromhex(hex_did_id)
675
-
676
- await time_out_assert(5, did_wallet.get_confirmed_balance, 1)
677
-
678
- nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
679
- wallet_node_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
680
- )
681
-
682
- nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
683
- wallet_node_1.wallet_state_manager, wallet_1, name="NFT WALLET 2"
684
- )
685
-
686
- royalty_pc = uint16(300)
687
- royalty_addr = ph_maker
458
+ async with env_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
459
+ ph_1 = await action_scope.get_puzzle_hash(env_1.wallet_state_manager)
688
460
 
689
- mint_total = 1
690
- fee = uint64(100)
691
- metadata_list = [
692
- {
693
- "program": Program.to(
694
- [("u", ["https://www.chia.net/img/branding/chia-logo.svg"]), ("h", bytes32.random(seeded_random).hex())]
461
+ await wallet_environments.process_pending_states(
462
+ [
463
+ WalletStateTransition(
464
+ pre_block_balance_updates={
465
+ "xch": {
466
+ "set_remainder": True,
467
+ },
468
+ "did": {
469
+ "init": True,
470
+ "set_remainder": True,
471
+ },
472
+ },
473
+ post_block_balance_updates={
474
+ "xch": {
475
+ "set_remainder": True,
476
+ },
477
+ "did": {
478
+ "set_remainder": True,
479
+ },
480
+ },
695
481
  ),
696
- "royalty_pc": royalty_pc,
697
- "royalty_ph": royalty_addr,
698
- }
699
- for x in range(mint_total)
700
- ]
701
-
702
- target_list = [(await wallet_1.get_new_puzzlehash()) for x in range(mint_total)]
703
-
704
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
705
- await nft_wallet_maker.mint_from_xch(
706
- metadata_list,
707
- action_scope,
708
- target_list=target_list,
709
- mint_number_start=1,
710
- mint_total=mint_total,
711
- fee=fee,
712
- )
713
-
714
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
715
-
716
- await time_out_assert(30, nft_count, mint_total, nft_wallet_taker)
717
- await time_out_assert(30, nft_count, 0, nft_wallet_maker)
718
-
719
- expected_xch_bal = funds - fee - mint_total - 1
720
- await time_out_assert(30, wallet_0.get_confirmed_balance, expected_xch_bal)
721
-
722
- nfts = await nft_wallet_taker.get_current_nfts()
723
- matched_data = dict(zip(target_list, metadata_list))
724
-
725
- # Check targets and metadata entries match in the final nfts
726
- for nft in nfts:
727
- mod, args = nft.full_puzzle.uncurry()
728
- unft = UncurriedNFT.uncurry(mod, args)
729
- assert isinstance(unft, UncurriedNFT)
730
- inner_args = unft.inner_puzzle.uncurry()[1]
731
- inner_ph = inner_args.at("rrrf").get_tree_hash()
732
- meta = unft.metadata.at("rfr").as_atom()
733
- # check that the target puzzle hashes of transferred nfts matches the metadata entry
734
- assert matched_data[inner_ph]["program"].at("rfr").as_atom() == meta
735
- assert not nft.minter_did
736
-
737
-
738
- @pytest.mark.parametrize(
739
- "trusted",
740
- [True, False],
741
- )
742
- @pytest.mark.anyio
743
- async def test_nft_mint_from_xch_rpc(
744
- two_wallet_nodes_services: SimulatorsAndWalletsServices,
745
- trusted: Any,
746
- self_hostname: str,
747
- seeded_random: random.Random,
748
- ) -> None:
749
- [full_node_service], wallet_services, bt = two_wallet_nodes_services
750
- full_node_api: FullNodeSimulator = full_node_service._api
751
- full_node_server = full_node_api.server
752
- wallet_node_maker = wallet_services[0]._node
753
- wallet_node_taker = wallet_services[1]._node
754
- server_0 = wallet_node_maker.server
755
- server_1 = wallet_node_taker.server
756
- wallet_maker = wallet_node_maker.wallet_state_manager.main_wallet
757
- wallet_taker = wallet_node_taker.wallet_state_manager.main_wallet
758
-
759
- ph_maker = await wallet_maker.get_new_puzzlehash()
760
- ph_taker = await wallet_taker.get_new_puzzlehash()
761
- ph_token = bytes32.random(seeded_random)
762
-
763
- if trusted:
764
- wallet_node_maker.config["trusted_peers"] = {
765
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
766
- }
767
- wallet_node_taker.config["trusted_peers"] = {
768
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
769
- }
770
- else:
771
- wallet_node_maker.config["trusted_peers"] = {}
772
- wallet_node_taker.config["trusted_peers"] = {}
773
-
774
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
775
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
776
-
777
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
778
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_taker))
779
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
780
-
781
- funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
782
-
783
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
784
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
785
- await time_out_assert(30, wallet_taker.get_unconfirmed_balance, funds)
786
- await time_out_assert(30, wallet_taker.get_confirmed_balance, funds)
787
-
788
- api_maker = WalletRpcApi(wallet_node_maker)
789
- api_taker = WalletRpcApi(wallet_node_taker)
790
- config = bt.config
791
-
792
- assert wallet_services[0].rpc_server is not None
793
- assert full_node_service.rpc_server is not None
794
-
795
- async with contextlib.AsyncExitStack() as exit_stack:
796
- client = await exit_stack.enter_async_context(
797
- WalletRpcClient.create_as_context(
798
- self_hostname,
799
- wallet_services[0].rpc_server.listen_port,
800
- wallet_services[0].root_path,
801
- wallet_services[0].config,
802
- )
803
- )
804
- client_node = await exit_stack.enter_async_context(
805
- FullNodeRpcClient.create_as_context(
806
- self_hostname,
807
- full_node_service.rpc_server.listen_port,
808
- full_node_service.root_path,
809
- full_node_service.config,
810
- )
811
- )
812
-
813
- async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
814
- did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
815
- wallet_node_maker.wallet_state_manager, wallet_maker, uint64(1), action_scope
816
- )
817
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
818
-
819
- await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
820
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds - 1)
821
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds - 1)
822
-
823
- hex_did_id = did_wallet_maker.get_my_DID()
824
- hmr_did_id = encode_puzzle_hash(bytes32.from_hexstr(hex_did_id), AddressType.DID.hrp(config))
825
-
826
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
827
-
828
- nft_wallet_maker = await api_maker.create_new_wallet(
829
- dict(wallet_type="nft_wallet", name="NFT WALLET 1", did_id=hmr_did_id)
830
- )
831
- assert isinstance(nft_wallet_maker, dict)
832
- assert nft_wallet_maker.get("success")
833
-
834
- nft_wallet_taker = await api_taker.create_new_wallet(dict(wallet_type="nft_wallet", name="NFT WALLET 2"))
835
-
836
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
837
-
838
- n = 10
839
- metadata_list = [
840
- {
841
- "hash": bytes32.random(seeded_random).hex(),
842
- "uris": [f"https://data.com/{i}"],
843
- "meta_hash": bytes32.random(seeded_random).hex(),
844
- "meta_uris": [f"https://meatadata.com/{i}"],
845
- "license_hash": bytes32.random(seeded_random).hex(),
846
- "license_uris": [f"https://license.com/{i}"],
847
- "edition_number": i + 1,
848
- "edition_total": n,
849
- }
850
- for i in range(n)
482
+ WalletStateTransition(),
851
483
  ]
852
- target_list = [encode_puzzle_hash((ph_taker), "xch") for x in range(n)]
853
- royalty_address = encode_puzzle_hash(bytes32.random(seeded_random), "xch")
854
- royalty_percentage = 300
855
- fee = 100
856
- required_amount = n + (fee * n)
857
- xch_coins = await client.select_coins(
858
- amount=required_amount, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=wallet_maker.id()
859
- )
860
- funding_coin = xch_coins[0]
861
- assert funding_coin.amount >= required_amount
862
- funding_coin_dict = xch_coins[0].to_json_dict()
863
- chunk = 5
864
- next_coin = funding_coin
865
- spends = []
866
-
867
- for i in range(0, n, chunk):
868
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
869
- resp = await client.nft_mint_bulk(
870
- wallet_id=nft_wallet_maker["wallet_id"],
871
- metadata_list=metadata_list[i : i + chunk],
872
- target_list=target_list[i : i + chunk],
873
- royalty_percentage=royalty_percentage,
874
- royalty_address=royalty_address,
875
- mint_number_start=i + 1,
876
- mint_total=n,
877
- xch_coins=[next_coin.to_json_dict()],
878
- xch_change_target=funding_coin_dict["puzzle_hash"],
879
- mint_from_did=False,
880
- fee=fee,
881
- tx_config=DEFAULT_TX_CONFIG,
882
- )
883
- sb = resp.spend_bundle
884
- spends.append(sb)
885
- xch_adds = [c for c in sb.additions() if c.puzzle_hash == funding_coin.puzzle_hash]
886
- assert len(xch_adds) == 1
887
- next_coin = xch_adds[0]
888
-
889
- for sb in spends:
890
- push_resp = await client_node.push_tx(sb)
891
- assert push_resp["success"]
892
- await full_node_api.process_spend_bundles([sb])
893
-
894
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
895
-
896
- async def get_taker_nfts() -> int:
897
- return int((await api_taker.nft_count_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["count"])
898
-
899
- # We are using a long time out here because it can take a long time for the NFTs to show up
900
- # Even with only 10 NFTs it regularly takes longer than 30-40s for them to be found
901
- await time_out_assert(60, get_taker_nfts, n)
902
-
903
- # check NFT edition numbers
904
- nfts = (await api_taker.nft_get_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["nft_list"]
905
- for nft in nfts:
906
- edition_num = nft.edition_number
907
- meta_dict = metadata_list[edition_num - 1]
908
- assert meta_dict["hash"] == nft.data_hash.hex()
909
- assert meta_dict["uris"] == nft.data_uris
910
- assert meta_dict["meta_hash"] == nft.metadata_hash.hex()
911
- assert meta_dict["meta_uris"] == nft.metadata_uris
912
- assert meta_dict["license_hash"] == nft.license_hash.hex()
913
- assert meta_dict["license_uris"] == nft.license_uris
914
- assert meta_dict["edition_number"] == nft.edition_number
915
- assert meta_dict["edition_total"] == nft.edition_total
916
-
917
-
918
- @pytest.mark.parametrize(
919
- "trusted",
920
- [True, False],
921
- )
922
- @pytest.mark.anyio
923
- async def test_nft_mint_from_xch_multiple_xch(
924
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
925
- ) -> None:
926
- full_nodes, wallets, _ = two_wallet_nodes
927
- full_node_api: FullNodeSimulator = full_nodes[0]
928
- full_node_server = full_node_api.server
929
- wallet_node_0, server_0 = wallets[0]
930
- wallet_node_1, server_1 = wallets[1]
931
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
932
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
933
- ph_maker = await wallet_maker.get_new_puzzlehash()
934
- ph_taker = await wallet_taker.get_new_puzzlehash()
935
- ph_token = bytes32.random(seeded_random)
936
-
937
- if trusted:
938
- wallet_node_0.config["trusted_peers"] = {
939
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
940
- }
941
- wallet_node_1.config["trusted_peers"] = {
942
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
943
- }
944
- else:
945
- wallet_node_0.config["trusted_peers"] = {}
946
- wallet_node_1.config["trusted_peers"] = {}
947
-
948
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
949
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
950
-
951
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
952
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
953
-
954
- funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
955
-
956
- await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
957
- await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
958
-
959
- async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
960
- did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
961
- wallet_node_0.wallet_state_manager, wallet_maker, uint64(1), action_scope
962
- )
963
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
964
- await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
484
+ )
965
485
 
966
486
  hex_did_id = did_wallet.get_my_DID()
967
487
  did_id = bytes32.fromhex(hex_did_id)
968
488
 
969
489
  await time_out_assert(5, did_wallet.get_confirmed_balance, 1)
970
490
 
971
- nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
972
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1", did_id=did_id
491
+ nft_wallet_0 = await NFTWallet.create_new_nft_wallet(
492
+ env_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
973
493
  )
974
494
 
975
- nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
976
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
977
- )
495
+ await NFTWallet.create_new_nft_wallet(wallet_1.wallet_state_manager, wallet_1, name="NFT WALLET 2")
496
+
497
+ await env_0.change_balances({"nft": {"init": True}})
498
+ await env_1.change_balances({"nft": {"init": True}})
978
499
 
979
500
  # construct sample metadata
980
501
  metadata = Program.to(
@@ -984,7 +505,7 @@ async def test_nft_mint_from_xch_multiple_xch(
984
505
  ]
985
506
  )
986
507
  royalty_pc = uint16(300)
987
- royalty_addr = ph_maker
508
+ royalty_addr = ph_0
988
509
 
989
510
  mint_total = 1
990
511
  fee = uint64(100)
@@ -993,32 +514,90 @@ async def test_nft_mint_from_xch_multiple_xch(
993
514
  ]
994
515
 
995
516
  # Grab two coins for testing that we can create a bulk minting with more than 1 xch coin
996
- async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
997
- xch_coins_1 = await wallet_maker.select_coins(amount=10000, action_scope=action_scope)
998
- xch_coins_2 = await wallet_maker.select_coins(
999
- amount=10000,
517
+ async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=False) as action_scope:
518
+ xch_coins_1 = await wallet_0.select_coins(amount=uint64(10000), action_scope=action_scope)
519
+ xch_coins_2 = await wallet_0.select_coins(
520
+ amount=uint64(10000),
1000
521
  action_scope=action_scope,
1001
522
  )
1002
523
  xch_coins = xch_coins_1.union(xch_coins_2)
1003
524
 
1004
- target_list = [ph_taker for x in range(mint_total)]
1005
-
1006
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1007
- await nft_wallet_maker.mint_from_xch(
1008
- metadata_list,
1009
- action_scope,
1010
- target_list=target_list,
1011
- mint_number_start=1,
1012
- mint_total=mint_total,
1013
- xch_coins=xch_coins,
1014
- fee=fee,
1015
- )
1016
-
1017
- await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
1018
-
1019
- await time_out_assert(30, nft_count, mint_total, nft_wallet_taker)
1020
- await time_out_assert(30, nft_count, 0, nft_wallet_maker)
525
+ target_list = [ph_1 for x in range(mint_total)]
526
+
527
+ async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
528
+ if with_did:
529
+ await nft_wallet_0.mint_from_did(
530
+ metadata_list,
531
+ action_scope,
532
+ target_list=target_list,
533
+ mint_number_start=1,
534
+ mint_total=mint_total,
535
+ xch_coins=xch_coins,
536
+ fee=fee,
537
+ )
538
+ else:
539
+ await nft_wallet_0.mint_from_xch(
540
+ metadata_list,
541
+ action_scope,
542
+ target_list=target_list,
543
+ mint_number_start=1,
544
+ mint_total=mint_total,
545
+ xch_coins=xch_coins,
546
+ fee=fee,
547
+ )
1021
548
 
1022
- # confirm that the spend uses the right amount of xch
1023
- expected_xch_bal = funds - fee - mint_total - 1
1024
- await time_out_assert(30, wallet_maker.get_confirmed_balance, expected_xch_bal)
549
+ await wallet_environments.process_pending_states(
550
+ [
551
+ WalletStateTransition(
552
+ pre_block_balance_updates={
553
+ "xch": {
554
+ "unconfirmed_wallet_balance": -fee - mint_total,
555
+ "<=#spendable_balance": -fee - mint_total,
556
+ "<=#max_send_amount": -fee - mint_total,
557
+ ">=#pending_change": 1,
558
+ "pending_coin_removal_count": 2,
559
+ },
560
+ "did": {
561
+ "spendable_balance": -1,
562
+ "max_send_amount": -1,
563
+ "pending_change": 1,
564
+ "pending_coin_removal_count": 1,
565
+ }
566
+ if with_did
567
+ else {},
568
+ "nft": {
569
+ "pending_coin_removal_count": mint_total,
570
+ },
571
+ },
572
+ post_block_balance_updates={
573
+ "xch": {
574
+ "confirmed_wallet_balance": -fee - mint_total,
575
+ ">=#spendable_balance": 1,
576
+ ">=#max_send_amount": 1,
577
+ "<=#pending_change": -1,
578
+ "pending_coin_removal_count": -2,
579
+ "unspent_coin_count": -1, # The two coins get combined for change
580
+ },
581
+ "did": {
582
+ "spendable_balance": 1,
583
+ "max_send_amount": 1,
584
+ "pending_change": -1,
585
+ "pending_coin_removal_count": -1,
586
+ }
587
+ if with_did
588
+ else {},
589
+ "nft": {
590
+ "pending_coin_removal_count": -mint_total,
591
+ },
592
+ },
593
+ ),
594
+ WalletStateTransition(
595
+ pre_block_balance_updates={},
596
+ post_block_balance_updates={
597
+ "nft": {
598
+ "unspent_coin_count": mint_total,
599
+ }
600
+ },
601
+ ),
602
+ ]
603
+ )