chia-blockchain 2.5.7rc4__py3-none-any.whl → 2.5.8rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/__init__.py +8 -4
- chia/_tests/blockchain/blockchain_test_utils.py +6 -8
- chia/_tests/blockchain/test_augmented_chain.py +4 -4
- chia/_tests/blockchain/test_blockchain.py +165 -190
- chia/_tests/blockchain/test_build_chains.py +2 -4
- chia/_tests/blockchain/test_get_block_generator.py +2 -3
- chia/_tests/clvm/coin_store.py +4 -7
- chia/_tests/clvm/test_clvm_step.py +4 -4
- chia/_tests/clvm/test_puzzle_compression.py +2 -1
- chia/_tests/clvm/test_puzzle_drivers.py +2 -2
- chia/_tests/clvm/test_singletons.py +2 -4
- chia/_tests/clvm/test_spend_sim.py +2 -2
- chia/_tests/cmds/cmd_test_utils.py +27 -45
- chia/_tests/cmds/test_cmd_framework.py +6 -6
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_show.py +4 -4
- chia/_tests/cmds/test_tx_config_args.py +1 -2
- chia/_tests/cmds/testing_classes.py +4 -5
- chia/_tests/cmds/wallet/test_did.py +24 -27
- chia/_tests/cmds/wallet/test_nft.py +12 -10
- chia/_tests/cmds/wallet/test_vcs.py +11 -12
- chia/_tests/cmds/wallet/test_wallet.py +134 -89
- chia/_tests/conftest.py +59 -30
- chia/_tests/connection_utils.py +2 -2
- chia/_tests/core/cmds/test_beta.py +4 -4
- chia/_tests/core/cmds/test_keys.py +2 -3
- chia/_tests/core/cmds/test_wallet.py +15 -15
- chia/_tests/core/consensus/test_pot_iterations.py +19 -73
- chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
- chia/_tests/core/daemon/test_daemon.py +11 -11
- chia/_tests/core/data_layer/conftest.py +2 -2
- chia/_tests/core/data_layer/test_data_rpc.py +28 -14
- chia/_tests/core/data_layer/test_data_store.py +10 -10
- chia/_tests/core/data_layer/util.py +11 -11
- chia/_tests/core/farmer/test_farmer_api.py +2 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
- chia/_tests/core/full_node/stores/test_block_store.py +5 -4
- chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
- chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +3 -4
- chia/_tests/core/full_node/test_conditions.py +21 -23
- chia/_tests/core/full_node/test_full_node.py +225 -62
- chia/_tests/core/full_node/test_hint_management.py +2 -4
- chia/_tests/core/full_node/test_performance.py +0 -1
- chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
- chia/_tests/core/full_node/test_transactions.py +1 -2
- chia/_tests/core/full_node/test_tx_processing_queue.py +109 -25
- chia/_tests/core/mempool/test_mempool.py +29 -37
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
- chia/_tests/core/mempool/test_mempool_manager.py +963 -839
- chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
- chia/_tests/core/server/serve.py +7 -7
- chia/_tests/core/server/test_dos.py +1 -2
- chia/_tests/core/server/test_event_loop.py +12 -4
- chia/_tests/core/server/test_loop.py +7 -8
- chia/_tests/core/server/test_rate_limits.py +9 -8
- chia/_tests/core/server/test_server.py +61 -1
- chia/_tests/core/services/test_services.py +2 -2
- chia/_tests/core/ssl/test_ssl.py +2 -2
- chia/_tests/core/test_cost_calculation.py +2 -6
- chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
- chia/_tests/core/test_filter.py +0 -1
- chia/_tests/core/test_full_node_rpc.py +2 -2
- chia/_tests/core/test_merkle_set.py +1 -2
- chia/_tests/core/test_seeder.py +4 -4
- chia/_tests/core/util/test_config.py +4 -4
- chia/_tests/core/util/test_jsonify.py +2 -2
- chia/_tests/core/util/test_keychain.py +3 -3
- chia/_tests/core/util/test_lockfile.py +2 -1
- chia/_tests/core/util/test_log_exceptions.py +1 -2
- chia/_tests/core/util/test_streamable.py +17 -17
- chia/_tests/db/test_db_wrapper.py +3 -2
- chia/_tests/environments/wallet.py +14 -14
- chia/_tests/ether.py +4 -3
- chia/_tests/farmer_harvester/test_farmer.py +41 -24
- chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
- chia/_tests/harvester/test_harvester_api.py +11 -4
- chia/_tests/plot_sync/test_plot_sync.py +13 -11
- chia/_tests/plot_sync/test_receiver.py +11 -10
- chia/_tests/plot_sync/test_sync_simulated.py +2 -2
- chia/_tests/plot_sync/util.py +1 -2
- chia/_tests/plotting/test_plot_manager.py +7 -6
- chia/_tests/plotting/test_prover.py +30 -38
- chia/_tests/pools/test_pool_cmdline.py +4 -6
- chia/_tests/pools/test_pool_rpc.py +203 -61
- chia/_tests/pools/test_pool_wallet.py +3 -3
- chia/_tests/pools/test_wallet_pool_store.py +1 -4
- chia/_tests/process_junit.py +2 -2
- chia/_tests/rpc/test_rpc_client.py +4 -4
- chia/_tests/rpc/test_rpc_server.py +3 -3
- chia/_tests/simulation/test_simulation.py +12 -25
- chia/_tests/solver/test_solver_service.py +13 -4
- chia/_tests/testconfig.py +2 -2
- chia/_tests/timelord/test_new_peak.py +22 -11
- chia/_tests/tools/test_run_block.py +0 -2
- chia/_tests/tools/test_virtual_project.py +2 -1
- chia/_tests/util/benchmarks.py +1 -0
- chia/_tests/util/blockchain.py +38 -36
- chia/_tests/util/blockchain_mock.py +11 -11
- chia/_tests/util/build_network_protocol_files.py +2 -1
- chia/_tests/util/coin_store.py +2 -1
- chia/_tests/util/config.py +1 -1
- chia/_tests/util/db_connection.py +2 -3
- chia/_tests/util/full_sync.py +9 -11
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/get_name_puzzle_conditions.py +2 -0
- chia/_tests/util/misc.py +24 -24
- chia/_tests/util/network_protocol_data.py +20 -3
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +292 -3
- chia/_tests/util/setup_nodes.py +62 -47
- chia/_tests/util/spend_sim.py +57 -57
- chia/_tests/util/test_async_pool.py +2 -3
- chia/_tests/util/test_chia_version.py +1 -3
- chia/_tests/util/test_config.py +3 -3
- chia/_tests/util/test_full_block_utils.py +6 -3
- chia/_tests/util/test_limited_semaphore.py +1 -2
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_network.py +1 -2
- chia/_tests/util/test_priority_mutex.py +3 -3
- chia/_tests/util/test_recursive_replace.py +5 -6
- chia/_tests/util/test_replace_str_to_bytes.py +8 -10
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/time_out_assert.py +2 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
- chia/_tests/wallet/conftest.py +6 -6
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
- chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
- chia/_tests/wallet/did_wallet/test_did.py +16 -6
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
- chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
- chia/_tests/wallet/sync/test_wallet_sync.py +43 -47
- chia/_tests/wallet/test_clvm_streamable.py +2 -3
- chia/_tests/wallet/test_coin_management.py +2 -2
- chia/_tests/wallet/test_conditions.py +45 -51
- chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
- chia/_tests/wallet/test_new_wallet_protocol.py +4 -6
- chia/_tests/wallet/test_notifications.py +14 -14
- chia/_tests/wallet/test_signer_protocol.py +5 -5
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
- chia/_tests/wallet/test_transaction_store.py +20 -20
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +380 -228
- chia/_tests/wallet/test_wallet_action_scope.py +4 -4
- chia/_tests/wallet/test_wallet_blockchain.py +12 -12
- chia/_tests/wallet/test_wallet_coin_store.py +3 -4
- chia/_tests/wallet/test_wallet_node.py +14 -14
- chia/_tests/wallet/test_wallet_test_framework.py +2 -1
- chia/_tests/wallet/test_wallet_utils.py +2 -3
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
- chia/_tests/wallet/wallet_block_tools.py +12 -11
- chia/_tests/weight_proof/config.py +1 -0
- chia/_tests/weight_proof/test_weight_proof.py +5 -4
- chia/apis/__init__.py +21 -0
- chia/apis/farmer_stub.py +102 -0
- chia/apis/full_node_stub.py +372 -0
- chia/apis/harvester_stub.py +57 -0
- chia/apis/introducer_stub.py +35 -0
- chia/apis/solver_stub.py +30 -0
- chia/apis/stub_protocol_registry.py +21 -0
- chia/apis/timelord_stub.py +39 -0
- chia/apis/wallet_stub.py +161 -0
- chia/cmds/beta.py +3 -4
- chia/cmds/beta_funcs.py +4 -3
- chia/cmds/check_wallet_db.py +4 -4
- chia/cmds/chia.py +1 -2
- chia/cmds/cmd_classes.py +11 -13
- chia/cmds/cmd_helpers.py +11 -11
- chia/cmds/cmds_util.py +15 -15
- chia/cmds/coin_funcs.py +6 -7
- chia/cmds/coins.py +2 -3
- chia/cmds/configure.py +1 -2
- chia/cmds/data.py +42 -42
- chia/cmds/data_funcs.py +81 -81
- chia/cmds/db.py +4 -5
- chia/cmds/db_backup_func.py +2 -2
- chia/cmds/db_upgrade_func.py +3 -3
- chia/cmds/db_validate_func.py +2 -2
- chia/cmds/dev/data.py +4 -4
- chia/cmds/dev/gh.py +5 -5
- chia/cmds/dev/installers.py +2 -3
- chia/cmds/dev/mempool.py +3 -4
- chia/cmds/dev/mempool_funcs.py +4 -4
- chia/cmds/dev/sim.py +8 -8
- chia/cmds/dump_keyring.py +3 -3
- chia/cmds/farm.py +6 -8
- chia/cmds/farm_funcs.py +25 -24
- chia/cmds/init_funcs.py +4 -4
- chia/cmds/keys.py +16 -18
- chia/cmds/keys_funcs.py +36 -36
- chia/cmds/netspace.py +1 -3
- chia/cmds/netspace_funcs.py +1 -2
- chia/cmds/options.py +3 -2
- chia/cmds/param_types.py +17 -16
- chia/cmds/passphrase.py +6 -7
- chia/cmds/passphrase_funcs.py +11 -13
- chia/cmds/peer.py +1 -3
- chia/cmds/peer_funcs.py +3 -3
- chia/cmds/plotnft.py +6 -7
- chia/cmds/plotnft_funcs.py +37 -26
- chia/cmds/rpc.py +3 -3
- chia/cmds/show.py +3 -5
- chia/cmds/show_funcs.py +9 -9
- chia/cmds/sim_funcs.py +25 -26
- chia/cmds/solver.py +1 -3
- chia/cmds/solver_funcs.py +1 -2
- chia/cmds/start_funcs.py +2 -2
- chia/cmds/wallet.py +76 -81
- chia/cmds/wallet_funcs.py +206 -177
- chia/consensus/augmented_chain.py +6 -6
- chia/consensus/block_body_validation.py +19 -15
- chia/consensus/block_creation.py +25 -21
- chia/consensus/block_header_validation.py +27 -13
- chia/consensus/block_height_map.py +3 -6
- chia/consensus/block_height_map_protocol.py +2 -2
- chia/consensus/block_record.py +2 -4
- chia/consensus/blockchain.py +58 -40
- chia/consensus/blockchain_interface.py +7 -7
- chia/consensus/coin_store_protocol.py +5 -6
- chia/consensus/condition_tools.py +4 -4
- chia/consensus/cost_calculator.py +2 -3
- chia/consensus/default_constants.py +16 -13
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +3 -5
- chia/consensus/find_fork_point.py +2 -4
- chia/consensus/full_block_to_block_record.py +11 -13
- chia/consensus/generator_tools.py +2 -3
- chia/consensus/get_block_challenge.py +42 -26
- chia/consensus/get_block_generator.py +2 -3
- chia/consensus/make_sub_epoch_summary.py +8 -7
- chia/consensus/multiprocess_validation.py +31 -20
- chia/consensus/pos_quality.py +6 -23
- chia/consensus/pot_iterations.py +17 -44
- chia/consensus/signage_point.py +4 -5
- chia/consensus/vdf_info_computation.py +2 -4
- chia/daemon/client.py +8 -8
- chia/daemon/keychain_proxy.py +31 -37
- chia/daemon/server.py +32 -33
- chia/daemon/windows_signal.py +4 -3
- chia/data_layer/data_layer.py +86 -77
- chia/data_layer/data_layer_rpc_api.py +9 -9
- chia/data_layer/data_layer_rpc_client.py +13 -15
- chia/data_layer/data_layer_server.py +3 -3
- chia/data_layer/data_layer_util.py +14 -14
- chia/data_layer/data_layer_wallet.py +94 -101
- chia/data_layer/data_store.py +50 -50
- chia/data_layer/dl_wallet_store.py +9 -12
- chia/data_layer/download_data.py +8 -9
- chia/data_layer/s3_plugin_service.py +5 -9
- chia/data_layer/start_data_layer.py +5 -5
- chia/farmer/farmer.py +31 -31
- chia/farmer/farmer_api.py +45 -33
- chia/farmer/farmer_rpc_api.py +5 -4
- chia/farmer/farmer_rpc_client.py +6 -6
- chia/farmer/start_farmer.py +6 -6
- chia/full_node/block_store.py +13 -16
- chia/full_node/check_fork_next_block.py +1 -2
- chia/full_node/coin_store.py +15 -16
- chia/full_node/eligible_coin_spends.py +3 -3
- chia/full_node/fee_estimate_store.py +2 -3
- chia/full_node/fee_tracker.py +1 -2
- chia/full_node/full_block_utils.py +4 -4
- chia/full_node/full_node.py +238 -224
- chia/full_node/full_node_api.py +193 -150
- chia/full_node/full_node_rpc_api.py +53 -31
- chia/full_node/full_node_rpc_client.py +18 -19
- chia/full_node/full_node_store.py +45 -43
- chia/full_node/hint_management.py +2 -2
- chia/full_node/mempool.py +17 -19
- chia/full_node/mempool_manager.py +89 -42
- chia/full_node/pending_tx_cache.py +2 -3
- chia/full_node/start_full_node.py +5 -5
- chia/full_node/sync_store.py +3 -4
- chia/full_node/tx_processing_queue.py +34 -13
- chia/full_node/weight_proof.py +61 -48
- chia/harvester/harvester.py +25 -24
- chia/harvester/harvester_api.py +61 -38
- chia/harvester/harvester_rpc_api.py +10 -10
- chia/harvester/start_harvester.py +4 -4
- chia/introducer/introducer.py +3 -3
- chia/introducer/introducer_api.py +6 -4
- chia/introducer/start_introducer.py +4 -4
- chia/legacy/keyring.py +3 -3
- chia/plot_sync/delta.py +1 -2
- chia/plot_sync/receiver.py +20 -17
- chia/plot_sync/sender.py +15 -10
- chia/plotters/bladebit.py +7 -7
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +4 -4
- chia/plotters/plotters.py +4 -4
- chia/plotters/plotters_util.py +3 -3
- chia/plotting/cache.py +20 -14
- chia/plotting/check_plots.py +26 -35
- chia/plotting/create_plots.py +22 -23
- chia/plotting/manager.py +21 -14
- chia/plotting/prover.py +59 -42
- chia/plotting/util.py +16 -16
- chia/pools/pool_config.py +2 -1
- chia/pools/pool_puzzles.py +11 -12
- chia/pools/pool_wallet.py +34 -57
- chia/pools/pool_wallet_info.py +39 -10
- chia/protocols/farmer_protocol.py +8 -9
- chia/protocols/fee_estimate.py +3 -4
- chia/protocols/full_node_protocol.py +3 -4
- chia/protocols/harvester_protocol.py +27 -15
- chia/protocols/outbound_message.py +3 -3
- chia/protocols/pool_protocol.py +8 -9
- chia/protocols/shared_protocol.py +1 -2
- chia/protocols/solver_protocol.py +9 -2
- chia/protocols/timelord_protocol.py +4 -7
- chia/protocols/wallet_protocol.py +11 -12
- chia/rpc/rpc_client.py +9 -9
- chia/rpc/rpc_server.py +17 -17
- chia/rpc/util.py +2 -2
- chia/seeder/crawler.py +8 -8
- chia/seeder/crawler_api.py +21 -27
- chia/seeder/crawler_rpc_api.py +2 -2
- chia/seeder/dns_server.py +21 -21
- chia/seeder/start_crawler.py +4 -4
- chia/server/address_manager.py +15 -16
- chia/server/api_protocol.py +11 -11
- chia/server/chia_policy.py +46 -26
- chia/server/introducer_peers.py +2 -3
- chia/server/node_discovery.py +19 -19
- chia/server/rate_limit_numbers.py +4 -5
- chia/server/rate_limits.py +4 -4
- chia/server/resolve_peer_info.py +4 -4
- chia/server/server.py +49 -52
- chia/server/signal_handlers.py +6 -6
- chia/server/start_service.py +17 -17
- chia/server/upnp.py +4 -6
- chia/server/ws_connection.py +52 -37
- chia/simulator/add_blocks_in_batches.py +1 -3
- chia/simulator/block_tools.py +312 -200
- chia/simulator/full_node_simulator.py +56 -35
- chia/simulator/keyring.py +2 -3
- chia/simulator/setup_services.py +15 -15
- chia/simulator/simulator_full_node_rpc_api.py +1 -2
- chia/simulator/simulator_full_node_rpc_client.py +1 -2
- chia/simulator/simulator_protocol.py +1 -2
- chia/simulator/simulator_test_tools.py +3 -3
- chia/simulator/start_simulator.py +7 -7
- chia/simulator/wallet_tools.py +10 -10
- chia/solver/solver.py +10 -10
- chia/solver/solver_api.py +10 -8
- chia/solver/solver_rpc_api.py +2 -2
- chia/solver/start_solver.py +4 -4
- chia/ssl/cacert.pem +148 -90
- chia/ssl/chia_ca.crt +14 -10
- chia/ssl/chia_ca_old.crt +19 -0
- chia/ssl/create_ssl.py +4 -4
- chia/ssl/renewedselfsignedca.conf +4 -0
- chia/ssl/ssl_check.py +1 -2
- chia/timelord/iters_from_block.py +1 -4
- chia/timelord/start_timelord.py +4 -4
- chia/timelord/timelord.py +44 -40
- chia/timelord/timelord_api.py +6 -4
- chia/timelord/timelord_launcher.py +2 -2
- chia/timelord/timelord_rpc_api.py +2 -2
- chia/timelord/timelord_state.py +11 -12
- chia/types/block_protocol.py +1 -3
- chia/types/blockchain_format/coin.py +1 -3
- chia/types/blockchain_format/program.py +11 -8
- chia/types/blockchain_format/proof_of_space.py +123 -76
- chia/types/blockchain_format/tree_hash.py +3 -3
- chia/types/blockchain_format/vdf.py +1 -2
- chia/types/coin_spend.py +3 -3
- chia/types/mempool_item.py +5 -5
- chia/types/mempool_submission_status.py +2 -3
- chia/types/peer_info.py +1 -2
- chia/types/unfinished_header_block.py +3 -4
- chia/types/validation_state.py +1 -2
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +5 -5
- chia/util/bech32m.py +1 -2
- chia/util/beta_metrics.py +2 -2
- chia/util/block_cache.py +4 -4
- chia/util/chia_logging.py +2 -2
- chia/util/chia_version.py +1 -2
- chia/util/config.py +15 -16
- chia/util/db_wrapper.py +26 -27
- chia/util/default_root.py +1 -2
- chia/util/errors.py +3 -3
- chia/util/file_keyring.py +14 -14
- chia/util/files.py +2 -3
- chia/util/hash.py +4 -4
- chia/util/initial-config.yaml +3 -5
- chia/util/inline_executor.py +2 -1
- chia/util/ip_address.py +1 -2
- chia/util/keychain.py +25 -27
- chia/util/keyring_wrapper.py +18 -19
- chia/util/lock.py +3 -4
- chia/util/log_exceptions.py +1 -2
- chia/util/lru_cache.py +2 -2
- chia/util/network.py +6 -6
- chia/util/path.py +2 -3
- chia/util/priority_mutex.py +2 -2
- chia/util/profiler.py +1 -2
- chia/util/safe_cancel_task.py +1 -2
- chia/util/streamable.py +22 -8
- chia/util/task_referencer.py +1 -1
- chia/util/timing.py +3 -3
- chia/util/virtual_project_analysis.py +6 -5
- chia/util/ws_message.py +2 -2
- chia/wallet/cat_wallet/cat_info.py +3 -4
- chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
- chia/wallet/cat_wallet/cat_utils.py +3 -4
- chia/wallet/cat_wallet/cat_wallet.py +61 -83
- chia/wallet/cat_wallet/lineage_store.py +3 -4
- chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
- chia/wallet/coin_selection.py +9 -10
- chia/wallet/conditions.py +120 -105
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
- chia/wallet/derivation_record.py +1 -2
- chia/wallet/derive_keys.py +2 -4
- chia/wallet/did_wallet/did_info.py +10 -11
- chia/wallet/did_wallet/did_wallet.py +36 -82
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
- chia/wallet/driver_protocol.py +5 -7
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
- chia/wallet/nft_wallet/nft_info.py +8 -9
- chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
- chia/wallet/nft_wallet/nft_wallet.py +79 -116
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
- chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
- chia/wallet/nft_wallet/uncurry_nft.py +10 -11
- chia/wallet/notification_manager.py +3 -3
- chia/wallet/notification_store.py +44 -61
- chia/wallet/outer_puzzles.py +6 -7
- chia/wallet/puzzle_drivers.py +34 -6
- chia/wallet/puzzles/clawback/drivers.py +6 -6
- chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
- chia/wallet/puzzles/load_clvm.py +1 -1
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
- chia/wallet/puzzles/singleton_top_layer.py +2 -3
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
- chia/wallet/puzzles/tails.py +3 -3
- chia/wallet/singleton.py +5 -7
- chia/wallet/singleton_record.py +3 -3
- chia/wallet/start_wallet.py +5 -5
- chia/wallet/trade_manager.py +37 -58
- chia/wallet/trade_record.py +4 -4
- chia/wallet/trading/offer.py +59 -46
- chia/wallet/trading/trade_store.py +8 -9
- chia/wallet/transaction_record.py +8 -8
- chia/wallet/uncurried_puzzle.py +1 -2
- chia/wallet/util/clvm_streamable.py +12 -12
- chia/wallet/util/compute_hints.py +4 -5
- chia/wallet/util/curry_and_treehash.py +1 -2
- chia/wallet/util/merkle_tree.py +2 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/wallet/util/signing.py +85 -0
- chia/wallet/util/tx_config.py +15 -6
- chia/wallet/util/wallet_sync_utils.py +14 -16
- chia/wallet/util/wallet_types.py +2 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
- chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
- chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
- chia/wallet/vc_wallet/vc_drivers.py +27 -27
- chia/wallet/vc_wallet/vc_store.py +5 -6
- chia/wallet/vc_wallet/vc_wallet.py +33 -61
- chia/wallet/wallet.py +50 -78
- chia/wallet/wallet_action_scope.py +11 -11
- chia/wallet/wallet_blockchain.py +12 -12
- chia/wallet/wallet_coin_record.py +12 -6
- chia/wallet/wallet_coin_store.py +24 -25
- chia/wallet/wallet_interested_store.py +3 -5
- chia/wallet/wallet_nft_store.py +10 -11
- chia/wallet/wallet_node.py +53 -61
- chia/wallet/wallet_node_api.py +5 -3
- chia/wallet/wallet_protocol.py +23 -23
- chia/wallet/wallet_puzzle_store.py +15 -18
- chia/wallet/wallet_request_types.py +778 -114
- chia/wallet/wallet_retry_store.py +1 -3
- chia/wallet/wallet_rpc_api.py +572 -909
- chia/wallet/wallet_rpc_client.py +87 -279
- chia/wallet/wallet_singleton_store.py +3 -4
- chia/wallet/wallet_state_manager.py +332 -106
- chia/wallet/wallet_transaction_store.py +11 -14
- chia/wallet/wallet_user_store.py +4 -6
- chia/wallet/wallet_weight_proof_handler.py +4 -4
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/METADATA +6 -5
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/RECORD +507 -516
- chia/apis.py +0 -21
- chia/consensus/check_time_locks.py +0 -57
- chia/data_layer/puzzles/__init__.py +0 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
- chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
- chia/types/coin_record.py +0 -44
- chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/entry_points.txt +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import asyncio
|
|
4
3
|
import dataclasses
|
|
5
4
|
import io
|
|
6
5
|
import json
|
|
7
6
|
import logging
|
|
8
|
-
import random
|
|
9
7
|
import re
|
|
10
|
-
from collections.abc import AsyncIterator
|
|
11
8
|
from operator import attrgetter
|
|
12
|
-
from typing import Any
|
|
9
|
+
from typing import Any
|
|
13
10
|
from unittest.mock import patch
|
|
14
11
|
|
|
15
12
|
import aiosqlite
|
|
16
13
|
import pytest
|
|
17
|
-
from chia_rs import CoinSpend, G1Element, G2Element
|
|
14
|
+
from chia_rs import CoinRecord, CoinSpend, G1Element, G2Element
|
|
18
15
|
from chia_rs.sized_bytes import bytes32
|
|
19
16
|
from chia_rs.sized_ints import uint16, uint32, uint64, uint128
|
|
20
17
|
|
|
21
18
|
from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework
|
|
22
|
-
from chia._tests.util.
|
|
23
|
-
from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_not_none
|
|
19
|
+
from chia._tests.util.time_out_assert import time_out_assert
|
|
24
20
|
from chia._tests.wallet.cat_wallet.test_cat_wallet import mint_cat
|
|
25
21
|
from chia._tests.wallet.test_wallet_coin_store import (
|
|
26
22
|
get_coin_records_amount_filter_tests,
|
|
@@ -50,29 +46,25 @@ from chia._tests.wallet.test_wallet_coin_store import (
|
|
|
50
46
|
)
|
|
51
47
|
from chia.cmds.coins import CombineCMD, SplitCMD
|
|
52
48
|
from chia.cmds.param_types import CliAmount
|
|
53
|
-
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
|
|
54
49
|
from chia.full_node.full_node_rpc_client import FullNodeRpcClient
|
|
50
|
+
from chia.pools.pool_wallet_info import NewPoolWalletInitialTargetState
|
|
55
51
|
from chia.rpc.rpc_client import ResponseFailureError
|
|
56
|
-
from chia.server.server import ChiaServer
|
|
57
52
|
from chia.simulator.full_node_simulator import FullNodeSimulator
|
|
58
|
-
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
|
|
59
53
|
from chia.types.blockchain_format.coin import Coin, coin_as_list
|
|
60
54
|
from chia.types.blockchain_format.program import Program
|
|
61
|
-
from chia.types.coin_record import CoinRecord
|
|
62
55
|
from chia.types.coin_spend import make_spend
|
|
63
|
-
from chia.types.peer_info import PeerInfo
|
|
64
56
|
from chia.types.signing_mode import SigningMode
|
|
65
57
|
from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
|
|
66
58
|
from chia.util.config import load_config, lock_and_load_config, save_config
|
|
67
59
|
from chia.util.db_wrapper import DBWrapper2
|
|
68
60
|
from chia.util.hash import std_hash
|
|
69
|
-
from chia.util.streamable import ConversionError, InvalidTypeError
|
|
70
61
|
from chia.wallet.cat_wallet.cat_constants import DEFAULT_CATS
|
|
71
62
|
from chia.wallet.cat_wallet.cat_utils import CAT_MOD, construct_cat_puzzle
|
|
72
63
|
from chia.wallet.cat_wallet.cat_wallet import CATWallet
|
|
73
64
|
from chia.wallet.cat_wallet.r_cat_wallet import RCATWallet
|
|
74
65
|
from chia.wallet.conditions import (
|
|
75
66
|
ConditionValidTimes,
|
|
67
|
+
ConditionValidTimesAbsolute,
|
|
76
68
|
CreateCoinAnnouncement,
|
|
77
69
|
CreatePuzzleAnnouncement,
|
|
78
70
|
Remark,
|
|
@@ -81,11 +73,11 @@ from chia.wallet.conditions import (
|
|
|
81
73
|
from chia.wallet.derive_keys import master_sk_to_wallet_sk, master_sk_to_wallet_sk_unhardened
|
|
82
74
|
from chia.wallet.did_wallet.did_wallet import DIDWallet
|
|
83
75
|
from chia.wallet.nft_wallet.nft_wallet import NFTWallet
|
|
84
|
-
from chia.wallet.
|
|
76
|
+
from chia.wallet.puzzle_drivers import PuzzleInfo
|
|
85
77
|
from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_hash_for_pk
|
|
86
78
|
from chia.wallet.signer_protocol import UnsignedTransaction
|
|
87
79
|
from chia.wallet.trade_record import TradeRecord
|
|
88
|
-
from chia.wallet.trading.offer import Offer
|
|
80
|
+
from chia.wallet.trading.offer import Offer, OfferSummary
|
|
89
81
|
from chia.wallet.trading.trade_status import TradeStatus
|
|
90
82
|
from chia.wallet.transaction_record import TransactionRecord
|
|
91
83
|
from chia.wallet.transaction_sorting import SortKey
|
|
@@ -96,15 +88,18 @@ from chia.wallet.util.clvm_streamable import byte_deserialize_clvm_streamable
|
|
|
96
88
|
from chia.wallet.util.compute_memos import compute_memos
|
|
97
89
|
from chia.wallet.util.query_filter import AmountFilter, HashFilter, TransactionTypeFilter
|
|
98
90
|
from chia.wallet.util.transaction_type import TransactionType
|
|
99
|
-
from chia.wallet.util.tx_config import
|
|
91
|
+
from chia.wallet.util.tx_config import TXConfig
|
|
100
92
|
from chia.wallet.util.wallet_types import CoinType, WalletType
|
|
101
93
|
from chia.wallet.wallet import Wallet
|
|
102
94
|
from chia.wallet.wallet_coin_record import WalletCoinRecord
|
|
103
95
|
from chia.wallet.wallet_coin_store import GetCoinRecords
|
|
104
|
-
from chia.wallet.wallet_node import WalletNode
|
|
96
|
+
from chia.wallet.wallet_node import WalletNode, get_wallet_db_path
|
|
105
97
|
from chia.wallet.wallet_protocol import WalletProtocol
|
|
106
98
|
from chia.wallet.wallet_request_types import (
|
|
99
|
+
Addition,
|
|
107
100
|
AddKey,
|
|
101
|
+
CancelOffer,
|
|
102
|
+
CancelOffers,
|
|
108
103
|
CATAssetIDToName,
|
|
109
104
|
CATGetAssetID,
|
|
110
105
|
CATGetName,
|
|
@@ -114,6 +109,10 @@ from chia.wallet.wallet_request_types import (
|
|
|
114
109
|
CheckOfferValidity,
|
|
115
110
|
ClawbackPuzzleDecoratorOverride,
|
|
116
111
|
CombineCoins,
|
|
112
|
+
CreateNewWallet,
|
|
113
|
+
CreateNewWalletType,
|
|
114
|
+
CreateOfferForIDs,
|
|
115
|
+
CreateSignedTransaction,
|
|
117
116
|
DefaultCAT,
|
|
118
117
|
DeleteKey,
|
|
119
118
|
DeleteNotifications,
|
|
@@ -126,11 +125,17 @@ from chia.wallet.wallet_request_types import (
|
|
|
126
125
|
DIDMessageSpend,
|
|
127
126
|
DIDSetWalletName,
|
|
128
127
|
DIDTransferDID,
|
|
128
|
+
DIDType,
|
|
129
129
|
DIDUpdateMetadata,
|
|
130
130
|
FungibleAsset,
|
|
131
|
+
GetAllOffers,
|
|
131
132
|
GetCoinRecordsByNames,
|
|
133
|
+
GetFarmedAmount,
|
|
134
|
+
GetFarmedAmountResponse,
|
|
132
135
|
GetNextAddress,
|
|
133
136
|
GetNotifications,
|
|
137
|
+
GetOffer,
|
|
138
|
+
GetOfferSummary,
|
|
134
139
|
GetPrivateKey,
|
|
135
140
|
GetSpendableCoins,
|
|
136
141
|
GetSyncStatusResponse,
|
|
@@ -153,55 +158,29 @@ from chia.wallet.wallet_request_types import (
|
|
|
153
158
|
SelectCoins,
|
|
154
159
|
SendNotification,
|
|
155
160
|
SendTransaction,
|
|
161
|
+
SendTransactionMulti,
|
|
156
162
|
SetWalletResyncOnStartup,
|
|
163
|
+
SignMessageByAddress,
|
|
157
164
|
SpendClawbackCoins,
|
|
158
165
|
SplitCoins,
|
|
166
|
+
TakeOffer,
|
|
167
|
+
VCSpend,
|
|
159
168
|
VerifySignature,
|
|
160
169
|
VerifySignatureResponse,
|
|
170
|
+
WalletCreationMode,
|
|
161
171
|
)
|
|
162
172
|
from chia.wallet.wallet_rpc_api import WalletRpcApi
|
|
163
173
|
from chia.wallet.wallet_rpc_client import WalletRpcClient
|
|
164
|
-
from chia.wallet.wallet_service import WalletService
|
|
165
174
|
from chia.wallet.wallet_spend_bundle import WalletSpendBundle
|
|
166
175
|
|
|
167
176
|
log = logging.getLogger(__name__)
|
|
168
177
|
|
|
169
178
|
|
|
170
|
-
@dataclasses.dataclass
|
|
171
|
-
class WalletBundle:
|
|
172
|
-
service: WalletService
|
|
173
|
-
node: WalletNode
|
|
174
|
-
rpc_client: WalletRpcClient
|
|
175
|
-
wallet: Wallet
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
@dataclasses.dataclass
|
|
179
|
-
class FullNodeBundle:
|
|
180
|
-
server: ChiaServer
|
|
181
|
-
api: FullNodeSimulator
|
|
182
|
-
rpc_client: FullNodeRpcClient
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
@dataclasses.dataclass
|
|
186
|
-
class WalletRpcTestEnvironment:
|
|
187
|
-
wallet_1: WalletBundle
|
|
188
|
-
wallet_2: WalletBundle
|
|
189
|
-
full_node: FullNodeBundle
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
async def check_client_synced(wallet_client: WalletRpcClient) -> bool:
|
|
193
|
-
return (await wallet_client.get_sync_status()).synced
|
|
194
|
-
|
|
195
|
-
|
|
196
179
|
async def farm_transaction_block(full_node_api: FullNodeSimulator, wallet_node: WalletNode) -> None:
|
|
197
180
|
await full_node_api.farm_blocks_to_puzzlehash(count=1)
|
|
198
181
|
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
|
|
199
182
|
|
|
200
183
|
|
|
201
|
-
def check_mempool_spend_count(full_node_api: FullNodeSimulator, num_of_spends: int) -> bool:
|
|
202
|
-
return full_node_api.full_node.mempool_manager.mempool.size() == num_of_spends
|
|
203
|
-
|
|
204
|
-
|
|
205
184
|
async def farm_transaction(
|
|
206
185
|
full_node_api: FullNodeSimulator, wallet_node: WalletNode, spend_bundle: WalletSpendBundle
|
|
207
186
|
) -> None:
|
|
@@ -211,124 +190,36 @@ async def farm_transaction(
|
|
|
211
190
|
assert full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle_name) is None
|
|
212
191
|
|
|
213
192
|
|
|
214
|
-
async def
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
# Farm a dummy block to confirm the created funds
|
|
228
|
-
await farm_transaction_block(full_node_api, wallet_bundle.node)
|
|
229
|
-
|
|
230
|
-
expected_confirmed = initial_balances.confirmed_wallet_balance + generated_funds
|
|
231
|
-
expected_unconfirmed = initial_balances.unconfirmed_wallet_balance + generated_funds
|
|
232
|
-
await time_out_assert(20, get_confirmed_balance, expected_confirmed, wallet_bundle.rpc_client, wallet_id)
|
|
233
|
-
await time_out_assert(20, get_unconfirmed_balance, expected_unconfirmed, wallet_bundle.rpc_client, wallet_id)
|
|
234
|
-
await time_out_assert(20, check_client_synced, True, wallet_bundle.rpc_client)
|
|
235
|
-
|
|
236
|
-
return generated_funds
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
@pytest.fixture(scope="function", params=[True, False])
|
|
240
|
-
async def wallet_rpc_environment(
|
|
241
|
-
two_wallet_nodes_services: SimulatorsAndWalletsServices, request: pytest.FixtureRequest, self_hostname: str
|
|
242
|
-
) -> AsyncIterator[WalletRpcTestEnvironment]:
|
|
243
|
-
full_node, wallets, bt = two_wallet_nodes_services
|
|
244
|
-
full_node_service = full_node[0]
|
|
245
|
-
full_node_api = full_node_service._api
|
|
246
|
-
full_node_server = full_node_api.full_node.server
|
|
247
|
-
wallet_service = wallets[0]
|
|
248
|
-
wallet_service_2 = wallets[1]
|
|
249
|
-
wallet_node = wallet_service._node
|
|
250
|
-
wallet_node_2 = wallet_service_2._node
|
|
251
|
-
wallet = wallet_node.wallet_state_manager.main_wallet
|
|
252
|
-
wallet_2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
253
|
-
|
|
254
|
-
config = bt.config
|
|
255
|
-
hostname = config["self_hostname"]
|
|
256
|
-
|
|
257
|
-
if request.param:
|
|
258
|
-
wallet_node.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
259
|
-
wallet_node_2.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
260
|
-
else:
|
|
261
|
-
wallet_node.config["trusted_peers"] = {}
|
|
262
|
-
wallet_node_2.config["trusted_peers"] = {}
|
|
263
|
-
|
|
264
|
-
await wallet_node.server.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
265
|
-
await wallet_node_2.server.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
266
|
-
|
|
267
|
-
assert wallet_service.rpc_server is not None
|
|
268
|
-
async with WalletRpcClient.create_as_context(
|
|
269
|
-
hostname, wallet_service.rpc_server.listen_port, wallet_service.root_path, wallet_service.config
|
|
270
|
-
) as client:
|
|
271
|
-
assert wallet_service_2.rpc_server is not None
|
|
272
|
-
async with WalletRpcClient.create_as_context(
|
|
273
|
-
hostname, wallet_service_2.rpc_server.listen_port, wallet_service_2.root_path, wallet_service_2.config
|
|
274
|
-
) as client_2:
|
|
275
|
-
assert full_node_service.rpc_server is not None
|
|
276
|
-
async with FullNodeRpcClient.create_as_context(
|
|
277
|
-
hostname,
|
|
278
|
-
full_node_service.rpc_server.listen_port,
|
|
279
|
-
full_node_service.root_path,
|
|
280
|
-
full_node_service.config,
|
|
281
|
-
) as client_node:
|
|
282
|
-
wallet_bundle_1 = WalletBundle(wallet_service, wallet_node, client, wallet)
|
|
283
|
-
wallet_bundle_2 = WalletBundle(wallet_service_2, wallet_node_2, client_2, wallet_2)
|
|
284
|
-
node_bundle = FullNodeBundle(full_node_server, full_node_api, client_node)
|
|
285
|
-
|
|
286
|
-
yield WalletRpcTestEnvironment(wallet_bundle_1, wallet_bundle_2, node_bundle)
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
async def create_tx_outputs(wallet: Wallet, output_args: list[tuple[int, Optional[list[str]]]]) -> list[dict[str, Any]]:
|
|
290
|
-
outputs = []
|
|
291
|
-
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
292
|
-
for args in output_args:
|
|
293
|
-
output = {
|
|
294
|
-
"amount": uint64(args[0]),
|
|
295
|
-
"puzzle_hash": await action_scope.get_puzzle_hash(
|
|
296
|
-
wallet.wallet_state_manager, override_reuse_puzhash_with=False
|
|
297
|
-
),
|
|
298
|
-
}
|
|
299
|
-
if args[1] is not None:
|
|
300
|
-
assert len(args[1]) > 0
|
|
301
|
-
output["memos"] = args[1]
|
|
302
|
-
outputs.append(output)
|
|
303
|
-
return outputs
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
async def assert_wallet_types(client: WalletRpcClient, expected: dict[WalletType, int]) -> None:
|
|
307
|
-
for wallet_type in WalletType:
|
|
308
|
-
wallets = (await client.get_wallets(GetWallets(uint16(wallet_type.value)))).wallets
|
|
309
|
-
wallet_count = len(wallets)
|
|
310
|
-
if wallet_type in expected:
|
|
311
|
-
assert wallet_count == expected.get(wallet_type, 0)
|
|
312
|
-
for wallet in wallets:
|
|
313
|
-
assert wallet.type == wallet_type.value
|
|
193
|
+
async def create_tx_outputs(
|
|
194
|
+
wallet: Wallet, tx_config: TXConfig, output_args: list[tuple[int, list[str] | None]]
|
|
195
|
+
) -> list[Addition]:
|
|
196
|
+
async with wallet.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
|
|
197
|
+
return [
|
|
198
|
+
Addition(
|
|
199
|
+
amount=uint64(args[0]),
|
|
200
|
+
puzzle_hash=await action_scope.get_puzzle_hash(wallet.wallet_state_manager),
|
|
201
|
+
memos=None if args[1] is None or len(args[1]) == 0 else args[1],
|
|
202
|
+
)
|
|
203
|
+
for args in output_args
|
|
204
|
+
]
|
|
314
205
|
|
|
315
206
|
|
|
316
207
|
def assert_tx_amounts(
|
|
317
208
|
tx: TransactionRecord,
|
|
318
|
-
outputs: list[
|
|
209
|
+
outputs: list[Addition],
|
|
319
210
|
*,
|
|
320
211
|
amount_fee: uint64,
|
|
321
212
|
change_expected: bool,
|
|
322
213
|
is_cat: bool = False,
|
|
323
214
|
) -> None:
|
|
324
215
|
assert tx.fee_amount == amount_fee
|
|
325
|
-
assert tx.amount == sum(output
|
|
216
|
+
assert tx.amount == sum(output.amount for output in outputs)
|
|
326
217
|
expected_additions = len(outputs) + 1 if change_expected else len(outputs)
|
|
327
218
|
assert len(tx.additions) == expected_additions
|
|
328
219
|
addition_amounts = [addition.amount for addition in tx.additions]
|
|
329
220
|
removal_amounts = [removal.amount for removal in tx.removals]
|
|
330
221
|
for output in outputs:
|
|
331
|
-
assert output
|
|
222
|
+
assert output.amount in addition_amounts
|
|
332
223
|
if is_cat:
|
|
333
224
|
assert (sum(removal_amounts) - sum(addition_amounts)) == 0
|
|
334
225
|
else:
|
|
@@ -356,7 +247,7 @@ async def assert_get_balance(rpc_client: WalletRpcClient, wallet_node: WalletNod
|
|
|
356
247
|
expected_balance_dict["fingerprint"] = wallet_node.logged_in_fingerprint
|
|
357
248
|
if wallet.type() in {WalletType.CAT, WalletType.CRCAT}:
|
|
358
249
|
assert isinstance(wallet, CATWallet)
|
|
359
|
-
expected_balance_dict["asset_id"] = "0x" + wallet.get_asset_id()
|
|
250
|
+
expected_balance_dict["asset_id"] = "0x" + wallet.get_asset_id().hex()
|
|
360
251
|
else:
|
|
361
252
|
expected_balance_dict["asset_id"] = None
|
|
362
253
|
assert (
|
|
@@ -381,24 +272,34 @@ async def get_unconfirmed_balance(client: WalletRpcClient, wallet_id: int) -> ui
|
|
|
381
272
|
).wallet_balance.unconfirmed_wallet_balance
|
|
382
273
|
|
|
383
274
|
|
|
275
|
+
@pytest.mark.parametrize(
|
|
276
|
+
"wallet_environments",
|
|
277
|
+
[
|
|
278
|
+
{
|
|
279
|
+
"num_environments": 2,
|
|
280
|
+
"blocks_needed": [1, 1],
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
indirect=True,
|
|
284
|
+
)
|
|
285
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
384
286
|
@pytest.mark.anyio
|
|
385
|
-
async def test_send_transaction(
|
|
386
|
-
env
|
|
387
|
-
|
|
388
|
-
wallet_2: Wallet =
|
|
389
|
-
wallet_node: WalletNode = env.
|
|
390
|
-
full_node_api: FullNodeSimulator =
|
|
391
|
-
client: WalletRpcClient = env.
|
|
392
|
-
|
|
393
|
-
generated_funds = await generate_funds(full_node_api, env.wallet_1)
|
|
287
|
+
async def test_send_transaction(wallet_environments: WalletTestFramework) -> None:
|
|
288
|
+
env = wallet_environments.environments[0]
|
|
289
|
+
env_2 = wallet_environments.environments[1]
|
|
290
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
291
|
+
wallet_node: WalletNode = env.node
|
|
292
|
+
full_node_api: FullNodeSimulator = wallet_environments.full_node
|
|
293
|
+
client: WalletRpcClient = env.rpc_client
|
|
394
294
|
|
|
395
|
-
|
|
295
|
+
INITIAL_FUNDS = await env.xch_wallet.get_confirmed_balance()
|
|
296
|
+
async with wallet_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
396
297
|
addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
|
|
397
298
|
tx_amount = uint64(15600000)
|
|
398
299
|
with pytest.raises(ValueError):
|
|
399
300
|
await client.send_transaction(
|
|
400
301
|
SendTransaction(wallet_id=uint32(1), amount=uint64(100000000000000001), address=addr, push=True),
|
|
401
|
-
|
|
302
|
+
wallet_environments.tx_config,
|
|
402
303
|
)
|
|
403
304
|
|
|
404
305
|
# Tests sending a basic transaction
|
|
@@ -409,7 +310,7 @@ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
409
310
|
SendTransaction(
|
|
410
311
|
wallet_id=uint32(1), amount=tx_amount, address=addr, memos=["this is a basic tx"], push=False
|
|
411
312
|
),
|
|
412
|
-
tx_config=
|
|
313
|
+
tx_config=wallet_environments.tx_config.override(
|
|
413
314
|
excluded_coin_amounts=[uint64(250000000000)],
|
|
414
315
|
excluded_coin_ids=[non_existent_coin.name()],
|
|
415
316
|
reuse_puzhash=True,
|
|
@@ -449,7 +350,7 @@ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
449
350
|
assert spend_bundle is not None
|
|
450
351
|
|
|
451
352
|
await time_out_assert(20, tx_in_mempool, True, client, transaction_id)
|
|
452
|
-
await time_out_assert(20, get_unconfirmed_balance,
|
|
353
|
+
await time_out_assert(20, get_unconfirmed_balance, INITIAL_FUNDS - tx_amount, client, 1)
|
|
453
354
|
|
|
454
355
|
await farm_transaction(full_node_api, wallet_node, spend_bundle)
|
|
455
356
|
|
|
@@ -460,38 +361,56 @@ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
460
361
|
assert [b"this is a basic tx"] in tx_confirmed.memos.values()
|
|
461
362
|
assert next(iter(tx_confirmed.memos.keys())) in [a.name() for a in spend_bundle.additions()]
|
|
462
363
|
|
|
463
|
-
await time_out_assert(20, get_confirmed_balance,
|
|
364
|
+
await time_out_assert(20, get_confirmed_balance, INITIAL_FUNDS - tx_amount, client, 1)
|
|
464
365
|
|
|
465
366
|
|
|
367
|
+
@pytest.mark.parametrize(
|
|
368
|
+
"wallet_environments",
|
|
369
|
+
[
|
|
370
|
+
{
|
|
371
|
+
"num_environments": 1,
|
|
372
|
+
"blocks_needed": [2],
|
|
373
|
+
}
|
|
374
|
+
],
|
|
375
|
+
indirect=True,
|
|
376
|
+
)
|
|
377
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
466
378
|
@pytest.mark.anyio
|
|
467
|
-
async def test_push_transactions(
|
|
468
|
-
env
|
|
469
|
-
|
|
470
|
-
wallet: Wallet = env.wallet_1.wallet
|
|
471
|
-
wallet_node: WalletNode = env.wallet_1.node
|
|
472
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
473
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
379
|
+
async def test_push_transactions(wallet_environments: WalletTestFramework) -> None:
|
|
380
|
+
env = wallet_environments.environments[0]
|
|
474
381
|
|
|
475
|
-
|
|
382
|
+
wallet: Wallet = env.xch_wallet
|
|
383
|
+
wallet_node: WalletNode = env.node
|
|
384
|
+
full_node_api: FullNodeSimulator = wallet_environments.full_node
|
|
385
|
+
client: WalletRpcClient = env.rpc_client
|
|
476
386
|
|
|
477
|
-
outputs = await create_tx_outputs(wallet, [(1234321, None)])
|
|
387
|
+
outputs = await create_tx_outputs(wallet, wallet_environments.tx_config, [(1234321, None)])
|
|
478
388
|
|
|
479
389
|
tx = (
|
|
480
390
|
await client.create_signed_transactions(
|
|
481
|
-
outputs,
|
|
482
|
-
tx_config=
|
|
483
|
-
fee=uint64(100),
|
|
391
|
+
CreateSignedTransaction(additions=outputs, fee=uint64(100)),
|
|
392
|
+
tx_config=wallet_environments.tx_config,
|
|
484
393
|
)
|
|
485
394
|
).signed_tx
|
|
486
395
|
|
|
396
|
+
with pytest.raises(ValueError, match="Cannot add conditions to a transaction if no new fee spend is being added"):
|
|
397
|
+
await client.push_transactions(
|
|
398
|
+
PushTransactions(transactions=[tx]),
|
|
399
|
+
tx_config=wallet_environments.tx_config,
|
|
400
|
+
extra_conditions=(Remark(rest=Program.to("foo")),),
|
|
401
|
+
)
|
|
402
|
+
|
|
487
403
|
resp_client = await client.push_transactions(
|
|
488
404
|
PushTransactions(transactions=[tx], fee=uint64(10)),
|
|
489
|
-
|
|
405
|
+
wallet_environments.tx_config,
|
|
490
406
|
)
|
|
407
|
+
await full_node_api.wait_for_wallet_synced(wallet_node)
|
|
491
408
|
resp = await client.fetch("push_transactions", {"transactions": [tx.to_json_dict()], "fee": 10})
|
|
492
409
|
assert resp["success"]
|
|
410
|
+
await full_node_api.wait_for_wallet_synced(wallet_node)
|
|
493
411
|
resp = await client.fetch("push_transactions", {"transactions": [bytes(tx).hex()], "fee": 10})
|
|
494
412
|
assert resp["success"]
|
|
413
|
+
await full_node_api.wait_for_wallet_synced(wallet_node)
|
|
495
414
|
|
|
496
415
|
spend_bundle = WalletSpendBundle.aggregate(
|
|
497
416
|
[tx.spend_bundle for tx in resp_client.transactions if tx.spend_bundle is not None]
|
|
@@ -508,15 +427,25 @@ async def test_push_transactions(wallet_rpc_environment: WalletRpcTestEnvironmen
|
|
|
508
427
|
assert resp["success"]
|
|
509
428
|
|
|
510
429
|
|
|
430
|
+
@pytest.mark.parametrize(
|
|
431
|
+
"wallet_environments",
|
|
432
|
+
[
|
|
433
|
+
{
|
|
434
|
+
"num_environments": 1,
|
|
435
|
+
"blocks_needed": [1],
|
|
436
|
+
}
|
|
437
|
+
],
|
|
438
|
+
indirect=True,
|
|
439
|
+
)
|
|
440
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
511
441
|
@pytest.mark.anyio
|
|
512
|
-
async def test_get_balance(
|
|
513
|
-
env =
|
|
514
|
-
wallet: Wallet = env.
|
|
515
|
-
wallet_node: WalletNode = env.
|
|
516
|
-
full_node_api: FullNodeSimulator =
|
|
517
|
-
wallet_rpc_client = env.
|
|
518
|
-
|
|
519
|
-
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
442
|
+
async def test_get_balance(wallet_environments: WalletTestFramework) -> None:
|
|
443
|
+
env = wallet_environments.environments[0]
|
|
444
|
+
wallet: Wallet = env.xch_wallet
|
|
445
|
+
wallet_node: WalletNode = env.node
|
|
446
|
+
full_node_api: FullNodeSimulator = wallet_environments.full_node
|
|
447
|
+
wallet_rpc_client = env.rpc_client
|
|
448
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
520
449
|
cat_wallet = await CATWallet.create_new_cat_wallet(
|
|
521
450
|
wallet_node.wallet_state_manager,
|
|
522
451
|
wallet,
|
|
@@ -530,44 +459,50 @@ async def test_get_balance(wallet_rpc_environment: WalletRpcTestEnvironment) ->
|
|
|
530
459
|
await assert_get_balance(wallet_rpc_client, wallet_node, cat_wallet)
|
|
531
460
|
|
|
532
461
|
|
|
462
|
+
@pytest.mark.parametrize(
|
|
463
|
+
"wallet_environments",
|
|
464
|
+
[{"num_environments": 1, "blocks_needed": [2], "reuse_puzhash": True, "trusted": True}],
|
|
465
|
+
indirect=True,
|
|
466
|
+
)
|
|
467
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
533
468
|
@pytest.mark.anyio
|
|
534
|
-
async def test_get_farmed_amount(
|
|
535
|
-
env =
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
await full_node_api.farm_blocks_to_wallet(2, wallet)
|
|
540
|
-
|
|
541
|
-
get_farmed_amount_result = await wallet_rpc_client.get_farmed_amount()
|
|
469
|
+
async def test_get_farmed_amount(wallet_environments: WalletTestFramework) -> None:
|
|
470
|
+
env = wallet_environments.environments[0]
|
|
471
|
+
wallet_rpc_client = env.rpc_client
|
|
472
|
+
|
|
473
|
+
get_farmed_amount_result = await wallet_rpc_client.get_farmed_amount(GetFarmedAmount())
|
|
542
474
|
get_timestamp_for_height_result = await wallet_rpc_client.get_timestamp_for_height(
|
|
543
475
|
GetTimestampForHeight(uint32(3))
|
|
544
476
|
) # genesis + 2
|
|
545
477
|
|
|
546
|
-
expected_result =
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
478
|
+
expected_result = GetFarmedAmountResponse(
|
|
479
|
+
blocks_won=uint32(2),
|
|
480
|
+
farmed_amount=uint64(4_000_000_000_000),
|
|
481
|
+
farmer_reward_amount=uint64(500_000_000_000),
|
|
482
|
+
fee_amount=uint64(0),
|
|
483
|
+
last_height_farmed=uint32(3),
|
|
484
|
+
last_time_farmed=uint64(get_timestamp_for_height_result.timestamp),
|
|
485
|
+
pool_reward_amount=uint64(3_500_000_000_000),
|
|
486
|
+
)
|
|
556
487
|
assert get_farmed_amount_result == expected_result
|
|
557
488
|
|
|
558
489
|
|
|
490
|
+
@pytest.mark.parametrize(
|
|
491
|
+
"wallet_environments",
|
|
492
|
+
[{"num_environments": 1, "blocks_needed": [2], "reuse_puzhash": True, "trusted": True}],
|
|
493
|
+
indirect=True,
|
|
494
|
+
)
|
|
495
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
559
496
|
@pytest.mark.anyio
|
|
560
|
-
async def test_get_farmed_amount_with_fee(
|
|
561
|
-
env =
|
|
562
|
-
wallet: Wallet = env.
|
|
563
|
-
full_node_api: FullNodeSimulator =
|
|
564
|
-
wallet_rpc_client = env.
|
|
565
|
-
wallet_node: WalletNode = env.
|
|
566
|
-
|
|
567
|
-
await generate_funds(full_node_api, env.wallet_1)
|
|
497
|
+
async def test_get_farmed_amount_with_fee(wallet_environments: WalletTestFramework) -> None:
|
|
498
|
+
env = wallet_environments.environments[0]
|
|
499
|
+
wallet: Wallet = env.xch_wallet
|
|
500
|
+
full_node_api: FullNodeSimulator = wallet_environments.full_node
|
|
501
|
+
wallet_rpc_client = env.rpc_client
|
|
502
|
+
wallet_node: WalletNode = env.node
|
|
568
503
|
|
|
569
504
|
fee_amount = 100
|
|
570
|
-
async with wallet.wallet_state_manager.new_action_scope(
|
|
505
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
571
506
|
await wallet.generate_signed_transaction(
|
|
572
507
|
amounts=[uint64(5)],
|
|
573
508
|
puzzle_hashes=[bytes32.zeros],
|
|
@@ -580,18 +515,20 @@ async def test_get_farmed_amount_with_fee(wallet_rpc_environment: WalletRpcTestE
|
|
|
580
515
|
await full_node_api.farm_blocks_to_puzzlehash(count=2, farm_to=our_ph, guarantee_transaction_blocks=True)
|
|
581
516
|
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
|
|
582
517
|
|
|
583
|
-
result = await wallet_rpc_client.get_farmed_amount()
|
|
584
|
-
assert result
|
|
518
|
+
result = await wallet_rpc_client.get_farmed_amount(GetFarmedAmount())
|
|
519
|
+
assert result.fee_amount == fee_amount
|
|
585
520
|
|
|
586
521
|
|
|
522
|
+
@pytest.mark.parametrize(
|
|
523
|
+
"wallet_environments",
|
|
524
|
+
[{"num_environments": 1, "blocks_needed": [1], "reuse_puzhash": True, "trusted": True}],
|
|
525
|
+
indirect=True,
|
|
526
|
+
)
|
|
527
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
587
528
|
@pytest.mark.anyio
|
|
588
|
-
async def test_get_timestamp_for_height(
|
|
589
|
-
env
|
|
590
|
-
|
|
591
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
592
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
593
|
-
|
|
594
|
-
await generate_funds(full_node_api, env.wallet_1)
|
|
529
|
+
async def test_get_timestamp_for_height(wallet_environments: WalletTestFramework) -> None:
|
|
530
|
+
env = wallet_environments.environments[0]
|
|
531
|
+
client: WalletRpcClient = env.rpc_client
|
|
595
532
|
|
|
596
533
|
# This tests that the client returns successfully, rather than raising or returning something unexpected
|
|
597
534
|
await client.get_timestamp_for_height(GetTimestampForHeight(uint32(1)))
|
|
@@ -613,44 +550,74 @@ async def test_get_timestamp_for_height(wallet_rpc_environment: WalletRpcTestEnv
|
|
|
613
550
|
([(120000000000, None), (120000000000, None)], 10000000000, True, False),
|
|
614
551
|
],
|
|
615
552
|
)
|
|
553
|
+
@pytest.mark.parametrize(
|
|
554
|
+
"wallet_environments",
|
|
555
|
+
[{"num_environments": 2, "blocks_needed": [2, 1], "config_overrides": {"automatically_add_unknown_cats": True}}],
|
|
556
|
+
indirect=True,
|
|
557
|
+
)
|
|
558
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
616
559
|
@pytest.mark.anyio
|
|
617
560
|
async def test_create_signed_transaction(
|
|
618
|
-
|
|
619
|
-
output_args: list[tuple[int,
|
|
561
|
+
wallet_environments: WalletTestFramework,
|
|
562
|
+
output_args: list[tuple[int, list[str] | None]],
|
|
620
563
|
fee: int,
|
|
621
564
|
select_coin: bool,
|
|
622
565
|
is_cat: bool,
|
|
623
566
|
) -> None:
|
|
624
|
-
|
|
567
|
+
if (
|
|
568
|
+
len(set(amount for amount, _ in output_args)) != len(output_args)
|
|
569
|
+
and wallet_environments.tx_config.reuse_puzhash
|
|
570
|
+
):
|
|
571
|
+
pytest.skip("Skipping reuse_puzhash + identical amounts for simplicity sake")
|
|
572
|
+
env = wallet_environments.environments[0]
|
|
573
|
+
env_2 = wallet_environments.environments[1]
|
|
574
|
+
|
|
575
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
576
|
+
wallet_1_rpc: WalletRpcClient = env.rpc_client
|
|
577
|
+
full_node_rpc: FullNodeRpcClient = wallet_environments.full_node_rpc_client
|
|
625
578
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
wallet_1_rpc: WalletRpcClient = env.wallet_1.rpc_client
|
|
629
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
630
|
-
full_node_rpc: FullNodeRpcClient = env.full_node.rpc_client
|
|
579
|
+
env.wallet_aliases = {"xch": 1, "cat": 2}
|
|
580
|
+
env_2.wallet_aliases = {"xch": 1, "cat": 2}
|
|
631
581
|
|
|
632
|
-
|
|
582
|
+
outputs = await create_tx_outputs(wallet_2, wallet_environments.tx_config, output_args)
|
|
583
|
+
amount_outputs = sum(output.amount for output in outputs)
|
|
584
|
+
amount_fee = uint64(fee)
|
|
633
585
|
|
|
634
586
|
wallet_id = 1
|
|
635
587
|
if is_cat:
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
588
|
+
create_cat_res = await wallet_1_rpc.create_new_wallet(
|
|
589
|
+
CreateNewWallet(
|
|
590
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
591
|
+
mode=WalletCreationMode.NEW,
|
|
592
|
+
amount=uint64(amount_outputs + 1),
|
|
593
|
+
test=True,
|
|
594
|
+
push=True,
|
|
595
|
+
),
|
|
596
|
+
tx_config=wallet_environments.tx_config,
|
|
597
|
+
)
|
|
598
|
+
wallet_id = create_cat_res.wallet_id
|
|
647
599
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
600
|
+
await wallet_environments.process_pending_states(
|
|
601
|
+
[
|
|
602
|
+
WalletStateTransition(
|
|
603
|
+
pre_block_balance_updates={
|
|
604
|
+
"xch": {"set_remainder": True},
|
|
605
|
+
"cat": {"init": True, "set_remainder": True},
|
|
606
|
+
},
|
|
607
|
+
post_block_balance_updates={
|
|
608
|
+
"xch": {"set_remainder": True},
|
|
609
|
+
"cat": {"set_remainder": True},
|
|
610
|
+
},
|
|
611
|
+
),
|
|
612
|
+
WalletStateTransition(
|
|
613
|
+
pre_block_balance_updates={},
|
|
614
|
+
post_block_balance_updates={},
|
|
615
|
+
),
|
|
616
|
+
]
|
|
617
|
+
)
|
|
651
618
|
|
|
652
619
|
if is_cat:
|
|
653
|
-
amount_total = amount_outputs
|
|
620
|
+
amount_total: int = amount_outputs
|
|
654
621
|
else:
|
|
655
622
|
amount_total = amount_outputs + amount_fee
|
|
656
623
|
|
|
@@ -658,7 +625,9 @@ async def test_create_signed_transaction(
|
|
|
658
625
|
if select_coin:
|
|
659
626
|
select_coins_response = await wallet_1_rpc.select_coins(
|
|
660
627
|
SelectCoins.from_coin_selection_config(
|
|
661
|
-
amount=amount_total
|
|
628
|
+
amount=uint64(amount_total),
|
|
629
|
+
wallet_id=uint32(wallet_id),
|
|
630
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config,
|
|
662
631
|
)
|
|
663
632
|
)
|
|
664
633
|
assert len(select_coins_response.coins) == 1
|
|
@@ -666,15 +635,17 @@ async def test_create_signed_transaction(
|
|
|
666
635
|
|
|
667
636
|
txs = (
|
|
668
637
|
await wallet_1_rpc.create_signed_transactions(
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
638
|
+
CreateSignedTransaction(
|
|
639
|
+
additions=outputs,
|
|
640
|
+
coins=[selected_coin] if selected_coin is not None else None,
|
|
641
|
+
fee=amount_fee,
|
|
642
|
+
wallet_id=uint32(wallet_id),
|
|
643
|
+
push=True,
|
|
644
|
+
),
|
|
673
645
|
# shouldn't actually block it
|
|
674
|
-
tx_config=
|
|
646
|
+
tx_config=wallet_environments.tx_config.override(
|
|
675
647
|
excluded_coin_amounts=[uint64(selected_coin.amount)] if selected_coin is not None else [],
|
|
676
648
|
),
|
|
677
|
-
push=True,
|
|
678
649
|
)
|
|
679
650
|
).transactions
|
|
680
651
|
change_expected = not selected_coin or selected_coin.amount - amount_total > 0
|
|
@@ -683,8 +654,72 @@ async def test_create_signed_transaction(
|
|
|
683
654
|
# Farm the transaction and make sure the wallet balance reflects it correct
|
|
684
655
|
spend_bundle = txs[0].spend_bundle
|
|
685
656
|
assert spend_bundle is not None
|
|
686
|
-
|
|
687
|
-
|
|
657
|
+
xch_delta = amount_total if not is_cat else amount_fee
|
|
658
|
+
cat_delta = amount_total if is_cat else 0
|
|
659
|
+
await wallet_environments.process_pending_states(
|
|
660
|
+
[
|
|
661
|
+
WalletStateTransition(
|
|
662
|
+
pre_block_balance_updates={ # type: ignore[arg-type]
|
|
663
|
+
"xch": {
|
|
664
|
+
"unconfirmed_wallet_balance": -xch_delta,
|
|
665
|
+
"<=#spendable_balance": -xch_delta,
|
|
666
|
+
"<=#max_send_amount": -xch_delta,
|
|
667
|
+
">=#pending_change": 0,
|
|
668
|
+
"pending_coin_removal_count": 1,
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
| (
|
|
672
|
+
{
|
|
673
|
+
"cat": {
|
|
674
|
+
"unconfirmed_wallet_balance": -cat_delta,
|
|
675
|
+
"<=#spendable_balance": -cat_delta,
|
|
676
|
+
"<=#max_send_amount": -cat_delta,
|
|
677
|
+
">=#pending_change": 1 if is_cat else 0,
|
|
678
|
+
"pending_coin_removal_count": 1 if is_cat else 0,
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if is_cat
|
|
682
|
+
else {}
|
|
683
|
+
),
|
|
684
|
+
post_block_balance_updates={ # type: ignore[arg-type]
|
|
685
|
+
"xch": {
|
|
686
|
+
"confirmed_wallet_balance": -xch_delta,
|
|
687
|
+
">=#spendable_balance": 0,
|
|
688
|
+
">=#max_send_amount": 0,
|
|
689
|
+
"<=#pending_change": 0,
|
|
690
|
+
"pending_coin_removal_count": -1,
|
|
691
|
+
"<=#unspent_coin_count": 0,
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
| (
|
|
695
|
+
{
|
|
696
|
+
"cat": {
|
|
697
|
+
"confirmed_wallet_balance": -cat_delta,
|
|
698
|
+
">=#spendable_balance": 1 if is_cat else 0,
|
|
699
|
+
">=#max_send_amount": 1 if is_cat else 0,
|
|
700
|
+
"<=#pending_change": -1 if is_cat else 0,
|
|
701
|
+
"pending_coin_removal_count": -1 if is_cat else 0,
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
if is_cat
|
|
705
|
+
else {}
|
|
706
|
+
),
|
|
707
|
+
),
|
|
708
|
+
WalletStateTransition(
|
|
709
|
+
pre_block_balance_updates={},
|
|
710
|
+
post_block_balance_updates={
|
|
711
|
+
"cat" if is_cat else "xch": {
|
|
712
|
+
"init": is_cat,
|
|
713
|
+
"confirmed_wallet_balance": amount_outputs,
|
|
714
|
+
"unconfirmed_wallet_balance": amount_outputs,
|
|
715
|
+
"spendable_balance": amount_outputs,
|
|
716
|
+
"max_send_amount": amount_outputs,
|
|
717
|
+
"unspent_coin_count": len(outputs),
|
|
718
|
+
}
|
|
719
|
+
},
|
|
720
|
+
),
|
|
721
|
+
]
|
|
722
|
+
)
|
|
688
723
|
|
|
689
724
|
# Assert every coin comes from the same parent
|
|
690
725
|
additions: list[Coin] = spend_bundle.additions()
|
|
@@ -692,9 +727,9 @@ async def test_create_signed_transaction(
|
|
|
692
727
|
|
|
693
728
|
# Assert you can get the spend for each addition
|
|
694
729
|
for addition in additions:
|
|
695
|
-
cr:
|
|
730
|
+
cr: CoinRecord | None = await full_node_rpc.get_coin_record_by_name(addition.name())
|
|
696
731
|
assert cr is not None
|
|
697
|
-
spend:
|
|
732
|
+
spend: CoinSpend | None = await full_node_rpc.get_puzzle_and_solution(
|
|
698
733
|
addition.parent_coin_info, cr.confirmed_block_index
|
|
699
734
|
)
|
|
700
735
|
assert spend is not None
|
|
@@ -703,35 +738,37 @@ async def test_create_signed_transaction(
|
|
|
703
738
|
addition_dict: dict[bytes32, Coin] = {addition.name(): addition for addition in additions}
|
|
704
739
|
memo_dictionary: dict[bytes32, list[bytes]] = compute_memos(spend_bundle)
|
|
705
740
|
for output in outputs:
|
|
706
|
-
if
|
|
741
|
+
if output.memos is not None:
|
|
707
742
|
found: bool = False
|
|
708
743
|
for addition_id, addition in addition_dict.items():
|
|
709
744
|
if (
|
|
710
745
|
is_cat
|
|
711
|
-
and addition.amount == output
|
|
712
|
-
and memo_dictionary[addition_id][0] == output
|
|
713
|
-
and memo_dictionary[addition_id][1:] == [memo.encode() for memo in output
|
|
746
|
+
and addition.amount == output.amount
|
|
747
|
+
and memo_dictionary[addition_id][0] == output.puzzle_hash
|
|
748
|
+
and memo_dictionary[addition_id][1:] == [memo.encode() for memo in output.memos]
|
|
714
749
|
) or (
|
|
715
|
-
addition.amount == output
|
|
716
|
-
and addition.puzzle_hash == output
|
|
717
|
-
and memo_dictionary[addition_id] == [memo.encode() for memo in output
|
|
750
|
+
addition.amount == output.amount
|
|
751
|
+
and addition.puzzle_hash == output.puzzle_hash
|
|
752
|
+
and memo_dictionary[addition_id] == [memo.encode() for memo in output.memos]
|
|
718
753
|
):
|
|
719
754
|
found = True
|
|
720
755
|
assert found
|
|
721
756
|
|
|
722
757
|
|
|
758
|
+
@pytest.mark.parametrize(
|
|
759
|
+
"wallet_environments",
|
|
760
|
+
[{"num_environments": 2, "blocks_needed": [1, 1]}],
|
|
761
|
+
indirect=True,
|
|
762
|
+
)
|
|
763
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
723
764
|
@pytest.mark.anyio
|
|
724
|
-
async def test_create_signed_transaction_with_coin_announcement(
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
env: WalletRpcTestEnvironment = wallet_rpc_environment
|
|
728
|
-
|
|
729
|
-
wallet_2: Wallet = env.wallet_2.wallet
|
|
730
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
731
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
732
|
-
client_node: FullNodeRpcClient = env.full_node.rpc_client
|
|
765
|
+
async def test_create_signed_transaction_with_coin_announcement(wallet_environments: WalletTestFramework) -> None:
|
|
766
|
+
env = wallet_environments.environments[0]
|
|
767
|
+
env_2 = wallet_environments.environments[1]
|
|
733
768
|
|
|
734
|
-
|
|
769
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
770
|
+
client: WalletRpcClient = env.rpc_client
|
|
771
|
+
client_node: FullNodeRpcClient = wallet_environments.full_node_rpc_client
|
|
735
772
|
|
|
736
773
|
signed_tx_amount = uint64(888000)
|
|
737
774
|
tx_coin_announcements = [
|
|
@@ -744,28 +781,32 @@ async def test_create_signed_transaction_with_coin_announcement(
|
|
|
744
781
|
std_hash(b"coin_id_2"),
|
|
745
782
|
),
|
|
746
783
|
]
|
|
747
|
-
outputs = await create_tx_outputs(wallet_2, [(signed_tx_amount, None)])
|
|
784
|
+
outputs = await create_tx_outputs(wallet_2, wallet_environments.tx_config, [(signed_tx_amount, None)])
|
|
748
785
|
tx_res: TransactionRecord = (
|
|
749
786
|
await client.create_signed_transactions(
|
|
750
|
-
outputs,
|
|
787
|
+
CreateSignedTransaction(additions=outputs),
|
|
788
|
+
tx_config=wallet_environments.tx_config,
|
|
789
|
+
extra_conditions=(*tx_coin_announcements,),
|
|
751
790
|
)
|
|
752
791
|
).signed_tx
|
|
753
792
|
assert_tx_amounts(tx_res, outputs, amount_fee=uint64(0), change_expected=True)
|
|
754
793
|
await assert_push_tx_error(client_node, tx_res)
|
|
755
794
|
|
|
756
795
|
|
|
796
|
+
@pytest.mark.parametrize(
|
|
797
|
+
"wallet_environments",
|
|
798
|
+
[{"num_environments": 2, "blocks_needed": [1, 1]}],
|
|
799
|
+
indirect=True,
|
|
800
|
+
)
|
|
801
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
757
802
|
@pytest.mark.anyio
|
|
758
|
-
async def test_create_signed_transaction_with_puzzle_announcement(
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
env: WalletRpcTestEnvironment = wallet_rpc_environment
|
|
762
|
-
|
|
763
|
-
wallet_2: Wallet = env.wallet_2.wallet
|
|
764
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
765
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
766
|
-
client_node: FullNodeRpcClient = env.full_node.rpc_client
|
|
803
|
+
async def test_create_signed_transaction_with_puzzle_announcement(wallet_environments: WalletTestFramework) -> None:
|
|
804
|
+
env = wallet_environments.environments[0]
|
|
805
|
+
env_2 = wallet_environments.environments[1]
|
|
767
806
|
|
|
768
|
-
|
|
807
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
808
|
+
client: WalletRpcClient = env.rpc_client
|
|
809
|
+
client_node: FullNodeRpcClient = wallet_environments.full_node_rpc_client
|
|
769
810
|
|
|
770
811
|
signed_tx_amount = uint64(888000)
|
|
771
812
|
tx_puzzle_announcements = [
|
|
@@ -778,38 +819,46 @@ async def test_create_signed_transaction_with_puzzle_announcement(
|
|
|
778
819
|
std_hash(b"puzzle_hash_2"),
|
|
779
820
|
),
|
|
780
821
|
]
|
|
781
|
-
outputs = await create_tx_outputs(wallet_2, [(signed_tx_amount, None)])
|
|
822
|
+
outputs = await create_tx_outputs(wallet_2, wallet_environments.tx_config, [(signed_tx_amount, None)])
|
|
782
823
|
tx_res = (
|
|
783
824
|
await client.create_signed_transactions(
|
|
784
|
-
outputs,
|
|
825
|
+
CreateSignedTransaction(additions=outputs),
|
|
826
|
+
tx_config=wallet_environments.tx_config,
|
|
827
|
+
extra_conditions=(*tx_puzzle_announcements,),
|
|
785
828
|
)
|
|
786
829
|
).signed_tx
|
|
787
830
|
assert_tx_amounts(tx_res, outputs, amount_fee=uint64(0), change_expected=True)
|
|
788
831
|
await assert_push_tx_error(client_node, tx_res)
|
|
789
832
|
|
|
790
833
|
|
|
834
|
+
@pytest.mark.parametrize(
|
|
835
|
+
"wallet_environments",
|
|
836
|
+
[{"num_environments": 1, "blocks_needed": [1]}],
|
|
837
|
+
indirect=True,
|
|
838
|
+
)
|
|
839
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
791
840
|
@pytest.mark.anyio
|
|
792
|
-
async def test_create_signed_transaction_with_excluded_coins(
|
|
793
|
-
env
|
|
794
|
-
wallet_1: Wallet = env.
|
|
795
|
-
wallet_1_rpc: WalletRpcClient = env.
|
|
796
|
-
|
|
797
|
-
full_node_rpc: FullNodeRpcClient = env.full_node.rpc_client
|
|
798
|
-
await generate_funds(full_node_api, env.wallet_1)
|
|
841
|
+
async def test_create_signed_transaction_with_excluded_coins(wallet_environments: WalletTestFramework) -> None:
|
|
842
|
+
env = wallet_environments.environments[0]
|
|
843
|
+
wallet_1: Wallet = env.xch_wallet
|
|
844
|
+
wallet_1_rpc: WalletRpcClient = env.rpc_client
|
|
845
|
+
full_node_rpc: FullNodeRpcClient = wallet_environments.full_node_rpc_client
|
|
799
846
|
|
|
800
847
|
async def it_does_not_include_the_excluded_coins() -> None:
|
|
801
848
|
select_coins_response = await wallet_1_rpc.select_coins(
|
|
802
849
|
SelectCoins.from_coin_selection_config(
|
|
803
|
-
amount=uint64(250000000000),
|
|
850
|
+
amount=uint64(250000000000),
|
|
851
|
+
wallet_id=uint32(1),
|
|
852
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config,
|
|
804
853
|
)
|
|
805
854
|
)
|
|
806
855
|
assert len(select_coins_response.coins) == 1
|
|
807
|
-
outputs = await create_tx_outputs(wallet_1, [(uint64(250000000000), None)])
|
|
856
|
+
outputs = await create_tx_outputs(wallet_1, wallet_environments.tx_config, [(uint64(250000000000), None)])
|
|
808
857
|
|
|
809
858
|
tx = (
|
|
810
859
|
await wallet_1_rpc.create_signed_transactions(
|
|
811
|
-
outputs,
|
|
812
|
-
|
|
860
|
+
CreateSignedTransaction(additions=outputs),
|
|
861
|
+
wallet_environments.tx_config.override(
|
|
813
862
|
excluded_coin_ids=[c.name() for c in select_coins_response.coins],
|
|
814
863
|
),
|
|
815
864
|
)
|
|
@@ -823,16 +872,18 @@ async def test_create_signed_transaction_with_excluded_coins(wallet_rpc_environm
|
|
|
823
872
|
async def it_throws_an_error_when_all_spendable_coins_are_excluded() -> None:
|
|
824
873
|
select_coins_response = await wallet_1_rpc.select_coins(
|
|
825
874
|
SelectCoins.from_coin_selection_config(
|
|
826
|
-
amount=uint64(1750000000000),
|
|
875
|
+
amount=uint64(1750000000000),
|
|
876
|
+
wallet_id=uint32(1),
|
|
877
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config,
|
|
827
878
|
)
|
|
828
879
|
)
|
|
829
880
|
assert len(select_coins_response.coins) == 1
|
|
830
|
-
outputs = await create_tx_outputs(wallet_1, [(uint64(1750000000000), None)])
|
|
881
|
+
outputs = await create_tx_outputs(wallet_1, wallet_environments.tx_config, [(uint64(1750000000000), None)])
|
|
831
882
|
|
|
832
883
|
with pytest.raises(ValueError):
|
|
833
884
|
await wallet_1_rpc.create_signed_transactions(
|
|
834
|
-
outputs,
|
|
835
|
-
|
|
885
|
+
CreateSignedTransaction(additions=outputs),
|
|
886
|
+
wallet_environments.tx_config.override(
|
|
836
887
|
excluded_coin_ids=[c.name() for c in select_coins_response.coins],
|
|
837
888
|
),
|
|
838
889
|
)
|
|
@@ -841,159 +892,47 @@ async def test_create_signed_transaction_with_excluded_coins(wallet_rpc_environm
|
|
|
841
892
|
await it_throws_an_error_when_all_spendable_coins_are_excluded()
|
|
842
893
|
|
|
843
894
|
|
|
895
|
+
@pytest.mark.parametrize(
|
|
896
|
+
"wallet_environments",
|
|
897
|
+
[{"num_environments": 2, "blocks_needed": [1, 1]}],
|
|
898
|
+
indirect=True,
|
|
899
|
+
)
|
|
900
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
844
901
|
@pytest.mark.anyio
|
|
845
|
-
async def
|
|
846
|
-
env
|
|
847
|
-
|
|
848
|
-
wallet_1_node: WalletNode = env.wallet_1.node
|
|
849
|
-
wallet_2_node: WalletNode = env.wallet_2.node
|
|
850
|
-
wallet_1_rpc: WalletRpcClient = env.wallet_1.rpc_client
|
|
851
|
-
wallet_2_rpc: WalletRpcClient = env.wallet_2.rpc_client
|
|
852
|
-
wallet_1 = wallet_1_node.wallet_state_manager.main_wallet
|
|
853
|
-
wallet_2 = wallet_2_node.wallet_state_manager.main_wallet
|
|
854
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
855
|
-
|
|
856
|
-
generated_funds = await generate_funds(full_node_api, env.wallet_1, 1)
|
|
857
|
-
await generate_funds(full_node_api, env.wallet_2, 1)
|
|
858
|
-
async with wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
859
|
-
wallet_1_puzhash = await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager)
|
|
860
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_1_node, timeout=20)
|
|
861
|
-
async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
862
|
-
wallet_2_puzhash = await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)
|
|
863
|
-
tx = (
|
|
864
|
-
await wallet_1_rpc.send_transaction(
|
|
865
|
-
SendTransaction(
|
|
866
|
-
wallet_id=uint32(1),
|
|
867
|
-
amount=uint64(500),
|
|
868
|
-
address=encode_puzzle_hash(wallet_2_puzhash, "txch"),
|
|
869
|
-
puzzle_decorator=[ClawbackPuzzleDecoratorOverride(decorator="CLAWBACK", clawback_timelock=uint64(5))],
|
|
870
|
-
push=True,
|
|
871
|
-
),
|
|
872
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
873
|
-
)
|
|
874
|
-
).transaction
|
|
875
|
-
clawback_coin_id_1 = tx.additions[0].name()
|
|
876
|
-
assert tx.spend_bundle is not None
|
|
877
|
-
await farm_transaction(full_node_api, wallet_1_node, tx.spend_bundle)
|
|
878
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_2_node, timeout=20)
|
|
879
|
-
tx = (
|
|
880
|
-
await wallet_2_rpc.send_transaction(
|
|
881
|
-
SendTransaction(
|
|
882
|
-
wallet_id=uint32(1),
|
|
883
|
-
amount=uint64(500),
|
|
884
|
-
address=encode_puzzle_hash(wallet_1_puzhash, "txch"),
|
|
885
|
-
puzzle_decorator=[ClawbackPuzzleDecoratorOverride(decorator="CLAWBACK", clawback_timelock=uint64(5))],
|
|
886
|
-
push=True,
|
|
887
|
-
),
|
|
888
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
889
|
-
)
|
|
890
|
-
).transaction
|
|
891
|
-
assert tx.spend_bundle is not None
|
|
892
|
-
clawback_coin_id_2 = tx.additions[0].name()
|
|
893
|
-
await farm_transaction(full_node_api, wallet_2_node, tx.spend_bundle)
|
|
894
|
-
await time_out_assert(20, get_confirmed_balance, generated_funds - 500, wallet_1_rpc, 1)
|
|
895
|
-
await time_out_assert(20, get_confirmed_balance, generated_funds - 500, wallet_2_rpc, 1)
|
|
896
|
-
await asyncio.sleep(10)
|
|
897
|
-
# Test coin ID is not a Clawback coin
|
|
898
|
-
invalid_coin_id = tx.removals[0].name()
|
|
899
|
-
resp = await wallet_2_rpc.spend_clawback_coins(
|
|
900
|
-
SpendClawbackCoins(coin_ids=[invalid_coin_id], fee=uint64(500), push=True), tx_config=DEFAULT_TX_CONFIG
|
|
901
|
-
)
|
|
902
|
-
assert resp.transaction_ids == []
|
|
903
|
-
# Test unsupported wallet
|
|
904
|
-
coin_record = await wallet_1_node.wallet_state_manager.coin_store.get_coin_record(clawback_coin_id_1)
|
|
905
|
-
assert coin_record is not None
|
|
906
|
-
await wallet_1_node.wallet_state_manager.coin_store.add_coin_record(
|
|
907
|
-
dataclasses.replace(coin_record, wallet_type=WalletType.CAT)
|
|
908
|
-
)
|
|
909
|
-
resp = await wallet_1_rpc.spend_clawback_coins(
|
|
910
|
-
SpendClawbackCoins(coin_ids=[clawback_coin_id_1], fee=uint64(100), push=True), tx_config=DEFAULT_TX_CONFIG
|
|
911
|
-
)
|
|
912
|
-
assert len(resp.transaction_ids) == 0
|
|
913
|
-
# Test missing metadata
|
|
914
|
-
await wallet_1_node.wallet_state_manager.coin_store.add_coin_record(dataclasses.replace(coin_record, metadata=None))
|
|
915
|
-
resp = await wallet_1_rpc.spend_clawback_coins(
|
|
916
|
-
SpendClawbackCoins(coin_ids=[clawback_coin_id_1], fee=uint64(100), push=True), tx_config=DEFAULT_TX_CONFIG
|
|
917
|
-
)
|
|
918
|
-
assert len(resp.transaction_ids) == 0
|
|
919
|
-
# Test missing incoming tx
|
|
920
|
-
coin_record = await wallet_1_node.wallet_state_manager.coin_store.get_coin_record(clawback_coin_id_2)
|
|
921
|
-
assert coin_record is not None
|
|
922
|
-
fake_coin = Coin(coin_record.coin.parent_coin_info, wallet_2_puzhash, coin_record.coin.amount)
|
|
923
|
-
await wallet_1_node.wallet_state_manager.coin_store.add_coin_record(
|
|
924
|
-
dataclasses.replace(coin_record, coin=fake_coin)
|
|
925
|
-
)
|
|
926
|
-
resp = await wallet_1_rpc.spend_clawback_coins(
|
|
927
|
-
SpendClawbackCoins(coin_ids=[fake_coin.name()], fee=uint64(100), push=True), tx_config=DEFAULT_TX_CONFIG
|
|
928
|
-
)
|
|
929
|
-
assert resp.transaction_ids == []
|
|
930
|
-
# Test coin puzzle hash doesn't match the puzzle
|
|
931
|
-
farmed_tx = (await wallet_1.wallet_state_manager.tx_store.get_farming_rewards())[0]
|
|
932
|
-
await wallet_1.wallet_state_manager.tx_store.add_transaction_record(
|
|
933
|
-
dataclasses.replace(farmed_tx, name=fake_coin.name())
|
|
934
|
-
)
|
|
935
|
-
await wallet_1_node.wallet_state_manager.coin_store.add_coin_record(
|
|
936
|
-
dataclasses.replace(coin_record, coin=fake_coin)
|
|
937
|
-
)
|
|
938
|
-
resp = await wallet_1_rpc.spend_clawback_coins(
|
|
939
|
-
SpendClawbackCoins(coin_ids=[fake_coin.name()], fee=uint64(100), push=True), tx_config=DEFAULT_TX_CONFIG
|
|
940
|
-
)
|
|
941
|
-
assert resp.transaction_ids == []
|
|
942
|
-
# Test claim spend
|
|
943
|
-
await wallet_2_rpc.set_auto_claim(
|
|
944
|
-
AutoClaimSettings(
|
|
945
|
-
enabled=False,
|
|
946
|
-
tx_fee=uint64(100),
|
|
947
|
-
min_amount=uint64(0),
|
|
948
|
-
batch_size=uint16(1),
|
|
949
|
-
)
|
|
950
|
-
)
|
|
951
|
-
resp = await wallet_2_rpc.spend_clawback_coins(
|
|
952
|
-
SpendClawbackCoins(coin_ids=[clawback_coin_id_1, clawback_coin_id_2], fee=uint64(100), push=True),
|
|
953
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
954
|
-
)
|
|
955
|
-
assert len(resp.transaction_ids) == 2
|
|
956
|
-
for clawback_tx in resp.transactions:
|
|
957
|
-
if clawback_tx.spend_bundle is not None:
|
|
958
|
-
await time_out_assert_not_none(
|
|
959
|
-
10, full_node_api.full_node.mempool_manager.get_spendbundle, clawback_tx.spend_bundle.name()
|
|
960
|
-
)
|
|
961
|
-
await farm_transaction_block(full_node_api, wallet_2_node)
|
|
962
|
-
await time_out_assert(20, get_confirmed_balance, generated_funds + 300, wallet_2_rpc, 1)
|
|
963
|
-
# Test spent coin
|
|
964
|
-
resp = await wallet_2_rpc.spend_clawback_coins(
|
|
965
|
-
SpendClawbackCoins(coin_ids=[clawback_coin_id_1], fee=uint64(500), push=True), tx_config=DEFAULT_TX_CONFIG
|
|
966
|
-
)
|
|
967
|
-
assert resp.transaction_ids == []
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
@pytest.mark.anyio
|
|
971
|
-
async def test_send_transaction_multi(wallet_rpc_environment: WalletRpcTestEnvironment) -> None:
|
|
972
|
-
env: WalletRpcTestEnvironment = wallet_rpc_environment
|
|
902
|
+
async def test_send_transaction_multi(wallet_environments: WalletTestFramework) -> None:
|
|
903
|
+
env = wallet_environments.environments[0]
|
|
904
|
+
env_2 = wallet_environments.environments[1]
|
|
973
905
|
|
|
974
|
-
wallet_2: Wallet =
|
|
975
|
-
wallet_node: WalletNode = env.
|
|
976
|
-
full_node_api: FullNodeSimulator =
|
|
977
|
-
client: WalletRpcClient = env.
|
|
906
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
907
|
+
wallet_node: WalletNode = env.node
|
|
908
|
+
full_node_api: FullNodeSimulator = wallet_environments.full_node
|
|
909
|
+
client: WalletRpcClient = env.rpc_client
|
|
978
910
|
|
|
979
|
-
|
|
911
|
+
INITIAL_BALANCE = await env.xch_wallet.get_confirmed_balance()
|
|
980
912
|
|
|
981
913
|
select_coins_response = await client.select_coins(
|
|
982
914
|
SelectCoins.from_coin_selection_config(
|
|
983
|
-
amount=uint64(1750000000000),
|
|
915
|
+
amount=uint64(1750000000000),
|
|
916
|
+
wallet_id=uint32(1),
|
|
917
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config,
|
|
984
918
|
)
|
|
985
919
|
) # we want a coin that won't be selected by default
|
|
986
|
-
outputs = await create_tx_outputs(
|
|
987
|
-
|
|
920
|
+
outputs = await create_tx_outputs(
|
|
921
|
+
wallet_2, wallet_environments.tx_config, [(uint64(1), ["memo_1"]), (uint64(2), ["memo_2"])]
|
|
922
|
+
)
|
|
923
|
+
amount_outputs = sum(output.amount for output in outputs)
|
|
988
924
|
amount_fee = uint64(amount_outputs + 1)
|
|
989
925
|
|
|
990
926
|
send_tx_res: TransactionRecord = (
|
|
991
927
|
await client.send_transaction_multi(
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
928
|
+
SendTransactionMulti(
|
|
929
|
+
wallet_id=uint32(1),
|
|
930
|
+
additions=outputs,
|
|
931
|
+
coins=select_coins_response.coins,
|
|
932
|
+
fee=amount_fee,
|
|
933
|
+
push=True,
|
|
934
|
+
),
|
|
935
|
+
tx_config=wallet_environments.tx_config,
|
|
997
936
|
)
|
|
998
937
|
).transaction
|
|
999
938
|
spend_bundle = send_tx_res.spend_bundle
|
|
@@ -1005,7 +944,7 @@ async def test_send_transaction_multi(wallet_rpc_environment: WalletRpcTestEnvir
|
|
|
1005
944
|
|
|
1006
945
|
await farm_transaction(full_node_api, wallet_node, spend_bundle)
|
|
1007
946
|
|
|
1008
|
-
await time_out_assert(20, get_confirmed_balance,
|
|
947
|
+
await time_out_assert(20, get_confirmed_balance, INITIAL_BALANCE - amount_outputs - amount_fee, client, 1)
|
|
1009
948
|
|
|
1010
949
|
# Checks that the memo can be retrieved
|
|
1011
950
|
tx_confirmed = (await client.get_transaction(GetTransaction(send_tx_res.name))).transaction
|
|
@@ -1013,30 +952,39 @@ async def test_send_transaction_multi(wallet_rpc_environment: WalletRpcTestEnvir
|
|
|
1013
952
|
memos = tx_confirmed.memos
|
|
1014
953
|
assert len(memos) == len(outputs)
|
|
1015
954
|
for output in outputs:
|
|
1016
|
-
assert
|
|
955
|
+
assert output.memos is not None
|
|
956
|
+
assert [output.memos[0].encode()] in memos.values()
|
|
1017
957
|
spend_bundle = send_tx_res.spend_bundle
|
|
1018
958
|
assert spend_bundle is not None
|
|
1019
959
|
for key in memos.keys():
|
|
1020
960
|
assert key in [a.name() for a in spend_bundle.additions()]
|
|
1021
961
|
|
|
1022
962
|
|
|
963
|
+
@pytest.mark.parametrize(
|
|
964
|
+
"wallet_environments",
|
|
965
|
+
[{"num_environments": 1, "blocks_needed": [3]}],
|
|
966
|
+
indirect=True,
|
|
967
|
+
)
|
|
968
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
1023
969
|
@pytest.mark.anyio
|
|
1024
|
-
async def test_get_transactions(
|
|
1025
|
-
env
|
|
1026
|
-
|
|
1027
|
-
wallet: Wallet = env.wallet_1.wallet
|
|
1028
|
-
wallet_node: WalletNode = env.wallet_1.node
|
|
1029
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
1030
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
970
|
+
async def test_get_transactions(wallet_environments: WalletTestFramework) -> None:
|
|
971
|
+
env = wallet_environments.environments[0]
|
|
1031
972
|
|
|
1032
|
-
|
|
973
|
+
wallet: Wallet = env.xch_wallet
|
|
974
|
+
wallet_node: WalletNode = env.node
|
|
975
|
+
full_node_api: FullNodeSimulator = wallet_environments.full_node
|
|
976
|
+
client: WalletRpcClient = env.rpc_client
|
|
1033
977
|
|
|
1034
978
|
all_transactions = (await client.get_transactions(GetTransactions(uint32(1)))).transactions
|
|
1035
|
-
|
|
979
|
+
initially_farmed_blocks = 3
|
|
980
|
+
# We expect 2 transactions per farmed block
|
|
981
|
+
expected_initial_txs_count = initially_farmed_blocks * 2
|
|
982
|
+
unconfirmed_txs_count = 0
|
|
983
|
+
assert len(all_transactions) == expected_initial_txs_count
|
|
1036
984
|
# Test transaction pagination
|
|
1037
|
-
some_transactions = (await client.get_transactions(GetTransactions(uint32(1),
|
|
985
|
+
some_transactions = (await client.get_transactions(GetTransactions(uint32(1), uint32(0), uint32(5)))).transactions
|
|
1038
986
|
some_transactions_2 = (
|
|
1039
|
-
await client.get_transactions(GetTransactions(uint32(1),
|
|
987
|
+
await client.get_transactions(GetTransactions(uint32(1), uint32(5), uint32(10)))
|
|
1040
988
|
).transactions
|
|
1041
989
|
assert some_transactions == all_transactions[0:5]
|
|
1042
990
|
assert some_transactions_2 == all_transactions[5:10]
|
|
@@ -1048,13 +996,14 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
1048
996
|
assert all_transactions == sorted(all_transactions, key=attrgetter("confirmed_at_height"), reverse=True)
|
|
1049
997
|
|
|
1050
998
|
# Test RELEVANCE
|
|
1051
|
-
async with wallet.wallet_state_manager.new_action_scope(
|
|
999
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1052
1000
|
puzhash = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
|
|
1053
1001
|
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
|
|
1054
1002
|
await client.send_transaction(
|
|
1055
1003
|
SendTransaction(wallet_id=uint32(1), amount=uint64(1), address=encode_puzzle_hash(puzhash, "txch"), push=True),
|
|
1056
|
-
|
|
1004
|
+
wallet_environments.tx_config,
|
|
1057
1005
|
) # Create a pending tx
|
|
1006
|
+
unconfirmed_txs_count += 1
|
|
1058
1007
|
|
|
1059
1008
|
with pytest.raises(ValueError, match="There is no known sort foo"):
|
|
1060
1009
|
await client.get_transactions(GetTransactions(uint32(1), sort_key="foo"))
|
|
@@ -1076,20 +1025,25 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
1076
1025
|
assert all_transactions == sorted_transactions
|
|
1077
1026
|
|
|
1078
1027
|
# Test get_transactions to address
|
|
1079
|
-
async with wallet.wallet_state_manager.new_action_scope(
|
|
1028
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1080
1029
|
ph_by_addr = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
|
|
1081
1030
|
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
|
|
1082
1031
|
await client.send_transaction(
|
|
1083
1032
|
SendTransaction(
|
|
1084
1033
|
wallet_id=uint32(1), amount=uint64(1), address=encode_puzzle_hash(ph_by_addr, "txch"), push=True
|
|
1085
1034
|
),
|
|
1086
|
-
|
|
1035
|
+
wallet_environments.tx_config,
|
|
1087
1036
|
)
|
|
1037
|
+
unconfirmed_txs_count += 1
|
|
1088
1038
|
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
|
|
1089
1039
|
tx_for_address = (
|
|
1090
1040
|
await client.get_transactions(GetTransactions(uint32(1), to_address=encode_puzzle_hash(ph_by_addr, "txch")))
|
|
1091
1041
|
).transactions
|
|
1092
|
-
assert
|
|
1042
|
+
assert (
|
|
1043
|
+
len(tx_for_address) == expected_initial_txs_count + unconfirmed_txs_count
|
|
1044
|
+
if wallet_environments.tx_config.reuse_puzhash
|
|
1045
|
+
else 1
|
|
1046
|
+
)
|
|
1093
1047
|
assert tx_for_address[0].to_puzzle_hash == ph_by_addr
|
|
1094
1048
|
|
|
1095
1049
|
# Test type filter
|
|
@@ -1098,14 +1052,15 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
1098
1052
|
GetTransactions(uint32(1), type_filter=TransactionTypeFilter.include([TransactionType.COINBASE_REWARD]))
|
|
1099
1053
|
)
|
|
1100
1054
|
).transactions
|
|
1101
|
-
|
|
1055
|
+
# Each farmed block creates one COINBASE_REWARD transaction
|
|
1056
|
+
assert len(all_transactions) == initially_farmed_blocks
|
|
1102
1057
|
assert all(transaction.type == TransactionType.COINBASE_REWARD.value for transaction in all_transactions)
|
|
1103
1058
|
# Test confirmed filter
|
|
1104
1059
|
all_transactions = (await client.get_transactions(GetTransactions(uint32(1), confirmed=True))).transactions
|
|
1105
|
-
assert len(all_transactions) ==
|
|
1060
|
+
assert len(all_transactions) == expected_initial_txs_count
|
|
1106
1061
|
assert all(transaction.confirmed for transaction in all_transactions)
|
|
1107
1062
|
all_transactions = (await client.get_transactions(GetTransactions(uint32(1), confirmed=False))).transactions
|
|
1108
|
-
assert len(all_transactions) ==
|
|
1063
|
+
assert len(all_transactions) == unconfirmed_txs_count
|
|
1109
1064
|
assert all(not transaction.confirmed for transaction in all_transactions)
|
|
1110
1065
|
|
|
1111
1066
|
# Test bypass broken txs
|
|
@@ -1124,14 +1079,16 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
1124
1079
|
assert len(all_transactions) == 1
|
|
1125
1080
|
|
|
1126
1081
|
|
|
1082
|
+
@pytest.mark.parametrize(
|
|
1083
|
+
"wallet_environments",
|
|
1084
|
+
[{"num_environments": 1, "blocks_needed": [1]}],
|
|
1085
|
+
indirect=True,
|
|
1086
|
+
)
|
|
1087
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
1127
1088
|
@pytest.mark.anyio
|
|
1128
|
-
async def test_get_transaction_count(
|
|
1129
|
-
env
|
|
1130
|
-
|
|
1131
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
1132
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
1133
|
-
|
|
1134
|
-
await generate_funds(full_node_api, env.wallet_1)
|
|
1089
|
+
async def test_get_transaction_count(wallet_environments: WalletTestFramework) -> None:
|
|
1090
|
+
env = wallet_environments.environments[0]
|
|
1091
|
+
client: WalletRpcClient = env.rpc_client
|
|
1135
1092
|
|
|
1136
1093
|
all_transactions = (await client.get_transactions(GetTransactions(uint32(1)))).transactions
|
|
1137
1094
|
assert len(all_transactions) > 0
|
|
@@ -1213,7 +1170,7 @@ async def test_cat_endpoints(wallet_environments: WalletTestFramework, wallet_ty
|
|
|
1213
1170
|
asset_id = (await env_0.rpc_client.get_cat_asset_id(CATGetAssetID(cat_0_id))).asset_id
|
|
1214
1171
|
assert (
|
|
1215
1172
|
await env_0.rpc_client.get_cat_name(CATGetName(cat_0_id))
|
|
1216
|
-
).name == wallet_type.default_wallet_name_for_unknown_cat(asset_id
|
|
1173
|
+
).name == wallet_type.default_wallet_name_for_unknown_cat(asset_id)
|
|
1217
1174
|
await env_0.rpc_client.set_cat_name(CATSetName(cat_0_id, "My cat"))
|
|
1218
1175
|
assert (await env_0.rpc_client.get_cat_name(CATGetName(cat_0_id))).name == "My cat"
|
|
1219
1176
|
asset_to_name_response = await env_0.rpc_client.cat_asset_id_to_name(CATAssetIDToName(asset_id))
|
|
@@ -1229,10 +1186,17 @@ async def test_cat_endpoints(wallet_environments: WalletTestFramework, wallet_ty
|
|
|
1229
1186
|
assert asset_to_name_response.name == next(iter(DEFAULT_CATS.items()))[1]["name"]
|
|
1230
1187
|
|
|
1231
1188
|
# Creates a second wallet with the same CAT
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1189
|
+
create_wallet_res = await env_1.rpc_client.create_new_wallet(
|
|
1190
|
+
CreateNewWallet(
|
|
1191
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
1192
|
+
mode=WalletCreationMode.EXISTING,
|
|
1193
|
+
asset_id=asset_id,
|
|
1194
|
+
push=True,
|
|
1195
|
+
),
|
|
1196
|
+
tx_config=wallet_environments.tx_config,
|
|
1197
|
+
)
|
|
1198
|
+
cat_1_id = create_wallet_res.wallet_id
|
|
1199
|
+
cat_1_asset_id = create_wallet_res.asset_id
|
|
1236
1200
|
assert cat_1_asset_id == asset_id
|
|
1237
1201
|
|
|
1238
1202
|
await wallet_environments.process_pending_states(
|
|
@@ -1525,12 +1489,21 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
|
|
1525
1489
|
cat_asset_id = cat_wallet.cat_info.limitations_program_hash
|
|
1526
1490
|
|
|
1527
1491
|
# Creates a wallet for the same CAT on wallet_2 and send 4 CAT from wallet_1 to it
|
|
1528
|
-
await env_2.rpc_client.
|
|
1492
|
+
await env_2.rpc_client.create_new_wallet(
|
|
1493
|
+
CreateNewWallet(
|
|
1494
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
1495
|
+
mode=WalletCreationMode.EXISTING,
|
|
1496
|
+
asset_id=cat_asset_id,
|
|
1497
|
+
push=True,
|
|
1498
|
+
),
|
|
1499
|
+
tx_config=wallet_environments.tx_config,
|
|
1500
|
+
)
|
|
1529
1501
|
wallet_2_address = (await env_2.rpc_client.get_next_address(GetNextAddress(cat_wallet_id, False))).address
|
|
1530
|
-
adds = [
|
|
1502
|
+
adds = [Addition(puzzle_hash=decode_puzzle_hash(wallet_2_address), amount=uint64(4), memos=["the cat memo"])]
|
|
1531
1503
|
tx_res = (
|
|
1532
1504
|
await env_1.rpc_client.send_transaction_multi(
|
|
1533
|
-
cat_wallet_id, additions=adds,
|
|
1505
|
+
SendTransactionMulti(wallet_id=uint32(cat_wallet_id), additions=adds, fee=uint64(0), push=True),
|
|
1506
|
+
tx_config=wallet_environments.tx_config,
|
|
1534
1507
|
)
|
|
1535
1508
|
).transaction
|
|
1536
1509
|
spend_bundle = tx_res.spend_bundle
|
|
@@ -1586,56 +1559,54 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
|
|
1586
1559
|
)
|
|
1587
1560
|
# Create an offer of 5 chia for one CAT
|
|
1588
1561
|
await env_1.rpc_client.create_offer_for_ids(
|
|
1589
|
-
{
|
|
1562
|
+
CreateOfferForIDs(offer={str(1): "-5", cat_asset_id.hex(): "1"}, validate_only=True),
|
|
1563
|
+
tx_config=wallet_environments.tx_config,
|
|
1590
1564
|
)
|
|
1591
|
-
all_offers = await env_1.rpc_client.get_all_offers()
|
|
1565
|
+
all_offers = (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1592
1566
|
assert len(all_offers) == 0
|
|
1593
1567
|
|
|
1594
|
-
driver_dict
|
|
1595
|
-
cat_asset_id
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1568
|
+
driver_dict = {
|
|
1569
|
+
cat_asset_id: PuzzleInfo(
|
|
1570
|
+
{
|
|
1571
|
+
"type": "CAT",
|
|
1572
|
+
"tail": "0x" + cat_asset_id.hex(),
|
|
1573
|
+
**(
|
|
1574
|
+
{}
|
|
1575
|
+
if wallet_type is CATWallet
|
|
1576
|
+
else {"also": {"type": "revocation layer", "hidden_puzzle_hash": "0x" + bytes32.zeros.hex()}}
|
|
1577
|
+
),
|
|
1578
|
+
}
|
|
1579
|
+
)
|
|
1604
1580
|
}
|
|
1605
1581
|
|
|
1606
1582
|
create_res = await env_1.rpc_client.create_offer_for_ids(
|
|
1607
|
-
{
|
|
1608
|
-
wallet_environments.tx_config,
|
|
1609
|
-
driver_dict=driver_dict,
|
|
1610
|
-
fee=uint64(1),
|
|
1583
|
+
CreateOfferForIDs(offer={str(1): "-5", cat_asset_id.hex(): "1"}, driver_dict=driver_dict, fee=uint64(1)),
|
|
1584
|
+
tx_config=wallet_environments.tx_config,
|
|
1611
1585
|
)
|
|
1612
1586
|
offer = create_res.offer
|
|
1613
1587
|
|
|
1614
|
-
|
|
1615
|
-
assert id == offer.name()
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
"
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
},
|
|
1631
|
-
}
|
|
1632
|
-
assert advanced_summary == summary
|
|
1588
|
+
offer_summary_response = await env_1.rpc_client.get_offer_summary(GetOfferSummary(offer.to_bech32()))
|
|
1589
|
+
assert offer_summary_response.id == offer.name()
|
|
1590
|
+
offer_summary_response_advanced = await env_1.rpc_client.get_offer_summary(
|
|
1591
|
+
GetOfferSummary(offer.to_bech32(), advanced=True)
|
|
1592
|
+
)
|
|
1593
|
+
assert offer_summary_response_advanced.id == offer.name()
|
|
1594
|
+
assert offer_summary_response_advanced.summary == OfferSummary(
|
|
1595
|
+
offered={"xch": "5"},
|
|
1596
|
+
requested={cat_asset_id.hex(): "1"},
|
|
1597
|
+
infos={key.hex(): info for key, info in driver_dict.items()},
|
|
1598
|
+
fees=uint64(1),
|
|
1599
|
+
additions=[c.name() for c in offer.additions()],
|
|
1600
|
+
removals=[c.name() for c in offer.removals()],
|
|
1601
|
+
valid_times=ConditionValidTimesAbsolute(),
|
|
1602
|
+
)
|
|
1603
|
+
assert offer_summary_response_advanced.summary == offer_summary_response.summary
|
|
1633
1604
|
|
|
1634
1605
|
offer_validity_response = await env_1.rpc_client.check_offer_validity(CheckOfferValidity(offer.to_bech32()))
|
|
1635
1606
|
assert offer_validity_response.id == offer.name()
|
|
1636
1607
|
assert offer_validity_response.valid
|
|
1637
1608
|
|
|
1638
|
-
all_offers = await env_1.rpc_client.get_all_offers(file_contents=True)
|
|
1609
|
+
all_offers = (await env_1.rpc_client.get_all_offers(GetAllOffers(file_contents=True))).trade_records
|
|
1639
1610
|
assert len(all_offers) == 1
|
|
1640
1611
|
assert TradeStatus(all_offers[0].status) == TradeStatus.PENDING_ACCEPT
|
|
1641
1612
|
assert all_offers[0].offer == bytes(offer)
|
|
@@ -1645,26 +1616,44 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
|
|
1645
1616
|
assert offer_count.my_offers_count == 1
|
|
1646
1617
|
assert offer_count.taken_offers_count == 0
|
|
1647
1618
|
|
|
1648
|
-
trade_record = (
|
|
1619
|
+
trade_record = (
|
|
1620
|
+
await env_2.rpc_client.take_offer(
|
|
1621
|
+
TakeOffer(
|
|
1622
|
+
offer=offer.to_bech32(),
|
|
1623
|
+
fee=uint64(1),
|
|
1624
|
+
push=True,
|
|
1625
|
+
),
|
|
1626
|
+
wallet_environments.tx_config,
|
|
1627
|
+
)
|
|
1628
|
+
).trade_record
|
|
1649
1629
|
assert TradeStatus(trade_record.status) == TradeStatus.PENDING_CONFIRM
|
|
1650
1630
|
|
|
1651
|
-
await env_1.rpc_client.cancel_offer(
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1631
|
+
await env_1.rpc_client.cancel_offer(
|
|
1632
|
+
CancelOffer(
|
|
1633
|
+
trade_id=offer.name(),
|
|
1634
|
+
secure=False,
|
|
1635
|
+
push=True,
|
|
1636
|
+
),
|
|
1637
|
+
tx_config=wallet_environments.tx_config,
|
|
1638
|
+
)
|
|
1639
|
+
|
|
1640
|
+
trade_record = (await env_1.rpc_client.get_offer(GetOffer(offer.name(), file_contents=True))).trade_record
|
|
1641
|
+
assert trade_record.offer == bytes(offer)
|
|
1642
|
+
assert TradeStatus(trade_record.status) == TradeStatus.CANCELLED
|
|
1656
1643
|
|
|
1657
1644
|
failed_cancel_res = await env_1.rpc_client.cancel_offer(
|
|
1658
|
-
offer.name(),
|
|
1645
|
+
CancelOffer(trade_id=offer.name(), fee=uint64(1), secure=True, push=True),
|
|
1646
|
+
tx_config=wallet_environments.tx_config,
|
|
1659
1647
|
)
|
|
1660
1648
|
|
|
1661
|
-
trade_record = await env_1.rpc_client.get_offer(offer.name())
|
|
1649
|
+
trade_record = (await env_1.rpc_client.get_offer(GetOffer(offer.name()))).trade_record
|
|
1662
1650
|
assert TradeStatus(trade_record.status) == TradeStatus.PENDING_CANCEL
|
|
1663
1651
|
|
|
1664
1652
|
create_res = await env_1.rpc_client.create_offer_for_ids(
|
|
1665
|
-
{
|
|
1653
|
+
CreateOfferForIDs(offer={str(1): "-5", str(cat_wallet_id): "1"}, fee=uint64(1)),
|
|
1654
|
+
tx_config=wallet_environments.tx_config,
|
|
1666
1655
|
)
|
|
1667
|
-
all_offers = await env_1.rpc_client.get_all_offers()
|
|
1656
|
+
all_offers = (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1668
1657
|
assert len(all_offers) == 2
|
|
1669
1658
|
offer_count = await env_1.rpc_client.get_offers_count()
|
|
1670
1659
|
assert offer_count.total == 2
|
|
@@ -1744,7 +1733,7 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
|
|
1744
1733
|
)
|
|
1745
1734
|
|
|
1746
1735
|
async def is_trade_confirmed(client: WalletRpcClient, offer: Offer) -> bool:
|
|
1747
|
-
trade_record = await client.get_offer(offer.name())
|
|
1736
|
+
trade_record = (await client.get_offer(GetOffer(offer.name()))).trade_record
|
|
1748
1737
|
return TradeStatus(trade_record.status) == TradeStatus.CONFIRMED
|
|
1749
1738
|
|
|
1750
1739
|
await time_out_assert(15, is_trade_confirmed, True, env_1.rpc_client, offer)
|
|
@@ -1753,39 +1742,64 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
|
|
1753
1742
|
def only_ids(trades: list[TradeRecord]) -> list[bytes32]:
|
|
1754
1743
|
return [t.trade_id for t in trades]
|
|
1755
1744
|
|
|
1756
|
-
trade_record = await env_1.rpc_client.get_offer(offer.name())
|
|
1757
|
-
all_offers =
|
|
1745
|
+
trade_record = (await env_1.rpc_client.get_offer(GetOffer(offer.name()))).trade_record
|
|
1746
|
+
all_offers = ( # confirmed at index descending
|
|
1747
|
+
await env_1.rpc_client.get_all_offers(GetAllOffers(include_completed=True))
|
|
1748
|
+
).trade_records
|
|
1758
1749
|
assert len(all_offers) == 2
|
|
1759
1750
|
assert only_ids(all_offers) == only_ids([trade_record, new_trade_record])
|
|
1760
|
-
all_offers =
|
|
1761
|
-
include_completed=True, reverse=True
|
|
1762
|
-
)
|
|
1751
|
+
all_offers = ( # confirmed at index ascending
|
|
1752
|
+
await env_1.rpc_client.get_all_offers(GetAllOffers(include_completed=True, reverse=True))
|
|
1753
|
+
).trade_records
|
|
1763
1754
|
assert only_ids(all_offers) == only_ids([new_trade_record, trade_record])
|
|
1764
|
-
all_offers =
|
|
1755
|
+
all_offers = ( # most relevant
|
|
1756
|
+
await env_1.rpc_client.get_all_offers(GetAllOffers(include_completed=True, sort_key="RELEVANCE"))
|
|
1757
|
+
).trade_records
|
|
1765
1758
|
assert only_ids(all_offers) == only_ids([new_trade_record, trade_record])
|
|
1766
|
-
all_offers =
|
|
1767
|
-
include_completed=True, sort_key="RELEVANCE", reverse=True
|
|
1768
|
-
)
|
|
1759
|
+
all_offers = ( # least relevant
|
|
1760
|
+
await env_1.rpc_client.get_all_offers(GetAllOffers(include_completed=True, sort_key="RELEVANCE", reverse=True))
|
|
1761
|
+
).trade_records
|
|
1769
1762
|
assert only_ids(all_offers) == only_ids([trade_record, new_trade_record])
|
|
1770
1763
|
# Test pagination
|
|
1771
|
-
all_offers =
|
|
1764
|
+
all_offers = (
|
|
1765
|
+
await env_1.rpc_client.get_all_offers(GetAllOffers(include_completed=True, start=uint16(0), end=uint16(1)))
|
|
1766
|
+
).trade_records
|
|
1772
1767
|
assert len(all_offers) == 1
|
|
1773
|
-
all_offers =
|
|
1768
|
+
all_offers = (
|
|
1769
|
+
await env_1.rpc_client.get_all_offers(GetAllOffers(include_completed=True, start=uint16(10)))
|
|
1770
|
+
).trade_records
|
|
1774
1771
|
assert len(all_offers) == 0
|
|
1775
|
-
all_offers =
|
|
1772
|
+
all_offers = (
|
|
1773
|
+
await env_1.rpc_client.get_all_offers(GetAllOffers(include_completed=True, start=uint16(0), end=uint16(50)))
|
|
1774
|
+
).trade_records
|
|
1776
1775
|
assert len(all_offers) == 2
|
|
1777
1776
|
|
|
1778
1777
|
await env_1.rpc_client.create_offer_for_ids(
|
|
1779
|
-
{
|
|
1780
|
-
wallet_environments.tx_config,
|
|
1781
|
-
driver_dict=driver_dict,
|
|
1778
|
+
CreateOfferForIDs(offer={str(1): "-5", cat_asset_id.hex(): "1"}, driver_dict=driver_dict),
|
|
1779
|
+
tx_config=wallet_environments.tx_config,
|
|
1782
1780
|
)
|
|
1783
1781
|
assert (
|
|
1784
|
-
len(
|
|
1782
|
+
len(
|
|
1783
|
+
[
|
|
1784
|
+
o
|
|
1785
|
+
for o in (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1786
|
+
if o.status == TradeStatus.PENDING_ACCEPT.value
|
|
1787
|
+
]
|
|
1788
|
+
)
|
|
1789
|
+
== 2
|
|
1790
|
+
)
|
|
1791
|
+
await env_1.rpc_client.cancel_offers(
|
|
1792
|
+
CancelOffers(secure=True, batch_size=uint16(1), push=True), tx_config=wallet_environments.tx_config
|
|
1785
1793
|
)
|
|
1786
|
-
await env_1.rpc_client.cancel_offers(wallet_environments.tx_config, batch_size=1)
|
|
1787
1794
|
assert (
|
|
1788
|
-
len(
|
|
1795
|
+
len(
|
|
1796
|
+
[
|
|
1797
|
+
o
|
|
1798
|
+
for o in (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1799
|
+
if o.status == TradeStatus.PENDING_ACCEPT.value
|
|
1800
|
+
]
|
|
1801
|
+
)
|
|
1802
|
+
== 0
|
|
1789
1803
|
)
|
|
1790
1804
|
await wallet_environments.process_pending_states(
|
|
1791
1805
|
[
|
|
@@ -1814,21 +1828,35 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
|
|
1814
1828
|
)
|
|
1815
1829
|
|
|
1816
1830
|
await env_1.rpc_client.create_offer_for_ids(
|
|
1817
|
-
{
|
|
1818
|
-
wallet_environments.tx_config,
|
|
1819
|
-
driver_dict=driver_dict,
|
|
1831
|
+
CreateOfferForIDs(offer={str(1): "-5", cat_asset_id.hex(): "1"}, driver_dict=driver_dict),
|
|
1832
|
+
tx_config=wallet_environments.tx_config,
|
|
1820
1833
|
)
|
|
1821
1834
|
await env_1.rpc_client.create_offer_for_ids(
|
|
1822
|
-
{
|
|
1823
|
-
wallet_environments.tx_config,
|
|
1824
|
-
driver_dict=driver_dict,
|
|
1835
|
+
CreateOfferForIDs(offer={str(1): "5", cat_asset_id.hex(): "-1"}, driver_dict=driver_dict),
|
|
1836
|
+
tx_config=wallet_environments.tx_config,
|
|
1825
1837
|
)
|
|
1826
1838
|
assert (
|
|
1827
|
-
len(
|
|
1839
|
+
len(
|
|
1840
|
+
[
|
|
1841
|
+
o
|
|
1842
|
+
for o in (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1843
|
+
if o.status == TradeStatus.PENDING_ACCEPT.value
|
|
1844
|
+
]
|
|
1845
|
+
)
|
|
1846
|
+
== 2
|
|
1847
|
+
)
|
|
1848
|
+
await env_1.rpc_client.cancel_offers(
|
|
1849
|
+
CancelOffers(secure=True, cancel_all=True, push=True), tx_config=wallet_environments.tx_config
|
|
1828
1850
|
)
|
|
1829
|
-
await env_1.rpc_client.cancel_offers(wallet_environments.tx_config, cancel_all=True)
|
|
1830
1851
|
assert (
|
|
1831
|
-
len(
|
|
1852
|
+
len(
|
|
1853
|
+
[
|
|
1854
|
+
o
|
|
1855
|
+
for o in (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1856
|
+
if o.status == TradeStatus.PENDING_ACCEPT.value
|
|
1857
|
+
]
|
|
1858
|
+
)
|
|
1859
|
+
== 0
|
|
1832
1860
|
)
|
|
1833
1861
|
|
|
1834
1862
|
await wallet_environments.process_pending_states(
|
|
@@ -1868,51 +1896,81 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
|
|
1868
1896
|
)
|
|
1869
1897
|
|
|
1870
1898
|
await env_1.rpc_client.create_offer_for_ids(
|
|
1871
|
-
{
|
|
1872
|
-
wallet_environments.tx_config,
|
|
1873
|
-
driver_dict=driver_dict,
|
|
1899
|
+
CreateOfferForIDs(offer={str(1): "5", cat_asset_id.hex(): "-1"}, driver_dict=driver_dict),
|
|
1900
|
+
tx_config=wallet_environments.tx_config,
|
|
1874
1901
|
)
|
|
1875
1902
|
assert (
|
|
1876
|
-
len(
|
|
1903
|
+
len(
|
|
1904
|
+
[
|
|
1905
|
+
o
|
|
1906
|
+
for o in (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1907
|
+
if o.status == TradeStatus.PENDING_ACCEPT.value
|
|
1908
|
+
]
|
|
1909
|
+
)
|
|
1910
|
+
== 1
|
|
1911
|
+
)
|
|
1912
|
+
await env_1.rpc_client.cancel_offers(
|
|
1913
|
+
CancelOffers(secure=True, asset_id=bytes32.zeros.hex(), push=True), tx_config=wallet_environments.tx_config
|
|
1877
1914
|
)
|
|
1878
|
-
await env_1.rpc_client.cancel_offers(wallet_environments.tx_config, asset_id=bytes32.zeros)
|
|
1879
1915
|
assert (
|
|
1880
|
-
len(
|
|
1916
|
+
len(
|
|
1917
|
+
[
|
|
1918
|
+
o
|
|
1919
|
+
for o in (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1920
|
+
if o.status == TradeStatus.PENDING_ACCEPT.value
|
|
1921
|
+
]
|
|
1922
|
+
)
|
|
1923
|
+
== 1
|
|
1924
|
+
)
|
|
1925
|
+
await env_1.rpc_client.cancel_offers(
|
|
1926
|
+
CancelOffers(secure=True, asset_id=cat_asset_id.hex(), push=True), tx_config=wallet_environments.tx_config
|
|
1881
1927
|
)
|
|
1882
|
-
await env_1.rpc_client.cancel_offers(wallet_environments.tx_config, asset_id=cat_asset_id)
|
|
1883
1928
|
assert (
|
|
1884
|
-
len(
|
|
1929
|
+
len(
|
|
1930
|
+
[
|
|
1931
|
+
o
|
|
1932
|
+
for o in (await env_1.rpc_client.get_all_offers(GetAllOffers())).trade_records
|
|
1933
|
+
if o.status == TradeStatus.PENDING_ACCEPT.value
|
|
1934
|
+
]
|
|
1935
|
+
)
|
|
1936
|
+
== 0
|
|
1885
1937
|
)
|
|
1886
1938
|
|
|
1887
1939
|
with pytest.raises(ValueError, match="not currently supported"):
|
|
1888
1940
|
await env_1.rpc_client.create_offer_for_ids(
|
|
1889
|
-
|
|
1941
|
+
CreateOfferForIDs(
|
|
1942
|
+
offer={str(1): "-5", cat_asset_id.hex(): "1"},
|
|
1943
|
+
driver_dict=driver_dict,
|
|
1944
|
+
),
|
|
1890
1945
|
wallet_environments.tx_config,
|
|
1891
|
-
driver_dict=driver_dict,
|
|
1892
1946
|
timelock_info=ConditionValidTimes(min_secs_since_created=uint64(1)),
|
|
1893
1947
|
)
|
|
1894
1948
|
|
|
1895
1949
|
|
|
1950
|
+
@pytest.mark.parametrize(
|
|
1951
|
+
"wallet_environments",
|
|
1952
|
+
[{"num_environments": 1, "blocks_needed": [5]}],
|
|
1953
|
+
indirect=True,
|
|
1954
|
+
)
|
|
1955
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
1896
1956
|
@pytest.mark.anyio
|
|
1897
|
-
async def test_get_coin_records_by_names(
|
|
1898
|
-
env
|
|
1899
|
-
wallet_node: WalletNode = env.
|
|
1900
|
-
client: WalletRpcClient = env.
|
|
1957
|
+
async def test_get_coin_records_by_names(wallet_environments: WalletTestFramework) -> None:
|
|
1958
|
+
env = wallet_environments.environments[0]
|
|
1959
|
+
wallet_node: WalletNode = env.node
|
|
1960
|
+
client: WalletRpcClient = env.rpc_client
|
|
1901
1961
|
store = wallet_node.wallet_state_manager.coin_store
|
|
1902
|
-
full_node_api =
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
async with env.
|
|
1906
|
-
address = encode_puzzle_hash(
|
|
1907
|
-
await action_scope.get_puzzle_hash(env.wallet_1.wallet.wallet_state_manager), "txch"
|
|
1908
|
-
)
|
|
1962
|
+
full_node_api = wallet_environments.full_node
|
|
1963
|
+
|
|
1964
|
+
INITIAL_BALANCE = await env.xch_wallet.get_confirmed_balance()
|
|
1965
|
+
async with env.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1966
|
+
address = encode_puzzle_hash(await action_scope.get_puzzle_hash(env.wallet_state_manager), "txch")
|
|
1909
1967
|
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
|
|
1910
1968
|
|
|
1911
1969
|
# Spend half of it back to the same wallet get some spent coins in the wallet
|
|
1912
1970
|
tx = (
|
|
1913
1971
|
await client.send_transaction(
|
|
1914
|
-
SendTransaction(wallet_id=uint32(1), amount=uint64(
|
|
1915
|
-
|
|
1972
|
+
SendTransaction(wallet_id=uint32(1), amount=uint64(INITIAL_BALANCE / 2), address=address, push=True),
|
|
1973
|
+
wallet_environments.tx_config,
|
|
1916
1974
|
)
|
|
1917
1975
|
).transaction
|
|
1918
1976
|
assert tx.spend_bundle is not None
|
|
@@ -1958,31 +2016,55 @@ async def test_get_coin_records_by_names(wallet_rpc_environment: WalletRpcTestEn
|
|
|
1958
2016
|
await client.get_coin_records_by_names(GetCoinRecordsByNames(coin_ids, include_spent_coins=False))
|
|
1959
2017
|
|
|
1960
2018
|
|
|
2019
|
+
@pytest.mark.parametrize(
|
|
2020
|
+
"wallet_environments",
|
|
2021
|
+
[{"num_environments": 2, "blocks_needed": [1, 1]}],
|
|
2022
|
+
indirect=True,
|
|
2023
|
+
)
|
|
2024
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
1961
2025
|
@pytest.mark.anyio
|
|
1962
|
-
async def test_did_endpoints(
|
|
1963
|
-
env
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
2026
|
+
async def test_did_endpoints(wallet_environments: WalletTestFramework) -> None:
|
|
2027
|
+
env = wallet_environments.environments[0]
|
|
2028
|
+
env_2 = wallet_environments.environments[1]
|
|
2029
|
+
|
|
2030
|
+
env.wallet_aliases = {
|
|
2031
|
+
"xch": 1,
|
|
2032
|
+
"did": 2,
|
|
2033
|
+
"nft": 3,
|
|
2034
|
+
}
|
|
2035
|
+
env_2.wallet_aliases = {
|
|
2036
|
+
"xch": 1,
|
|
2037
|
+
"did": 2,
|
|
2038
|
+
}
|
|
1973
2039
|
|
|
1974
|
-
|
|
2040
|
+
wallet_1: Wallet = env.xch_wallet
|
|
2041
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
2042
|
+
wallet_1_node: WalletNode = env.node
|
|
2043
|
+
wallet_2_node: WalletNode = env_2.node
|
|
2044
|
+
wallet_1_rpc: WalletRpcClient = env.rpc_client
|
|
2045
|
+
wallet_2_rpc: WalletRpcClient = env_2.rpc_client
|
|
2046
|
+
wallet_1_id = wallet_1.id()
|
|
1975
2047
|
|
|
1976
2048
|
# Create a DID wallet
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2049
|
+
create_new_res = await wallet_1_rpc.create_new_wallet(
|
|
2050
|
+
CreateNewWallet(
|
|
2051
|
+
wallet_type=CreateNewWalletType.DID_WALLET,
|
|
2052
|
+
did_type=DIDType.NEW,
|
|
2053
|
+
amount=uint64(1),
|
|
2054
|
+
wallet_name="Profile 1",
|
|
2055
|
+
push=True,
|
|
2056
|
+
),
|
|
2057
|
+
tx_config=wallet_environments.tx_config,
|
|
2058
|
+
)
|
|
2059
|
+
did_wallet_id_0 = create_new_res.wallet_id
|
|
2060
|
+
did_id_0 = create_new_res.my_did
|
|
2061
|
+
await env.change_balances({"did": {"init": True, "set_remainder": True}})
|
|
2062
|
+
await env.change_balances({"nft": {"init": True, "set_remainder": True}})
|
|
1981
2063
|
|
|
1982
2064
|
# Get wallet name
|
|
1983
2065
|
get_name_res = await wallet_1_rpc.did_get_wallet_name(DIDGetWalletName(did_wallet_id_0))
|
|
1984
2066
|
assert get_name_res.name == "Profile 1"
|
|
1985
|
-
nft_wallet = wallet_1_node.wallet_state_manager.wallets[did_wallet_id_0 + 1]
|
|
2067
|
+
nft_wallet = wallet_1_node.wallet_state_manager.wallets[uint32(did_wallet_id_0 + 1)]
|
|
1986
2068
|
assert isinstance(nft_wallet, NFTWallet)
|
|
1987
2069
|
assert nft_wallet.get_name() == "Profile 1 NFT Wallet"
|
|
1988
2070
|
|
|
@@ -2000,36 +2082,80 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -
|
|
|
2000
2082
|
# Create backup file
|
|
2001
2083
|
await wallet_1_rpc.create_did_backup_file(DIDCreateBackupFile(did_wallet_id_0))
|
|
2002
2084
|
|
|
2003
|
-
await
|
|
2004
|
-
|
|
2085
|
+
await wallet_environments.process_pending_states(
|
|
2086
|
+
[
|
|
2087
|
+
WalletStateTransition(
|
|
2088
|
+
pre_block_balance_updates={
|
|
2089
|
+
"xch": {"set_remainder": True},
|
|
2090
|
+
"did": {"set_remainder": True},
|
|
2091
|
+
},
|
|
2092
|
+
post_block_balance_updates={
|
|
2093
|
+
"xch": {"set_remainder": True},
|
|
2094
|
+
"did": {"set_remainder": True},
|
|
2095
|
+
},
|
|
2096
|
+
),
|
|
2097
|
+
WalletStateTransition(),
|
|
2098
|
+
]
|
|
2099
|
+
)
|
|
2005
2100
|
|
|
2006
2101
|
# Update metadata
|
|
2007
2102
|
with pytest.raises(ValueError, match="wallet id 1 is of type Wallet but type DIDWallet is required"):
|
|
2008
2103
|
await wallet_1_rpc.update_did_metadata(
|
|
2009
|
-
DIDUpdateMetadata(wallet_id=wallet_1_id, metadata={"Twitter": "Https://test"}, push=True),
|
|
2104
|
+
DIDUpdateMetadata(wallet_id=wallet_1_id, metadata={"Twitter": "Https://test"}, push=True),
|
|
2105
|
+
wallet_environments.tx_config,
|
|
2010
2106
|
)
|
|
2011
2107
|
await wallet_1_rpc.update_did_metadata(
|
|
2012
|
-
DIDUpdateMetadata(wallet_id=did_wallet_id_0, metadata={"Twitter": "Https://test"}, push=True),
|
|
2108
|
+
DIDUpdateMetadata(wallet_id=did_wallet_id_0, metadata={"Twitter": "Https://test"}, push=True),
|
|
2109
|
+
wallet_environments.tx_config,
|
|
2013
2110
|
)
|
|
2014
2111
|
|
|
2015
2112
|
get_metadata_res = await wallet_1_rpc.get_did_metadata(DIDGetMetadata(did_wallet_id_0))
|
|
2016
2113
|
assert get_metadata_res.metadata["Twitter"] == "Https://test"
|
|
2017
2114
|
|
|
2018
|
-
await
|
|
2019
|
-
|
|
2115
|
+
await wallet_environments.process_pending_states(
|
|
2116
|
+
[
|
|
2117
|
+
WalletStateTransition(
|
|
2118
|
+
pre_block_balance_updates={
|
|
2119
|
+
"xch": {"set_remainder": True},
|
|
2120
|
+
"did": {"set_remainder": True},
|
|
2121
|
+
},
|
|
2122
|
+
post_block_balance_updates={
|
|
2123
|
+
"xch": {"set_remainder": True},
|
|
2124
|
+
"did": {"set_remainder": True},
|
|
2125
|
+
},
|
|
2126
|
+
),
|
|
2127
|
+
WalletStateTransition(),
|
|
2128
|
+
]
|
|
2129
|
+
)
|
|
2020
2130
|
|
|
2021
2131
|
# Transfer DID
|
|
2022
|
-
async with wallet_2.wallet_state_manager.new_action_scope(
|
|
2132
|
+
async with wallet_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
2023
2133
|
addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
|
|
2024
2134
|
await wallet_1_rpc.did_transfer_did(
|
|
2025
2135
|
DIDTransferDID(
|
|
2026
2136
|
wallet_id=did_wallet_id_0, inner_address=addr, fee=uint64(0), with_recovery_info=True, push=True
|
|
2027
2137
|
),
|
|
2028
|
-
|
|
2138
|
+
wallet_environments.tx_config,
|
|
2029
2139
|
)
|
|
2030
2140
|
|
|
2031
|
-
await
|
|
2032
|
-
|
|
2141
|
+
await wallet_environments.process_pending_states(
|
|
2142
|
+
[
|
|
2143
|
+
WalletStateTransition(
|
|
2144
|
+
pre_block_balance_updates={
|
|
2145
|
+
"xch": {"set_remainder": True},
|
|
2146
|
+
"did": {"set_remainder": True},
|
|
2147
|
+
},
|
|
2148
|
+
post_block_balance_updates={
|
|
2149
|
+
"xch": {"set_remainder": True},
|
|
2150
|
+
},
|
|
2151
|
+
),
|
|
2152
|
+
WalletStateTransition(
|
|
2153
|
+
post_block_balance_updates={
|
|
2154
|
+
"did": {"init": True, "set_remainder": True},
|
|
2155
|
+
}
|
|
2156
|
+
),
|
|
2157
|
+
]
|
|
2158
|
+
)
|
|
2033
2159
|
|
|
2034
2160
|
async def num_wallets() -> int:
|
|
2035
2161
|
return len(await wallet_2_node.wallet_state_manager.get_all_wallet_info_entries())
|
|
@@ -2052,23 +2178,52 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -
|
|
|
2052
2178
|
assert metadata["Twitter"] == "Https://test"
|
|
2053
2179
|
|
|
2054
2180
|
last_did_coin = await did_wallet_2.get_coin()
|
|
2055
|
-
await wallet_2_rpc.did_message_spend(
|
|
2181
|
+
await wallet_2_rpc.did_message_spend(
|
|
2182
|
+
DIDMessageSpend(wallet_id=did_wallet_2.id(), push=True), wallet_environments.tx_config
|
|
2183
|
+
)
|
|
2056
2184
|
await wallet_2_node.wallet_state_manager.add_interested_coin_ids([last_did_coin.name()])
|
|
2057
2185
|
|
|
2058
|
-
await
|
|
2059
|
-
|
|
2186
|
+
await wallet_environments.process_pending_states(
|
|
2187
|
+
[
|
|
2188
|
+
WalletStateTransition(),
|
|
2189
|
+
WalletStateTransition(
|
|
2190
|
+
pre_block_balance_updates={
|
|
2191
|
+
"xch": {"set_remainder": True},
|
|
2192
|
+
"did": {"set_remainder": True},
|
|
2193
|
+
},
|
|
2194
|
+
post_block_balance_updates={
|
|
2195
|
+
"xch": {"set_remainder": True},
|
|
2196
|
+
"did": {"set_remainder": True},
|
|
2197
|
+
},
|
|
2198
|
+
),
|
|
2199
|
+
]
|
|
2200
|
+
)
|
|
2060
2201
|
|
|
2061
2202
|
next_did_coin = await did_wallet_2.get_coin()
|
|
2062
2203
|
assert next_did_coin.parent_coin_info == last_did_coin.name()
|
|
2063
2204
|
last_did_coin = next_did_coin
|
|
2064
2205
|
|
|
2065
2206
|
await wallet_2_rpc.did_message_spend(
|
|
2066
|
-
DIDMessageSpend(wallet_id=did_wallet_2.id(), push=True),
|
|
2207
|
+
DIDMessageSpend(wallet_id=did_wallet_2.id(), push=True),
|
|
2208
|
+
wallet_environments.tx_config.override(reuse_puzhash=True),
|
|
2067
2209
|
)
|
|
2068
2210
|
await wallet_2_node.wallet_state_manager.add_interested_coin_ids([last_did_coin.name()])
|
|
2069
2211
|
|
|
2070
|
-
await
|
|
2071
|
-
|
|
2212
|
+
await wallet_environments.process_pending_states(
|
|
2213
|
+
[
|
|
2214
|
+
WalletStateTransition(),
|
|
2215
|
+
WalletStateTransition(
|
|
2216
|
+
pre_block_balance_updates={
|
|
2217
|
+
"xch": {"set_remainder": True},
|
|
2218
|
+
"did": {"set_remainder": True},
|
|
2219
|
+
},
|
|
2220
|
+
post_block_balance_updates={
|
|
2221
|
+
"xch": {"set_remainder": True},
|
|
2222
|
+
"did": {"set_remainder": True},
|
|
2223
|
+
},
|
|
2224
|
+
),
|
|
2225
|
+
]
|
|
2226
|
+
)
|
|
2072
2227
|
|
|
2073
2228
|
next_did_coin = await did_wallet_2.get_coin()
|
|
2074
2229
|
assert next_did_coin.parent_coin_info == last_did_coin.name()
|
|
@@ -2079,21 +2234,37 @@ async def test_did_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -
|
|
|
2079
2234
|
assert isinstance(pubkey_res.pubkey, G1Element)
|
|
2080
2235
|
|
|
2081
2236
|
|
|
2237
|
+
@pytest.mark.parametrize(
|
|
2238
|
+
"wallet_environments",
|
|
2239
|
+
[{"num_environments": 2, "blocks_needed": [1, 1]}],
|
|
2240
|
+
indirect=True,
|
|
2241
|
+
)
|
|
2242
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2082
2243
|
@pytest.mark.anyio
|
|
2083
|
-
async def test_nft_endpoints(
|
|
2084
|
-
env
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2244
|
+
async def test_nft_endpoints(wallet_environments: WalletTestFramework) -> None:
|
|
2245
|
+
env = wallet_environments.environments[0]
|
|
2246
|
+
env_2 = wallet_environments.environments[1]
|
|
2247
|
+
wallet_1_node: WalletNode = env.node
|
|
2248
|
+
wallet_1_rpc: WalletRpcClient = env.rpc_client
|
|
2249
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
2250
|
+
wallet_2_node: WalletNode = env_2.node
|
|
2251
|
+
wallet_2_rpc: WalletRpcClient = env_2.rpc_client
|
|
2252
|
+
|
|
2253
|
+
env.wallet_aliases = {
|
|
2254
|
+
"xch": 1,
|
|
2255
|
+
"nft": 2,
|
|
2256
|
+
}
|
|
2257
|
+
env_2.wallet_aliases = {
|
|
2258
|
+
"xch": 1,
|
|
2259
|
+
"nft": 2,
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
create_wallet_res = await wallet_1_rpc.create_new_wallet(
|
|
2263
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, did_id=None, push=True),
|
|
2264
|
+
wallet_environments.tx_config,
|
|
2265
|
+
)
|
|
2266
|
+
nft_wallet_id = create_wallet_res.wallet_id
|
|
2267
|
+
await wallet_1_rpc.mint_nft(
|
|
2097
2268
|
request=NFTMintNFTRequest(
|
|
2098
2269
|
wallet_id=nft_wallet_id,
|
|
2099
2270
|
royalty_address=None,
|
|
@@ -2102,14 +2273,24 @@ async def test_nft_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -
|
|
|
2102
2273
|
uris=["https://www.chia.net/img/branding/chia-logo.svg"],
|
|
2103
2274
|
push=True,
|
|
2104
2275
|
),
|
|
2105
|
-
tx_config=
|
|
2276
|
+
tx_config=wallet_environments.tx_config,
|
|
2106
2277
|
)
|
|
2107
2278
|
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2279
|
+
await wallet_environments.process_pending_states(
|
|
2280
|
+
[
|
|
2281
|
+
WalletStateTransition(
|
|
2282
|
+
pre_block_balance_updates={
|
|
2283
|
+
"xch": {"set_remainder": True},
|
|
2284
|
+
"nft": {"init": True, "set_remainder": True},
|
|
2285
|
+
},
|
|
2286
|
+
post_block_balance_updates={
|
|
2287
|
+
"xch": {"set_remainder": True},
|
|
2288
|
+
"nft": {"set_remainder": True},
|
|
2289
|
+
},
|
|
2290
|
+
),
|
|
2291
|
+
WalletStateTransition(),
|
|
2292
|
+
]
|
|
2293
|
+
)
|
|
2113
2294
|
|
|
2114
2295
|
nft_wallet = wallet_1_node.wallet_state_manager.wallets[nft_wallet_id]
|
|
2115
2296
|
assert isinstance(nft_wallet, NFTWallet)
|
|
@@ -2132,17 +2313,34 @@ async def test_nft_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -
|
|
|
2132
2313
|
nft_info = (await wallet_1_rpc.get_nft_info(NFTGetInfo(hmr_nft_id))).nft_info
|
|
2133
2314
|
assert nft_info.nft_coin_id == (await nft_wallet.get_current_nfts())[0].coin.name()
|
|
2134
2315
|
|
|
2135
|
-
async with wallet_2.wallet_state_manager.new_action_scope(
|
|
2316
|
+
async with wallet_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
2136
2317
|
addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
|
|
2137
2318
|
await wallet_1_rpc.transfer_nft(
|
|
2138
|
-
NFTTransferNFT(wallet_id=nft_wallet_id, nft_coin_id=nft_id, target_address=addr, push=True),
|
|
2319
|
+
NFTTransferNFT(wallet_id=nft_wallet_id, nft_coin_id=nft_id, target_address=addr, push=True),
|
|
2320
|
+
wallet_environments.tx_config,
|
|
2139
2321
|
)
|
|
2140
|
-
await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
|
|
2141
|
-
await farm_transaction_block(full_node_api, wallet_1_node)
|
|
2142
|
-
await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 0)
|
|
2143
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_1_node, timeout=5)
|
|
2144
2322
|
|
|
2145
|
-
await
|
|
2323
|
+
await wallet_environments.process_pending_states(
|
|
2324
|
+
[
|
|
2325
|
+
WalletStateTransition(
|
|
2326
|
+
pre_block_balance_updates={
|
|
2327
|
+
"xch": {"set_remainder": True},
|
|
2328
|
+
"nft": {"set_remainder": True},
|
|
2329
|
+
},
|
|
2330
|
+
post_block_balance_updates={
|
|
2331
|
+
"xch": {"set_remainder": True},
|
|
2332
|
+
"nft": {"set_remainder": True},
|
|
2333
|
+
},
|
|
2334
|
+
),
|
|
2335
|
+
WalletStateTransition(
|
|
2336
|
+
pre_block_balance_updates={},
|
|
2337
|
+
post_block_balance_updates={
|
|
2338
|
+
"xch": {"set_remainder": True},
|
|
2339
|
+
"nft": {"init": True, "set_remainder": True},
|
|
2340
|
+
},
|
|
2341
|
+
),
|
|
2342
|
+
]
|
|
2343
|
+
)
|
|
2146
2344
|
|
|
2147
2345
|
nft_wallet_id_1 = (
|
|
2148
2346
|
await wallet_2_node.wallet_state_manager.get_all_wallet_info_entries(wallet_type=WalletType.NFT)
|
|
@@ -2261,13 +2459,19 @@ async def _check_delete_key(
|
|
|
2261
2459
|
assert resp.used_for_pool_rewards is False
|
|
2262
2460
|
|
|
2263
2461
|
|
|
2462
|
+
@pytest.mark.parametrize(
|
|
2463
|
+
"wallet_environments",
|
|
2464
|
+
[{"num_environments": 1, "blocks_needed": [1]}],
|
|
2465
|
+
indirect=True,
|
|
2466
|
+
)
|
|
2467
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2264
2468
|
@pytest.mark.anyio
|
|
2265
|
-
async def test_key_and_address_endpoints(
|
|
2266
|
-
env
|
|
2469
|
+
async def test_key_and_address_endpoints(wallet_environments: WalletTestFramework) -> None:
|
|
2470
|
+
env = wallet_environments.environments[0]
|
|
2267
2471
|
|
|
2268
|
-
wallet: Wallet = env.
|
|
2269
|
-
wallet_node: WalletNode = env.
|
|
2270
|
-
client: WalletRpcClient = env.
|
|
2472
|
+
wallet: Wallet = env.xch_wallet
|
|
2473
|
+
wallet_node: WalletNode = env.node
|
|
2474
|
+
client: WalletRpcClient = env.rpc_client
|
|
2271
2475
|
|
|
2272
2476
|
address = (await client.get_next_address(GetNextAddress(uint32(1), True))).address
|
|
2273
2477
|
assert len(address) > 10
|
|
@@ -2275,18 +2479,17 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
|
|
|
2275
2479
|
pks = (await client.get_public_keys()).pk_fingerprints
|
|
2276
2480
|
assert len(pks) == 1
|
|
2277
2481
|
|
|
2278
|
-
await generate_funds(env.full_node.api, env.wallet_1)
|
|
2279
|
-
|
|
2280
2482
|
assert (await client.get_height_info()).height > 0
|
|
2281
2483
|
|
|
2282
|
-
async with wallet.wallet_state_manager.new_action_scope(
|
|
2484
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
2283
2485
|
ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
|
|
2486
|
+
await wallet_environments.full_node.wait_for_wallet_synced(wallet_node)
|
|
2284
2487
|
addr = encode_puzzle_hash(ph, "txch")
|
|
2285
2488
|
tx_amount = uint64(15600000)
|
|
2286
|
-
await env.full_node.api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
|
|
2287
2489
|
created_tx = (
|
|
2288
2490
|
await client.send_transaction(
|
|
2289
|
-
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True),
|
|
2491
|
+
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True),
|
|
2492
|
+
wallet_environments.tx_config,
|
|
2290
2493
|
)
|
|
2291
2494
|
).transaction
|
|
2292
2495
|
|
|
@@ -2340,7 +2543,9 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
|
|
|
2340
2543
|
assert delete_key_resp.used_for_farmer_rewards is False
|
|
2341
2544
|
assert delete_key_resp.used_for_pool_rewards is False
|
|
2342
2545
|
|
|
2546
|
+
assert get_wallet_db_path(wallet_node.root_path, wallet_node.config, str(pks[0])).exists()
|
|
2343
2547
|
await client.delete_key(DeleteKey(pks[0]))
|
|
2548
|
+
assert not get_wallet_db_path(wallet_node.root_path, wallet_node.config, str(pks[0])).exists()
|
|
2344
2549
|
await client.log_in(LogIn(uint32(pks[1])))
|
|
2345
2550
|
assert len((await client.get_public_keys()).pk_fingerprints) == 1
|
|
2346
2551
|
|
|
@@ -2353,28 +2558,46 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
|
|
|
2353
2558
|
with pytest.raises(ValueError):
|
|
2354
2559
|
await client.send_transaction(
|
|
2355
2560
|
SendTransaction(wallet_id=uint32(wallets[0].id), amount=uint64(100), address=addr, push=True),
|
|
2356
|
-
|
|
2561
|
+
wallet_environments.tx_config,
|
|
2357
2562
|
)
|
|
2358
2563
|
|
|
2359
2564
|
# Delete all keys
|
|
2565
|
+
resp = await client.generate_mnemonic()
|
|
2566
|
+
add_key_resp = await client.add_key(AddKey(resp.mnemonic))
|
|
2567
|
+
assert get_wallet_db_path(wallet_node.root_path, wallet_node.config, str(pks[1])).exists()
|
|
2568
|
+
assert get_wallet_db_path(wallet_node.root_path, wallet_node.config, str(add_key_resp.fingerprint)).exists()
|
|
2360
2569
|
await client.delete_all_keys()
|
|
2570
|
+
assert not get_wallet_db_path(wallet_node.root_path, wallet_node.config, str(pks[1])).exists()
|
|
2571
|
+
assert not get_wallet_db_path(wallet_node.root_path, wallet_node.config, str(add_key_resp.fingerprint)).exists()
|
|
2361
2572
|
assert len((await client.get_public_keys()).pk_fingerprints) == 0
|
|
2362
2573
|
|
|
2363
2574
|
|
|
2575
|
+
@pytest.mark.parametrize(
|
|
2576
|
+
"wallet_environments",
|
|
2577
|
+
[{"num_environments": 2, "blocks_needed": [1, 0]}],
|
|
2578
|
+
indirect=True,
|
|
2579
|
+
)
|
|
2580
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2364
2581
|
@pytest.mark.anyio
|
|
2365
|
-
async def test_select_coins_rpc(
|
|
2366
|
-
env
|
|
2582
|
+
async def test_select_coins_rpc(wallet_environments: WalletTestFramework) -> None:
|
|
2583
|
+
env = wallet_environments.environments[0]
|
|
2584
|
+
env_2 = wallet_environments.environments[1]
|
|
2367
2585
|
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
2371
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
2372
|
-
client_2: WalletRpcClient = env.wallet_2.rpc_client
|
|
2586
|
+
env.wallet_aliases = {"xch": 1}
|
|
2587
|
+
env_2.wallet_aliases = {"xch": 1}
|
|
2373
2588
|
|
|
2374
|
-
|
|
2589
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
2590
|
+
client: WalletRpcClient = env.rpc_client
|
|
2591
|
+
client_2: WalletRpcClient = env_2.rpc_client
|
|
2375
2592
|
|
|
2376
|
-
|
|
2377
|
-
|
|
2593
|
+
funds: int = await env.xch_wallet.get_confirmed_balance()
|
|
2594
|
+
|
|
2595
|
+
# since this wallet farms no blocks, this first request will always make a new puzzle hash
|
|
2596
|
+
with wallet_environments.new_puzzle_hashes_allowed():
|
|
2597
|
+
async with wallet_2.wallet_state_manager.new_action_scope(
|
|
2598
|
+
wallet_environments.tx_config, push=True
|
|
2599
|
+
) as action_scope:
|
|
2600
|
+
addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
|
|
2378
2601
|
coin_300: list[Coin]
|
|
2379
2602
|
tx_amounts: list[uint64] = [uint64(1000), uint64(300), uint64(1000), uint64(1000), uint64(10000)]
|
|
2380
2603
|
for tx_amount in tx_amounts:
|
|
@@ -2382,7 +2605,8 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2382
2605
|
# create coins for tests
|
|
2383
2606
|
tx = (
|
|
2384
2607
|
await client.send_transaction(
|
|
2385
|
-
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True),
|
|
2608
|
+
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True),
|
|
2609
|
+
wallet_environments.tx_config,
|
|
2386
2610
|
)
|
|
2387
2611
|
).transaction
|
|
2388
2612
|
spend_bundle = tx.spend_bundle
|
|
@@ -2391,16 +2615,27 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2391
2615
|
if coin.amount == uint64(300):
|
|
2392
2616
|
coin_300 = [coin]
|
|
2393
2617
|
|
|
2394
|
-
await
|
|
2395
|
-
|
|
2396
|
-
|
|
2618
|
+
await wallet_environments.process_pending_states(
|
|
2619
|
+
[
|
|
2620
|
+
WalletStateTransition(
|
|
2621
|
+
pre_block_balance_updates={"xch": {"set_remainder": True}},
|
|
2622
|
+
post_block_balance_updates={"xch": {"set_remainder": True}},
|
|
2623
|
+
),
|
|
2624
|
+
WalletStateTransition(
|
|
2625
|
+
pre_block_balance_updates={},
|
|
2626
|
+
post_block_balance_updates={"xch": {"set_remainder": True}},
|
|
2627
|
+
),
|
|
2628
|
+
]
|
|
2629
|
+
)
|
|
2397
2630
|
|
|
2398
2631
|
# test min coin amount
|
|
2399
2632
|
min_coins_response = await client_2.select_coins(
|
|
2400
2633
|
SelectCoins.from_coin_selection_config(
|
|
2401
2634
|
amount=uint64(1000),
|
|
2402
2635
|
wallet_id=uint32(1),
|
|
2403
|
-
coin_selection_config=
|
|
2636
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2637
|
+
min_coin_amount=uint64(1001)
|
|
2638
|
+
),
|
|
2404
2639
|
)
|
|
2405
2640
|
)
|
|
2406
2641
|
assert len(min_coins_response.coins) == 1
|
|
@@ -2411,7 +2646,7 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2411
2646
|
SelectCoins.from_coin_selection_config(
|
|
2412
2647
|
amount=uint64(2000),
|
|
2413
2648
|
wallet_id=uint32(1),
|
|
2414
|
-
coin_selection_config=
|
|
2649
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2415
2650
|
min_coin_amount=uint64(999), max_coin_amount=uint64(9999)
|
|
2416
2651
|
),
|
|
2417
2652
|
)
|
|
@@ -2425,7 +2660,9 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2425
2660
|
SelectCoins.from_coin_selection_config(
|
|
2426
2661
|
amount=uint64(non_1000_amt),
|
|
2427
2662
|
wallet_id=uint32(1),
|
|
2428
|
-
coin_selection_config=
|
|
2663
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2664
|
+
excluded_coin_amounts=[uint64(1000)]
|
|
2665
|
+
),
|
|
2429
2666
|
)
|
|
2430
2667
|
)
|
|
2431
2668
|
assert len(excluded_amt_coins_response.coins) == len([a for a in tx_amounts if a != 1000])
|
|
@@ -2437,7 +2674,7 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2437
2674
|
SelectCoins.from_coin_selection_config(
|
|
2438
2675
|
amount=uint64(5000),
|
|
2439
2676
|
wallet_id=uint32(1),
|
|
2440
|
-
coin_selection_config=
|
|
2677
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2441
2678
|
excluded_coin_ids=[c.name() for c in min_coins_response.coins]
|
|
2442
2679
|
),
|
|
2443
2680
|
)
|
|
@@ -2446,7 +2683,7 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2446
2683
|
SelectCoins.from_coin_selection_config(
|
|
2447
2684
|
amount=uint64(1300),
|
|
2448
2685
|
wallet_id=uint32(1),
|
|
2449
|
-
coin_selection_config=
|
|
2686
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2450
2687
|
excluded_coin_ids=[c.name() for c in coin_300]
|
|
2451
2688
|
),
|
|
2452
2689
|
)
|
|
@@ -2474,7 +2711,7 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2474
2711
|
spendable_coins_response = await client_2.get_spendable_coins(
|
|
2475
2712
|
GetSpendableCoins.from_coin_selection_config(
|
|
2476
2713
|
wallet_id=uint32(1),
|
|
2477
|
-
coin_selection_config=
|
|
2714
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2478
2715
|
excluded_coin_ids=[c.name() for c in excluded_amt_coins_response.coins]
|
|
2479
2716
|
),
|
|
2480
2717
|
),
|
|
@@ -2488,14 +2725,18 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2488
2725
|
spendable_coins_response = await client_2.get_spendable_coins(
|
|
2489
2726
|
GetSpendableCoins.from_coin_selection_config(
|
|
2490
2727
|
wallet_id=uint32(1),
|
|
2491
|
-
coin_selection_config=
|
|
2728
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2729
|
+
excluded_coin_amounts=[uint64(1000)]
|
|
2730
|
+
),
|
|
2492
2731
|
)
|
|
2493
2732
|
)
|
|
2494
2733
|
assert len([rec for rec in spendable_coins_response.confirmed_records if rec.coin.amount == 1000]) == 0
|
|
2495
2734
|
spendable_coins_response = await client_2.get_spendable_coins(
|
|
2496
2735
|
GetSpendableCoins.from_coin_selection_config(
|
|
2497
2736
|
wallet_id=uint32(1),
|
|
2498
|
-
coin_selection_config=
|
|
2737
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2738
|
+
max_coin_amount=uint64(999)
|
|
2739
|
+
),
|
|
2499
2740
|
)
|
|
2500
2741
|
)
|
|
2501
2742
|
assert spendable_coins_response.confirmed_records[0].coin == coin_300[0]
|
|
@@ -2503,16 +2744,24 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
|
|
|
2503
2744
|
await client_2.get_spendable_coins(
|
|
2504
2745
|
GetSpendableCoins.from_coin_selection_config(
|
|
2505
2746
|
wallet_id=uint32(1),
|
|
2506
|
-
coin_selection_config=
|
|
2747
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config.override(
|
|
2748
|
+
excluded_coin_ids=[b"a"]
|
|
2749
|
+
),
|
|
2507
2750
|
)
|
|
2508
2751
|
)
|
|
2509
2752
|
|
|
2510
2753
|
|
|
2754
|
+
@pytest.mark.parametrize(
|
|
2755
|
+
"wallet_environments",
|
|
2756
|
+
[{"num_environments": 1, "blocks_needed": [0], "reuse_puzhash": True, "trusted": True}],
|
|
2757
|
+
indirect=True,
|
|
2758
|
+
)
|
|
2759
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2511
2760
|
@pytest.mark.anyio
|
|
2512
|
-
async def test_get_coin_records_rpc(
|
|
2513
|
-
env
|
|
2514
|
-
wallet_node: WalletNode = env.
|
|
2515
|
-
client: WalletRpcClient = env.
|
|
2761
|
+
async def test_get_coin_records_rpc(wallet_environments: WalletTestFramework) -> None:
|
|
2762
|
+
env = wallet_environments.environments[0]
|
|
2763
|
+
wallet_node: WalletNode = env.node
|
|
2764
|
+
client: WalletRpcClient = env.rpc_client
|
|
2516
2765
|
store = wallet_node.wallet_state_manager.coin_store
|
|
2517
2766
|
|
|
2518
2767
|
for record in [record_1, record_2, record_3, record_4, record_5, record_6, record_7, record_8, record_9]:
|
|
@@ -2521,7 +2770,7 @@ async def test_get_coin_records_rpc(wallet_rpc_environment: WalletRpcTestEnviron
|
|
|
2521
2770
|
async def run_test_case(
|
|
2522
2771
|
test_case: str,
|
|
2523
2772
|
test_request: GetCoinRecords,
|
|
2524
|
-
test_total_count:
|
|
2773
|
+
test_total_count: int | None,
|
|
2525
2774
|
test_records: list[WalletCoinRecord],
|
|
2526
2775
|
) -> None:
|
|
2527
2776
|
response = await client.get_coin_records(test_request)
|
|
@@ -2554,28 +2803,28 @@ async def test_get_coin_records_rpc(wallet_rpc_environment: WalletRpcTestEnviron
|
|
|
2554
2803
|
await run_test_case(f"{name}-{i}", request, expected_total_count, expected_records)
|
|
2555
2804
|
|
|
2556
2805
|
|
|
2806
|
+
@pytest.mark.parametrize(
|
|
2807
|
+
"wallet_environments",
|
|
2808
|
+
[{"num_environments": 1, "blocks_needed": [0], "reuse_puzhash": True, "trusted": True}],
|
|
2809
|
+
indirect=True,
|
|
2810
|
+
)
|
|
2811
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2557
2812
|
@pytest.mark.anyio
|
|
2558
|
-
async def test_get_coin_records_rpc_limits(
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
env: WalletRpcTestEnvironment = wallet_rpc_environment
|
|
2563
|
-
wallet_node: WalletNode = env.wallet_1.node
|
|
2564
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
2565
|
-
rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
|
|
2566
|
-
assert rpc_server is not None
|
|
2567
|
-
api: WalletRpcApi = rpc_server.rpc_api
|
|
2813
|
+
async def test_get_coin_records_rpc_limits(wallet_environments: WalletTestFramework) -> None:
|
|
2814
|
+
env = wallet_environments.environments[0]
|
|
2815
|
+
wallet_node: WalletNode = env.node
|
|
2816
|
+
client: WalletRpcClient = env.rpc_client
|
|
2568
2817
|
store = wallet_node.wallet_state_manager.coin_store
|
|
2569
2818
|
|
|
2570
2819
|
# Adjust the limits for faster testing
|
|
2571
2820
|
WalletRpcApi.max_get_coin_records_limit = uint32(5)
|
|
2572
2821
|
WalletRpcApi.max_get_coin_records_filter_items = uint32(5)
|
|
2573
2822
|
|
|
2574
|
-
max_coins =
|
|
2823
|
+
max_coins = WalletRpcApi.max_get_coin_records_limit * 10
|
|
2575
2824
|
coin_records = [
|
|
2576
2825
|
WalletCoinRecord(
|
|
2577
|
-
Coin(bytes32
|
|
2578
|
-
uint32(
|
|
2826
|
+
Coin(bytes32(bytes([i] * 32)), bytes32(bytes([i] * 32)), uint64(i)),
|
|
2827
|
+
uint32(i),
|
|
2579
2828
|
uint32(0),
|
|
2580
2829
|
False,
|
|
2581
2830
|
False,
|
|
@@ -2584,15 +2833,15 @@ async def test_get_coin_records_rpc_limits(
|
|
|
2584
2833
|
CoinType.NORMAL,
|
|
2585
2834
|
None,
|
|
2586
2835
|
)
|
|
2587
|
-
for
|
|
2836
|
+
for i in range(max_coins)
|
|
2588
2837
|
]
|
|
2589
2838
|
for record in coin_records:
|
|
2590
2839
|
await store.add_coin_record(record)
|
|
2591
2840
|
|
|
2592
|
-
limit =
|
|
2841
|
+
limit = WalletRpcApi.max_get_coin_records_limit
|
|
2593
2842
|
response_records = []
|
|
2594
|
-
for i in range(int(max_coins /
|
|
2595
|
-
offset = uint32(
|
|
2843
|
+
for i in range(int(max_coins / WalletRpcApi.max_get_coin_records_limit)):
|
|
2844
|
+
offset = uint32(WalletRpcApi.max_get_coin_records_limit * i)
|
|
2596
2845
|
response = await client.get_coin_records(GetCoinRecords(limit=limit, offset=offset, include_total_count=True))
|
|
2597
2846
|
response_records.extend(list(response["coin_records"]))
|
|
2598
2847
|
|
|
@@ -2603,7 +2852,7 @@ async def test_get_coin_records_rpc_limits(
|
|
|
2603
2852
|
assert expected_record in response_records
|
|
2604
2853
|
|
|
2605
2854
|
# Request coins with the max number of filter items
|
|
2606
|
-
max_filter_items =
|
|
2855
|
+
max_filter_items = WalletRpcApi.max_get_coin_records_filter_items
|
|
2607
2856
|
filter_records = coin_records[:max_filter_items]
|
|
2608
2857
|
coin_id_filter = HashFilter.include([coin.name() for coin in filter_records])
|
|
2609
2858
|
puzzle_hash_filter = HashFilter.include([coin.coin.puzzle_hash for coin in filter_records])
|
|
@@ -2627,24 +2876,22 @@ async def test_get_coin_records_rpc_limits(
|
|
|
2627
2876
|
assert expected_record in response["coin_records"]
|
|
2628
2877
|
|
|
2629
2878
|
|
|
2879
|
+
@pytest.mark.parametrize(
|
|
2880
|
+
"wallet_environments",
|
|
2881
|
+
[{"num_environments": 1, "blocks_needed": [0], "reuse_puzhash": True, "trusted": True}],
|
|
2882
|
+
indirect=True,
|
|
2883
|
+
)
|
|
2884
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2630
2885
|
@pytest.mark.anyio
|
|
2631
|
-
async def test_get_coin_records_rpc_failures(
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
|
|
2638
|
-
assert rpc_server is not None
|
|
2639
|
-
api = rpc_server.rpc_api
|
|
2640
|
-
|
|
2641
|
-
too_many_hashes = [bytes32.random(seeded_random) for _ in range(api.max_get_coin_records_filter_items + 1)]
|
|
2642
|
-
too_many_amounts = [
|
|
2643
|
-
uint64(uint64(seeded_random.randrange(2**64))) for _ in range(api.max_get_coin_records_filter_items + 1)
|
|
2644
|
-
]
|
|
2886
|
+
async def test_get_coin_records_rpc_failures(wallet_environments: WalletTestFramework) -> None:
|
|
2887
|
+
env = wallet_environments.environments[0]
|
|
2888
|
+
client: WalletRpcClient = env.rpc_client
|
|
2889
|
+
|
|
2890
|
+
too_many_hashes = [bytes32.secret() for i in range(WalletRpcApi.max_get_coin_records_filter_items + 1)]
|
|
2891
|
+
too_many_amounts = [uint64(i) for i in range(WalletRpcApi.max_get_coin_records_filter_items + 1)]
|
|
2645
2892
|
# Run requests which exceeds the allowed limit and contain too much filter items
|
|
2646
2893
|
for name, request in {
|
|
2647
|
-
"limit": GetCoinRecords(limit=uint32(
|
|
2894
|
+
"limit": GetCoinRecords(limit=uint32(WalletRpcApi.max_get_coin_records_limit + 1)),
|
|
2648
2895
|
"coin_id_filter": GetCoinRecords(coin_id_filter=HashFilter.include(too_many_hashes)),
|
|
2649
2896
|
"puzzle_hash_filter": GetCoinRecords(puzzle_hash_filter=HashFilter.include(too_many_hashes)),
|
|
2650
2897
|
"parent_coin_id_filter": GetCoinRecords(parent_coin_id_filter=HashFilter.include(too_many_hashes)),
|
|
@@ -2653,44 +2900,33 @@ async def test_get_coin_records_rpc_failures(
|
|
|
2653
2900
|
with pytest.raises(ValueError, match=name):
|
|
2654
2901
|
await client.get_coin_records(request)
|
|
2655
2902
|
|
|
2656
|
-
# Type validation is handled via `Streamable.from_json_dict` but the below should make at least sure it triggers.
|
|
2657
|
-
for field, value in {
|
|
2658
|
-
"offset": "invalid",
|
|
2659
|
-
"limit": "invalid",
|
|
2660
|
-
"wallet_id": "invalid",
|
|
2661
|
-
"wallet_type": 100,
|
|
2662
|
-
"coin_type": 100,
|
|
2663
|
-
"coin_id_filter": "invalid",
|
|
2664
|
-
"puzzle_hash_filter": "invalid",
|
|
2665
|
-
"parent_coin_id_filter": "invalid",
|
|
2666
|
-
"amount_filter": "invalid",
|
|
2667
|
-
"amount_range": "invalid",
|
|
2668
|
-
"confirmed_range": "invalid",
|
|
2669
|
-
"spent_range": "invalid",
|
|
2670
|
-
"order": 8,
|
|
2671
|
-
}.items():
|
|
2672
|
-
with pytest.raises((ConversionError, InvalidTypeError, ValueError)):
|
|
2673
|
-
json_dict = GetCoinRecords().to_json_dict()
|
|
2674
|
-
json_dict[field] = value
|
|
2675
|
-
await api.get_coin_records(json_dict)
|
|
2676
|
-
|
|
2677
2903
|
|
|
2904
|
+
@pytest.mark.parametrize(
|
|
2905
|
+
"wallet_environments",
|
|
2906
|
+
[
|
|
2907
|
+
{
|
|
2908
|
+
"num_environments": 2,
|
|
2909
|
+
"blocks_needed": [1, 1],
|
|
2910
|
+
"config_overrides": {"enable_notifications": True, "required_notification_amount": 100000000000},
|
|
2911
|
+
}
|
|
2912
|
+
],
|
|
2913
|
+
indirect=True,
|
|
2914
|
+
)
|
|
2915
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2678
2916
|
@pytest.mark.anyio
|
|
2679
|
-
async def test_notification_rpcs(
|
|
2680
|
-
env
|
|
2681
|
-
|
|
2682
|
-
wallet_2: Wallet = env.wallet_2.wallet
|
|
2683
|
-
wallet_node: WalletNode = env.wallet_1.node
|
|
2684
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
2685
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
2686
|
-
client_2: WalletRpcClient = env.wallet_2.rpc_client
|
|
2917
|
+
async def test_notification_rpcs(wallet_environments: WalletTestFramework) -> None:
|
|
2918
|
+
env = wallet_environments.environments[0]
|
|
2919
|
+
env_2 = wallet_environments.environments[1]
|
|
2687
2920
|
|
|
2688
|
-
|
|
2921
|
+
env.wallet_aliases = {"xch": 1}
|
|
2922
|
+
env_2.wallet_aliases = {"xch": 1}
|
|
2689
2923
|
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2924
|
+
wallet_2: Wallet = env_2.xch_wallet
|
|
2925
|
+
client: WalletRpcClient = env.rpc_client
|
|
2926
|
+
client_2: WalletRpcClient = env_2.rpc_client
|
|
2927
|
+
|
|
2928
|
+
async with wallet_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
2929
|
+
await client.send_notification(
|
|
2694
2930
|
SendNotification(
|
|
2695
2931
|
target=(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)),
|
|
2696
2932
|
message=b"hello",
|
|
@@ -2698,18 +2934,29 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
|
|
|
2698
2934
|
fee=uint64(100000000000),
|
|
2699
2935
|
push=True,
|
|
2700
2936
|
),
|
|
2701
|
-
tx_config=
|
|
2937
|
+
tx_config=wallet_environments.tx_config,
|
|
2702
2938
|
)
|
|
2703
2939
|
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2940
|
+
await wallet_environments.process_pending_states(
|
|
2941
|
+
[
|
|
2942
|
+
WalletStateTransition(
|
|
2943
|
+
pre_block_balance_updates={
|
|
2944
|
+
"xch": {"set_remainder": True},
|
|
2945
|
+
},
|
|
2946
|
+
post_block_balance_updates={
|
|
2947
|
+
"xch": {"set_remainder": True},
|
|
2948
|
+
},
|
|
2949
|
+
),
|
|
2950
|
+
WalletStateTransition(
|
|
2951
|
+
pre_block_balance_updates={
|
|
2952
|
+
"xch": {"set_remainder": True},
|
|
2953
|
+
},
|
|
2954
|
+
post_block_balance_updates={
|
|
2955
|
+
"xch": {"set_remainder": True},
|
|
2956
|
+
},
|
|
2957
|
+
),
|
|
2958
|
+
]
|
|
2710
2959
|
)
|
|
2711
|
-
await farm_transaction(full_node_api, wallet_node, response.tx.spend_bundle)
|
|
2712
|
-
await time_out_assert(20, env.wallet_2.wallet.get_confirmed_balance, uint64(100000000000))
|
|
2713
2960
|
|
|
2714
2961
|
notification = (await client_2.get_notifications(GetNotifications())).notifications[0]
|
|
2715
2962
|
assert [notification] == (await client_2.get_notifications(GetNotifications([notification.id]))).notifications
|
|
@@ -2720,8 +2967,8 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
|
|
|
2720
2967
|
await client_2.delete_notifications(DeleteNotifications())
|
|
2721
2968
|
assert [] == (await client_2.get_notifications(GetNotifications([notification.id]))).notifications
|
|
2722
2969
|
|
|
2723
|
-
async with wallet_2.wallet_state_manager.new_action_scope(
|
|
2724
|
-
|
|
2970
|
+
async with wallet_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
2971
|
+
await client.send_notification(
|
|
2725
2972
|
SendNotification(
|
|
2726
2973
|
target=(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)),
|
|
2727
2974
|
message=b"hello",
|
|
@@ -2729,18 +2976,29 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
|
|
|
2729
2976
|
fee=uint64(100000000000),
|
|
2730
2977
|
push=True,
|
|
2731
2978
|
),
|
|
2732
|
-
tx_config=
|
|
2979
|
+
tx_config=wallet_environments.tx_config,
|
|
2733
2980
|
)
|
|
2734
2981
|
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2982
|
+
await wallet_environments.process_pending_states(
|
|
2983
|
+
[
|
|
2984
|
+
WalletStateTransition(
|
|
2985
|
+
pre_block_balance_updates={
|
|
2986
|
+
"xch": {"set_remainder": True},
|
|
2987
|
+
},
|
|
2988
|
+
post_block_balance_updates={
|
|
2989
|
+
"xch": {"set_remainder": True},
|
|
2990
|
+
},
|
|
2991
|
+
),
|
|
2992
|
+
WalletStateTransition(
|
|
2993
|
+
pre_block_balance_updates={
|
|
2994
|
+
"xch": {"set_remainder": True},
|
|
2995
|
+
},
|
|
2996
|
+
post_block_balance_updates={
|
|
2997
|
+
"xch": {"set_remainder": True},
|
|
2998
|
+
},
|
|
2999
|
+
),
|
|
3000
|
+
]
|
|
2741
3001
|
)
|
|
2742
|
-
await farm_transaction(full_node_api, wallet_node, response.tx.spend_bundle)
|
|
2743
|
-
await time_out_assert(20, env.wallet_2.wallet.get_confirmed_balance, uint64(200000000000))
|
|
2744
3002
|
|
|
2745
3003
|
notification = (await client_2.get_notifications(GetNotifications())).notifications[0]
|
|
2746
3004
|
await client_2.delete_notifications(DeleteNotifications([notification.id]))
|
|
@@ -2882,82 +3140,120 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
|
|
|
2882
3140
|
],
|
|
2883
3141
|
)
|
|
2884
3142
|
@pytest.mark.parametrize("prefix_hex_strings", [True, False], ids=["with 0x", "no 0x"])
|
|
3143
|
+
@pytest.mark.parametrize(
|
|
3144
|
+
"wallet_environments",
|
|
3145
|
+
[
|
|
3146
|
+
{
|
|
3147
|
+
"num_environments": 1,
|
|
3148
|
+
"blocks_needed": [1],
|
|
3149
|
+
"reuse_puzhash": True,
|
|
3150
|
+
"trusted": True,
|
|
3151
|
+
}
|
|
3152
|
+
],
|
|
3153
|
+
indirect=True,
|
|
3154
|
+
)
|
|
2885
3155
|
@pytest.mark.anyio
|
|
2886
3156
|
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2887
3157
|
async def test_verify_signature(
|
|
2888
|
-
|
|
3158
|
+
wallet_environments: WalletTestFramework,
|
|
2889
3159
|
rpc_request: dict[str, Any],
|
|
2890
3160
|
rpc_response: VerifySignatureResponse,
|
|
2891
3161
|
prefix_hex_strings: bool,
|
|
2892
3162
|
) -> None:
|
|
2893
|
-
rpc_server = wallet_rpc_environment.wallet_1.service.rpc_server
|
|
2894
|
-
assert rpc_server is not None
|
|
2895
3163
|
updated_request = rpc_request.copy()
|
|
2896
3164
|
updated_request["pubkey"] = ("0x" if prefix_hex_strings else "") + updated_request["pubkey"]
|
|
2897
3165
|
updated_request["signature"] = ("0x" if prefix_hex_strings else "") + updated_request["signature"]
|
|
2898
|
-
res = await
|
|
3166
|
+
res = await wallet_environments.environments[0].rpc_client.verify_signature(
|
|
2899
3167
|
VerifySignature.from_json_dict(updated_request)
|
|
2900
3168
|
)
|
|
2901
3169
|
assert res == rpc_response
|
|
2902
3170
|
|
|
2903
3171
|
|
|
3172
|
+
@pytest.mark.parametrize(
|
|
3173
|
+
"wallet_environments",
|
|
3174
|
+
[
|
|
3175
|
+
{
|
|
3176
|
+
"num_environments": 1,
|
|
3177
|
+
"blocks_needed": [1],
|
|
3178
|
+
"reuse_puzhash": True,
|
|
3179
|
+
"trusted": True,
|
|
3180
|
+
}
|
|
3181
|
+
],
|
|
3182
|
+
indirect=True,
|
|
3183
|
+
)
|
|
2904
3184
|
@pytest.mark.anyio
|
|
2905
3185
|
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2906
|
-
async def
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
await
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
assert has_exception
|
|
2921
|
-
req = {"enabled": False, "batch_size": 0, "min_amount": 100}
|
|
2922
|
-
res = await env.wallet_1.rpc_client.set_auto_claim(
|
|
2923
|
-
AutoClaimSettings(enabled=False, batch_size=uint16(0), min_amount=uint64(100))
|
|
3186
|
+
async def test_sign_message_by_address(wallet_environments: WalletTestFramework) -> None:
|
|
3187
|
+
client: WalletRpcClient = wallet_environments.environments[0].rpc_client
|
|
3188
|
+
|
|
3189
|
+
message = "foo"
|
|
3190
|
+
address = await client.get_next_address(GetNextAddress(uint32(1)))
|
|
3191
|
+
signed_message = await client.sign_message_by_address(SignMessageByAddress(address.address, message))
|
|
3192
|
+
|
|
3193
|
+
await wallet_environments.environments[0].rpc_client.verify_signature(
|
|
3194
|
+
VerifySignature(
|
|
3195
|
+
message=message,
|
|
3196
|
+
pubkey=signed_message.pubkey,
|
|
3197
|
+
signature=signed_message.signature,
|
|
3198
|
+
signing_mode=signed_message.signing_mode,
|
|
3199
|
+
)
|
|
2924
3200
|
)
|
|
2925
|
-
assert not res.enabled
|
|
2926
|
-
assert res.tx_fee == 0
|
|
2927
|
-
assert res.min_amount == 100
|
|
2928
|
-
assert res.batch_size == 50
|
|
2929
3201
|
|
|
2930
3202
|
|
|
2931
|
-
@pytest.mark.
|
|
3203
|
+
@pytest.mark.parametrize(
|
|
3204
|
+
"wallet_environments",
|
|
3205
|
+
[{"num_environments": 2, "blocks_needed": [1, 0]}],
|
|
3206
|
+
indirect=True,
|
|
3207
|
+
)
|
|
2932
3208
|
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
res = await env.wallet_1.rpc_client.get_auto_claim()
|
|
2940
|
-
assert not res.enabled
|
|
2941
|
-
assert res.tx_fee == 0
|
|
2942
|
-
assert res.min_amount == 0
|
|
2943
|
-
assert res.batch_size == 50
|
|
3209
|
+
@pytest.mark.anyio
|
|
3210
|
+
async def test_set_wallet_resync_on_startup(wallet_environments: WalletTestFramework) -> None:
|
|
3211
|
+
env = wallet_environments.environments[0]
|
|
3212
|
+
env_2 = wallet_environments.environments[1]
|
|
3213
|
+
client: WalletRpcClient = env.rpc_client
|
|
3214
|
+
wc = env.rpc_client
|
|
2944
3215
|
|
|
3216
|
+
env.wallet_aliases = {
|
|
3217
|
+
"xch": 1,
|
|
3218
|
+
"did": 2,
|
|
3219
|
+
"nft1": 3,
|
|
3220
|
+
"nft0": 4,
|
|
3221
|
+
}
|
|
2945
3222
|
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
await
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
3223
|
+
await wc.create_new_wallet(
|
|
3224
|
+
CreateNewWallet(
|
|
3225
|
+
wallet_type=CreateNewWalletType.DID_WALLET,
|
|
3226
|
+
did_type=DIDType.NEW,
|
|
3227
|
+
amount=uint64(1),
|
|
3228
|
+
push=True,
|
|
3229
|
+
),
|
|
3230
|
+
tx_config=wallet_environments.tx_config,
|
|
3231
|
+
)
|
|
3232
|
+
|
|
3233
|
+
await wallet_environments.process_pending_states(
|
|
3234
|
+
[
|
|
3235
|
+
WalletStateTransition(
|
|
3236
|
+
pre_block_balance_updates={
|
|
3237
|
+
"xch": {"set_remainder": True},
|
|
3238
|
+
"did": {"init": True, "set_remainder": True},
|
|
3239
|
+
"nft1": {"init": True, "set_remainder": True},
|
|
3240
|
+
},
|
|
3241
|
+
post_block_balance_updates={
|
|
3242
|
+
"xch": {"set_remainder": True},
|
|
3243
|
+
"did": {"set_remainder": True},
|
|
3244
|
+
"nft1": {"set_remainder": True},
|
|
3245
|
+
},
|
|
3246
|
+
),
|
|
3247
|
+
WalletStateTransition(),
|
|
3248
|
+
]
|
|
3249
|
+
)
|
|
3250
|
+
|
|
3251
|
+
nft_wallet_res = await wc.create_new_wallet(
|
|
3252
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, did_id=None, push=True),
|
|
3253
|
+
wallet_environments.tx_config,
|
|
3254
|
+
)
|
|
3255
|
+
nft_wallet_id = nft_wallet_res.wallet_id
|
|
3256
|
+
address = (await wc.get_next_address(GetNextAddress(env.xch_wallet.id(), True))).address
|
|
2961
3257
|
await wc.mint_nft(
|
|
2962
3258
|
request=NFTMintNFTRequest(
|
|
2963
3259
|
wallet_id=nft_wallet_id,
|
|
@@ -2967,14 +3263,31 @@ async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTes
|
|
|
2967
3263
|
uris=["http://test.nft"],
|
|
2968
3264
|
push=True,
|
|
2969
3265
|
),
|
|
2970
|
-
tx_config=
|
|
3266
|
+
tx_config=wallet_environments.tx_config,
|
|
2971
3267
|
)
|
|
2972
|
-
await time_out_assert(5, check_mempool_spend_count, True, full_node_api, 1)
|
|
2973
|
-
await farm_transaction_block(full_node_api, env.wallet_1.node)
|
|
2974
|
-
await time_out_assert(20, check_client_synced, True, wc)
|
|
2975
3268
|
|
|
2976
|
-
|
|
2977
|
-
|
|
3269
|
+
await wallet_environments.process_pending_states(
|
|
3270
|
+
[
|
|
3271
|
+
WalletStateTransition(
|
|
3272
|
+
pre_block_balance_updates={
|
|
3273
|
+
"xch": {"set_remainder": True},
|
|
3274
|
+
"did": {"set_remainder": True},
|
|
3275
|
+
"nft1": {"set_remainder": True},
|
|
3276
|
+
"nft0": {"init": True, "set_remainder": True},
|
|
3277
|
+
},
|
|
3278
|
+
post_block_balance_updates={
|
|
3279
|
+
"xch": {"set_remainder": True},
|
|
3280
|
+
"did": {"set_remainder": True},
|
|
3281
|
+
"nft1": {"set_remainder": True},
|
|
3282
|
+
"nft0": {"set_remainder": True},
|
|
3283
|
+
},
|
|
3284
|
+
),
|
|
3285
|
+
WalletStateTransition(),
|
|
3286
|
+
]
|
|
3287
|
+
)
|
|
3288
|
+
|
|
3289
|
+
wallet_node: WalletNode = env.node
|
|
3290
|
+
wallet_node_2: WalletNode = env_2.node
|
|
2978
3291
|
# Test Clawback resync
|
|
2979
3292
|
tx = (
|
|
2980
3293
|
await wc.send_transaction(
|
|
@@ -2985,21 +3298,57 @@ async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTes
|
|
|
2985
3298
|
puzzle_decorator=[ClawbackPuzzleDecoratorOverride(decorator="CLAWBACK", clawback_timelock=uint64(5))],
|
|
2986
3299
|
push=True,
|
|
2987
3300
|
),
|
|
2988
|
-
tx_config=
|
|
3301
|
+
tx_config=wallet_environments.tx_config,
|
|
2989
3302
|
)
|
|
2990
3303
|
).transaction
|
|
2991
3304
|
clawback_coin_id = tx.additions[0].name()
|
|
2992
|
-
|
|
2993
|
-
await
|
|
2994
|
-
|
|
2995
|
-
|
|
3305
|
+
|
|
3306
|
+
await wallet_environments.process_pending_states(
|
|
3307
|
+
[
|
|
3308
|
+
WalletStateTransition(
|
|
3309
|
+
pre_block_balance_updates={
|
|
3310
|
+
"xch": {"set_remainder": True},
|
|
3311
|
+
"did": {"set_remainder": True},
|
|
3312
|
+
"nft1": {"set_remainder": True},
|
|
3313
|
+
"nft0": {"set_remainder": True},
|
|
3314
|
+
},
|
|
3315
|
+
post_block_balance_updates={
|
|
3316
|
+
"xch": {"set_remainder": True},
|
|
3317
|
+
"did": {"set_remainder": True},
|
|
3318
|
+
"nft1": {"set_remainder": True},
|
|
3319
|
+
"nft0": {"set_remainder": True},
|
|
3320
|
+
},
|
|
3321
|
+
),
|
|
3322
|
+
WalletStateTransition(),
|
|
3323
|
+
]
|
|
3324
|
+
)
|
|
3325
|
+
|
|
2996
3326
|
resp = await wc.spend_clawback_coins(
|
|
2997
|
-
SpendClawbackCoins(coin_ids=[clawback_coin_id], fee=uint64(0), push=True),
|
|
3327
|
+
SpendClawbackCoins(coin_ids=[clawback_coin_id], fee=uint64(0), push=True),
|
|
3328
|
+
tx_config=wallet_environments.tx_config,
|
|
2998
3329
|
)
|
|
2999
3330
|
assert len(resp.transaction_ids) == 1
|
|
3000
|
-
|
|
3001
|
-
await
|
|
3002
|
-
|
|
3331
|
+
|
|
3332
|
+
await wallet_environments.process_pending_states(
|
|
3333
|
+
[
|
|
3334
|
+
WalletStateTransition(
|
|
3335
|
+
pre_block_balance_updates={
|
|
3336
|
+
"xch": {"set_remainder": True},
|
|
3337
|
+
"did": {"set_remainder": True},
|
|
3338
|
+
"nft1": {"set_remainder": True},
|
|
3339
|
+
"nft0": {"set_remainder": True},
|
|
3340
|
+
},
|
|
3341
|
+
post_block_balance_updates={
|
|
3342
|
+
"xch": {"set_remainder": True},
|
|
3343
|
+
"did": {"set_remainder": True},
|
|
3344
|
+
"nft1": {"set_remainder": True},
|
|
3345
|
+
"nft0": {"set_remainder": True},
|
|
3346
|
+
},
|
|
3347
|
+
),
|
|
3348
|
+
WalletStateTransition(),
|
|
3349
|
+
]
|
|
3350
|
+
)
|
|
3351
|
+
|
|
3003
3352
|
wallet_node_2._close()
|
|
3004
3353
|
await wallet_node_2._await_closed()
|
|
3005
3354
|
# set flag to reset wallet sync data on start
|
|
@@ -3044,14 +3393,19 @@ async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTes
|
|
|
3044
3393
|
await wallet_node_2._await_closed()
|
|
3045
3394
|
|
|
3046
3395
|
|
|
3396
|
+
@pytest.mark.parametrize(
|
|
3397
|
+
"wallet_environments",
|
|
3398
|
+
[{"num_environments": 2, "blocks_needed": [1, 0]}],
|
|
3399
|
+
indirect=True,
|
|
3400
|
+
)
|
|
3401
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
3047
3402
|
@pytest.mark.anyio
|
|
3048
|
-
async def test_set_wallet_resync_on_startup_disable(
|
|
3049
|
-
env
|
|
3050
|
-
|
|
3051
|
-
client: WalletRpcClient = env.
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
wallet_node_2: WalletNode = env.wallet_2.node
|
|
3403
|
+
async def test_set_wallet_resync_on_startup_disable(wallet_environments: WalletTestFramework) -> None:
|
|
3404
|
+
env = wallet_environments.environments[0]
|
|
3405
|
+
env_2 = wallet_environments.environments[1]
|
|
3406
|
+
client: WalletRpcClient = env.rpc_client
|
|
3407
|
+
wallet_node: WalletNode = env.node
|
|
3408
|
+
wallet_node_2: WalletNode = env_2.node
|
|
3055
3409
|
wallet_node_2._close()
|
|
3056
3410
|
await wallet_node_2._await_closed()
|
|
3057
3411
|
# set flag to reset wallet sync data on start
|
|
@@ -3083,13 +3437,16 @@ async def test_set_wallet_resync_on_startup_disable(wallet_rpc_environment: Wall
|
|
|
3083
3437
|
await wallet_node_2._await_closed()
|
|
3084
3438
|
|
|
3085
3439
|
|
|
3086
|
-
@pytest.mark.
|
|
3440
|
+
@pytest.mark.parametrize(
|
|
3441
|
+
"wallet_environments",
|
|
3442
|
+
[{"num_environments": 1, "blocks_needed": [0]}],
|
|
3443
|
+
indirect=True,
|
|
3444
|
+
)
|
|
3087
3445
|
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
wallet_node: WalletNode = env.wallet_1.node
|
|
3446
|
+
@pytest.mark.anyio
|
|
3447
|
+
async def test_set_wallet_resync_schema(wallet_environments: WalletTestFramework) -> None:
|
|
3448
|
+
env = wallet_environments.environments[0]
|
|
3449
|
+
wallet_node: WalletNode = env.node
|
|
3093
3450
|
fingerprint = wallet_node.logged_in_fingerprint
|
|
3094
3451
|
assert fingerprint is not None
|
|
3095
3452
|
db_path = wallet_node.wallet_state_manager.db_path
|
|
@@ -3106,21 +3463,30 @@ async def test_set_wallet_resync_schema(wallet_rpc_environment: WalletRpcTestEnv
|
|
|
3106
3463
|
)
|
|
3107
3464
|
|
|
3108
3465
|
|
|
3466
|
+
@pytest.mark.parametrize(
|
|
3467
|
+
"wallet_environments",
|
|
3468
|
+
[{"num_environments": 1, "blocks_needed": [1]}],
|
|
3469
|
+
indirect=True,
|
|
3470
|
+
)
|
|
3471
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
3109
3472
|
@pytest.mark.anyio
|
|
3110
|
-
async def test_cat_spend_run_tail(
|
|
3111
|
-
env
|
|
3473
|
+
async def test_cat_spend_run_tail(wallet_environments: WalletTestFramework) -> None:
|
|
3474
|
+
env = wallet_environments.environments[0]
|
|
3112
3475
|
|
|
3113
|
-
wallet_node: WalletNode = env.
|
|
3114
|
-
client: WalletRpcClient = env.
|
|
3115
|
-
full_node_api: FullNodeSimulator =
|
|
3116
|
-
full_node_rpc: FullNodeRpcClient =
|
|
3476
|
+
wallet_node: WalletNode = env.node
|
|
3477
|
+
client: WalletRpcClient = env.rpc_client
|
|
3478
|
+
full_node_api: FullNodeSimulator = wallet_environments.full_node
|
|
3479
|
+
full_node_rpc: FullNodeRpcClient = wallet_environments.full_node_rpc_client
|
|
3117
3480
|
|
|
3118
|
-
|
|
3481
|
+
env.wallet_aliases = {
|
|
3482
|
+
"xch": 1,
|
|
3483
|
+
"cat": 2,
|
|
3484
|
+
}
|
|
3119
3485
|
|
|
3120
3486
|
# Send to a CAT with an anyone can spend TAIL
|
|
3121
|
-
async with env.
|
|
3122
|
-
our_ph = await action_scope.get_puzzle_hash(env.
|
|
3123
|
-
cat_puzzle: Program = construct_cat_puzzle(CAT_MOD, Program.
|
|
3487
|
+
async with env.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
3488
|
+
our_ph = await action_scope.get_puzzle_hash(env.wallet_state_manager)
|
|
3489
|
+
cat_puzzle: Program = construct_cat_puzzle(CAT_MOD, Program.NIL.get_tree_hash(), Program.to(1))
|
|
3124
3490
|
addr = encode_puzzle_hash(
|
|
3125
3491
|
cat_puzzle.get_tree_hash(),
|
|
3126
3492
|
"txch",
|
|
@@ -3129,15 +3495,25 @@ async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironme
|
|
|
3129
3495
|
|
|
3130
3496
|
tx = (
|
|
3131
3497
|
await client.send_transaction(
|
|
3132
|
-
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True),
|
|
3498
|
+
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True),
|
|
3499
|
+
wallet_environments.tx_config,
|
|
3133
3500
|
)
|
|
3134
3501
|
).transaction
|
|
3135
|
-
transaction_id = tx.name
|
|
3136
3502
|
spend_bundle = tx.spend_bundle
|
|
3137
3503
|
assert spend_bundle is not None
|
|
3138
3504
|
|
|
3139
|
-
await
|
|
3140
|
-
|
|
3505
|
+
await wallet_environments.process_pending_states(
|
|
3506
|
+
[
|
|
3507
|
+
WalletStateTransition(
|
|
3508
|
+
pre_block_balance_updates={
|
|
3509
|
+
"xch": {"set_remainder": True},
|
|
3510
|
+
},
|
|
3511
|
+
post_block_balance_updates={
|
|
3512
|
+
"xch": {"set_remainder": True},
|
|
3513
|
+
},
|
|
3514
|
+
)
|
|
3515
|
+
]
|
|
3516
|
+
)
|
|
3141
3517
|
|
|
3142
3518
|
# Do the eve spend back to our wallet
|
|
3143
3519
|
cat_coin = next(c for c in spend_bundle.additions() if c.amount == tx_amount)
|
|
@@ -3165,10 +3541,26 @@ async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironme
|
|
|
3165
3541
|
await farm_transaction(full_node_api, wallet_node, eve_spend)
|
|
3166
3542
|
|
|
3167
3543
|
# Make sure we have the CAT
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3544
|
+
create_wallet_res = await client.create_new_wallet(
|
|
3545
|
+
CreateNewWallet(
|
|
3546
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
3547
|
+
mode=WalletCreationMode.EXISTING,
|
|
3548
|
+
asset_id=Program.to(None).get_tree_hash(),
|
|
3549
|
+
push=True,
|
|
3550
|
+
),
|
|
3551
|
+
tx_config=wallet_environments.tx_config,
|
|
3552
|
+
)
|
|
3553
|
+
cat_wallet_id = create_wallet_res.wallet_id
|
|
3554
|
+
await wallet_environments.process_pending_states(
|
|
3555
|
+
[
|
|
3556
|
+
WalletStateTransition(
|
|
3557
|
+
pre_block_balance_updates={
|
|
3558
|
+
"cat": {"init": True, "set_remainder": True},
|
|
3559
|
+
},
|
|
3560
|
+
post_block_balance_updates={},
|
|
3561
|
+
)
|
|
3562
|
+
]
|
|
3563
|
+
)
|
|
3172
3564
|
|
|
3173
3565
|
# Attempt to melt it fully
|
|
3174
3566
|
tx = (
|
|
@@ -3182,40 +3574,89 @@ async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironme
|
|
|
3182
3574
|
tail_solution=b"\x80",
|
|
3183
3575
|
push=True,
|
|
3184
3576
|
),
|
|
3185
|
-
tx_config=
|
|
3577
|
+
tx_config=wallet_environments.tx_config,
|
|
3186
3578
|
)
|
|
3187
3579
|
).transaction
|
|
3188
|
-
transaction_id = tx.name
|
|
3189
|
-
spend_bundle = tx.spend_bundle
|
|
3190
|
-
assert spend_bundle is not None
|
|
3191
|
-
|
|
3192
|
-
await time_out_assert(20, tx_in_mempool, True, client, transaction_id)
|
|
3193
|
-
await farm_transaction(full_node_api, wallet_node, spend_bundle)
|
|
3194
3580
|
|
|
3195
|
-
await
|
|
3581
|
+
await wallet_environments.process_pending_states(
|
|
3582
|
+
[
|
|
3583
|
+
WalletStateTransition(
|
|
3584
|
+
pre_block_balance_updates={
|
|
3585
|
+
"xch": {},
|
|
3586
|
+
"cat": {
|
|
3587
|
+
"unconfirmed_wallet_balance": -tx_amount,
|
|
3588
|
+
"spendable_balance": -tx_amount,
|
|
3589
|
+
"max_send_amount": -tx_amount,
|
|
3590
|
+
"pending_coin_removal_count": 1,
|
|
3591
|
+
},
|
|
3592
|
+
},
|
|
3593
|
+
post_block_balance_updates={
|
|
3594
|
+
"xch": {},
|
|
3595
|
+
"cat": {
|
|
3596
|
+
"confirmed_wallet_balance": -tx_amount,
|
|
3597
|
+
"pending_coin_removal_count": -1,
|
|
3598
|
+
},
|
|
3599
|
+
},
|
|
3600
|
+
)
|
|
3601
|
+
]
|
|
3602
|
+
)
|
|
3196
3603
|
|
|
3197
3604
|
|
|
3605
|
+
@pytest.mark.parametrize(
|
|
3606
|
+
"wallet_environments",
|
|
3607
|
+
[{"num_environments": 1, "blocks_needed": [1]}],
|
|
3608
|
+
indirect=True,
|
|
3609
|
+
)
|
|
3610
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
3198
3611
|
@pytest.mark.anyio
|
|
3199
|
-
async def test_get_balances(
|
|
3200
|
-
env
|
|
3201
|
-
|
|
3202
|
-
client: WalletRpcClient = env.wallet_1.rpc_client
|
|
3203
|
-
wallet_node: WalletNode = env.wallet_1.node
|
|
3204
|
-
|
|
3205
|
-
full_node_api: FullNodeSimulator = env.full_node.api
|
|
3612
|
+
async def test_get_balances(wallet_environments: WalletTestFramework) -> None:
|
|
3613
|
+
env = wallet_environments.environments[0]
|
|
3614
|
+
client: WalletRpcClient = env.rpc_client
|
|
3206
3615
|
|
|
3207
|
-
|
|
3616
|
+
env.wallet_aliases = {
|
|
3617
|
+
"xch": 1,
|
|
3618
|
+
"cat": 2,
|
|
3619
|
+
"cat2": 3,
|
|
3620
|
+
}
|
|
3208
3621
|
|
|
3209
|
-
await time_out_assert(20, check_client_synced, True, client)
|
|
3210
3622
|
# Creates a CAT wallet with 100 mojos and a CAT with 20 mojos
|
|
3211
|
-
await client.
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3623
|
+
await client.create_new_wallet(
|
|
3624
|
+
CreateNewWallet(
|
|
3625
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
3626
|
+
mode=WalletCreationMode.NEW,
|
|
3627
|
+
amount=uint64(100),
|
|
3628
|
+
test=True,
|
|
3629
|
+
push=True,
|
|
3630
|
+
),
|
|
3631
|
+
tx_config=wallet_environments.tx_config,
|
|
3632
|
+
)
|
|
3633
|
+
await client.create_new_wallet(
|
|
3634
|
+
CreateNewWallet(
|
|
3635
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
3636
|
+
mode=WalletCreationMode.NEW,
|
|
3637
|
+
amount=uint64(20),
|
|
3638
|
+
test=True,
|
|
3639
|
+
push=True,
|
|
3640
|
+
),
|
|
3641
|
+
tx_config=wallet_environments.tx_config,
|
|
3642
|
+
)
|
|
3643
|
+
await wallet_environments.process_pending_states(
|
|
3644
|
+
[
|
|
3645
|
+
WalletStateTransition(
|
|
3646
|
+
pre_block_balance_updates={
|
|
3647
|
+
"xch": {"set_remainder": True},
|
|
3648
|
+
"cat": {"init": True, "set_remainder": True},
|
|
3649
|
+
"cat2": {"init": True, "set_remainder": True},
|
|
3650
|
+
},
|
|
3651
|
+
post_block_balance_updates={
|
|
3652
|
+
"xch": {"set_remainder": True},
|
|
3653
|
+
"cat": {"set_remainder": True},
|
|
3654
|
+
"cat2": {"set_remainder": True},
|
|
3655
|
+
},
|
|
3656
|
+
),
|
|
3657
|
+
WalletStateTransition(),
|
|
3658
|
+
]
|
|
3659
|
+
)
|
|
3219
3660
|
bals_response = await client.get_wallet_balances(GetWalletBalances())
|
|
3220
3661
|
assert len(bals_response.wallet_balances) == 3
|
|
3221
3662
|
assert bals_response.wallet_balances[uint32(1)].confirmed_wallet_balance == 1999999999880
|
|
@@ -3265,9 +3706,12 @@ async def test_split_coins(wallet_environments: WalletTestFramework, capsys: pyt
|
|
|
3265
3706
|
}
|
|
3266
3707
|
)
|
|
3267
3708
|
|
|
3268
|
-
with pytest.raises(
|
|
3709
|
+
with pytest.raises(ValueError, match="501 coins is greater then the maximum limit of 500 coins"):
|
|
3269
3710
|
await dataclasses.replace(xch_request, number_of_coins=501).run()
|
|
3270
3711
|
|
|
3712
|
+
with pytest.raises(ValueError, match="Cannot split into 0 new coins"):
|
|
3713
|
+
await dataclasses.replace(xch_request, number_of_coins=0).run()
|
|
3714
|
+
|
|
3271
3715
|
with pytest.raises(ResponseFailureError, match="Could not find coin with ID 00000000000000000"):
|
|
3272
3716
|
await dataclasses.replace(xch_request, target_coin_id=bytes32.zeros).run()
|
|
3273
3717
|
|
|
@@ -3298,10 +3742,6 @@ async def test_split_coins(wallet_environments: WalletTestFramework, capsys: pyt
|
|
|
3298
3742
|
|
|
3299
3743
|
del env.wallet_state_manager.wallets[uint32(42)]
|
|
3300
3744
|
|
|
3301
|
-
await dataclasses.replace(xch_request, number_of_coins=0).run()
|
|
3302
|
-
output = (capsys.readouterr()).out
|
|
3303
|
-
assert "Transaction sent" not in output
|
|
3304
|
-
|
|
3305
3745
|
with wallet_environments.new_puzzle_hashes_allowed():
|
|
3306
3746
|
await xch_request.run()
|
|
3307
3747
|
|
|
@@ -3461,13 +3901,13 @@ async def test_combine_coins(wallet_environments: WalletTestFramework, capsys: p
|
|
|
3461
3901
|
)
|
|
3462
3902
|
|
|
3463
3903
|
# Test some error cases first
|
|
3464
|
-
with pytest.raises(
|
|
3904
|
+
with pytest.raises(ValueError, match="greater then the maximum limit"):
|
|
3465
3905
|
await dataclasses.replace(xch_combine_request, number_of_coins=uint16(501)).run()
|
|
3466
3906
|
|
|
3467
|
-
with pytest.raises(
|
|
3907
|
+
with pytest.raises(ValueError, match="You need at least two coins to combine"):
|
|
3468
3908
|
await dataclasses.replace(xch_combine_request, number_of_coins=uint16(0)).run()
|
|
3469
3909
|
|
|
3470
|
-
with pytest.raises(
|
|
3910
|
+
with pytest.raises(ValueError, match="More coin IDs specified than desired number of coins to combine"):
|
|
3471
3911
|
await dataclasses.replace(xch_combine_request, input_coins=(bytes32.zeros,) * 100).run()
|
|
3472
3912
|
|
|
3473
3913
|
# We catch this one
|
|
@@ -3718,3 +4158,339 @@ async def test_fee_bigger_than_selection_coin_combining(wallet_environments: Wal
|
|
|
3718
4158
|
)
|
|
3719
4159
|
]
|
|
3720
4160
|
)
|
|
4161
|
+
|
|
4162
|
+
|
|
4163
|
+
def test_send_transaction_multi_post_init() -> None:
|
|
4164
|
+
with pytest.raises(
|
|
4165
|
+
ValueError,
|
|
4166
|
+
match=re.escape('Specified "morph_bytes" for a CAT-type wallet. Maybe you meant to specify an XCH wallet?'),
|
|
4167
|
+
):
|
|
4168
|
+
SendTransactionMulti(
|
|
4169
|
+
wallet_id=uint32(1),
|
|
4170
|
+
morph_bytes=b"",
|
|
4171
|
+
).convert_to_proxy(CATSpend)
|
|
4172
|
+
|
|
4173
|
+
with pytest.raises(
|
|
4174
|
+
ValueError,
|
|
4175
|
+
match=re.escape(
|
|
4176
|
+
'Specified "coin/puzzle_announcements" for a CAT-type wallet.Maybe you meant to specify an XCH wallet?'
|
|
4177
|
+
),
|
|
4178
|
+
):
|
|
4179
|
+
SendTransactionMulti(
|
|
4180
|
+
wallet_id=uint32(1),
|
|
4181
|
+
coin_announcements=[],
|
|
4182
|
+
).convert_to_proxy(CATSpend)
|
|
4183
|
+
|
|
4184
|
+
with pytest.raises(
|
|
4185
|
+
ValueError,
|
|
4186
|
+
match=re.escape(
|
|
4187
|
+
'Specified "coin/puzzle_announcements" for a CAT-type wallet.Maybe you meant to specify an XCH wallet?'
|
|
4188
|
+
),
|
|
4189
|
+
):
|
|
4190
|
+
SendTransactionMulti(
|
|
4191
|
+
wallet_id=uint32(1),
|
|
4192
|
+
puzzle_announcements=[],
|
|
4193
|
+
).convert_to_proxy(CATSpend)
|
|
4194
|
+
|
|
4195
|
+
with pytest.raises(
|
|
4196
|
+
ValueError,
|
|
4197
|
+
match=re.escape('Specified "amount" for an XCH wallet. Maybe you meant to specify a CAT-type wallet?'),
|
|
4198
|
+
):
|
|
4199
|
+
SendTransactionMulti(
|
|
4200
|
+
wallet_id=uint32(1),
|
|
4201
|
+
amount=uint64(100),
|
|
4202
|
+
).convert_to_proxy(CreateSignedTransaction)
|
|
4203
|
+
|
|
4204
|
+
with pytest.raises(
|
|
4205
|
+
ValueError,
|
|
4206
|
+
match=re.escape('Specified "inner_address" for an XCH wallet. Maybe you meant to specify a CAT-type wallet?'),
|
|
4207
|
+
):
|
|
4208
|
+
SendTransactionMulti(
|
|
4209
|
+
wallet_id=uint32(1),
|
|
4210
|
+
inner_address="foo",
|
|
4211
|
+
).convert_to_proxy(CreateSignedTransaction)
|
|
4212
|
+
|
|
4213
|
+
with pytest.raises(
|
|
4214
|
+
ValueError,
|
|
4215
|
+
match=re.escape('Specified "memos" for an XCH wallet. Maybe you meant to specify a CAT-type wallet?'),
|
|
4216
|
+
):
|
|
4217
|
+
SendTransactionMulti(
|
|
4218
|
+
wallet_id=uint32(1),
|
|
4219
|
+
memos=["foo"],
|
|
4220
|
+
).convert_to_proxy(CreateSignedTransaction)
|
|
4221
|
+
|
|
4222
|
+
with pytest.raises(
|
|
4223
|
+
ValueError,
|
|
4224
|
+
match=re.escape(
|
|
4225
|
+
'Specified "extra_delta", "tail_reveal", or "tail_solution" for an XCH wallet.'
|
|
4226
|
+
"Maybe you meant to specify a CAT-type wallet?"
|
|
4227
|
+
),
|
|
4228
|
+
):
|
|
4229
|
+
SendTransactionMulti(
|
|
4230
|
+
wallet_id=uint32(1),
|
|
4231
|
+
extra_delta="1",
|
|
4232
|
+
).convert_to_proxy(CreateSignedTransaction)
|
|
4233
|
+
|
|
4234
|
+
with pytest.raises(
|
|
4235
|
+
ValueError,
|
|
4236
|
+
match=re.escape(
|
|
4237
|
+
'Specified "extra_delta", "tail_reveal", or "tail_solution" for an XCH wallet.'
|
|
4238
|
+
"Maybe you meant to specify a CAT-type wallet?"
|
|
4239
|
+
),
|
|
4240
|
+
):
|
|
4241
|
+
SendTransactionMulti(
|
|
4242
|
+
wallet_id=uint32(1),
|
|
4243
|
+
tail_reveal=b"",
|
|
4244
|
+
).convert_to_proxy(CreateSignedTransaction)
|
|
4245
|
+
|
|
4246
|
+
with pytest.raises(
|
|
4247
|
+
ValueError,
|
|
4248
|
+
match=re.escape(
|
|
4249
|
+
'Specified "extra_delta", "tail_reveal", or "tail_solution" for an XCH wallet.'
|
|
4250
|
+
"Maybe you meant to specify a CAT-type wallet?"
|
|
4251
|
+
),
|
|
4252
|
+
):
|
|
4253
|
+
SendTransactionMulti(
|
|
4254
|
+
wallet_id=uint32(1),
|
|
4255
|
+
tail_solution=b"",
|
|
4256
|
+
).convert_to_proxy(CreateSignedTransaction)
|
|
4257
|
+
|
|
4258
|
+
with pytest.raises(
|
|
4259
|
+
ValueError,
|
|
4260
|
+
match=re.escape('"additions" are required for XCH wallets.'),
|
|
4261
|
+
):
|
|
4262
|
+
SendTransactionMulti(
|
|
4263
|
+
wallet_id=uint32(1),
|
|
4264
|
+
).convert_to_proxy(CreateSignedTransaction)
|
|
4265
|
+
|
|
4266
|
+
with pytest.raises(
|
|
4267
|
+
ValueError,
|
|
4268
|
+
match=re.escape("An unsupported wallet type was selected for `send_transaction_multi`"),
|
|
4269
|
+
):
|
|
4270
|
+
SendTransactionMulti( # type: ignore[type-var]
|
|
4271
|
+
wallet_id=uint32(1),
|
|
4272
|
+
).convert_to_proxy(VCSpend)
|
|
4273
|
+
|
|
4274
|
+
|
|
4275
|
+
def test_create_new_wallet_post_init() -> None:
|
|
4276
|
+
with pytest.raises(
|
|
4277
|
+
ValueError,
|
|
4278
|
+
match=re.escape("Invalid pool wallet initial state: FOO"),
|
|
4279
|
+
):
|
|
4280
|
+
NewPoolWalletInitialTargetState(state="FOO")
|
|
4281
|
+
|
|
4282
|
+
with pytest.raises(
|
|
4283
|
+
ValueError,
|
|
4284
|
+
match=re.escape("target_puzzle_hash must be set when state is FARMING_TO_POOL"),
|
|
4285
|
+
):
|
|
4286
|
+
NewPoolWalletInitialTargetState(state="FARMING_TO_POOL")
|
|
4287
|
+
|
|
4288
|
+
with pytest.raises(
|
|
4289
|
+
ValueError,
|
|
4290
|
+
match=re.escape("pool_url must be set when state is FARMING_TO_POOL"),
|
|
4291
|
+
):
|
|
4292
|
+
NewPoolWalletInitialTargetState(state="FARMING_TO_POOL", target_puzzle_hash=bytes32.zeros)
|
|
4293
|
+
|
|
4294
|
+
with pytest.raises(
|
|
4295
|
+
ValueError,
|
|
4296
|
+
match=re.escape("relative_lock_height must be set when state is FARMING_TO_POOL"),
|
|
4297
|
+
):
|
|
4298
|
+
NewPoolWalletInitialTargetState(state="FARMING_TO_POOL", target_puzzle_hash=bytes32.zeros, pool_url="")
|
|
4299
|
+
|
|
4300
|
+
with pytest.raises(
|
|
4301
|
+
ValueError,
|
|
4302
|
+
match=re.escape("target_puzzle_hash is only valid for FARMING_TO_POOL"),
|
|
4303
|
+
):
|
|
4304
|
+
NewPoolWalletInitialTargetState(state="SELF_POOLING", target_puzzle_hash=bytes32.zeros)
|
|
4305
|
+
|
|
4306
|
+
with pytest.raises(
|
|
4307
|
+
ValueError,
|
|
4308
|
+
match=re.escape("pool_url is only valid for FARMING_TO_POOL"),
|
|
4309
|
+
):
|
|
4310
|
+
NewPoolWalletInitialTargetState(state="SELF_POOLING", pool_url="")
|
|
4311
|
+
|
|
4312
|
+
with pytest.raises(
|
|
4313
|
+
ValueError,
|
|
4314
|
+
match=re.escape("relative_lock_height is only valid for FARMING_TO_POOL"),
|
|
4315
|
+
):
|
|
4316
|
+
NewPoolWalletInitialTargetState(state="SELF_POOLING", relative_lock_height=uint32(0))
|
|
4317
|
+
|
|
4318
|
+
with pytest.raises(
|
|
4319
|
+
ValueError,
|
|
4320
|
+
match=re.escape('Must specify a "mode" when creating a new CAT wallet'),
|
|
4321
|
+
):
|
|
4322
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.CAT_WALLET)
|
|
4323
|
+
|
|
4324
|
+
with pytest.raises(
|
|
4325
|
+
ValueError,
|
|
4326
|
+
match=re.escape("Support for this RPC mode has been dropped."),
|
|
4327
|
+
):
|
|
4328
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.CAT_WALLET, mode=WalletCreationMode.NEW)
|
|
4329
|
+
|
|
4330
|
+
with pytest.raises(
|
|
4331
|
+
ValueError,
|
|
4332
|
+
match=re.escape('Must specify an "amount" of CATs to generate'),
|
|
4333
|
+
):
|
|
4334
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.CAT_WALLET, mode=WalletCreationMode.NEW, test=True)
|
|
4335
|
+
|
|
4336
|
+
with pytest.raises(
|
|
4337
|
+
ValueError,
|
|
4338
|
+
match=re.escape('"asset_id" is not an argument for new CAT wallets. Maybe you meant existing?'),
|
|
4339
|
+
):
|
|
4340
|
+
CreateNewWallet(
|
|
4341
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
4342
|
+
mode=WalletCreationMode.NEW,
|
|
4343
|
+
test=True,
|
|
4344
|
+
amount=uint64(0),
|
|
4345
|
+
asset_id=bytes32.zeros,
|
|
4346
|
+
)
|
|
4347
|
+
|
|
4348
|
+
with pytest.raises(
|
|
4349
|
+
ValueError,
|
|
4350
|
+
match=re.escape('Must specify an "asset_id" when creating an existing CAT wallet'),
|
|
4351
|
+
):
|
|
4352
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.CAT_WALLET, mode=WalletCreationMode.EXISTING)
|
|
4353
|
+
|
|
4354
|
+
with pytest.raises(
|
|
4355
|
+
ValueError,
|
|
4356
|
+
match=re.escape('"amount" is not an argument for existing CAT wallets'),
|
|
4357
|
+
):
|
|
4358
|
+
CreateNewWallet(
|
|
4359
|
+
wallet_type=CreateNewWalletType.CAT_WALLET,
|
|
4360
|
+
mode=WalletCreationMode.EXISTING,
|
|
4361
|
+
asset_id=bytes32.zeros,
|
|
4362
|
+
amount=uint64(0),
|
|
4363
|
+
)
|
|
4364
|
+
|
|
4365
|
+
with pytest.raises(
|
|
4366
|
+
ValueError,
|
|
4367
|
+
match=re.escape('"test" mode is not supported except for new CAT wallets'),
|
|
4368
|
+
):
|
|
4369
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, test=True)
|
|
4370
|
+
|
|
4371
|
+
with pytest.raises(
|
|
4372
|
+
ValueError,
|
|
4373
|
+
match=re.escape('"asset_id" is not a valid argument. Maybe you meant to create an existing CAT wallet?'),
|
|
4374
|
+
):
|
|
4375
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, asset_id=bytes32.zeros)
|
|
4376
|
+
|
|
4377
|
+
with pytest.raises(
|
|
4378
|
+
ValueError,
|
|
4379
|
+
match=re.escape('"mode": "existing" is only valid for CAT wallets'),
|
|
4380
|
+
):
|
|
4381
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, mode=WalletCreationMode.EXISTING)
|
|
4382
|
+
|
|
4383
|
+
with pytest.raises(
|
|
4384
|
+
ValueError,
|
|
4385
|
+
match=re.escape('Must specify "did_type": "new/recovery"'),
|
|
4386
|
+
):
|
|
4387
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET)
|
|
4388
|
+
|
|
4389
|
+
with pytest.raises(
|
|
4390
|
+
ValueError,
|
|
4391
|
+
match=re.escape('Must specify an "amount" when creating a new DID'),
|
|
4392
|
+
):
|
|
4393
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, did_type=DIDType.NEW)
|
|
4394
|
+
|
|
4395
|
+
with pytest.raises(
|
|
4396
|
+
ValueError,
|
|
4397
|
+
match=re.escape('Recovery options are no longer supported. "backup_dids" cannot be set.'),
|
|
4398
|
+
):
|
|
4399
|
+
CreateNewWallet(
|
|
4400
|
+
wallet_type=CreateNewWalletType.DID_WALLET, did_type=DIDType.NEW, amount=uint64(0), backup_dids=["foo"]
|
|
4401
|
+
)
|
|
4402
|
+
|
|
4403
|
+
with pytest.raises(
|
|
4404
|
+
ValueError,
|
|
4405
|
+
match=re.escape('"backup_data" is only an option in "did_type": "recovery"'),
|
|
4406
|
+
):
|
|
4407
|
+
CreateNewWallet(
|
|
4408
|
+
wallet_type=CreateNewWalletType.DID_WALLET, did_type=DIDType.NEW, amount=uint64(0), backup_data="foo"
|
|
4409
|
+
)
|
|
4410
|
+
|
|
4411
|
+
with pytest.raises(
|
|
4412
|
+
ValueError,
|
|
4413
|
+
match=re.escape('Cannot specify an "amount" when recovering a DID'),
|
|
4414
|
+
):
|
|
4415
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, did_type=DIDType.RECOVERY, amount=uint64(0))
|
|
4416
|
+
|
|
4417
|
+
with pytest.raises(
|
|
4418
|
+
ValueError,
|
|
4419
|
+
match=re.escape('Cannot specify "backup_dids" when recovering a DID'),
|
|
4420
|
+
):
|
|
4421
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, did_type=DIDType.RECOVERY, backup_dids=["foo"])
|
|
4422
|
+
|
|
4423
|
+
with pytest.raises(
|
|
4424
|
+
ValueError,
|
|
4425
|
+
match=re.escape('Cannot specify "metadata" when recovering a DID'),
|
|
4426
|
+
):
|
|
4427
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, did_type=DIDType.RECOVERY, metadata={"foo": "bar"})
|
|
4428
|
+
|
|
4429
|
+
with pytest.raises(
|
|
4430
|
+
ValueError,
|
|
4431
|
+
match=re.escape('Must specify "backup_data" when recovering a DID'),
|
|
4432
|
+
):
|
|
4433
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.DID_WALLET, did_type=DIDType.RECOVERY)
|
|
4434
|
+
|
|
4435
|
+
with pytest.raises(
|
|
4436
|
+
ValueError,
|
|
4437
|
+
match=re.escape('"did_type" is only a valid argument for DID wallets'),
|
|
4438
|
+
):
|
|
4439
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, did_type=DIDType.NEW)
|
|
4440
|
+
|
|
4441
|
+
with pytest.raises(
|
|
4442
|
+
ValueError,
|
|
4443
|
+
match=re.escape('"backup_dids" is only a valid argument for DID wallets'),
|
|
4444
|
+
):
|
|
4445
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, backup_dids=["foo"])
|
|
4446
|
+
|
|
4447
|
+
with pytest.raises(
|
|
4448
|
+
ValueError,
|
|
4449
|
+
match=re.escape('"metadata" is only a valid argument for DID wallets'),
|
|
4450
|
+
):
|
|
4451
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, metadata={"foo": "bar"})
|
|
4452
|
+
|
|
4453
|
+
with pytest.raises(
|
|
4454
|
+
ValueError,
|
|
4455
|
+
match=re.escape('"wallet_name" is only a valid argument for DID wallets'),
|
|
4456
|
+
):
|
|
4457
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, wallet_name="foo")
|
|
4458
|
+
|
|
4459
|
+
with pytest.raises(
|
|
4460
|
+
ValueError,
|
|
4461
|
+
match=re.escape('"backup_data" is only a valid argument for DID wallets'),
|
|
4462
|
+
):
|
|
4463
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, backup_data="foo")
|
|
4464
|
+
|
|
4465
|
+
with pytest.raises(
|
|
4466
|
+
ValueError,
|
|
4467
|
+
match=re.escape('"did_id" is only a valid argument for NFT wallets'),
|
|
4468
|
+
):
|
|
4469
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.POOL_WALLET, did_id="foo")
|
|
4470
|
+
|
|
4471
|
+
with pytest.raises(
|
|
4472
|
+
ValueError,
|
|
4473
|
+
match=re.escape('"initial_target_state" is required for new pool wallets'),
|
|
4474
|
+
):
|
|
4475
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.POOL_WALLET)
|
|
4476
|
+
|
|
4477
|
+
with pytest.raises(
|
|
4478
|
+
ValueError,
|
|
4479
|
+
match=re.escape('"initial_target_state" is only a valid argument for pool wallets'),
|
|
4480
|
+
):
|
|
4481
|
+
CreateNewWallet(
|
|
4482
|
+
wallet_type=CreateNewWalletType.NFT_WALLET,
|
|
4483
|
+
initial_target_state=NewPoolWalletInitialTargetState("SELF_POOLING"),
|
|
4484
|
+
)
|
|
4485
|
+
|
|
4486
|
+
with pytest.raises(
|
|
4487
|
+
ValueError,
|
|
4488
|
+
match=re.escape('"p2_singleton_delayed_ph" is only a valid argument for pool wallets'),
|
|
4489
|
+
):
|
|
4490
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, p2_singleton_delayed_ph=bytes32.zeros)
|
|
4491
|
+
|
|
4492
|
+
with pytest.raises(
|
|
4493
|
+
ValueError,
|
|
4494
|
+
match=re.escape('"p2_singleton_delay_time" is only a valid argument for pool wallets'),
|
|
4495
|
+
):
|
|
4496
|
+
CreateNewWallet(wallet_type=CreateNewWalletType.NFT_WALLET, p2_singleton_delay_time=uint64(0))
|