chia-blockchain 2.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1028) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +197 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +147 -0
  9. chia/_tests/blockchain/test_blockchain.py +4100 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1050 -0
  11. chia/_tests/blockchain/test_build_chains.py +61 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +195 -0
  14. chia/_tests/build-init-files.py +93 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +73 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +147 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +57 -0
  26. chia/_tests/clvm/test_program.py +150 -0
  27. chia/_tests/clvm/test_puzzle_compression.py +144 -0
  28. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  29. chia/_tests/clvm/test_puzzles.py +247 -0
  30. chia/_tests/clvm/test_singletons.py +540 -0
  31. chia/_tests/clvm/test_spend_sim.py +181 -0
  32. chia/_tests/cmds/__init__.py +0 -0
  33. chia/_tests/cmds/cmd_test_utils.py +472 -0
  34. chia/_tests/cmds/config.py +3 -0
  35. chia/_tests/cmds/conftest.py +23 -0
  36. chia/_tests/cmds/test_click_types.py +195 -0
  37. chia/_tests/cmds/test_cmd_framework.py +400 -0
  38. chia/_tests/cmds/test_cmds_util.py +97 -0
  39. chia/_tests/cmds/test_daemon.py +92 -0
  40. chia/_tests/cmds/test_farm_cmd.py +67 -0
  41. chia/_tests/cmds/test_show.py +116 -0
  42. chia/_tests/cmds/test_sim.py +207 -0
  43. chia/_tests/cmds/test_timelock_args.py +75 -0
  44. chia/_tests/cmds/test_tx_config_args.py +153 -0
  45. chia/_tests/cmds/testing_classes.py +59 -0
  46. chia/_tests/cmds/wallet/__init__.py +0 -0
  47. chia/_tests/cmds/wallet/test_coins.py +195 -0
  48. chia/_tests/cmds/wallet/test_consts.py +47 -0
  49. chia/_tests/cmds/wallet/test_dao.py +565 -0
  50. chia/_tests/cmds/wallet/test_did.py +403 -0
  51. chia/_tests/cmds/wallet/test_nft.py +470 -0
  52. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  53. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  54. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  55. chia/_tests/cmds/wallet/test_vcs.py +376 -0
  56. chia/_tests/cmds/wallet/test_wallet.py +1126 -0
  57. chia/_tests/cmds/wallet/test_wallet_check.py +111 -0
  58. chia/_tests/conftest.py +1304 -0
  59. chia/_tests/connection_utils.py +124 -0
  60. chia/_tests/core/__init__.py +0 -0
  61. chia/_tests/core/cmds/__init__.py +0 -0
  62. chia/_tests/core/cmds/test_beta.py +382 -0
  63. chia/_tests/core/cmds/test_keys.py +1734 -0
  64. chia/_tests/core/cmds/test_wallet.py +126 -0
  65. chia/_tests/core/config.py +3 -0
  66. chia/_tests/core/consensus/__init__.py +0 -0
  67. chia/_tests/core/consensus/test_block_creation.py +56 -0
  68. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  69. chia/_tests/core/custom_types/__init__.py +0 -0
  70. chia/_tests/core/custom_types/test_coin.py +109 -0
  71. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  72. chia/_tests/core/custom_types/test_spend_bundle.py +71 -0
  73. chia/_tests/core/daemon/__init__.py +0 -0
  74. chia/_tests/core/daemon/config.py +4 -0
  75. chia/_tests/core/daemon/test_daemon.py +2128 -0
  76. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  77. chia/_tests/core/daemon/test_keychain_proxy.py +100 -0
  78. chia/_tests/core/data_layer/__init__.py +0 -0
  79. chia/_tests/core/data_layer/config.py +5 -0
  80. chia/_tests/core/data_layer/conftest.py +105 -0
  81. chia/_tests/core/data_layer/test_data_cli.py +57 -0
  82. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  83. chia/_tests/core/data_layer/test_data_layer_util.py +219 -0
  84. chia/_tests/core/data_layer/test_data_rpc.py +3865 -0
  85. chia/_tests/core/data_layer/test_data_store.py +2423 -0
  86. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  87. chia/_tests/core/data_layer/test_plugin.py +91 -0
  88. chia/_tests/core/data_layer/util.py +232 -0
  89. chia/_tests/core/farmer/__init__.py +0 -0
  90. chia/_tests/core/farmer/config.py +3 -0
  91. chia/_tests/core/farmer/test_farmer_api.py +101 -0
  92. chia/_tests/core/full_node/__init__.py +0 -0
  93. chia/_tests/core/full_node/config.py +4 -0
  94. chia/_tests/core/full_node/dos/__init__.py +0 -0
  95. chia/_tests/core/full_node/dos/config.py +3 -0
  96. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  97. chia/_tests/core/full_node/full_sync/config.py +4 -0
  98. chia/_tests/core/full_node/full_sync/test_full_sync.py +448 -0
  99. chia/_tests/core/full_node/ram_db.py +27 -0
  100. chia/_tests/core/full_node/stores/__init__.py +0 -0
  101. chia/_tests/core/full_node/stores/config.py +4 -0
  102. chia/_tests/core/full_node/stores/test_block_store.py +488 -0
  103. chia/_tests/core/full_node/stores/test_coin_store.py +888 -0
  104. chia/_tests/core/full_node/stores/test_full_node_store.py +1215 -0
  105. chia/_tests/core/full_node/stores/test_hint_store.py +230 -0
  106. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  107. chia/_tests/core/full_node/test_address_manager.py +588 -0
  108. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  109. chia/_tests/core/full_node/test_conditions.py +558 -0
  110. chia/_tests/core/full_node/test_full_node.py +2445 -0
  111. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  112. chia/_tests/core/full_node/test_hint_management.py +104 -0
  113. chia/_tests/core/full_node/test_node_load.py +34 -0
  114. chia/_tests/core/full_node/test_performance.py +182 -0
  115. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  116. chia/_tests/core/full_node/test_transactions.py +203 -0
  117. chia/_tests/core/full_node/test_tx_processing_queue.py +154 -0
  118. chia/_tests/core/large_block.py +2388 -0
  119. chia/_tests/core/make_block_generator.py +72 -0
  120. chia/_tests/core/mempool/__init__.py +0 -0
  121. chia/_tests/core/mempool/config.py +4 -0
  122. chia/_tests/core/mempool/test_mempool.py +3180 -0
  123. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  124. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  125. chia/_tests/core/mempool/test_mempool_item_queries.py +192 -0
  126. chia/_tests/core/mempool/test_mempool_manager.py +2054 -0
  127. chia/_tests/core/mempool/test_mempool_performance.py +65 -0
  128. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  129. chia/_tests/core/node_height.py +28 -0
  130. chia/_tests/core/server/__init__.py +0 -0
  131. chia/_tests/core/server/config.py +3 -0
  132. chia/_tests/core/server/flood.py +82 -0
  133. chia/_tests/core/server/serve.py +132 -0
  134. chia/_tests/core/server/test_capabilities.py +68 -0
  135. chia/_tests/core/server/test_dos.py +320 -0
  136. chia/_tests/core/server/test_event_loop.py +109 -0
  137. chia/_tests/core/server/test_loop.py +290 -0
  138. chia/_tests/core/server/test_node_discovery.py +74 -0
  139. chia/_tests/core/server/test_rate_limits.py +370 -0
  140. chia/_tests/core/server/test_server.py +225 -0
  141. chia/_tests/core/server/test_upnp.py +8 -0
  142. chia/_tests/core/services/__init__.py +0 -0
  143. chia/_tests/core/services/config.py +3 -0
  144. chia/_tests/core/services/test_services.py +166 -0
  145. chia/_tests/core/ssl/__init__.py +0 -0
  146. chia/_tests/core/ssl/config.py +3 -0
  147. chia/_tests/core/ssl/test_ssl.py +198 -0
  148. chia/_tests/core/test_coins.py +33 -0
  149. chia/_tests/core/test_cost_calculation.py +314 -0
  150. chia/_tests/core/test_crawler.py +175 -0
  151. chia/_tests/core/test_crawler_rpc.py +53 -0
  152. chia/_tests/core/test_daemon_rpc.py +24 -0
  153. chia/_tests/core/test_db_conversion.py +129 -0
  154. chia/_tests/core/test_db_validation.py +161 -0
  155. chia/_tests/core/test_farmer_harvester_rpc.py +504 -0
  156. chia/_tests/core/test_filter.py +37 -0
  157. chia/_tests/core/test_full_node_rpc.py +794 -0
  158. chia/_tests/core/test_merkle_set.py +343 -0
  159. chia/_tests/core/test_program.py +49 -0
  160. chia/_tests/core/test_rpc_util.py +87 -0
  161. chia/_tests/core/test_seeder.py +308 -0
  162. chia/_tests/core/test_setproctitle.py +13 -0
  163. chia/_tests/core/util/__init__.py +0 -0
  164. chia/_tests/core/util/config.py +4 -0
  165. chia/_tests/core/util/test_block_cache.py +44 -0
  166. chia/_tests/core/util/test_cached_bls.py +57 -0
  167. chia/_tests/core/util/test_config.py +337 -0
  168. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  169. chia/_tests/core/util/test_files.py +391 -0
  170. chia/_tests/core/util/test_jsonify.py +146 -0
  171. chia/_tests/core/util/test_keychain.py +514 -0
  172. chia/_tests/core/util/test_keyring_wrapper.py +490 -0
  173. chia/_tests/core/util/test_lockfile.py +380 -0
  174. chia/_tests/core/util/test_log_exceptions.py +187 -0
  175. chia/_tests/core/util/test_lru_cache.py +56 -0
  176. chia/_tests/core/util/test_significant_bits.py +40 -0
  177. chia/_tests/core/util/test_streamable.py +883 -0
  178. chia/_tests/db/__init__.py +0 -0
  179. chia/_tests/db/test_db_wrapper.py +565 -0
  180. chia/_tests/environments/__init__.py +0 -0
  181. chia/_tests/environments/common.py +35 -0
  182. chia/_tests/environments/full_node.py +47 -0
  183. chia/_tests/environments/wallet.py +368 -0
  184. chia/_tests/ether.py +19 -0
  185. chia/_tests/farmer_harvester/__init__.py +0 -0
  186. chia/_tests/farmer_harvester/config.py +3 -0
  187. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  188. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  189. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +130 -0
  190. chia/_tests/farmer_harvester/test_third_party_harvesters.py +501 -0
  191. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  192. chia/_tests/fee_estimation/__init__.py +0 -0
  193. chia/_tests/fee_estimation/config.py +3 -0
  194. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  195. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +145 -0
  197. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  198. chia/_tests/generator/__init__.py +0 -0
  199. chia/_tests/generator/puzzles/__init__.py +0 -0
  200. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  201. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  202. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  203. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  204. chia/_tests/generator/test_compression.py +218 -0
  205. chia/_tests/generator/test_generator_types.py +44 -0
  206. chia/_tests/generator/test_rom.py +182 -0
  207. chia/_tests/plot_sync/__init__.py +0 -0
  208. chia/_tests/plot_sync/config.py +3 -0
  209. chia/_tests/plot_sync/test_delta.py +102 -0
  210. chia/_tests/plot_sync/test_plot_sync.py +617 -0
  211. chia/_tests/plot_sync/test_receiver.py +451 -0
  212. chia/_tests/plot_sync/test_sender.py +116 -0
  213. chia/_tests/plot_sync/test_sync_simulated.py +450 -0
  214. chia/_tests/plot_sync/util.py +67 -0
  215. chia/_tests/plotting/__init__.py +0 -0
  216. chia/_tests/plotting/config.py +3 -0
  217. chia/_tests/plotting/test_plot_manager.py +738 -0
  218. chia/_tests/plotting/util.py +13 -0
  219. chia/_tests/pools/__init__.py +0 -0
  220. chia/_tests/pools/config.py +5 -0
  221. chia/_tests/pools/test_pool_cmdline.py +23 -0
  222. chia/_tests/pools/test_pool_config.py +44 -0
  223. chia/_tests/pools/test_pool_puzzles_lifecycle.py +398 -0
  224. chia/_tests/pools/test_pool_rpc.py +1010 -0
  225. chia/_tests/pools/test_pool_wallet.py +201 -0
  226. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  227. chia/_tests/process_junit.py +349 -0
  228. chia/_tests/rpc/__init__.py +0 -0
  229. chia/_tests/rpc/test_rpc_client.py +81 -0
  230. chia/_tests/simulation/__init__.py +0 -0
  231. chia/_tests/simulation/config.py +6 -0
  232. chia/_tests/simulation/test_simulation.py +501 -0
  233. chia/_tests/simulation/test_simulator.py +234 -0
  234. chia/_tests/simulation/test_start_simulator.py +106 -0
  235. chia/_tests/testconfig.py +13 -0
  236. chia/_tests/timelord/__init__.py +0 -0
  237. chia/_tests/timelord/config.py +3 -0
  238. chia/_tests/timelord/test_new_peak.py +437 -0
  239. chia/_tests/timelord/test_timelord.py +11 -0
  240. chia/_tests/tools/1315537.json +170 -0
  241. chia/_tests/tools/1315544.json +160 -0
  242. chia/_tests/tools/1315630.json +150 -0
  243. chia/_tests/tools/300000.json +105 -0
  244. chia/_tests/tools/442734.json +140 -0
  245. chia/_tests/tools/466212.json +130 -0
  246. chia/_tests/tools/__init__.py +0 -0
  247. chia/_tests/tools/config.py +5 -0
  248. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  249. chia/_tests/tools/test_full_sync.py +30 -0
  250. chia/_tests/tools/test_legacy_keyring.py +82 -0
  251. chia/_tests/tools/test_run_block.py +129 -0
  252. chia/_tests/util/__init__.py +0 -0
  253. chia/_tests/util/benchmark_cost.py +170 -0
  254. chia/_tests/util/benchmarks.py +154 -0
  255. chia/_tests/util/bip39_test_vectors.json +148 -0
  256. chia/_tests/util/blockchain.py +133 -0
  257. chia/_tests/util/blockchain_mock.py +132 -0
  258. chia/_tests/util/build_network_protocol_files.py +302 -0
  259. chia/_tests/util/clvm_generator.bin +0 -0
  260. chia/_tests/util/config.py +3 -0
  261. chia/_tests/util/constants.py +20 -0
  262. chia/_tests/util/db_connection.py +36 -0
  263. chia/_tests/util/full_sync.py +245 -0
  264. chia/_tests/util/gen_ssl_certs.py +115 -0
  265. chia/_tests/util/generator_tools_testing.py +47 -0
  266. chia/_tests/util/key_tool.py +37 -0
  267. chia/_tests/util/misc.py +722 -0
  268. chia/_tests/util/network_protocol_data.py +1074 -0
  269. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  270. chia/_tests/util/protocol_messages_json.py +2700 -0
  271. chia/_tests/util/rpc.py +23 -0
  272. chia/_tests/util/run_block.py +163 -0
  273. chia/_tests/util/setup_nodes.py +479 -0
  274. chia/_tests/util/split_managers.py +99 -0
  275. chia/_tests/util/temp_file.py +14 -0
  276. chia/_tests/util/test_action_scope.py +143 -0
  277. chia/_tests/util/test_async_pool.py +366 -0
  278. chia/_tests/util/test_build_job_matrix.py +43 -0
  279. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  280. chia/_tests/util/test_chia_version.py +50 -0
  281. chia/_tests/util/test_collection.py +11 -0
  282. chia/_tests/util/test_condition_tools.py +231 -0
  283. chia/_tests/util/test_config.py +426 -0
  284. chia/_tests/util/test_dump_keyring.py +60 -0
  285. chia/_tests/util/test_errors.py +10 -0
  286. chia/_tests/util/test_full_block_utils.py +271 -0
  287. chia/_tests/util/test_installed.py +20 -0
  288. chia/_tests/util/test_limited_semaphore.py +52 -0
  289. chia/_tests/util/test_logging_filter.py +43 -0
  290. chia/_tests/util/test_misc.py +444 -0
  291. chia/_tests/util/test_network.py +74 -0
  292. chia/_tests/util/test_network_protocol_files.py +579 -0
  293. chia/_tests/util/test_network_protocol_json.py +266 -0
  294. chia/_tests/util/test_network_protocol_test.py +257 -0
  295. chia/_tests/util/test_paginator.py +72 -0
  296. chia/_tests/util/test_pprint.py +17 -0
  297. chia/_tests/util/test_priority_mutex.py +487 -0
  298. chia/_tests/util/test_recursive_replace.py +116 -0
  299. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  300. chia/_tests/util/test_service_groups.py +15 -0
  301. chia/_tests/util/test_ssl_check.py +31 -0
  302. chia/_tests/util/test_testnet_overrides.py +19 -0
  303. chia/_tests/util/test_tests_misc.py +38 -0
  304. chia/_tests/util/test_timing.py +37 -0
  305. chia/_tests/util/test_trusted_peer.py +51 -0
  306. chia/_tests/util/time_out_assert.py +154 -0
  307. chia/_tests/wallet/__init__.py +0 -0
  308. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  309. chia/_tests/wallet/cat_wallet/config.py +4 -0
  310. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  311. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  312. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1738 -0
  313. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  314. chia/_tests/wallet/cat_wallet/test_trades.py +2578 -0
  315. chia/_tests/wallet/clawback/__init__.py +0 -0
  316. chia/_tests/wallet/clawback/config.py +3 -0
  317. chia/_tests/wallet/clawback/test_clawback_decorator.py +80 -0
  318. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  319. chia/_tests/wallet/clawback/test_clawback_metadata.py +51 -0
  320. chia/_tests/wallet/config.py +4 -0
  321. chia/_tests/wallet/conftest.py +217 -0
  322. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  323. chia/_tests/wallet/dao_wallet/config.py +3 -0
  324. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1322 -0
  325. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  326. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  327. chia/_tests/wallet/db_wallet/config.py +3 -0
  328. chia/_tests/wallet/db_wallet/test_db_graftroot.py +143 -0
  329. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  330. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  331. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  332. chia/_tests/wallet/did_wallet/config.py +4 -0
  333. chia/_tests/wallet/did_wallet/test_did.py +1481 -0
  334. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  335. chia/_tests/wallet/nft_wallet/config.py +4 -0
  336. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1492 -0
  337. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1014 -0
  338. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +376 -0
  339. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  340. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  341. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2558 -0
  342. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  343. chia/_tests/wallet/rpc/__init__.py +0 -0
  344. chia/_tests/wallet/rpc/config.py +4 -0
  345. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +287 -0
  346. chia/_tests/wallet/rpc/test_wallet_rpc.py +3106 -0
  347. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  348. chia/_tests/wallet/simple_sync/config.py +3 -0
  349. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +719 -0
  350. chia/_tests/wallet/sync/__init__.py +0 -0
  351. chia/_tests/wallet/sync/config.py +4 -0
  352. chia/_tests/wallet/sync/test_wallet_sync.py +1529 -0
  353. chia/_tests/wallet/test_address_type.py +189 -0
  354. chia/_tests/wallet/test_bech32m.py +45 -0
  355. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  356. chia/_tests/wallet/test_coin_selection.py +589 -0
  357. chia/_tests/wallet/test_conditions.py +388 -0
  358. chia/_tests/wallet/test_debug_spend_bundle.py +76 -0
  359. chia/_tests/wallet/test_new_wallet_protocol.py +1176 -0
  360. chia/_tests/wallet/test_nft_store.py +193 -0
  361. chia/_tests/wallet/test_notifications.py +196 -0
  362. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  363. chia/_tests/wallet/test_puzzle_store.py +133 -0
  364. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  365. chia/_tests/wallet/test_signer_protocol.py +948 -0
  366. chia/_tests/wallet/test_singleton.py +122 -0
  367. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  368. chia/_tests/wallet/test_singleton_store.py +152 -0
  369. chia/_tests/wallet/test_taproot.py +19 -0
  370. chia/_tests/wallet/test_transaction_store.py +941 -0
  371. chia/_tests/wallet/test_util.py +181 -0
  372. chia/_tests/wallet/test_wallet.py +2139 -0
  373. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  374. chia/_tests/wallet/test_wallet_blockchain.py +113 -0
  375. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  376. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  377. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  378. chia/_tests/wallet/test_wallet_node.py +783 -0
  379. chia/_tests/wallet/test_wallet_retry.py +95 -0
  380. chia/_tests/wallet/test_wallet_state_manager.py +252 -0
  381. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  382. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  383. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  384. chia/_tests/wallet/test_wallet_utils.py +155 -0
  385. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  386. chia/_tests/wallet/vc_wallet/config.py +3 -0
  387. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  388. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  389. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +801 -0
  390. chia/_tests/wallet/wallet_block_tools.py +327 -0
  391. chia/_tests/weight_proof/__init__.py +0 -0
  392. chia/_tests/weight_proof/config.py +3 -0
  393. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  394. chia/clvm/__init__.py +0 -0
  395. chia/clvm/spend_sim.py +488 -0
  396. chia/cmds/__init__.py +0 -0
  397. chia/cmds/beta.py +183 -0
  398. chia/cmds/beta_funcs.py +133 -0
  399. chia/cmds/check_wallet_db.py +418 -0
  400. chia/cmds/chia.py +143 -0
  401. chia/cmds/cmd_classes.py +315 -0
  402. chia/cmds/cmds_util.py +498 -0
  403. chia/cmds/coin_funcs.py +260 -0
  404. chia/cmds/coins.py +220 -0
  405. chia/cmds/completion.py +49 -0
  406. chia/cmds/configure.py +331 -0
  407. chia/cmds/dao.py +1008 -0
  408. chia/cmds/dao_funcs.py +576 -0
  409. chia/cmds/data.py +707 -0
  410. chia/cmds/data_funcs.py +380 -0
  411. chia/cmds/db.py +86 -0
  412. chia/cmds/db_backup_func.py +77 -0
  413. chia/cmds/db_upgrade_func.py +452 -0
  414. chia/cmds/db_validate_func.py +184 -0
  415. chia/cmds/dev.py +16 -0
  416. chia/cmds/farm.py +87 -0
  417. chia/cmds/farm_funcs.py +207 -0
  418. chia/cmds/init.py +70 -0
  419. chia/cmds/init_funcs.py +367 -0
  420. chia/cmds/installers.py +129 -0
  421. chia/cmds/keys.py +510 -0
  422. chia/cmds/keys_funcs.py +864 -0
  423. chia/cmds/netspace.py +47 -0
  424. chia/cmds/netspace_funcs.py +53 -0
  425. chia/cmds/options.py +32 -0
  426. chia/cmds/param_types.py +228 -0
  427. chia/cmds/passphrase.py +130 -0
  428. chia/cmds/passphrase_funcs.py +346 -0
  429. chia/cmds/peer.py +50 -0
  430. chia/cmds/peer_funcs.py +129 -0
  431. chia/cmds/plotnft.py +206 -0
  432. chia/cmds/plotnft_funcs.py +374 -0
  433. chia/cmds/plots.py +222 -0
  434. chia/cmds/plotters.py +17 -0
  435. chia/cmds/rpc.py +188 -0
  436. chia/cmds/show.py +71 -0
  437. chia/cmds/show_funcs.py +214 -0
  438. chia/cmds/signer.py +304 -0
  439. chia/cmds/sim.py +217 -0
  440. chia/cmds/sim_funcs.py +509 -0
  441. chia/cmds/start.py +24 -0
  442. chia/cmds/start_funcs.py +112 -0
  443. chia/cmds/stop.py +61 -0
  444. chia/cmds/units.py +11 -0
  445. chia/cmds/wallet.py +1745 -0
  446. chia/cmds/wallet_funcs.py +1800 -0
  447. chia/consensus/__init__.py +0 -0
  448. chia/consensus/block_body_validation.py +515 -0
  449. chia/consensus/block_creation.py +525 -0
  450. chia/consensus/block_header_validation.py +1064 -0
  451. chia/consensus/block_record.py +32 -0
  452. chia/consensus/block_rewards.py +53 -0
  453. chia/consensus/block_root_validation.py +46 -0
  454. chia/consensus/blockchain.py +1100 -0
  455. chia/consensus/blockchain_interface.py +56 -0
  456. chia/consensus/coinbase.py +30 -0
  457. chia/consensus/condition_costs.py +9 -0
  458. chia/consensus/constants.py +49 -0
  459. chia/consensus/cost_calculator.py +15 -0
  460. chia/consensus/default_constants.py +90 -0
  461. chia/consensus/deficit.py +55 -0
  462. chia/consensus/difficulty_adjustment.py +412 -0
  463. chia/consensus/find_fork_point.py +111 -0
  464. chia/consensus/full_block_to_block_record.py +167 -0
  465. chia/consensus/get_block_challenge.py +106 -0
  466. chia/consensus/get_block_generator.py +26 -0
  467. chia/consensus/make_sub_epoch_summary.py +210 -0
  468. chia/consensus/multiprocess_validation.py +365 -0
  469. chia/consensus/pos_quality.py +19 -0
  470. chia/consensus/pot_iterations.py +67 -0
  471. chia/consensus/puzzles/__init__.py +0 -0
  472. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  473. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  474. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  475. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  476. chia/consensus/vdf_info_computation.py +156 -0
  477. chia/daemon/__init__.py +0 -0
  478. chia/daemon/client.py +233 -0
  479. chia/daemon/keychain_proxy.py +501 -0
  480. chia/daemon/keychain_server.py +365 -0
  481. chia/daemon/server.py +1616 -0
  482. chia/daemon/windows_signal.py +56 -0
  483. chia/data_layer/__init__.py +0 -0
  484. chia/data_layer/data_layer.py +1303 -0
  485. chia/data_layer/data_layer_api.py +25 -0
  486. chia/data_layer/data_layer_errors.py +50 -0
  487. chia/data_layer/data_layer_server.py +170 -0
  488. chia/data_layer/data_layer_util.py +985 -0
  489. chia/data_layer/data_layer_wallet.py +1315 -0
  490. chia/data_layer/data_store.py +2267 -0
  491. chia/data_layer/dl_wallet_store.py +407 -0
  492. chia/data_layer/download_data.py +389 -0
  493. chia/data_layer/puzzles/__init__.py +0 -0
  494. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  495. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  496. chia/data_layer/s3_plugin_config.yml +33 -0
  497. chia/data_layer/s3_plugin_service.py +468 -0
  498. chia/data_layer/util/__init__.py +0 -0
  499. chia/data_layer/util/benchmark.py +108 -0
  500. chia/data_layer/util/plugin.py +41 -0
  501. chia/farmer/__init__.py +0 -0
  502. chia/farmer/farmer.py +920 -0
  503. chia/farmer/farmer_api.py +814 -0
  504. chia/full_node/__init__.py +0 -0
  505. chia/full_node/bitcoin_fee_estimator.py +85 -0
  506. chia/full_node/block_height_map.py +271 -0
  507. chia/full_node/block_store.py +570 -0
  508. chia/full_node/bundle_tools.py +19 -0
  509. chia/full_node/coin_store.py +646 -0
  510. chia/full_node/fee_estimate.py +54 -0
  511. chia/full_node/fee_estimate_store.py +24 -0
  512. chia/full_node/fee_estimation.py +93 -0
  513. chia/full_node/fee_estimator.py +90 -0
  514. chia/full_node/fee_estimator_constants.py +38 -0
  515. chia/full_node/fee_estimator_interface.py +42 -0
  516. chia/full_node/fee_history.py +26 -0
  517. chia/full_node/fee_tracker.py +564 -0
  518. chia/full_node/full_node.py +3052 -0
  519. chia/full_node/full_node_api.py +1974 -0
  520. chia/full_node/full_node_store.py +1033 -0
  521. chia/full_node/hint_management.py +56 -0
  522. chia/full_node/hint_store.py +94 -0
  523. chia/full_node/mempool.py +583 -0
  524. chia/full_node/mempool_check_conditions.py +177 -0
  525. chia/full_node/mempool_manager.py +858 -0
  526. chia/full_node/pending_tx_cache.py +112 -0
  527. chia/full_node/puzzles/__init__.py +0 -0
  528. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  529. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  530. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  531. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  532. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  533. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  534. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  535. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  536. chia/full_node/signage_point.py +16 -0
  537. chia/full_node/subscriptions.py +248 -0
  538. chia/full_node/sync_store.py +145 -0
  539. chia/full_node/tx_processing_queue.py +78 -0
  540. chia/full_node/weight_proof.py +1719 -0
  541. chia/harvester/__init__.py +0 -0
  542. chia/harvester/harvester.py +271 -0
  543. chia/harvester/harvester_api.py +374 -0
  544. chia/introducer/__init__.py +0 -0
  545. chia/introducer/introducer.py +120 -0
  546. chia/introducer/introducer_api.py +64 -0
  547. chia/legacy/__init__.py +0 -0
  548. chia/legacy/keyring.py +154 -0
  549. chia/plot_sync/__init__.py +0 -0
  550. chia/plot_sync/delta.py +61 -0
  551. chia/plot_sync/exceptions.py +56 -0
  552. chia/plot_sync/receiver.py +385 -0
  553. chia/plot_sync/sender.py +337 -0
  554. chia/plot_sync/util.py +43 -0
  555. chia/plotters/__init__.py +0 -0
  556. chia/plotters/bladebit.py +388 -0
  557. chia/plotters/chiapos.py +63 -0
  558. chia/plotters/madmax.py +224 -0
  559. chia/plotters/plotters.py +577 -0
  560. chia/plotters/plotters_util.py +131 -0
  561. chia/plotting/__init__.py +0 -0
  562. chia/plotting/cache.py +212 -0
  563. chia/plotting/check_plots.py +283 -0
  564. chia/plotting/create_plots.py +278 -0
  565. chia/plotting/manager.py +436 -0
  566. chia/plotting/util.py +324 -0
  567. chia/pools/__init__.py +0 -0
  568. chia/pools/pool_config.py +110 -0
  569. chia/pools/pool_puzzles.py +459 -0
  570. chia/pools/pool_wallet.py +926 -0
  571. chia/pools/pool_wallet_info.py +118 -0
  572. chia/pools/puzzles/__init__.py +0 -0
  573. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  574. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  575. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  576. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  577. chia/protocols/__init__.py +0 -0
  578. chia/protocols/farmer_protocol.py +102 -0
  579. chia/protocols/full_node_protocol.py +219 -0
  580. chia/protocols/harvester_protocol.py +216 -0
  581. chia/protocols/introducer_protocol.py +26 -0
  582. chia/protocols/pool_protocol.py +177 -0
  583. chia/protocols/protocol_message_types.py +139 -0
  584. chia/protocols/protocol_state_machine.py +87 -0
  585. chia/protocols/protocol_timing.py +7 -0
  586. chia/protocols/shared_protocol.py +86 -0
  587. chia/protocols/timelord_protocol.py +93 -0
  588. chia/protocols/wallet_protocol.py +401 -0
  589. chia/py.typed +0 -0
  590. chia/rpc/__init__.py +0 -0
  591. chia/rpc/crawler_rpc_api.py +75 -0
  592. chia/rpc/data_layer_rpc_api.py +639 -0
  593. chia/rpc/data_layer_rpc_client.py +188 -0
  594. chia/rpc/data_layer_rpc_util.py +62 -0
  595. chia/rpc/farmer_rpc_api.py +360 -0
  596. chia/rpc/farmer_rpc_client.py +86 -0
  597. chia/rpc/full_node_rpc_api.py +954 -0
  598. chia/rpc/full_node_rpc_client.py +292 -0
  599. chia/rpc/harvester_rpc_api.py +136 -0
  600. chia/rpc/harvester_rpc_client.py +54 -0
  601. chia/rpc/rpc_client.py +144 -0
  602. chia/rpc/rpc_server.py +447 -0
  603. chia/rpc/timelord_rpc_api.py +27 -0
  604. chia/rpc/util.py +293 -0
  605. chia/rpc/wallet_request_types.py +688 -0
  606. chia/rpc/wallet_rpc_api.py +4779 -0
  607. chia/rpc/wallet_rpc_client.py +1844 -0
  608. chia/seeder/__init__.py +0 -0
  609. chia/seeder/crawl_store.py +427 -0
  610. chia/seeder/crawler.py +423 -0
  611. chia/seeder/crawler_api.py +129 -0
  612. chia/seeder/dns_server.py +544 -0
  613. chia/seeder/peer_record.py +146 -0
  614. chia/seeder/start_crawler.py +88 -0
  615. chia/server/__init__.py +0 -0
  616. chia/server/address_manager.py +658 -0
  617. chia/server/address_manager_store.py +237 -0
  618. chia/server/api_protocol.py +11 -0
  619. chia/server/capabilities.py +24 -0
  620. chia/server/chia_policy.py +345 -0
  621. chia/server/introducer_peers.py +76 -0
  622. chia/server/node_discovery.py +718 -0
  623. chia/server/outbound_message.py +33 -0
  624. chia/server/rate_limit_numbers.py +204 -0
  625. chia/server/rate_limits.py +113 -0
  626. chia/server/server.py +720 -0
  627. chia/server/signal_handlers.py +117 -0
  628. chia/server/ssl_context.py +32 -0
  629. chia/server/start_data_layer.py +137 -0
  630. chia/server/start_farmer.py +86 -0
  631. chia/server/start_full_node.py +106 -0
  632. chia/server/start_harvester.py +80 -0
  633. chia/server/start_introducer.py +69 -0
  634. chia/server/start_service.py +328 -0
  635. chia/server/start_timelord.py +82 -0
  636. chia/server/start_wallet.py +109 -0
  637. chia/server/upnp.py +117 -0
  638. chia/server/ws_connection.py +752 -0
  639. chia/simulator/__init__.py +0 -0
  640. chia/simulator/block_tools.py +2053 -0
  641. chia/simulator/full_node_simulator.py +802 -0
  642. chia/simulator/keyring.py +128 -0
  643. chia/simulator/setup_services.py +505 -0
  644. chia/simulator/simulator_constants.py +13 -0
  645. chia/simulator/simulator_full_node_rpc_api.py +101 -0
  646. chia/simulator/simulator_full_node_rpc_client.py +62 -0
  647. chia/simulator/simulator_protocol.py +29 -0
  648. chia/simulator/simulator_test_tools.py +163 -0
  649. chia/simulator/socket.py +27 -0
  650. chia/simulator/ssl_certs.py +114 -0
  651. chia/simulator/ssl_certs_1.py +699 -0
  652. chia/simulator/ssl_certs_10.py +699 -0
  653. chia/simulator/ssl_certs_2.py +699 -0
  654. chia/simulator/ssl_certs_3.py +699 -0
  655. chia/simulator/ssl_certs_4.py +699 -0
  656. chia/simulator/ssl_certs_5.py +699 -0
  657. chia/simulator/ssl_certs_6.py +699 -0
  658. chia/simulator/ssl_certs_7.py +699 -0
  659. chia/simulator/ssl_certs_8.py +699 -0
  660. chia/simulator/ssl_certs_9.py +699 -0
  661. chia/simulator/start_simulator.py +135 -0
  662. chia/simulator/wallet_tools.py +245 -0
  663. chia/ssl/__init__.py +0 -0
  664. chia/ssl/chia_ca.crt +19 -0
  665. chia/ssl/chia_ca.key +28 -0
  666. chia/ssl/create_ssl.py +249 -0
  667. chia/ssl/dst_root_ca.pem +20 -0
  668. chia/timelord/__init__.py +0 -0
  669. chia/timelord/iters_from_block.py +50 -0
  670. chia/timelord/timelord.py +1202 -0
  671. chia/timelord/timelord_api.py +132 -0
  672. chia/timelord/timelord_launcher.py +188 -0
  673. chia/timelord/timelord_state.py +244 -0
  674. chia/timelord/types.py +22 -0
  675. chia/types/__init__.py +0 -0
  676. chia/types/aliases.py +35 -0
  677. chia/types/block_protocol.py +20 -0
  678. chia/types/blockchain_format/__init__.py +0 -0
  679. chia/types/blockchain_format/classgroup.py +5 -0
  680. chia/types/blockchain_format/coin.py +28 -0
  681. chia/types/blockchain_format/foliage.py +8 -0
  682. chia/types/blockchain_format/pool_target.py +5 -0
  683. chia/types/blockchain_format/program.py +270 -0
  684. chia/types/blockchain_format/proof_of_space.py +135 -0
  685. chia/types/blockchain_format/reward_chain_block.py +6 -0
  686. chia/types/blockchain_format/serialized_program.py +5 -0
  687. chia/types/blockchain_format/sized_bytes.py +11 -0
  688. chia/types/blockchain_format/slots.py +9 -0
  689. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  690. chia/types/blockchain_format/tree_hash.py +72 -0
  691. chia/types/blockchain_format/vdf.py +86 -0
  692. chia/types/clvm_cost.py +13 -0
  693. chia/types/coin_record.py +43 -0
  694. chia/types/coin_spend.py +115 -0
  695. chia/types/condition_opcodes.py +73 -0
  696. chia/types/condition_with_args.py +17 -0
  697. chia/types/eligible_coin_spends.py +364 -0
  698. chia/types/end_of_slot_bundle.py +5 -0
  699. chia/types/fee_rate.py +38 -0
  700. chia/types/full_block.py +5 -0
  701. chia/types/generator_types.py +14 -0
  702. chia/types/header_block.py +5 -0
  703. chia/types/internal_mempool_item.py +19 -0
  704. chia/types/mempool_inclusion_status.py +9 -0
  705. chia/types/mempool_item.py +85 -0
  706. chia/types/mempool_submission_status.py +30 -0
  707. chia/types/mojos.py +7 -0
  708. chia/types/peer_info.py +64 -0
  709. chia/types/signing_mode.py +29 -0
  710. chia/types/spend_bundle.py +31 -0
  711. chia/types/spend_bundle_conditions.py +7 -0
  712. chia/types/transaction_queue_entry.py +55 -0
  713. chia/types/unfinished_block.py +5 -0
  714. chia/types/unfinished_header_block.py +37 -0
  715. chia/types/weight_proof.py +50 -0
  716. chia/util/__init__.py +0 -0
  717. chia/util/action_scope.py +168 -0
  718. chia/util/api_decorators.py +89 -0
  719. chia/util/async_pool.py +224 -0
  720. chia/util/augmented_chain.py +130 -0
  721. chia/util/batches.py +39 -0
  722. chia/util/bech32m.py +123 -0
  723. chia/util/beta_metrics.py +118 -0
  724. chia/util/block_cache.py +56 -0
  725. chia/util/byte_types.py +10 -0
  726. chia/util/check_fork_next_block.py +32 -0
  727. chia/util/chia_logging.py +124 -0
  728. chia/util/chia_version.py +33 -0
  729. chia/util/collection.py +17 -0
  730. chia/util/condition_tools.py +201 -0
  731. chia/util/config.py +366 -0
  732. chia/util/cpu.py +20 -0
  733. chia/util/db_synchronous.py +21 -0
  734. chia/util/db_version.py +30 -0
  735. chia/util/db_wrapper.py +427 -0
  736. chia/util/default_root.py +10 -0
  737. chia/util/dump_keyring.py +93 -0
  738. chia/util/english.txt +2048 -0
  739. chia/util/errors.py +351 -0
  740. chia/util/file_keyring.py +480 -0
  741. chia/util/files.py +95 -0
  742. chia/util/full_block_utils.py +321 -0
  743. chia/util/generator_tools.py +62 -0
  744. chia/util/hash.py +29 -0
  745. chia/util/initial-config.yaml +675 -0
  746. chia/util/inline_executor.py +24 -0
  747. chia/util/ints.py +19 -0
  748. chia/util/json_util.py +41 -0
  749. chia/util/keychain.py +673 -0
  750. chia/util/keyring_wrapper.py +266 -0
  751. chia/util/limited_semaphore.py +39 -0
  752. chia/util/lock.py +47 -0
  753. chia/util/log_exceptions.py +29 -0
  754. chia/util/logging.py +34 -0
  755. chia/util/lru_cache.py +29 -0
  756. chia/util/math.py +20 -0
  757. chia/util/network.py +240 -0
  758. chia/util/paginator.py +46 -0
  759. chia/util/path.py +29 -0
  760. chia/util/permissions.py +19 -0
  761. chia/util/pprint.py +40 -0
  762. chia/util/prev_transaction_block.py +23 -0
  763. chia/util/priority_mutex.py +92 -0
  764. chia/util/profiler.py +194 -0
  765. chia/util/recursive_replace.py +22 -0
  766. chia/util/safe_cancel_task.py +14 -0
  767. chia/util/service_groups.py +47 -0
  768. chia/util/setproctitle.py +20 -0
  769. chia/util/significant_bits.py +30 -0
  770. chia/util/ssl_check.py +213 -0
  771. chia/util/streamable.py +654 -0
  772. chia/util/task_timing.py +378 -0
  773. chia/util/timing.py +64 -0
  774. chia/util/vdf_prover.py +31 -0
  775. chia/util/ws_message.py +66 -0
  776. chia/wallet/__init__.py +0 -0
  777. chia/wallet/cat_wallet/__init__.py +0 -0
  778. chia/wallet/cat_wallet/cat_constants.py +75 -0
  779. chia/wallet/cat_wallet/cat_info.py +47 -0
  780. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  781. chia/wallet/cat_wallet/cat_utils.py +163 -0
  782. chia/wallet/cat_wallet/cat_wallet.py +869 -0
  783. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  784. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  785. chia/wallet/cat_wallet/lineage_store.py +74 -0
  786. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  787. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  788. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  789. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  790. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  791. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  792. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  793. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  794. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  795. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  796. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  797. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  798. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  799. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  800. chia/wallet/coin_selection.py +188 -0
  801. chia/wallet/conditions.py +1326 -0
  802. chia/wallet/dao_wallet/__init__.py +0 -0
  803. chia/wallet/dao_wallet/dao_info.py +61 -0
  804. chia/wallet/dao_wallet/dao_utils.py +810 -0
  805. chia/wallet/dao_wallet/dao_wallet.py +2121 -0
  806. chia/wallet/db_wallet/__init__.py +0 -0
  807. chia/wallet/db_wallet/db_wallet_puzzles.py +107 -0
  808. chia/wallet/derivation_record.py +30 -0
  809. chia/wallet/derive_keys.py +146 -0
  810. chia/wallet/did_wallet/__init__.py +0 -0
  811. chia/wallet/did_wallet/did_info.py +39 -0
  812. chia/wallet/did_wallet/did_wallet.py +1485 -0
  813. chia/wallet/did_wallet/did_wallet_puzzles.py +220 -0
  814. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  815. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  816. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  817. chia/wallet/driver_protocol.py +26 -0
  818. chia/wallet/key_val_store.py +55 -0
  819. chia/wallet/lineage_proof.py +58 -0
  820. chia/wallet/nft_wallet/__init__.py +0 -0
  821. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  822. chia/wallet/nft_wallet/nft_info.py +120 -0
  823. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  824. chia/wallet/nft_wallet/nft_wallet.py +1686 -0
  825. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  826. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  827. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  828. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  829. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  830. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  831. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  832. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  833. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  834. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  835. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  836. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  837. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  838. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  839. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  840. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  841. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  842. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  843. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  844. chia/wallet/notification_manager.py +117 -0
  845. chia/wallet/notification_store.py +178 -0
  846. chia/wallet/outer_puzzles.py +84 -0
  847. chia/wallet/payment.py +34 -0
  848. chia/wallet/puzzle_drivers.py +118 -0
  849. chia/wallet/puzzles/__init__.py +0 -0
  850. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  851. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  852. chia/wallet/puzzles/clawback/__init__.py +0 -0
  853. chia/wallet/puzzles/clawback/drivers.py +188 -0
  854. chia/wallet/puzzles/clawback/metadata.py +38 -0
  855. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  856. chia/wallet/puzzles/condition_codes.clib +77 -0
  857. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  858. chia/wallet/puzzles/curry.clib +135 -0
  859. chia/wallet/puzzles/curry_by_index.clib +16 -0
  860. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  861. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  862. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  863. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  864. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  865. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  866. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  867. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  868. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  869. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  870. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  871. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  872. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  873. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  874. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  876. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  877. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  878. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  879. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  880. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  881. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  882. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  883. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  884. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  885. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  886. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  887. chia/wallet/puzzles/json.clib +25 -0
  888. chia/wallet/puzzles/load_clvm.py +162 -0
  889. chia/wallet/puzzles/merkle_utils.clib +18 -0
  890. chia/wallet/puzzles/notification.clsp +7 -0
  891. chia/wallet/puzzles/notification.clsp.hex +1 -0
  892. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  893. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  894. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  895. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  896. chia/wallet/puzzles/p2_conditions.py +27 -0
  897. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  898. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  899. chia/wallet/puzzles/p2_delegated_conditions.py +22 -0
  900. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  901. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  902. chia/wallet/puzzles/p2_delegated_puzzle.py +35 -0
  903. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  904. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +161 -0
  906. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  907. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  908. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +22 -0
  909. chia/wallet/puzzles/p2_parent.clsp +19 -0
  910. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  911. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  912. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  913. chia/wallet/puzzles/p2_puzzle_hash.py +28 -0
  914. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  915. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  916. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  917. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  919. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  920. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  921. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  922. chia/wallet/puzzles/puzzle_utils.py +34 -0
  923. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  924. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  925. chia/wallet/puzzles/sha256tree.clib +11 -0
  926. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  927. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  928. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  929. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  930. chia/wallet/puzzles/singleton_top_layer.py +295 -0
  931. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  932. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  933. chia/wallet/puzzles/singleton_top_layer_v1_1.py +344 -0
  934. chia/wallet/puzzles/singleton_truths.clib +21 -0
  935. chia/wallet/puzzles/tails.py +344 -0
  936. chia/wallet/puzzles/utility_macros.clib +48 -0
  937. chia/wallet/signer_protocol.py +126 -0
  938. chia/wallet/singleton.py +106 -0
  939. chia/wallet/singleton_record.py +30 -0
  940. chia/wallet/trade_manager.py +1088 -0
  941. chia/wallet/trade_record.py +67 -0
  942. chia/wallet/trading/__init__.py +0 -0
  943. chia/wallet/trading/offer.py +703 -0
  944. chia/wallet/trading/trade_status.py +13 -0
  945. chia/wallet/trading/trade_store.py +526 -0
  946. chia/wallet/transaction_record.py +143 -0
  947. chia/wallet/transaction_sorting.py +14 -0
  948. chia/wallet/uncurried_puzzle.py +17 -0
  949. chia/wallet/util/__init__.py +0 -0
  950. chia/wallet/util/address_type.py +55 -0
  951. chia/wallet/util/blind_signer_tl.py +168 -0
  952. chia/wallet/util/clvm_streamable.py +203 -0
  953. chia/wallet/util/compute_hints.py +66 -0
  954. chia/wallet/util/compute_memos.py +45 -0
  955. chia/wallet/util/curry_and_treehash.py +90 -0
  956. chia/wallet/util/debug_spend_bundle.py +234 -0
  957. chia/wallet/util/merkle_tree.py +100 -0
  958. chia/wallet/util/merkle_utils.py +102 -0
  959. chia/wallet/util/new_peak_queue.py +82 -0
  960. chia/wallet/util/notifications.py +12 -0
  961. chia/wallet/util/peer_request_cache.py +174 -0
  962. chia/wallet/util/puzzle_compression.py +96 -0
  963. chia/wallet/util/puzzle_decorator.py +100 -0
  964. chia/wallet/util/puzzle_decorator_type.py +7 -0
  965. chia/wallet/util/query_filter.py +60 -0
  966. chia/wallet/util/transaction_type.py +23 -0
  967. chia/wallet/util/tx_config.py +158 -0
  968. chia/wallet/util/wallet_sync_utils.py +348 -0
  969. chia/wallet/util/wallet_types.py +65 -0
  970. chia/wallet/vc_wallet/__init__.py +0 -0
  971. chia/wallet/vc_wallet/cr_cat_drivers.py +663 -0
  972. chia/wallet/vc_wallet/cr_cat_wallet.py +875 -0
  973. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  974. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  975. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  976. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  977. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  978. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  979. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  980. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  981. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  982. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  983. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  984. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  985. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  986. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  987. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  988. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  989. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  990. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  992. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  994. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  996. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  997. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  998. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_store.py +263 -0
  1002. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1003. chia/wallet/wallet.py +698 -0
  1004. chia/wallet/wallet_action_scope.py +95 -0
  1005. chia/wallet/wallet_blockchain.py +244 -0
  1006. chia/wallet/wallet_coin_record.py +72 -0
  1007. chia/wallet/wallet_coin_store.py +351 -0
  1008. chia/wallet/wallet_info.py +36 -0
  1009. chia/wallet/wallet_interested_store.py +188 -0
  1010. chia/wallet/wallet_nft_store.py +279 -0
  1011. chia/wallet/wallet_node.py +1769 -0
  1012. chia/wallet/wallet_node_api.py +201 -0
  1013. chia/wallet/wallet_pool_store.py +120 -0
  1014. chia/wallet/wallet_protocol.py +90 -0
  1015. chia/wallet/wallet_puzzle_store.py +365 -0
  1016. chia/wallet/wallet_retry_store.py +70 -0
  1017. chia/wallet/wallet_singleton_store.py +258 -0
  1018. chia/wallet/wallet_spend_bundle.py +41 -0
  1019. chia/wallet/wallet_state_manager.py +2820 -0
  1020. chia/wallet/wallet_transaction_store.py +470 -0
  1021. chia/wallet/wallet_user_store.py +110 -0
  1022. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1023. chia_blockchain-2.4.4.dist-info/LICENSE +201 -0
  1024. chia_blockchain-2.4.4.dist-info/METADATA +161 -0
  1025. chia_blockchain-2.4.4.dist-info/RECORD +1028 -0
  1026. chia_blockchain-2.4.4.dist-info/WHEEL +4 -0
  1027. chia_blockchain-2.4.4.dist-info/entry_points.txt +17 -0
  1028. mozilla-ca/cacert.pem +3666 -0
@@ -0,0 +1,1481 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import json
5
+ from typing import Optional
6
+
7
+ import pytest
8
+ from chia_rs import AugSchemeMPL, G1Element, G2Element
9
+
10
+ from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework
11
+ from chia._tests.util.setup_nodes import OldSimulatorsAndWallets
12
+ from chia._tests.util.time_out_assert import time_out_assert
13
+ from chia.rpc.wallet_request_types import DIDGetCurrentCoinInfo, DIDGetRecoveryInfo
14
+ from chia.rpc.wallet_rpc_api import WalletRpcApi
15
+ from chia.simulator.simulator_protocol import FarmNewBlockProtocol
16
+ from chia.types.blockchain_format.program import Program
17
+ from chia.types.blockchain_format.sized_bytes import bytes32
18
+ from chia.types.condition_opcodes import ConditionOpcode
19
+ from chia.types.peer_info import PeerInfo
20
+ from chia.types.signing_mode import CHIP_0002_SIGN_MESSAGE_PREFIX
21
+ from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
22
+ from chia.util.condition_tools import conditions_dict_for_solution
23
+ from chia.util.ints import uint16, uint32, uint64
24
+ from chia.wallet.did_wallet.did_wallet import DIDWallet
25
+ from chia.wallet.singleton import create_singleton_puzzle
26
+ from chia.wallet.util.address_type import AddressType
27
+ from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
28
+ from chia.wallet.util.wallet_types import WalletType
29
+ from chia.wallet.wallet_spend_bundle import WalletSpendBundle
30
+
31
+
32
+ async def get_wallet_num(wallet_manager):
33
+ return len(await wallet_manager.get_all_wallet_info_entries())
34
+
35
+
36
+ def get_parent_num(did_wallet: DIDWallet):
37
+ return len(did_wallet.did_info.parent_info)
38
+
39
+
40
+ class TestDIDWallet:
41
+ @pytest.mark.parametrize(
42
+ "trusted",
43
+ [True, False],
44
+ )
45
+ @pytest.mark.anyio
46
+ async def test_creation_from_coin_spend(
47
+ self, self_hostname, two_nodes_two_wallets_with_same_keys: OldSimulatorsAndWallets, trusted
48
+ ):
49
+ """
50
+ Verify that DIDWallet.create_new_did_wallet_from_coin_spend() is called after Singleton creation on
51
+ the blockchain, and that the wallet is created in the second wallet node.
52
+ """
53
+ full_nodes, wallets, _ = two_nodes_two_wallets_with_same_keys
54
+ full_node_api = full_nodes[0]
55
+ full_node_server = full_node_api.server
56
+ wallet_node_0, server_0 = wallets[0]
57
+ wallet_node_1, server_1 = wallets[1]
58
+
59
+ wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
60
+ wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
61
+
62
+ ph0 = await wallet_0.get_new_puzzlehash()
63
+ ph1 = await wallet_1.get_new_puzzlehash()
64
+
65
+ sk0 = await wallet_node_0.wallet_state_manager.get_private_key(ph0)
66
+ sk1 = await wallet_node_1.wallet_state_manager.get_private_key(ph1)
67
+ assert sk0 == sk1
68
+
69
+ if trusted:
70
+ wallet_node_0.config["trusted_peers"] = {
71
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
72
+ }
73
+ wallet_node_1.config["trusted_peers"] = {
74
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
75
+ }
76
+
77
+ else:
78
+ wallet_node_0.config["trusted_peers"] = {}
79
+ wallet_node_1.config["trusted_peers"] = {}
80
+ await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
81
+ await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
82
+
83
+ await full_node_api.farm_blocks_to_wallet(1, wallet_0)
84
+ await full_node_api.farm_blocks_to_wallet(1, wallet_1)
85
+
86
+ # Wallet1 sets up DIDWallet1 without any backup set
87
+ async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
88
+ did_wallet_0: DIDWallet = await DIDWallet.create_new_did_wallet(
89
+ wallet_node_0.wallet_state_manager, wallet_0, uint64(101), action_scope
90
+ )
91
+
92
+ with pytest.raises(RuntimeError):
93
+ assert await did_wallet_0.get_coin() == set()
94
+ assert await did_wallet_0.get_info_for_recovery() is None
95
+
96
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
97
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1])
98
+
99
+ await time_out_assert(15, did_wallet_0.get_confirmed_balance, 101)
100
+ await time_out_assert(15, did_wallet_0.get_unconfirmed_balance, 101)
101
+ await time_out_assert(15, did_wallet_0.get_pending_change_balance, 0)
102
+
103
+ await full_node_api.farm_blocks_to_wallet(1, wallet_0)
104
+
105
+ #######################
106
+ all_node_0_wallets = await wallet_node_0.wallet_state_manager.user_store.get_all_wallet_info_entries()
107
+ all_node_1_wallets = await wallet_node_1.wallet_state_manager.user_store.get_all_wallet_info_entries()
108
+ assert (
109
+ json.loads(all_node_0_wallets[1].data)["current_inner"]
110
+ == json.loads(all_node_1_wallets[1].data)["current_inner"]
111
+ )
112
+
113
+ # TODO: Porting this test to this fixture revealed some balance peculiarities. Fix them.
114
+ @pytest.mark.parametrize(
115
+ "wallet_environments",
116
+ [
117
+ {
118
+ "num_environments": 3,
119
+ "blocks_needed": [1, 1, 1],
120
+ }
121
+ ],
122
+ indirect=True,
123
+ )
124
+ @pytest.mark.anyio
125
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
126
+ async def test_creation_from_backup_file(self, wallet_environments: WalletTestFramework) -> None:
127
+ env_0 = wallet_environments.environments[0]
128
+ env_1 = wallet_environments.environments[1]
129
+ env_2 = wallet_environments.environments[2]
130
+
131
+ env_0.wallet_aliases = {
132
+ "xch": 1,
133
+ "did": 2,
134
+ }
135
+ env_1.wallet_aliases = {
136
+ "xch": 1,
137
+ "did": 2,
138
+ }
139
+ env_2.wallet_aliases = {
140
+ "xch": 1,
141
+ "did": 2,
142
+ }
143
+
144
+ # Wallet1 sets up DIDWallet1 without any backup set
145
+ async with env_0.wallet_state_manager.new_action_scope(
146
+ wallet_environments.tx_config, push=True
147
+ ) as action_scope:
148
+ did_wallet_0: DIDWallet = await DIDWallet.create_new_did_wallet(
149
+ env_0.wallet_state_manager, env_0.xch_wallet, uint64(101), action_scope
150
+ )
151
+
152
+ await wallet_environments.process_pending_states(
153
+ [
154
+ WalletStateTransition(
155
+ pre_block_balance_updates={
156
+ "xch": {
157
+ "unconfirmed_wallet_balance": -101,
158
+ "<=#spendable_balance": -101,
159
+ "<=#max_send_amount": -101,
160
+ ">=#pending_change": 1,
161
+ "pending_coin_removal_count": 1,
162
+ },
163
+ "did": {
164
+ "init": True,
165
+ "unconfirmed_wallet_balance": 101,
166
+ "pending_change": 202, # TODO: this is not correct, fix this
167
+ "pending_coin_removal_count": 2, # TODO: this might not be correct
168
+ },
169
+ },
170
+ post_block_balance_updates={
171
+ "xch": {
172
+ "confirmed_wallet_balance": -101,
173
+ ">=#spendable_balance": 1,
174
+ ">=#max_send_amount": 1,
175
+ "<=#pending_change": -1,
176
+ "pending_coin_removal_count": -1,
177
+ },
178
+ "did": {
179
+ "confirmed_wallet_balance": 101,
180
+ "spendable_balance": 101,
181
+ "max_send_amount": 101,
182
+ "unspent_coin_count": 1,
183
+ "pending_change": -202, # TODO: this is not correct, fix this
184
+ "pending_coin_removal_count": -2, # TODO: this might not be correct
185
+ },
186
+ },
187
+ ),
188
+ WalletStateTransition(
189
+ pre_block_balance_updates={},
190
+ post_block_balance_updates={},
191
+ ),
192
+ WalletStateTransition(
193
+ pre_block_balance_updates={},
194
+ post_block_balance_updates={},
195
+ ),
196
+ ]
197
+ )
198
+
199
+ # Wallet1 sets up DIDWallet_1 with DIDWallet_0 as backup
200
+ backup_ids = [bytes32.from_hexstr(did_wallet_0.get_my_DID())]
201
+
202
+ async with env_1.wallet_state_manager.new_action_scope(
203
+ wallet_environments.tx_config, push=True
204
+ ) as action_scope:
205
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
206
+ env_1.wallet_state_manager, env_1.xch_wallet, uint64(201), action_scope, backup_ids
207
+ )
208
+
209
+ await wallet_environments.process_pending_states(
210
+ [
211
+ WalletStateTransition(
212
+ pre_block_balance_updates={},
213
+ post_block_balance_updates={},
214
+ ),
215
+ WalletStateTransition(
216
+ pre_block_balance_updates={
217
+ "xch": {
218
+ "unconfirmed_wallet_balance": -201,
219
+ "<=#spendable_balance": -201,
220
+ "<=#max_send_amount": -201,
221
+ ">=#pending_change": 1,
222
+ "pending_coin_removal_count": 1,
223
+ },
224
+ "did": {
225
+ "init": True,
226
+ "unconfirmed_wallet_balance": 201,
227
+ "pending_change": 402, # TODO: this is not correct, fix this
228
+ "pending_coin_removal_count": 2, # TODO: this might not be correct
229
+ },
230
+ },
231
+ post_block_balance_updates={
232
+ "xch": {
233
+ "confirmed_wallet_balance": -201,
234
+ ">=#spendable_balance": 1,
235
+ ">=#max_send_amount": 1,
236
+ "<=#pending_change": -1,
237
+ "pending_coin_removal_count": -1,
238
+ },
239
+ "did": {
240
+ "confirmed_wallet_balance": 201,
241
+ "spendable_balance": 201,
242
+ "max_send_amount": 201,
243
+ "unspent_coin_count": 1,
244
+ "pending_change": -402, # TODO: this is not correct, fix this
245
+ "pending_coin_removal_count": -2, # TODO: this might not be correct
246
+ },
247
+ },
248
+ ),
249
+ WalletStateTransition(
250
+ pre_block_balance_updates={},
251
+ post_block_balance_updates={},
252
+ ),
253
+ ]
254
+ )
255
+
256
+ backup_data = did_wallet_1.create_backup()
257
+
258
+ # Wallet2 recovers DIDWallet2 to a new set of keys
259
+ await env_2.rpc_client.create_new_did_wallet(
260
+ uint64(1),
261
+ DEFAULT_TX_CONFIG,
262
+ type="recovery",
263
+ backup_data=backup_data,
264
+ )
265
+ did_wallet_2 = env_2.wallet_state_manager.get_wallet(id=uint32(2), required_type=DIDWallet)
266
+ recovery_info = await env_2.rpc_client.did_get_recovery_info(
267
+ DIDGetRecoveryInfo(uint32(env_2.wallet_aliases["did"]))
268
+ )
269
+ assert recovery_info.wallet_id == env_2.wallet_aliases["did"]
270
+ assert recovery_info.backup_dids == backup_ids
271
+ current_coin_info_response = await env_0.rpc_client.did_get_current_coin_info(
272
+ DIDGetCurrentCoinInfo(uint32(env_0.wallet_aliases["did"]))
273
+ )
274
+ # TODO: this check is kind of weak, we should research when this endpoint might actually be useful
275
+ assert current_coin_info_response.wallet_id == env_0.wallet_aliases["did"]
276
+ async with env_0.wallet_state_manager.new_action_scope(
277
+ wallet_environments.tx_config, push=True
278
+ ) as action_scope:
279
+ message_spend_bundle, attest_data = await did_wallet_0.create_attestment(
280
+ recovery_info.coin_name, recovery_info.newpuzhash, recovery_info.pubkey, action_scope
281
+ )
282
+
283
+ await wallet_environments.process_pending_states(
284
+ [
285
+ WalletStateTransition(
286
+ pre_block_balance_updates={
287
+ "did": {
288
+ "spendable_balance": -101,
289
+ "pending_change": 101,
290
+ "pending_coin_removal_count": 1,
291
+ }
292
+ },
293
+ post_block_balance_updates={
294
+ "did": {
295
+ "spendable_balance": 101,
296
+ "pending_change": -101,
297
+ "pending_coin_removal_count": -1,
298
+ }
299
+ },
300
+ ),
301
+ WalletStateTransition(
302
+ pre_block_balance_updates={},
303
+ post_block_balance_updates={},
304
+ ),
305
+ WalletStateTransition(
306
+ pre_block_balance_updates={
307
+ "did": {
308
+ "init": True,
309
+ }
310
+ },
311
+ post_block_balance_updates={},
312
+ ),
313
+ ]
314
+ )
315
+
316
+ (
317
+ test_info_list,
318
+ test_message_spend_bundle,
319
+ ) = await did_wallet_2.load_attest_files_for_recovery_spend([attest_data])
320
+ assert message_spend_bundle == test_message_spend_bundle
321
+
322
+ async with env_2.wallet_state_manager.new_action_scope(
323
+ wallet_environments.tx_config, push=True
324
+ ) as action_scope:
325
+ assert did_wallet_2.did_info.temp_coin is not None
326
+ await did_wallet_2.recovery_spend(
327
+ did_wallet_2.did_info.temp_coin,
328
+ recovery_info.newpuzhash,
329
+ test_info_list,
330
+ recovery_info.pubkey,
331
+ test_message_spend_bundle,
332
+ action_scope,
333
+ )
334
+
335
+ await wallet_environments.process_pending_states(
336
+ [
337
+ WalletStateTransition(
338
+ pre_block_balance_updates={},
339
+ post_block_balance_updates={},
340
+ ),
341
+ WalletStateTransition(
342
+ pre_block_balance_updates={},
343
+ post_block_balance_updates={
344
+ "did": {
345
+ "confirmed_wallet_balance": -201,
346
+ "unconfirmed_wallet_balance": -201,
347
+ "spendable_balance": -201,
348
+ "max_send_amount": -201,
349
+ "unspent_coin_count": -1,
350
+ }
351
+ },
352
+ ),
353
+ WalletStateTransition(
354
+ pre_block_balance_updates={
355
+ "did": {
356
+ "unconfirmed_wallet_balance": 201,
357
+ "pending_coin_removal_count": 2,
358
+ }
359
+ },
360
+ post_block_balance_updates={
361
+ "did": {
362
+ "confirmed_wallet_balance": 201,
363
+ "spendable_balance": 201,
364
+ "max_send_amount": 201,
365
+ "unspent_coin_count": 1,
366
+ "pending_coin_removal_count": -2,
367
+ }
368
+ },
369
+ ),
370
+ ]
371
+ )
372
+
373
+ for wallet in [did_wallet_0, did_wallet_1, did_wallet_2]:
374
+ assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
375
+
376
+ some_ph = bytes32(32 * b"\2")
377
+ async with env_2.wallet_state_manager.new_action_scope(
378
+ wallet_environments.tx_config, push=True
379
+ ) as action_scope:
380
+ await did_wallet_2.create_exit_spend(some_ph, action_scope)
381
+
382
+ await wallet_environments.process_pending_states(
383
+ [
384
+ WalletStateTransition(
385
+ pre_block_balance_updates={},
386
+ post_block_balance_updates={},
387
+ ),
388
+ WalletStateTransition(
389
+ pre_block_balance_updates={},
390
+ post_block_balance_updates={},
391
+ ),
392
+ WalletStateTransition(
393
+ pre_block_balance_updates={
394
+ "did": {
395
+ "unconfirmed_wallet_balance": -201,
396
+ "spendable_balance": -201,
397
+ # "max_send_amount": -201, # TODO: Uncomment this
398
+ "pending_coin_removal_count": 1,
399
+ }
400
+ },
401
+ post_block_balance_updates={
402
+ "did": {
403
+ "confirmed_wallet_balance": -201,
404
+ "max_send_amount": -201, # TODO: Delete this when uncommented above
405
+ "unspent_coin_count": -1,
406
+ "pending_coin_removal_count": -1,
407
+ }
408
+ },
409
+ ),
410
+ ]
411
+ )
412
+
413
+ async def get_coins_with_ph() -> bool:
414
+ coins = await wallet_environments.full_node.full_node.coin_store.get_coin_records_by_puzzle_hash(
415
+ True, some_ph
416
+ )
417
+ return len(coins) == 1
418
+
419
+ await time_out_assert(15, get_coins_with_ph, True)
420
+
421
+ for wallet in [did_wallet_0, did_wallet_1]:
422
+ assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
423
+
424
+ @pytest.mark.parametrize(
425
+ "trusted",
426
+ [True, False],
427
+ )
428
+ @pytest.mark.anyio
429
+ async def test_did_recovery_with_multiple_backup_dids(self, self_hostname, two_wallet_nodes, trusted):
430
+ full_nodes, wallets, _ = two_wallet_nodes
431
+ full_node_api = full_nodes[0]
432
+ server_1 = full_node_api.server
433
+ wallet_node, server_2 = wallets[0]
434
+ wallet_node_2, server_3 = wallets[1]
435
+ wallet = wallet_node.wallet_state_manager.main_wallet
436
+ wallet2 = wallet_node_2.wallet_state_manager.main_wallet
437
+
438
+ if trusted:
439
+ wallet_node.config["trusted_peers"] = {
440
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
441
+ }
442
+ wallet_node_2.config["trusted_peers"] = {
443
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
444
+ }
445
+ else:
446
+ wallet_node.config["trusted_peers"] = {}
447
+ wallet_node_2.config["trusted_peers"] = {}
448
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
449
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
450
+
451
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
452
+ await full_node_api.farm_blocks_to_wallet(1, wallet2)
453
+
454
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
455
+ did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
456
+ wallet_node.wallet_state_manager, wallet, uint64(101), action_scope
457
+ )
458
+ assert did_wallet.get_name() == "Profile 1"
459
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
460
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
461
+
462
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
463
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
464
+
465
+ recovery_list = [bytes.fromhex(did_wallet.get_my_DID())]
466
+
467
+ async with wallet2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
468
+ did_wallet_2: DIDWallet = await DIDWallet.create_new_did_wallet(
469
+ wallet_node_2.wallet_state_manager, wallet2, uint64(101), action_scope, recovery_list
470
+ )
471
+
472
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
473
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
474
+
475
+ await time_out_assert(15, did_wallet_2.get_confirmed_balance, 101)
476
+ await time_out_assert(15, did_wallet_2.get_unconfirmed_balance, 101)
477
+
478
+ assert did_wallet_2.did_info.backup_ids == recovery_list
479
+
480
+ recovery_list.append(bytes.fromhex(did_wallet_2.get_my_DID()))
481
+
482
+ async with wallet2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
483
+ did_wallet_3: DIDWallet = await DIDWallet.create_new_did_wallet(
484
+ wallet_node_2.wallet_state_manager, wallet2, uint64(201), action_scope, recovery_list
485
+ )
486
+
487
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
488
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
489
+
490
+ assert did_wallet_3.did_info.backup_ids == recovery_list
491
+ await time_out_assert(15, did_wallet_3.get_confirmed_balance, 201)
492
+ await time_out_assert(15, did_wallet_3.get_unconfirmed_balance, 201)
493
+ coin = await did_wallet_3.get_coin()
494
+
495
+ backup_data = did_wallet_3.create_backup()
496
+
497
+ async with wallet_node.wallet_state_manager.lock:
498
+ did_wallet_4 = await DIDWallet.create_new_did_wallet_from_recovery(
499
+ wallet_node.wallet_state_manager,
500
+ wallet,
501
+ backup_data,
502
+ )
503
+ assert did_wallet_4.get_name() == "Profile 2"
504
+
505
+ pubkey = (
506
+ await did_wallet_4.wallet_state_manager.get_unused_derivation_record(did_wallet_2.wallet_info.id)
507
+ ).pubkey
508
+ new_ph = did_wallet_4.did_info.temp_puzhash
509
+ async with did_wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
510
+ message_spend_bundle, attest1 = await did_wallet.create_attestment(
511
+ coin.name(), new_ph, pubkey, action_scope
512
+ )
513
+
514
+ async with did_wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope_2:
515
+ message_spend_bundle2, attest2 = await did_wallet_2.create_attestment(
516
+ coin.name(), new_ph, pubkey, action_scope_2
517
+ )
518
+
519
+ message_spend_bundle = message_spend_bundle.aggregate([message_spend_bundle, message_spend_bundle2])
520
+
521
+ (
522
+ test_info_list,
523
+ test_message_spend_bundle,
524
+ ) = await did_wallet_4.load_attest_files_for_recovery_spend([attest1, attest2])
525
+ assert message_spend_bundle == test_message_spend_bundle
526
+
527
+ await full_node_api.process_transaction_records(
528
+ records=[*action_scope.side_effects.transactions, *action_scope_2.side_effects.transactions]
529
+ )
530
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
531
+ await time_out_assert(15, did_wallet_4.get_confirmed_balance, 0)
532
+ await time_out_assert(15, did_wallet_4.get_unconfirmed_balance, 0)
533
+ async with did_wallet_4.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
534
+ await did_wallet_4.recovery_spend(coin, new_ph, test_info_list, pubkey, message_spend_bundle, action_scope)
535
+ await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
536
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
537
+
538
+ await time_out_assert(15, did_wallet_4.get_confirmed_balance, 201)
539
+ await time_out_assert(15, did_wallet_4.get_unconfirmed_balance, 201)
540
+ await time_out_assert(15, did_wallet_3.get_confirmed_balance, 0)
541
+ await time_out_assert(15, did_wallet_3.get_unconfirmed_balance, 0)
542
+
543
+ for wallet in [did_wallet, did_wallet_2, did_wallet_3, did_wallet_4]:
544
+ assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
545
+
546
+ @pytest.mark.parametrize(
547
+ "trusted",
548
+ [True, False],
549
+ )
550
+ @pytest.mark.anyio
551
+ async def test_did_recovery_with_empty_set(self, self_hostname, two_wallet_nodes, trusted):
552
+ full_nodes, wallets, _ = two_wallet_nodes
553
+ full_node_api = full_nodes[0]
554
+ server_1 = full_node_api.server
555
+ wallet_node, server_2 = wallets[0]
556
+ wallet_node_2, server_3 = wallets[1]
557
+ wallet = wallet_node.wallet_state_manager.main_wallet
558
+
559
+ ph = await wallet.get_new_puzzlehash()
560
+ if trusted:
561
+ wallet_node.config["trusted_peers"] = {
562
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
563
+ }
564
+ wallet_node_2.config["trusted_peers"] = {
565
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
566
+ }
567
+ else:
568
+ wallet_node.config["trusted_peers"] = {}
569
+ wallet_node_2.config["trusted_peers"] = {}
570
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
571
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
572
+
573
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
574
+
575
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
576
+ did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
577
+ wallet_node.wallet_state_manager, wallet, uint64(101), action_scope
578
+ )
579
+
580
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
581
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
582
+
583
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
584
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
585
+ coin = await did_wallet.get_coin()
586
+ info = Program.to([])
587
+ pubkey = (await did_wallet.wallet_state_manager.get_unused_derivation_record(did_wallet.wallet_info.id)).pubkey
588
+ with pytest.raises(Exception): # We expect a CLVM 80 error for this test
589
+ async with did_wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
590
+ await did_wallet.recovery_spend(
591
+ coin, ph, info, pubkey, WalletSpendBundle([], AugSchemeMPL.aggregate([])), action_scope
592
+ )
593
+
594
+ @pytest.mark.parametrize(
595
+ "trusted",
596
+ [True, False],
597
+ )
598
+ @pytest.mark.anyio
599
+ async def test_did_find_lost_did(self, self_hostname, two_wallet_nodes, trusted):
600
+ full_nodes, wallets, _ = two_wallet_nodes
601
+ full_node_api = full_nodes[0]
602
+ server_1 = full_node_api.server
603
+ wallet_node, server_2 = wallets[0]
604
+ wallet_node_2, server_3 = wallets[1]
605
+ wallet = wallet_node.wallet_state_manager.main_wallet
606
+ api_0 = WalletRpcApi(wallet_node)
607
+ if trusted:
608
+ wallet_node.config["trusted_peers"] = {
609
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
610
+ }
611
+ wallet_node_2.config["trusted_peers"] = {
612
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
613
+ }
614
+ else:
615
+ wallet_node.config["trusted_peers"] = {}
616
+ wallet_node_2.config["trusted_peers"] = {}
617
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
618
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
619
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
620
+
621
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
622
+ did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
623
+ wallet_node.wallet_state_manager, wallet, uint64(101), action_scope
624
+ )
625
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
626
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
627
+
628
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
629
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
630
+ # Delete the coin and wallet
631
+ coin = await did_wallet.get_coin()
632
+ await wallet_node.wallet_state_manager.coin_store.delete_coin_record(coin.name())
633
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 0)
634
+ await wallet_node.wallet_state_manager.user_store.delete_wallet(did_wallet.wallet_info.id)
635
+ wallet_node.wallet_state_manager.wallets.pop(did_wallet.wallet_info.id)
636
+ assert len(wallet_node.wallet_state_manager.wallets) == 1
637
+ # Find lost DID
638
+ resp = await api_0.did_find_lost_did({"coin_id": did_wallet.did_info.origin_coin.name().hex()})
639
+ assert resp["success"]
640
+ did_wallets = list(
641
+ filter(
642
+ lambda w: (w.type == WalletType.DECENTRALIZED_ID),
643
+ await wallet_node.wallet_state_manager.get_all_wallet_info_entries(),
644
+ )
645
+ )
646
+ did_wallet: Optional[DIDWallet] = wallet_node.wallet_state_manager.wallets[did_wallets[0].id]
647
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
648
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
649
+ # Spend DID
650
+ recovery_list = [bytes32.fromhex(did_wallet.get_my_DID())]
651
+ await did_wallet.update_recovery_list(recovery_list, uint64(1))
652
+ assert did_wallet.did_info.backup_ids == recovery_list
653
+ async with did_wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
654
+ await did_wallet.create_update_spend(action_scope)
655
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
656
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
657
+
658
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
659
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
660
+ # Delete the coin and change inner puzzle
661
+ coin = await did_wallet.get_coin()
662
+ await wallet_node.wallet_state_manager.coin_store.delete_coin_record(coin.name())
663
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 0)
664
+ new_inner_puzzle = await did_wallet.get_new_did_innerpuz()
665
+ did_wallet.did_info = dataclasses.replace(did_wallet.did_info, current_inner=new_inner_puzzle)
666
+ # Recovery the coin
667
+ resp = await api_0.did_find_lost_did({"coin_id": did_wallet.did_info.origin_coin.name().hex()})
668
+ assert resp["success"]
669
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
670
+ assert did_wallet.did_info.current_inner != new_inner_puzzle
671
+
672
+ @pytest.mark.parametrize(
673
+ "trusted",
674
+ [True, False],
675
+ )
676
+ @pytest.mark.anyio
677
+ async def test_did_attest_after_recovery(self, self_hostname, two_wallet_nodes, trusted):
678
+ full_nodes, wallets, _ = two_wallet_nodes
679
+ full_node_api = full_nodes[0]
680
+ server_1 = full_node_api.server
681
+ wallet_node, server_2 = wallets[0]
682
+ wallet_node_2, server_3 = wallets[1]
683
+ wallet = wallet_node.wallet_state_manager.main_wallet
684
+ wallet2 = wallet_node_2.wallet_state_manager.main_wallet
685
+ if trusted:
686
+ wallet_node.config["trusted_peers"] = {
687
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
688
+ }
689
+ wallet_node_2.config["trusted_peers"] = {
690
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
691
+ }
692
+ else:
693
+ wallet_node.config["trusted_peers"] = {}
694
+ wallet_node_2.config["trusted_peers"] = {}
695
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
696
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
697
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
698
+ await full_node_api.farm_blocks_to_wallet(1, wallet2)
699
+
700
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
701
+ did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
702
+ wallet_node.wallet_state_manager, wallet, uint64(101), action_scope
703
+ )
704
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
705
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
706
+
707
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
708
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
709
+ recovery_list = [bytes.fromhex(did_wallet.get_my_DID())]
710
+
711
+ async with wallet2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
712
+ did_wallet_2: DIDWallet = await DIDWallet.create_new_did_wallet(
713
+ wallet_node_2.wallet_state_manager, wallet2, uint64(101), action_scope, recovery_list
714
+ )
715
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
716
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
717
+ await time_out_assert(25, did_wallet_2.get_confirmed_balance, 101)
718
+ await time_out_assert(25, did_wallet_2.get_unconfirmed_balance, 101)
719
+ assert did_wallet_2.did_info.backup_ids == recovery_list
720
+
721
+ # Update coin with new ID info
722
+ recovery_list = [bytes.fromhex(did_wallet_2.get_my_DID())]
723
+ await did_wallet.update_recovery_list(recovery_list, uint64(1))
724
+ assert did_wallet.did_info.backup_ids == recovery_list
725
+ async with did_wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
726
+ await did_wallet.create_update_spend(action_scope)
727
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
728
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
729
+
730
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
731
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
732
+
733
+ # DID Wallet 2 recovers into DID Wallet 3 with new innerpuz
734
+ backup_data = did_wallet_2.create_backup()
735
+
736
+ async with wallet_node.wallet_state_manager.lock:
737
+ did_wallet_3 = await DIDWallet.create_new_did_wallet_from_recovery(
738
+ wallet_node.wallet_state_manager,
739
+ wallet,
740
+ backup_data,
741
+ )
742
+ new_ph = await did_wallet_3.get_new_did_inner_hash()
743
+ coin = await did_wallet_2.get_coin()
744
+ pubkey = (
745
+ await did_wallet_3.wallet_state_manager.get_unused_derivation_record(did_wallet_3.wallet_info.id)
746
+ ).pubkey
747
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
748
+ async with did_wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
749
+ message_spend_bundle, attest_data = await did_wallet.create_attestment(
750
+ coin.name(), new_ph, pubkey, action_scope
751
+ )
752
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
753
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
754
+
755
+ (
756
+ info,
757
+ message_spend_bundle,
758
+ ) = await did_wallet_3.load_attest_files_for_recovery_spend([attest_data])
759
+ async with did_wallet_3.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
760
+ await did_wallet_3.recovery_spend(coin, new_ph, info, pubkey, message_spend_bundle, action_scope)
761
+ await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
762
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
763
+
764
+ await time_out_assert(15, did_wallet_3.get_confirmed_balance, 101)
765
+ await time_out_assert(15, did_wallet_3.get_unconfirmed_balance, 101)
766
+
767
+ # DID Wallet 1 recovery spends into DID Wallet 4
768
+ backup_data = did_wallet.create_backup()
769
+
770
+ async with wallet_node_2.wallet_state_manager.lock:
771
+ did_wallet_4 = await DIDWallet.create_new_did_wallet_from_recovery(
772
+ wallet_node_2.wallet_state_manager,
773
+ wallet2,
774
+ backup_data,
775
+ )
776
+ coin = await did_wallet.get_coin()
777
+ new_ph = await did_wallet_4.get_new_did_inner_hash()
778
+ pubkey = (
779
+ await did_wallet_4.wallet_state_manager.get_unused_derivation_record(did_wallet_4.wallet_info.id)
780
+ ).pubkey
781
+ async with did_wallet_3.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
782
+ message_spend_bundle, attest1 = await did_wallet_3.create_attestment(
783
+ coin.name(), new_ph, pubkey, action_scope
784
+ )
785
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
786
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
787
+ await time_out_assert(15, wallet.get_pending_change_balance, 0)
788
+ (
789
+ test_info_list,
790
+ test_message_spend_bundle,
791
+ ) = await did_wallet_4.load_attest_files_for_recovery_spend([attest1])
792
+ async with did_wallet_4.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
793
+ await did_wallet_4.recovery_spend(
794
+ coin, new_ph, test_info_list, pubkey, test_message_spend_bundle, action_scope
795
+ )
796
+
797
+ await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
798
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
799
+
800
+ await time_out_assert(15, did_wallet_4.get_confirmed_balance, 101)
801
+ await time_out_assert(15, did_wallet_4.get_unconfirmed_balance, 101)
802
+ await time_out_assert(15, did_wallet.get_confirmed_balance, 0)
803
+ await time_out_assert(15, did_wallet.get_unconfirmed_balance, 0)
804
+
805
+ for wallet in [did_wallet, did_wallet_3, did_wallet_4]:
806
+ assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
807
+
808
+ @pytest.mark.parametrize(
809
+ "with_recovery",
810
+ [True, False],
811
+ )
812
+ @pytest.mark.parametrize(
813
+ "trusted",
814
+ [True, False],
815
+ )
816
+ @pytest.mark.anyio
817
+ async def test_did_transfer(self, self_hostname, two_wallet_nodes, with_recovery, trusted):
818
+ fee = uint64(1000)
819
+ full_nodes, wallets, _ = two_wallet_nodes
820
+ full_node_api = full_nodes[0]
821
+ server_1 = full_node_api.server
822
+ wallet_node, server_2 = wallets[0]
823
+ wallet_node_2, server_3 = wallets[1]
824
+ wallet = wallet_node.wallet_state_manager.main_wallet
825
+ wallet2 = wallet_node_2.wallet_state_manager.main_wallet
826
+ ph = await wallet.get_new_puzzlehash()
827
+
828
+ if trusted:
829
+ wallet_node.config["trusted_peers"] = {
830
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
831
+ }
832
+ wallet_node_2.config["trusted_peers"] = {
833
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
834
+ }
835
+ else:
836
+ wallet_node.config["trusted_peers"] = {}
837
+ wallet_node_2.config["trusted_peers"] = {}
838
+
839
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
840
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
841
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
842
+
843
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
844
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
845
+ wallet_node.wallet_state_manager,
846
+ wallet,
847
+ uint64(101),
848
+ action_scope,
849
+ [bytes(ph)],
850
+ uint64(1),
851
+ {"Twitter": "Test", "GitHub": "测试"},
852
+ fee=fee,
853
+ )
854
+ assert did_wallet_1.get_name() == "Profile 1"
855
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
856
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
857
+ await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
858
+ await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
859
+ # Transfer DID
860
+ new_puzhash = await wallet2.get_new_puzzlehash()
861
+ async with did_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
862
+ await did_wallet_1.transfer_did(new_puzhash, fee, with_recovery, action_scope)
863
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
864
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
865
+ # Check if the DID wallet is created in the wallet2
866
+
867
+ await time_out_assert(30, get_wallet_num, 2, wallet_node_2.wallet_state_manager)
868
+ await time_out_assert(30, get_wallet_num, 1, wallet_node.wallet_state_manager)
869
+ # Get the new DID wallet
870
+ did_wallets = list(
871
+ filter(
872
+ lambda w: (w.type == WalletType.DECENTRALIZED_ID),
873
+ await wallet_node_2.wallet_state_manager.get_all_wallet_info_entries(),
874
+ )
875
+ )
876
+ did_wallet_2: Optional[DIDWallet] = wallet_node_2.wallet_state_manager.wallets[did_wallets[0].id]
877
+ assert len(wallet_node.wallet_state_manager.wallets) == 1
878
+ assert did_wallet_1.did_info.origin_coin == did_wallet_2.did_info.origin_coin
879
+ if with_recovery:
880
+ assert did_wallet_1.did_info.backup_ids[0] == did_wallet_2.did_info.backup_ids[0]
881
+ assert did_wallet_1.did_info.num_of_backup_ids_needed == did_wallet_2.did_info.num_of_backup_ids_needed
882
+ metadata = json.loads(did_wallet_2.did_info.metadata)
883
+ assert metadata["Twitter"] == "Test"
884
+ assert metadata["GitHub"] == "测试"
885
+
886
+ # Test match_hinted_coin
887
+ assert await did_wallet_2.match_hinted_coin(
888
+ await did_wallet_2.get_coin(),
889
+ new_puzhash,
890
+ )
891
+
892
+ @pytest.mark.parametrize(
893
+ "trusted",
894
+ [True, False],
895
+ )
896
+ @pytest.mark.anyio
897
+ async def test_update_recovery_list(self, self_hostname, two_wallet_nodes, trusted):
898
+ full_nodes, wallets, _ = two_wallet_nodes
899
+ full_node_api = full_nodes[0]
900
+ server_1 = full_node_api.server
901
+ wallet_node, server_2 = wallets[0]
902
+ wallet_node_2, server_3 = wallets[1]
903
+ wallet = wallet_node.wallet_state_manager.main_wallet
904
+ ph = await wallet.get_new_puzzlehash()
905
+
906
+ if trusted:
907
+ wallet_node.config["trusted_peers"] = {
908
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
909
+ }
910
+ wallet_node_2.config["trusted_peers"] = {
911
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
912
+ }
913
+ else:
914
+ wallet_node.config["trusted_peers"] = {}
915
+ wallet_node_2.config["trusted_peers"] = {}
916
+
917
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
918
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
919
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
920
+
921
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
922
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
923
+ wallet_node.wallet_state_manager, wallet, uint64(101), action_scope, []
924
+ )
925
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
926
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
927
+ await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
928
+ await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
929
+ await did_wallet_1.update_recovery_list([bytes(ph)], 1)
930
+ async with did_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
931
+ await did_wallet_1.create_update_spend(action_scope)
932
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
933
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
934
+ await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
935
+ await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
936
+ assert did_wallet_1.did_info.backup_ids[0] == bytes(ph)
937
+ assert did_wallet_1.did_info.num_of_backup_ids_needed == 1
938
+
939
+ @pytest.mark.parametrize(
940
+ "trusted",
941
+ [True, False],
942
+ )
943
+ @pytest.mark.anyio
944
+ async def test_get_info(self, self_hostname, two_wallet_nodes, trusted):
945
+ fee = uint64(1000)
946
+ full_nodes, wallets, _ = two_wallet_nodes
947
+ full_node_api = full_nodes[0]
948
+ server_1 = full_node_api.server
949
+ wallet_node, server_2 = wallets[0]
950
+ wallet_node_2, server_3 = wallets[1]
951
+ wallet = wallet_node.wallet_state_manager.main_wallet
952
+ wallet1 = wallet_node_2.wallet_state_manager.main_wallet
953
+ ph1 = await wallet1.get_new_puzzlehash()
954
+ api_0 = WalletRpcApi(wallet_node)
955
+ if trusted:
956
+ wallet_node.config["trusted_peers"] = {
957
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
958
+ }
959
+ wallet_node_2.config["trusted_peers"] = {
960
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
961
+ }
962
+ else:
963
+ wallet_node.config["trusted_peers"] = {}
964
+ wallet_node_2.config["trusted_peers"] = {}
965
+
966
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
967
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
968
+ await full_node_api.farm_blocks_to_wallet(count=2, wallet=wallet)
969
+ did_amount = uint64(101)
970
+
971
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
972
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
973
+ wallet_node.wallet_state_manager,
974
+ wallet,
975
+ did_amount,
976
+ action_scope,
977
+ [],
978
+ metadata={"twitter": "twitter"},
979
+ fee=fee,
980
+ )
981
+
982
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
983
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=15)
984
+
985
+ assert await did_wallet_1.get_confirmed_balance() == did_amount
986
+ assert await did_wallet_1.get_unconfirmed_balance() == did_amount
987
+ response = await api_0.did_get_info({"coin_id": did_wallet_1.did_info.origin_coin.name().hex()})
988
+ assert response["did_id"] == encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value)
989
+ assert response["launcher_id"] == did_wallet_1.did_info.origin_coin.name().hex()
990
+ assert response["full_puzzle"].to_program() == create_singleton_puzzle(
991
+ did_wallet_1.did_info.current_inner, did_wallet_1.did_info.origin_coin.name()
992
+ )
993
+ assert response["metadata"]["twitter"] == "twitter"
994
+ assert response["latest_coin"] == (await did_wallet_1.get_coin()).name().hex()
995
+ assert response["num_verification"] == 0
996
+ assert response["recovery_list_hash"] == Program(Program.to([])).get_tree_hash().hex()
997
+ assert decode_puzzle_hash(response["p2_address"]).hex() == response["hints"][0]
998
+
999
+ # Test non-singleton coin
1000
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1001
+ coin = (await wallet.select_coins(uint64(1), action_scope)).pop()
1002
+ assert coin.amount % 2 == 1
1003
+ coin_id = coin.name()
1004
+ response = await api_0.did_get_info({"coin_id": coin_id.hex()})
1005
+ assert not response["success"]
1006
+
1007
+ # Test multiple odd coins
1008
+ odd_amount = uint64(1)
1009
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1010
+ async with action_scope.use() as interface:
1011
+ interface.side_effects.selected_coins.append(coin)
1012
+ coin_1 = (await wallet.select_coins(odd_amount, action_scope)).pop()
1013
+ assert coin_1.amount % 2 == 0
1014
+ async with wallet.wallet_state_manager.new_action_scope(
1015
+ DEFAULT_TX_CONFIG.override(excluded_coin_ids=[coin_id]), push=True
1016
+ ) as action_scope:
1017
+ await wallet.generate_signed_transaction(odd_amount, ph1, action_scope, fee)
1018
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1019
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_2, timeout=15)
1020
+
1021
+ assert await wallet1.get_confirmed_balance() == odd_amount
1022
+ with pytest.raises(ValueError):
1023
+ await api_0.did_get_info({"coin_id": coin_1.name().hex()})
1024
+
1025
+ @pytest.mark.parametrize(
1026
+ "trusted",
1027
+ [True, False],
1028
+ )
1029
+ @pytest.mark.anyio
1030
+ async def test_message_spend(self, self_hostname, two_wallet_nodes, trusted):
1031
+ fee = uint64(1000)
1032
+ full_nodes, wallets, _ = two_wallet_nodes
1033
+ full_node_api = full_nodes[0]
1034
+ server_1 = full_node_api.server
1035
+ wallet_node, server_2 = wallets[0]
1036
+ wallet_node_2, server_3 = wallets[1]
1037
+ wallet = wallet_node.wallet_state_manager.main_wallet
1038
+ api_0 = WalletRpcApi(wallet_node)
1039
+ if trusted:
1040
+ wallet_node.config["trusted_peers"] = {
1041
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1042
+ }
1043
+ wallet_node_2.config["trusted_peers"] = {
1044
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1045
+ }
1046
+ else:
1047
+ wallet_node.config["trusted_peers"] = {}
1048
+ wallet_node_2.config["trusted_peers"] = {}
1049
+
1050
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
1051
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
1052
+
1053
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
1054
+
1055
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1056
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
1057
+ wallet_node.wallet_state_manager, wallet, uint64(101), action_scope, [], fee=fee
1058
+ )
1059
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1060
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
1061
+ await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
1062
+ await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
1063
+ response = await api_0.did_message_spend(
1064
+ {"wallet_id": did_wallet_1.wallet_id, "coin_announcements": ["0abc"], "puzzle_announcements": ["0def"]}
1065
+ )
1066
+ spend = response["spend_bundle"].coin_spends[0]
1067
+ conditions = conditions_dict_for_solution(
1068
+ spend.puzzle_reveal, spend.solution, wallet.wallet_state_manager.constants.MAX_BLOCK_COST_CLVM
1069
+ )
1070
+
1071
+ assert len(conditions[ConditionOpcode.CREATE_COIN_ANNOUNCEMENT]) == 1
1072
+ assert conditions[ConditionOpcode.CREATE_COIN_ANNOUNCEMENT][0].vars[0].hex() == "0abc"
1073
+ assert len(conditions[ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT]) == 1
1074
+ assert conditions[ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT][0].vars[0].hex() == "0def"
1075
+
1076
+ @pytest.mark.parametrize(
1077
+ "trusted",
1078
+ [True, False],
1079
+ )
1080
+ @pytest.mark.anyio
1081
+ async def test_update_metadata(self, self_hostname, two_wallet_nodes, trusted):
1082
+ fee = uint64(1000)
1083
+ full_nodes, wallets, _ = two_wallet_nodes
1084
+ full_node_api = full_nodes[0]
1085
+ server_1 = full_node_api.server
1086
+ wallet_node, server_2 = wallets[0]
1087
+ wallet_node_2, server_3 = wallets[1]
1088
+ wallet = wallet_node.wallet_state_manager.main_wallet
1089
+ if trusted:
1090
+ wallet_node.config["trusted_peers"] = {
1091
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1092
+ }
1093
+ wallet_node_2.config["trusted_peers"] = {
1094
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1095
+ }
1096
+ else:
1097
+ wallet_node.config["trusted_peers"] = {}
1098
+ wallet_node_2.config["trusted_peers"] = {}
1099
+
1100
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
1101
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
1102
+ expected_confirmed_balance = await full_node_api.farm_blocks_to_wallet(count=2, wallet=wallet)
1103
+ did_amount = uint64(101)
1104
+
1105
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1106
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
1107
+ wallet_node.wallet_state_manager, wallet, did_amount, action_scope, [], fee=fee
1108
+ )
1109
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1110
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=15)
1111
+
1112
+ expected_confirmed_balance -= did_amount + fee
1113
+ assert await did_wallet_1.get_confirmed_balance() == did_amount
1114
+ assert await did_wallet_1.get_unconfirmed_balance() == did_amount
1115
+ assert await wallet.get_confirmed_balance() == expected_confirmed_balance
1116
+ assert await wallet.get_unconfirmed_balance() == expected_confirmed_balance
1117
+ puzhash = did_wallet_1.did_info.current_inner.get_tree_hash()
1118
+ parent_num = get_parent_num(did_wallet_1)
1119
+
1120
+ bad_metadata = {"Twitter": {"url": "http://www.twitter.com"}}
1121
+ with pytest.raises(ValueError) as e:
1122
+ await did_wallet_1.update_metadata(bad_metadata)
1123
+ assert e.match("Metadata key value pairs must be strings.")
1124
+
1125
+ metadata = {}
1126
+ metadata["Twitter"] = "http://www.twitter.com"
1127
+ await did_wallet_1.update_metadata(metadata)
1128
+ async with did_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1129
+ await did_wallet_1.create_update_spend(action_scope, fee)
1130
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1131
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
1132
+
1133
+ expected_confirmed_balance -= fee
1134
+
1135
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=15)
1136
+
1137
+ assert await did_wallet_1.get_confirmed_balance() == did_amount
1138
+ assert await did_wallet_1.get_unconfirmed_balance() == did_amount
1139
+
1140
+ assert get_parent_num(did_wallet_1) == parent_num + 2
1141
+ assert puzhash != did_wallet_1.did_info.current_inner.get_tree_hash()
1142
+ assert await wallet.get_confirmed_balance() == expected_confirmed_balance
1143
+ assert await wallet.get_unconfirmed_balance() == expected_confirmed_balance
1144
+
1145
+ assert did_wallet_1.did_info.metadata.find("Twitter") > 0
1146
+
1147
+ @pytest.mark.parametrize(
1148
+ "trusted",
1149
+ [True, False],
1150
+ )
1151
+ @pytest.mark.anyio
1152
+ async def test_did_sign_message(self, self_hostname, two_wallet_nodes, trusted):
1153
+ fee = uint64(1000)
1154
+ full_nodes, wallets, _ = two_wallet_nodes
1155
+ full_node_api = full_nodes[0]
1156
+ server_1 = full_node_api.server
1157
+ wallet_node, server_2 = wallets[0]
1158
+ wallet_node_2, server_3 = wallets[1]
1159
+ wallet = wallet_node.wallet_state_manager.main_wallet
1160
+ api_0 = WalletRpcApi(wallet_node)
1161
+ ph = await wallet.get_new_puzzlehash()
1162
+
1163
+ if trusted:
1164
+ wallet_node.config["trusted_peers"] = {
1165
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1166
+ }
1167
+ wallet_node_2.config["trusted_peers"] = {
1168
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1169
+ }
1170
+ else:
1171
+ wallet_node.config["trusted_peers"] = {}
1172
+ wallet_node_2.config["trusted_peers"] = {}
1173
+
1174
+ await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
1175
+ await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
1176
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
1177
+
1178
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1179
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
1180
+ wallet_node.wallet_state_manager,
1181
+ wallet,
1182
+ uint64(101),
1183
+ action_scope,
1184
+ [bytes(ph)],
1185
+ uint64(1),
1186
+ {"Twitter": "Test", "GitHub": "测试"},
1187
+ fee=fee,
1188
+ )
1189
+ assert did_wallet_1.get_name() == "Profile 1"
1190
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1191
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
1192
+ await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
1193
+ # Test general string
1194
+ message = "Hello World"
1195
+ response = await api_0.sign_message_by_id(
1196
+ {
1197
+ "id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
1198
+ "message": message,
1199
+ }
1200
+ )
1201
+ puzzle: Program = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message))
1202
+ assert AugSchemeMPL.verify(
1203
+ G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
1204
+ puzzle.get_tree_hash(),
1205
+ G2Element.from_bytes(bytes.fromhex(response["signature"])),
1206
+ )
1207
+ # Test hex string
1208
+ message = "0123456789ABCDEF"
1209
+ response = await api_0.sign_message_by_id(
1210
+ {
1211
+ "id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
1212
+ "message": message,
1213
+ "is_hex": True,
1214
+ }
1215
+ )
1216
+ puzzle: Program = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, bytes.fromhex(message)))
1217
+
1218
+ assert AugSchemeMPL.verify(
1219
+ G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
1220
+ puzzle.get_tree_hash(),
1221
+ G2Element.from_bytes(bytes.fromhex(response["signature"])),
1222
+ )
1223
+
1224
+ # Test BLS sign string
1225
+ message = "Hello World"
1226
+ response = await api_0.sign_message_by_id(
1227
+ {
1228
+ "id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
1229
+ "message": message,
1230
+ "is_hex": "False",
1231
+ "safe_mode": "False",
1232
+ }
1233
+ )
1234
+
1235
+ assert AugSchemeMPL.verify(
1236
+ G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
1237
+ bytes(message, "utf-8"),
1238
+ G2Element.from_bytes(bytes.fromhex(response["signature"])),
1239
+ )
1240
+ # Test BLS sign hex
1241
+ message = "0123456789ABCDEF"
1242
+ response = await api_0.sign_message_by_id(
1243
+ {
1244
+ "id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
1245
+ "message": message,
1246
+ "is_hex": True,
1247
+ "safe_mode": False,
1248
+ }
1249
+ )
1250
+
1251
+ assert AugSchemeMPL.verify(
1252
+ G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
1253
+ bytes.fromhex(message),
1254
+ G2Element.from_bytes(bytes.fromhex(response["signature"])),
1255
+ )
1256
+
1257
+ @pytest.mark.parametrize(
1258
+ "trusted",
1259
+ [True, False],
1260
+ )
1261
+ @pytest.mark.anyio
1262
+ async def test_create_did_with_recovery_list(self, self_hostname, two_nodes_two_wallets_with_same_keys, trusted):
1263
+ """
1264
+ A DID is created on-chain in client0, causing a DID Wallet to be created in client1, which shares the same key.
1265
+ This can happen if someone uses the same key on multiple computers, or is syncing a wallet from scratch.
1266
+
1267
+ For this test, we assign a recovery list hash at DID creation time, but the recovery list is not yet available
1268
+ to the wallet_node that the DID Wallet is being created in (client1).
1269
+
1270
+ """
1271
+ full_nodes, wallets, _ = two_nodes_two_wallets_with_same_keys
1272
+ full_node_api = full_nodes[0]
1273
+ full_node_server = full_node_api.server
1274
+ wallet_node_0, server_0 = wallets[0]
1275
+ wallet_node_1, server_1 = wallets[1]
1276
+
1277
+ wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
1278
+ wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
1279
+
1280
+ ph0 = await wallet_0.get_new_puzzlehash()
1281
+ ph1 = await wallet_1.get_new_puzzlehash()
1282
+
1283
+ sk0 = await wallet_node_0.wallet_state_manager.get_private_key(ph0)
1284
+ sk1 = await wallet_node_1.wallet_state_manager.get_private_key(ph1)
1285
+ assert sk0 == sk1
1286
+
1287
+ if trusted:
1288
+ wallet_node_0.config["trusted_peers"] = {
1289
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1290
+ }
1291
+ wallet_node_1.config["trusted_peers"] = {
1292
+ full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
1293
+ }
1294
+
1295
+ else:
1296
+ wallet_node_0.config["trusted_peers"] = {}
1297
+ wallet_node_1.config["trusted_peers"] = {}
1298
+ await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
1299
+ await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
1300
+
1301
+ await full_node_api.farm_blocks_to_wallet(1, wallet_0)
1302
+ await full_node_api.farm_blocks_to_wallet(1, wallet_1)
1303
+
1304
+ # Node 0 sets up a DID Wallet with a backup set, but num_of_backup_ids_needed=0
1305
+ # (a malformed solution, but legal for the clvm puzzle)
1306
+ recovery_list = [bytes.fromhex("00" * 32)]
1307
+ async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1308
+ did_wallet_0: DIDWallet = await DIDWallet.create_new_did_wallet(
1309
+ wallet_node_0.wallet_state_manager,
1310
+ wallet_0,
1311
+ uint64(101),
1312
+ action_scope,
1313
+ backups_ids=recovery_list,
1314
+ num_of_backup_ids_needed=0,
1315
+ )
1316
+
1317
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1318
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0])
1319
+
1320
+ await time_out_assert(15, did_wallet_0.get_confirmed_balance, 101)
1321
+ await time_out_assert(15, did_wallet_0.get_unconfirmed_balance, 101)
1322
+ await time_out_assert(15, did_wallet_0.get_pending_change_balance, 0)
1323
+
1324
+ await full_node_api.farm_blocks_to_wallet(1, wallet_0)
1325
+
1326
+ #######################
1327
+ all_node_0_wallets = await wallet_node_0.wallet_state_manager.user_store.get_all_wallet_info_entries()
1328
+ all_node_1_wallets = await wallet_node_1.wallet_state_manager.user_store.get_all_wallet_info_entries()
1329
+ assert len(all_node_0_wallets) == len(all_node_1_wallets)
1330
+
1331
+ # Note that the inner program we expect is different than the on-chain inner.
1332
+ # This means that we have more work to do in the checks for the two different spend cases of
1333
+ # the DID wallet Singleton
1334
+ # assert (
1335
+ # json.loads(all_node_0_wallets[1].data)["current_inner"]
1336
+ # == json.loads(all_node_1_wallets[1].data)["current_inner"]
1337
+ # )
1338
+
1339
+ @pytest.mark.parametrize(
1340
+ "trusted",
1341
+ [True, False],
1342
+ )
1343
+ @pytest.mark.anyio
1344
+ async def test_did_resync(self, self_hostname, two_wallet_nodes, trusted) -> None:
1345
+ full_nodes, wallets, _ = two_wallet_nodes
1346
+ full_node_api = full_nodes[0]
1347
+ full_node_server = full_node_api.full_node.server
1348
+ wallet_node_1, wallet_server_1 = wallets[0]
1349
+ wallet_node_2, wallet_server_2 = wallets[1]
1350
+ wallet = wallet_node_1.wallet_state_manager.main_wallet
1351
+ wallet2 = wallet_node_2.wallet_state_manager.main_wallet
1352
+ fee = uint64(0)
1353
+ wallet_api_1 = WalletRpcApi(wallet_node_1)
1354
+ wallet_api_2 = WalletRpcApi(wallet_node_2)
1355
+ ph = await wallet.get_new_puzzlehash()
1356
+ if trusted:
1357
+ wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
1358
+ wallet_node_2.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
1359
+ else:
1360
+ wallet_node_1.config["trusted_peers"] = {}
1361
+ wallet_node_2.config["trusted_peers"] = {}
1362
+ await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
1363
+ await wallet_server_2.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
1364
+ await full_node_api.farm_blocks_to_wallet(1, wallet)
1365
+
1366
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1367
+ did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
1368
+ wallet_node_1.wallet_state_manager,
1369
+ wallet,
1370
+ uint64(101),
1371
+ action_scope,
1372
+ [bytes32(ph)],
1373
+ uint64(1),
1374
+ {"Twitter": "Test", "GitHub": "测试"},
1375
+ fee=fee,
1376
+ )
1377
+ assert did_wallet_1.get_name() == "Profile 1"
1378
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1379
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_1, wallet_node_2])
1380
+ await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
1381
+ await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
1382
+ # Transfer DID
1383
+ new_puzhash = await wallet2.get_new_puzzlehash()
1384
+ async with did_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1385
+ await did_wallet_1.transfer_did(new_puzhash, fee, True, action_scope=action_scope)
1386
+ await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1387
+ await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_1, wallet_node_2])
1388
+ # Check if the DID wallet is created in the wallet2
1389
+ await time_out_assert(30, get_wallet_num, 2, wallet_node_2.wallet_state_manager)
1390
+ await time_out_assert(30, get_wallet_num, 1, wallet_node_1.wallet_state_manager)
1391
+ did_wallet_2 = wallet_node_2.wallet_state_manager.get_wallet(uint32(2), DIDWallet)
1392
+ did_info = did_wallet_2.did_info
1393
+ # set flag to reset wallet sync data on start
1394
+ await wallet_api_1.set_wallet_resync_on_startup({"enable": True})
1395
+ fingerprint_1 = wallet_node_1.logged_in_fingerprint
1396
+ await wallet_api_2.set_wallet_resync_on_startup({"enable": True})
1397
+ fingerprint_2 = wallet_node_2.logged_in_fingerprint
1398
+ # 2 reward coins
1399
+ assert len(await wallet_node_1.wallet_state_manager.coin_store.get_all_unspent_coins()) == 2
1400
+ # Delete tx records
1401
+ await wallet_node_1.wallet_state_manager.tx_store.rollback_to_block(0)
1402
+ wallet_node_1._close()
1403
+ await wallet_node_1._await_closed()
1404
+ wallet_node_2._close()
1405
+ await wallet_node_2._await_closed()
1406
+ wallet_node_1.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_1_CHALLENGE_KEY.sqlite"
1407
+ wallet_node_2.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_2_CHALLENGE_KEY.sqlite"
1408
+ # Start resync
1409
+ await wallet_node_1._start_with_fingerprint(fingerprint_1)
1410
+ await wallet_node_2._start_with_fingerprint(fingerprint_2)
1411
+ await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
1412
+ await wallet_server_2.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
1413
+ await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(bytes32(b"\00" * 32)))
1414
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_1, timeout=20)
1415
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_2, timeout=20)
1416
+ await time_out_assert(30, get_wallet_num, 1, wallet_node_1.wallet_state_manager)
1417
+ await time_out_assert(30, get_wallet_num, 2, wallet_node_2.wallet_state_manager)
1418
+ did_wallet_2 = wallet_node_2.wallet_state_manager.get_wallet(uint32(2), DIDWallet)
1419
+ assert did_info == did_wallet_2.did_info
1420
+
1421
+
1422
+ @pytest.mark.parametrize(
1423
+ "wallet_environments",
1424
+ [
1425
+ {
1426
+ "num_environments": 1,
1427
+ "blocks_needed": [1],
1428
+ }
1429
+ ],
1430
+ indirect=True,
1431
+ )
1432
+ @pytest.mark.anyio
1433
+ async def test_did_coin_records(wallet_environments: WalletTestFramework, monkeypatch: pytest.MonkeyPatch) -> None:
1434
+ # Setup
1435
+ wallet_node = wallet_environments.environments[0].node
1436
+ wallet = wallet_environments.environments[0].xch_wallet
1437
+
1438
+ # Generate DID wallet
1439
+ async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1440
+ did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
1441
+ wallet_node.wallet_state_manager, wallet, uint64(1), action_scope
1442
+ )
1443
+
1444
+ await wallet_environments.process_pending_states(
1445
+ [
1446
+ WalletStateTransition(
1447
+ pre_block_balance_updates={
1448
+ 1: {"set_remainder": True},
1449
+ 2: {"init": True, "set_remainder": True},
1450
+ },
1451
+ post_block_balance_updates={
1452
+ 1: {"set_remainder": True},
1453
+ 2: {"set_remainder": True},
1454
+ },
1455
+ ),
1456
+ WalletStateTransition(),
1457
+ ]
1458
+ )
1459
+
1460
+ for _ in range(0, 2):
1461
+ async with did_wallet.wallet_state_manager.new_action_scope(
1462
+ wallet_environments.tx_config, push=True
1463
+ ) as action_scope:
1464
+ await did_wallet.transfer_did(await wallet.get_puzzle_hash(new=False), uint64(0), True, action_scope)
1465
+ await wallet_environments.process_pending_states(
1466
+ [
1467
+ WalletStateTransition(
1468
+ pre_block_balance_updates={
1469
+ 1: {"set_remainder": True},
1470
+ 2: {"set_remainder": True},
1471
+ },
1472
+ post_block_balance_updates={
1473
+ 1: {"set_remainder": True},
1474
+ 2: {"set_remainder": True},
1475
+ },
1476
+ ),
1477
+ WalletStateTransition(),
1478
+ ]
1479
+ )
1480
+
1481
+ assert len(await wallet.wallet_state_manager.get_spendable_coins_for_wallet(did_wallet.id())) == 1