chia-blockchain 2.5.0rc2__py3-none-any.whl → 2.5.1rc2__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/_tests/README.md +1 -1
- chia/_tests/blockchain/blockchain_test_utils.py +24 -26
- chia/_tests/blockchain/test_augmented_chain.py +6 -8
- chia/_tests/blockchain/test_blockchain.py +409 -307
- chia/_tests/blockchain/test_blockchain_transactions.py +56 -75
- chia/_tests/blockchain/test_build_chains.py +11 -13
- chia/_tests/blockchain/test_get_block_generator.py +8 -8
- chia/_tests/blockchain/test_lookup_fork_chain.py +3 -4
- chia/_tests/build-init-files.py +3 -4
- chia/_tests/build-job-matrix.py +9 -9
- chia/_tests/check_sql_statements.py +2 -3
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +7 -5
- chia/_tests/clvm/test_chialisp_deserialization.py +8 -8
- chia/_tests/clvm/test_condition_codes.py +2 -2
- chia/_tests/clvm/test_curry_and_treehash.py +2 -4
- chia/_tests/clvm/test_message_conditions.py +184 -0
- chia/_tests/clvm/test_puzzle_compression.py +1 -2
- chia/_tests/clvm/test_puzzle_drivers.py +3 -3
- chia/_tests/clvm/test_puzzles.py +13 -18
- chia/_tests/clvm/test_singletons.py +17 -17
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +42 -45
- chia/_tests/cmds/conftest.py +2 -2
- chia/_tests/cmds/test_click_types.py +21 -16
- chia/_tests/cmds/test_cmd_framework.py +255 -35
- chia/_tests/cmds/test_cmds_util.py +2 -2
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_dev_gh.py +131 -0
- chia/_tests/cmds/test_farm_cmd.py +1 -2
- chia/_tests/cmds/test_show.py +6 -6
- chia/_tests/cmds/test_tx_config_args.py +2 -1
- chia/_tests/cmds/wallet/test_dao.py +23 -23
- chia/_tests/cmds/wallet/test_did.py +29 -29
- chia/_tests/cmds/wallet/test_nft.py +24 -23
- chia/_tests/cmds/wallet/test_notifications.py +8 -8
- chia/_tests/cmds/wallet/test_tx_decorators.py +3 -3
- chia/_tests/cmds/wallet/test_vcs.py +97 -73
- chia/_tests/cmds/wallet/test_wallet.py +74 -75
- chia/_tests/cmds/wallet/test_wallet_check.py +5 -7
- chia/_tests/conftest.py +153 -38
- chia/_tests/connection_utils.py +7 -6
- chia/_tests/core/cmds/test_beta.py +3 -3
- chia/_tests/core/cmds/test_keys.py +6 -6
- chia/_tests/core/cmds/test_wallet.py +3 -3
- chia/_tests/core/consensus/test_block_creation.py +3 -5
- chia/_tests/core/custom_types/test_coin.py +1 -3
- chia/_tests/core/custom_types/test_spend_bundle.py +3 -4
- chia/_tests/core/daemon/test_daemon.py +58 -58
- chia/_tests/core/daemon/test_keychain_proxy.py +2 -1
- chia/_tests/core/data_layer/conftest.py +4 -3
- chia/_tests/core/data_layer/test_data_cli.py +1 -2
- chia/_tests/core/data_layer/test_data_layer.py +5 -5
- chia/_tests/core/data_layer/test_data_layer_util.py +8 -9
- chia/_tests/core/data_layer/test_data_rpc.py +75 -93
- chia/_tests/core/data_layer/test_data_store.py +38 -37
- chia/_tests/core/data_layer/test_data_store_schema.py +11 -11
- chia/_tests/core/data_layer/util.py +11 -10
- chia/_tests/core/farmer/test_farmer_api.py +6 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +5 -10
- chia/_tests/core/full_node/ram_db.py +2 -2
- chia/_tests/core/full_node/stores/test_block_store.py +113 -11
- chia/_tests/core/full_node/stores/test_coin_store.py +37 -28
- chia/_tests/core/full_node/stores/test_full_node_store.py +34 -30
- chia/_tests/core/full_node/stores/test_hint_store.py +3 -4
- chia/_tests/core/full_node/test_address_manager.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +1 -1
- chia/_tests/core/full_node/test_conditions.py +10 -12
- chia/_tests/core/full_node/test_full_node.py +2077 -1822
- chia/_tests/core/full_node/test_generator_tools.py +4 -4
- chia/_tests/core/full_node/test_hint_management.py +2 -2
- chia/_tests/core/full_node/test_performance.py +2 -5
- chia/_tests/core/full_node/test_subscriptions.py +4 -4
- chia/_tests/core/full_node/test_tx_processing_queue.py +5 -4
- chia/_tests/core/make_block_generator.py +5 -7
- chia/_tests/core/mempool/test_mempool.py +205 -208
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +5 -5
- chia/_tests/core/mempool/test_mempool_item_queries.py +2 -4
- chia/_tests/core/mempool/test_mempool_manager.py +109 -80
- chia/_tests/core/mempool/test_mempool_performance.py +3 -4
- chia/_tests/core/mempool/test_singleton_fast_forward.py +12 -12
- chia/_tests/core/server/flood.py +6 -4
- chia/_tests/core/server/serve.py +10 -7
- chia/_tests/core/server/test_api_protocol.py +21 -0
- chia/_tests/core/server/test_capabilities.py +3 -5
- chia/_tests/core/server/test_dos.py +15 -16
- chia/_tests/core/server/test_loop.py +14 -10
- chia/_tests/core/server/test_node_discovery.py +1 -2
- chia/_tests/core/server/test_rate_limits.py +156 -44
- chia/_tests/core/server/test_server.py +8 -7
- chia/_tests/core/services/test_services.py +59 -37
- chia/_tests/core/ssl/test_ssl.py +5 -3
- chia/_tests/core/test_cost_calculation.py +5 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_db_conversion.py +5 -4
- chia/_tests/core/test_db_validation.py +6 -5
- chia/_tests/core/test_farmer_harvester_rpc.py +8 -7
- chia/_tests/core/test_filter.py +3 -5
- chia/_tests/core/test_full_node_rpc.py +64 -90
- chia/_tests/core/test_merkle_set.py +10 -10
- chia/_tests/core/test_program.py +2 -4
- chia/_tests/core/test_rpc_util.py +1 -2
- chia/_tests/core/test_seeder.py +124 -12
- chia/_tests/core/util/test_block_cache.py +5 -5
- chia/_tests/core/util/test_cached_bls.py +3 -3
- chia/_tests/core/util/test_config.py +13 -13
- chia/_tests/core/util/test_files.py +2 -2
- chia/_tests/core/util/test_jsonify.py +9 -9
- chia/_tests/core/util/test_keychain.py +13 -5
- chia/_tests/core/util/test_keyring_wrapper.py +6 -5
- chia/_tests/core/util/test_log_exceptions.py +3 -3
- chia/_tests/core/util/test_streamable.py +38 -38
- chia/_tests/db/test_db_wrapper.py +13 -12
- chia/_tests/environments/common.py +2 -2
- chia/_tests/environments/full_node.py +2 -2
- chia/_tests/environments/wallet.py +109 -48
- chia/_tests/farmer_harvester/test_farmer.py +35 -35
- chia/_tests/farmer_harvester/test_farmer_harvester.py +17 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +73 -46
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +8 -8
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +47 -47
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +6 -7
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +11 -11
- chia/_tests/generator/test_compression.py +13 -30
- chia/_tests/generator/test_generator_types.py +3 -3
- chia/_tests/generator/test_rom.py +7 -9
- chia/_tests/plot_sync/test_delta.py +2 -3
- chia/_tests/plot_sync/test_plot_sync.py +25 -24
- chia/_tests/plot_sync/test_receiver.py +9 -9
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +27 -26
- chia/_tests/plot_sync/util.py +2 -1
- chia/_tests/plotting/test_plot_manager.py +54 -11
- chia/_tests/plotting/util.py +2 -3
- chia/_tests/pools/test_pool_cli_parsing.py +128 -0
- chia/_tests/pools/test_pool_cmdline.py +993 -15
- chia/_tests/pools/test_pool_config.py +3 -5
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +10 -11
- chia/_tests/pools/test_pool_rpc.py +203 -90
- chia/_tests/pools/test_pool_wallet.py +12 -8
- chia/_tests/pools/test_wallet_pool_store.py +3 -3
- chia/_tests/process_junit.py +16 -17
- chia/_tests/rpc/test_rpc_client.py +59 -2
- chia/_tests/rpc/test_rpc_server.py +183 -0
- chia/_tests/simulation/test_simulation.py +5 -5
- chia/_tests/simulation/test_simulator.py +8 -10
- chia/_tests/simulation/test_start_simulator.py +5 -4
- chia/_tests/timelord/test_new_peak.py +19 -19
- chia/_tests/tools/test_run_block.py +1 -2
- chia/_tests/tools/test_virtual_project.py +591 -0
- chia/_tests/util/benchmark_cost.py +9 -9
- chia/_tests/util/benchmarks.py +1 -2
- chia/_tests/util/blockchain.py +12 -11
- chia/_tests/util/blockchain_mock.py +15 -15
- chia/_tests/util/build_network_protocol_files.py +12 -12
- chia/_tests/util/db_connection.py +3 -2
- chia/_tests/util/full_sync.py +14 -6
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/generator_tools_testing.py +5 -7
- chia/_tests/util/get_name_puzzle_conditions.py +52 -0
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +59 -106
- chia/_tests/util/network_protocol_data.py +7 -9
- chia/_tests/util/protocol_messages_json.py +112 -111
- chia/_tests/util/rpc.py +3 -0
- chia/_tests/util/run_block.py +16 -16
- chia/_tests/util/setup_nodes.py +25 -23
- chia/{clvm → _tests/util}/spend_sim.py +59 -55
- chia/_tests/util/split_managers.py +12 -9
- chia/_tests/util/temp_file.py +1 -1
- chia/_tests/util/test_action_scope.py +2 -1
- chia/_tests/util/test_async_pool.py +8 -8
- chia/_tests/util/test_build_job_matrix.py +2 -3
- chia/_tests/util/test_condition_tools.py +4 -6
- chia/_tests/util/test_config.py +5 -5
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +19 -11
- chia/_tests/util/test_limited_semaphore.py +4 -3
- chia/_tests/util/test_logging_filter.py +2 -3
- chia/_tests/util/test_misc.py +29 -28
- chia/_tests/util/test_network.py +32 -31
- chia/_tests/util/test_network_protocol_files.py +2 -3
- chia/_tests/util/test_network_protocol_json.py +1 -0
- chia/_tests/util/test_network_protocol_test.py +18 -19
- chia/_tests/util/test_paginator.py +3 -4
- chia/_tests/util/test_pprint.py +1 -1
- chia/_tests/util/test_priority_mutex.py +18 -17
- chia/_tests/util/test_recursive_replace.py +2 -2
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/test_timing.py +1 -1
- chia/_tests/util/test_trusted_peer.py +2 -2
- chia/_tests/util/time_out_assert.py +43 -6
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +117 -29
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +15 -15
- chia/_tests/wallet/cat_wallet/test_trades.py +50 -28
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -5
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +6 -6
- chia/_tests/wallet/clawback/test_clawback_metadata.py +1 -2
- chia/_tests/wallet/conftest.py +135 -74
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +25 -17
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +75 -75
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +10 -12
- chia/_tests/wallet/db_wallet/test_dl_offers.py +6 -6
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +18 -18
- chia/_tests/wallet/did_wallet/test_did.py +1277 -474
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +12 -11
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +115 -105
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +6 -7
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +16 -16
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +3 -3
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +38 -12
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +1 -1
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +31 -33
- chia/_tests/wallet/rpc/test_wallet_rpc.py +218 -171
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +36 -37
- chia/_tests/wallet/sync/test_wallet_sync.py +241 -78
- chia/_tests/wallet/test_address_type.py +20 -20
- chia/_tests/wallet/test_clvm_streamable.py +5 -5
- chia/_tests/wallet/test_coin_management.py +354 -0
- chia/_tests/wallet/test_coin_selection.py +34 -35
- chia/_tests/wallet/test_conditions.py +28 -16
- chia/_tests/wallet/test_debug_spend_bundle.py +156 -14
- chia/_tests/wallet/test_new_wallet_protocol.py +29 -31
- chia/_tests/wallet/test_nft_store.py +1 -2
- chia/_tests/wallet/test_notifications.py +2 -2
- chia/_tests/wallet/test_offer_parsing_performance.py +1 -1
- chia/_tests/wallet/test_puzzle_store.py +2 -3
- chia/_tests/wallet/test_sign_coin_spends.py +3 -3
- chia/_tests/wallet/test_signer_protocol.py +33 -34
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +29 -29
- chia/_tests/wallet/test_taproot.py +1 -1
- chia/_tests/wallet/test_transaction_store.py +23 -19
- chia/_tests/wallet/test_util.py +36 -32
- chia/_tests/wallet/test_wallet.py +37 -37
- chia/_tests/wallet/test_wallet_action_scope.py +8 -8
- chia/_tests/wallet/test_wallet_blockchain.py +4 -6
- chia/_tests/wallet/test_wallet_coin_store.py +34 -34
- chia/_tests/wallet/test_wallet_node.py +69 -72
- chia/_tests/wallet/test_wallet_retry.py +3 -3
- chia/_tests/wallet/test_wallet_state_manager.py +12 -5
- chia/_tests/wallet/test_wallet_trade_store.py +2 -2
- chia/_tests/wallet/test_wallet_utils.py +5 -4
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -3
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +18 -18
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +69 -40
- chia/_tests/wallet/wallet_block_tools.py +27 -27
- chia/_tests/weight_proof/test_weight_proof.py +30 -30
- chia/apis.py +19 -0
- chia/cmds/beta.py +8 -7
- chia/cmds/beta_funcs.py +15 -11
- chia/cmds/check_wallet_db.py +29 -27
- chia/cmds/chia.py +17 -9
- chia/cmds/cmd_classes.py +87 -79
- chia/cmds/cmd_helpers.py +242 -0
- chia/cmds/cmds_util.py +56 -66
- chia/cmds/coin_funcs.py +168 -153
- chia/cmds/coins.py +156 -194
- chia/cmds/configure.py +4 -3
- chia/cmds/dao.py +89 -33
- chia/cmds/dao_funcs.py +55 -33
- chia/cmds/data.py +7 -6
- chia/cmds/data_funcs.py +26 -21
- chia/cmds/db.py +4 -3
- 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.py +2 -0
- chia/cmds/farm.py +18 -5
- chia/cmds/farm_funcs.py +17 -24
- chia/cmds/gh.py +275 -0
- chia/cmds/init.py +4 -11
- chia/cmds/init_funcs.py +9 -9
- chia/cmds/installers.py +5 -3
- chia/cmds/keys.py +56 -39
- chia/cmds/keys_funcs.py +30 -31
- chia/cmds/netspace.py +6 -3
- chia/cmds/netspace_funcs.py +3 -2
- chia/cmds/param_types.py +16 -6
- chia/cmds/passphrase.py +8 -7
- chia/cmds/passphrase_funcs.py +7 -61
- chia/cmds/peer.py +2 -1
- chia/cmds/peer_funcs.py +5 -5
- chia/cmds/plotnft.py +207 -153
- chia/cmds/plotnft_funcs.py +205 -174
- chia/cmds/plots.py +14 -6
- chia/cmds/plotters.py +2 -1
- chia/cmds/rpc.py +48 -28
- chia/cmds/show.py +2 -1
- chia/cmds/show_funcs.py +7 -6
- chia/cmds/signer.py +50 -58
- chia/cmds/sim.py +22 -14
- chia/cmds/sim_funcs.py +11 -11
- chia/cmds/start.py +3 -3
- chia/cmds/start_funcs.py +9 -12
- chia/cmds/stop.py +4 -3
- chia/cmds/units.py +1 -3
- chia/cmds/wallet.py +252 -96
- chia/cmds/wallet_funcs.py +217 -143
- chia/consensus/block_body_validation.py +133 -86
- chia/consensus/block_creation.py +42 -21
- chia/consensus/block_header_validation.py +32 -37
- chia/consensus/block_record.py +1 -2
- chia/consensus/blockchain.py +167 -180
- chia/consensus/blockchain_interface.py +10 -10
- chia/consensus/constants.py +2 -2
- chia/consensus/default_constants.py +3 -4
- chia/consensus/difficulty_adjustment.py +5 -5
- chia/consensus/find_fork_point.py +5 -5
- chia/consensus/full_block_to_block_record.py +4 -4
- chia/consensus/get_block_challenge.py +2 -2
- chia/consensus/get_block_generator.py +4 -3
- chia/consensus/multiprocess_validation.py +207 -304
- chia/consensus/vdf_info_computation.py +3 -3
- chia/daemon/client.py +46 -27
- chia/daemon/keychain_proxy.py +10 -9
- chia/daemon/keychain_server.py +18 -18
- chia/daemon/server.py +103 -113
- chia/daemon/windows_signal.py +2 -2
- chia/data_layer/data_layer.py +64 -76
- chia/data_layer/data_layer_api.py +8 -0
- chia/data_layer/data_layer_errors.py +3 -3
- chia/data_layer/data_layer_server.py +2 -2
- chia/data_layer/data_layer_util.py +71 -71
- chia/data_layer/data_layer_wallet.py +63 -67
- chia/data_layer/data_store.py +72 -72
- chia/data_layer/dl_wallet_store.py +10 -10
- chia/data_layer/download_data.py +5 -5
- chia/data_layer/s3_plugin_service.py +9 -9
- chia/data_layer/util/benchmark.py +0 -1
- chia/data_layer/util/plugin.py +2 -3
- chia/farmer/farmer.py +46 -43
- chia/farmer/farmer_api.py +27 -21
- chia/full_node/block_height_map.py +6 -6
- chia/full_node/block_store.py +41 -35
- chia/full_node/coin_store.py +42 -41
- chia/full_node/fee_estimate.py +2 -2
- chia/full_node/fee_estimation.py +1 -2
- chia/full_node/fee_history.py +5 -6
- chia/full_node/fee_tracker.py +24 -24
- chia/full_node/full_node.py +574 -300
- chia/full_node/full_node_api.py +181 -130
- chia/full_node/full_node_store.py +43 -43
- chia/full_node/hint_management.py +4 -4
- chia/full_node/hint_store.py +9 -10
- chia/full_node/mempool.py +25 -19
- chia/full_node/mempool_check_conditions.py +11 -42
- chia/full_node/mempool_manager.py +48 -53
- chia/full_node/pending_tx_cache.py +9 -9
- chia/full_node/subscriptions.py +23 -24
- chia/full_node/sync_store.py +8 -7
- chia/full_node/tx_processing_queue.py +3 -3
- chia/full_node/util/__init__.py +0 -0
- chia/full_node/weight_proof.py +79 -78
- chia/harvester/harvester.py +9 -8
- chia/harvester/harvester_api.py +19 -13
- chia/introducer/introducer.py +7 -5
- chia/introducer/introducer_api.py +9 -3
- chia/legacy/keyring.py +6 -5
- chia/plot_sync/delta.py +8 -8
- chia/plot_sync/receiver.py +12 -11
- chia/plot_sync/sender.py +15 -12
- chia/plotters/bladebit.py +12 -12
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +8 -8
- chia/plotters/plotters.py +6 -6
- chia/plotters/plotters_util.py +6 -4
- chia/plotting/cache.py +8 -7
- chia/plotting/check_plots.py +8 -8
- chia/plotting/create_plots.py +6 -6
- chia/plotting/manager.py +22 -22
- chia/plotting/util.py +31 -19
- chia/pools/pool_config.py +7 -7
- chia/pools/pool_puzzles.py +16 -16
- chia/pools/pool_wallet.py +64 -57
- chia/pools/pool_wallet_info.py +3 -3
- chia/protocols/full_node_protocol.py +3 -3
- chia/protocols/harvester_protocol.py +12 -12
- chia/protocols/introducer_protocol.py +1 -2
- chia/protocols/protocol_message_types.py +4 -4
- chia/protocols/protocol_state_machine.py +2 -2
- chia/protocols/protocol_timing.py +1 -0
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +2 -2
- chia/protocols/wallet_protocol.py +33 -33
- chia/rpc/crawler_rpc_api.py +12 -7
- chia/rpc/data_layer_rpc_api.py +49 -44
- chia/rpc/data_layer_rpc_client.py +41 -41
- chia/rpc/data_layer_rpc_util.py +7 -11
- chia/rpc/farmer_rpc_api.py +32 -27
- chia/rpc/farmer_rpc_client.py +14 -14
- chia/rpc/full_node_rpc_api.py +53 -48
- chia/rpc/full_node_rpc_client.py +30 -30
- chia/rpc/harvester_rpc_api.py +16 -11
- chia/rpc/harvester_rpc_client.py +6 -6
- chia/rpc/rpc_client.py +34 -14
- chia/rpc/rpc_server.py +117 -43
- chia/rpc/timelord_rpc_api.py +9 -4
- chia/rpc/util.py +11 -211
- chia/rpc/wallet_request_types.py +276 -60
- chia/rpc/wallet_rpc_api.py +563 -399
- chia/rpc/wallet_rpc_client.py +220 -250
- chia/seeder/crawl_store.py +6 -8
- chia/seeder/crawler.py +23 -36
- chia/seeder/crawler_api.py +28 -22
- chia/seeder/dns_server.py +99 -50
- chia/seeder/start_crawler.py +13 -9
- chia/server/address_manager.py +19 -19
- chia/server/address_manager_store.py +17 -17
- chia/server/api_protocol.py +106 -1
- chia/server/capabilities.py +3 -3
- chia/server/chia_policy.py +17 -16
- chia/server/introducer_peers.py +3 -3
- chia/server/node_discovery.py +34 -38
- chia/server/rate_limit_numbers.py +26 -16
- chia/server/rate_limits.py +67 -27
- chia/server/server.py +52 -31
- chia/server/signal_handlers.py +6 -3
- chia/server/ssl_context.py +5 -5
- chia/server/start_data_layer.py +37 -23
- chia/server/start_farmer.py +28 -16
- chia/server/start_full_node.py +29 -23
- chia/server/start_harvester.py +28 -15
- chia/server/start_introducer.py +27 -15
- chia/server/start_service.py +17 -29
- chia/server/start_timelord.py +25 -18
- chia/server/start_wallet.py +22 -18
- chia/server/upnp.py +4 -3
- chia/server/ws_connection.py +68 -54
- chia/simulator/add_blocks_in_batches.py +54 -0
- chia/simulator/block_tools.py +65 -64
- chia/simulator/full_node_simulator.py +66 -74
- chia/simulator/setup_services.py +10 -9
- chia/simulator/simulator_full_node_rpc_api.py +12 -14
- chia/simulator/simulator_full_node_rpc_client.py +3 -5
- chia/simulator/simulator_test_tools.py +8 -7
- chia/simulator/socket.py +1 -4
- chia/simulator/ssl_certs.py +5 -5
- chia/simulator/ssl_certs_1.py +2 -4
- chia/simulator/ssl_certs_10.py +2 -4
- chia/simulator/ssl_certs_2.py +2 -4
- chia/simulator/ssl_certs_3.py +2 -4
- chia/simulator/ssl_certs_4.py +2 -4
- chia/simulator/ssl_certs_5.py +2 -4
- chia/simulator/ssl_certs_6.py +2 -4
- chia/simulator/ssl_certs_7.py +2 -4
- chia/simulator/ssl_certs_8.py +2 -4
- chia/simulator/ssl_certs_9.py +2 -4
- chia/simulator/start_simulator.py +14 -6
- chia/simulator/wallet_tools.py +21 -20
- chia/ssl/create_ssl.py +11 -11
- chia/timelord/iters_from_block.py +2 -2
- chia/timelord/timelord.py +57 -33
- chia/timelord/timelord_api.py +12 -6
- chia/timelord/timelord_launcher.py +10 -8
- chia/timelord/timelord_state.py +5 -5
- chia/types/block_protocol.py +2 -2
- chia/types/blockchain_format/coin.py +3 -3
- chia/types/blockchain_format/program.py +17 -18
- chia/types/blockchain_format/tree_hash.py +9 -9
- chia/types/coin_spend.py +8 -8
- chia/types/condition_with_args.py +1 -2
- chia/types/eligible_coin_spends.py +16 -15
- chia/types/generator_types.py +1 -2
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +7 -7
- chia/types/mempool_submission_status.py +2 -2
- chia/types/peer_info.py +1 -1
- chia/types/spend_bundle.py +1 -2
- chia/types/transaction_queue_entry.py +2 -2
- chia/types/unfinished_header_block.py +2 -2
- chia/types/validation_state.py +14 -0
- chia/types/weight_proof.py +5 -6
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +6 -4
- chia/util/augmented_chain.py +13 -9
- chia/util/batches.py +5 -2
- chia/util/bech32m.py +14 -11
- chia/util/beta_metrics.py +5 -4
- chia/util/block_cache.py +5 -5
- chia/util/byte_types.py +2 -0
- chia/util/check_fork_next_block.py +3 -2
- chia/util/chia_logging.py +41 -21
- chia/util/collection.py +3 -3
- chia/util/condition_tools.py +18 -18
- chia/util/config.py +26 -25
- chia/util/cpu.py +2 -0
- chia/util/db_synchronous.py +2 -0
- chia/util/db_version.py +2 -0
- chia/util/db_wrapper.py +13 -10
- chia/util/default_root.py +17 -0
- chia/util/dump_keyring.py +6 -6
- chia/util/errors.py +5 -3
- chia/util/file_keyring.py +22 -33
- chia/util/files.py +2 -0
- chia/util/full_block_utils.py +31 -7
- chia/util/generator_tools.py +18 -8
- chia/util/hash.py +3 -1
- chia/util/initial-config.yaml +19 -0
- chia/util/inline_executor.py +2 -0
- chia/util/ip_address.py +39 -0
- chia/util/json_util.py +0 -4
- chia/util/keychain.py +27 -24
- chia/util/keyring_wrapper.py +65 -4
- chia/util/limited_semaphore.py +3 -1
- chia/util/lock.py +4 -2
- chia/util/log_exceptions.py +5 -2
- chia/util/logging.py +3 -1
- chia/util/lru_cache.py +2 -0
- chia/util/math.py +4 -4
- chia/util/network.py +15 -73
- chia/util/paginator.py +3 -1
- chia/util/path.py +2 -0
- chia/util/permissions.py +3 -2
- chia/util/prev_transaction_block.py +1 -3
- chia/util/priority_mutex.py +6 -3
- chia/util/profiler.py +7 -4
- chia/util/recursive_replace.py +2 -0
- chia/util/safe_cancel_task.py +2 -0
- chia/util/service_groups.py +2 -2
- chia/util/setproctitle.py +2 -0
- chia/util/significant_bits.py +2 -0
- chia/util/ssl_check.py +11 -11
- chia/util/streamable.py +44 -56
- chia/util/task_referencer.py +59 -0
- chia/util/task_timing.py +22 -18
- chia/util/timing.py +4 -1
- chia/util/vdf_prover.py +2 -3
- chia/util/virtual_project_analysis.py +540 -0
- chia/util/ws_message.py +6 -6
- chia/wallet/cat_wallet/cat_info.py +3 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -3
- chia/wallet/cat_wallet/cat_utils.py +5 -4
- chia/wallet/cat_wallet/cat_wallet.py +56 -70
- chia/wallet/cat_wallet/dao_cat_info.py +3 -3
- chia/wallet/cat_wallet/dao_cat_wallet.py +18 -18
- chia/wallet/cat_wallet/lineage_store.py +2 -2
- chia/wallet/coin_selection.py +15 -15
- chia/wallet/conditions.py +257 -71
- chia/wallet/dao_wallet/dao_info.py +4 -4
- chia/wallet/dao_wallet/dao_utils.py +43 -42
- chia/wallet/dao_wallet/dao_wallet.py +66 -68
- chia/wallet/db_wallet/db_wallet_puzzles.py +12 -8
- chia/wallet/derive_keys.py +11 -11
- chia/wallet/did_wallet/did_info.py +3 -3
- chia/wallet/did_wallet/did_wallet.py +56 -47
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -6
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/nft_info.py +4 -4
- chia/wallet/nft_wallet/nft_puzzles.py +16 -16
- chia/wallet/nft_wallet/nft_wallet.py +90 -89
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/transfer_program_puzzle.py +2 -2
- chia/wallet/nft_wallet/uncurry_nft.py +2 -2
- chia/wallet/notification_manager.py +5 -5
- chia/wallet/notification_store.py +6 -6
- chia/wallet/outer_puzzles.py +2 -2
- chia/wallet/payment.py +4 -5
- chia/wallet/puzzle_drivers.py +4 -4
- chia/wallet/puzzles/clawback/drivers.py +5 -5
- chia/wallet/puzzles/clawback/puzzle_decorator.py +7 -7
- chia/wallet/puzzles/load_clvm.py +2 -3
- chia/wallet/puzzles/p2_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_puzzle.py +2 -3
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -4
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +1 -2
- chia/wallet/puzzles/p2_puzzle_hash.py +1 -2
- chia/wallet/puzzles/puzzle_utils.py +7 -7
- chia/wallet/puzzles/singleton_top_layer.py +6 -5
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +6 -5
- chia/wallet/puzzles/tails.py +34 -30
- chia/wallet/signer_protocol.py +7 -8
- chia/wallet/singleton.py +4 -4
- chia/wallet/trade_manager.py +155 -141
- chia/wallet/trade_record.py +5 -5
- chia/wallet/trading/offer.py +100 -101
- chia/wallet/trading/trade_store.py +14 -14
- chia/wallet/transaction_record.py +31 -16
- chia/wallet/util/address_type.py +4 -4
- chia/wallet/util/blind_signer_tl.py +8 -12
- chia/wallet/util/clvm_streamable.py +15 -15
- chia/wallet/util/compute_hints.py +5 -5
- chia/wallet/util/compute_memos.py +4 -6
- chia/wallet/util/curry_and_treehash.py +3 -2
- chia/wallet/util/debug_spend_bundle.py +6 -8
- chia/wallet/util/merkle_tree.py +10 -10
- chia/wallet/util/merkle_utils.py +10 -10
- chia/wallet/util/new_peak_queue.py +3 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/{util → wallet/util}/pprint.py +2 -3
- chia/wallet/util/puzzle_compression.py +3 -4
- chia/wallet/util/puzzle_decorator.py +10 -10
- chia/wallet/util/query_filter.py +9 -10
- chia/wallet/util/tx_config.py +12 -12
- chia/wallet/util/wallet_sync_utils.py +24 -21
- chia/wallet/util/wallet_types.py +9 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +28 -27
- chia/wallet/vc_wallet/cr_cat_wallet.py +42 -40
- chia/wallet/vc_wallet/cr_outer_puzzle.py +4 -4
- chia/wallet/vc_wallet/vc_drivers.py +16 -16
- chia/wallet/vc_wallet/vc_store.py +9 -9
- chia/wallet/vc_wallet/vc_wallet.py +35 -35
- chia/wallet/wallet.py +54 -54
- chia/wallet/wallet_action_scope.py +14 -13
- chia/wallet/wallet_blockchain.py +10 -10
- chia/wallet/wallet_coin_record.py +2 -2
- chia/wallet/wallet_coin_store.py +10 -10
- chia/wallet/wallet_info.py +1 -2
- chia/wallet/wallet_interested_store.py +5 -5
- chia/wallet/wallet_nft_store.py +6 -6
- chia/wallet/wallet_node.py +72 -76
- chia/wallet/wallet_node_api.py +33 -27
- chia/wallet/wallet_pool_store.py +1 -2
- chia/wallet/wallet_protocol.py +15 -15
- chia/wallet/wallet_puzzle_store.py +35 -4
- chia/wallet/wallet_retry_store.py +2 -2
- chia/wallet/wallet_singleton_store.py +10 -9
- chia/wallet/wallet_spend_bundle.py +4 -20
- chia/wallet/wallet_state_manager.py +223 -224
- chia/wallet/wallet_transaction_store.py +44 -18
- chia/wallet/wallet_user_store.py +2 -2
- chia/wallet/wallet_weight_proof_handler.py +2 -2
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/LICENSE +1 -1
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/METADATA +67 -72
- chia_blockchain-2.5.1rc2.dist-info/RECORD +1042 -0
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/WHEEL +1 -1
- mozilla-ca/cacert.pem +32 -87
- chia/_tests/cmds/wallet/test_coins.py +0 -195
- chia/consensus/block_root_validation.py +0 -46
- chia/util/api_decorators.py +0 -89
- chia_blockchain-2.5.0rc2.dist-info/RECORD +0 -1028
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/entry_points.txt +0 -0
|
@@ -7,23 +7,10 @@ import logging
|
|
|
7
7
|
import multiprocessing.context
|
|
8
8
|
import time
|
|
9
9
|
import traceback
|
|
10
|
+
from collections.abc import AsyncIterator, Iterator
|
|
10
11
|
from contextlib import asynccontextmanager
|
|
11
12
|
from pathlib import Path
|
|
12
|
-
from typing import
|
|
13
|
-
TYPE_CHECKING,
|
|
14
|
-
Any,
|
|
15
|
-
AsyncIterator,
|
|
16
|
-
Callable,
|
|
17
|
-
Dict,
|
|
18
|
-
Iterator,
|
|
19
|
-
List,
|
|
20
|
-
Optional,
|
|
21
|
-
Set,
|
|
22
|
-
Tuple,
|
|
23
|
-
Type,
|
|
24
|
-
TypeVar,
|
|
25
|
-
Union,
|
|
26
|
-
)
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union
|
|
27
14
|
|
|
28
15
|
import aiosqlite
|
|
29
16
|
from chia_rs import AugSchemeMPL, G1Element, G2Element, PrivateKey
|
|
@@ -121,7 +108,7 @@ from chia.wallet.singleton import create_singleton_puzzle, get_inner_puzzle_from
|
|
|
121
108
|
from chia.wallet.trade_manager import TradeManager
|
|
122
109
|
from chia.wallet.trading.offer import Offer
|
|
123
110
|
from chia.wallet.trading.trade_status import TradeStatus
|
|
124
|
-
from chia.wallet.transaction_record import TransactionRecord
|
|
111
|
+
from chia.wallet.transaction_record import LightTransactionRecord, TransactionRecord
|
|
125
112
|
from chia.wallet.uncurried_puzzle import uncurry_puzzle
|
|
126
113
|
from chia.wallet.util.address_type import AddressType
|
|
127
114
|
from chia.wallet.util.compute_hints import compute_spend_hints_and_additions
|
|
@@ -168,10 +155,12 @@ PendingTxCallback = Callable[[], None]
|
|
|
168
155
|
|
|
169
156
|
|
|
170
157
|
class WalletStateManager:
|
|
171
|
-
|
|
172
|
-
|
|
158
|
+
# Ruff thinks these are "mutable class attributes" that should be annotated with `ClassVar`
|
|
159
|
+
# When this is a dataclass, these errors should go away
|
|
160
|
+
interested_ph_cache: dict[bytes32, list[int]] = {} # noqa: RUF012
|
|
161
|
+
interested_coin_cache: dict[bytes32, list[int]] = {} # noqa: RUF012
|
|
173
162
|
constants: ConsensusConstants
|
|
174
|
-
config:
|
|
163
|
+
config: dict[str, Any]
|
|
175
164
|
tx_store: WalletTransactionStore
|
|
176
165
|
puzzle_store: WalletPuzzleStore
|
|
177
166
|
user_store: WalletUserStore
|
|
@@ -193,7 +182,7 @@ class WalletStateManager:
|
|
|
193
182
|
db_wrapper: DBWrapper2
|
|
194
183
|
|
|
195
184
|
main_wallet: Wallet
|
|
196
|
-
wallets:
|
|
185
|
+
wallets: dict[uint32, WalletProtocol[Any]]
|
|
197
186
|
private_key: Optional[PrivateKey]
|
|
198
187
|
root_pubkey: G1Element
|
|
199
188
|
|
|
@@ -209,15 +198,15 @@ class WalletStateManager:
|
|
|
209
198
|
wallet_node: WalletNode
|
|
210
199
|
pool_store: WalletPoolStore
|
|
211
200
|
dl_store: DataLayerStore
|
|
212
|
-
default_cats:
|
|
213
|
-
asset_to_wallet_map:
|
|
201
|
+
default_cats: dict[str, Any]
|
|
202
|
+
asset_to_wallet_map: dict[AssetType, Any]
|
|
214
203
|
initial_num_public_keys: int
|
|
215
204
|
decorator_manager: PuzzleDecoratorManager
|
|
216
205
|
|
|
217
206
|
@staticmethod
|
|
218
207
|
async def create(
|
|
219
208
|
private_key: Optional[PrivateKey],
|
|
220
|
-
config:
|
|
209
|
+
config: dict[str, Any],
|
|
221
210
|
db_path: Path,
|
|
222
211
|
constants: ConsensusConstants,
|
|
223
212
|
server: ChiaServer,
|
|
@@ -392,7 +381,7 @@ class WalletStateManager:
|
|
|
392
381
|
|
|
393
382
|
return self.private_key
|
|
394
383
|
|
|
395
|
-
def get_wallet(self, id: uint32, required_type:
|
|
384
|
+
def get_wallet(self, id: uint32, required_type: type[TWalletType]) -> TWalletType:
|
|
396
385
|
wallet = self.wallets[id]
|
|
397
386
|
if not isinstance(wallet, required_type):
|
|
398
387
|
raise Exception(
|
|
@@ -431,7 +420,7 @@ class WalletStateManager:
|
|
|
431
420
|
|
|
432
421
|
# iterate all wallets that need derived keys and establish the start
|
|
433
422
|
# index for all of them
|
|
434
|
-
start_index_by_wallet:
|
|
423
|
+
start_index_by_wallet: dict[uint32, int] = {}
|
|
435
424
|
last_index = unused + to_generate
|
|
436
425
|
for wallet_id in targets:
|
|
437
426
|
target_wallet = self.wallets[wallet_id]
|
|
@@ -457,8 +446,8 @@ class WalletStateManager:
|
|
|
457
446
|
|
|
458
447
|
# now derive the keysfrom lowest_start_index to last_index
|
|
459
448
|
# these maps derivation index to public key
|
|
460
|
-
hardened_keys:
|
|
461
|
-
unhardened_keys:
|
|
449
|
+
hardened_keys: dict[int, G1Element] = {}
|
|
450
|
+
unhardened_keys: dict[int, G1Element] = {}
|
|
462
451
|
|
|
463
452
|
if self.private_key is not None:
|
|
464
453
|
# Hardened
|
|
@@ -476,7 +465,7 @@ class WalletStateManager:
|
|
|
476
465
|
assert target_wallet.type() != WalletType.POOLING_WALLET
|
|
477
466
|
assert start_index < last_index
|
|
478
467
|
|
|
479
|
-
derivation_paths:
|
|
468
|
+
derivation_paths: list[DerivationRecord] = []
|
|
480
469
|
creating_msg = f"Creating puzzle hashes from {start_index} to {last_index - 1} for wallet_id: {wallet_id}"
|
|
481
470
|
self.log.info(f"Start: {creating_msg}")
|
|
482
471
|
for index in range(start_index, last_index):
|
|
@@ -527,10 +516,10 @@ class WalletStateManager:
|
|
|
527
516
|
await self.puzzle_store.set_used_up_to(uint32(unused - 1))
|
|
528
517
|
|
|
529
518
|
async def update_wallet_puzzle_hashes(self, wallet_id: uint32) -> None:
|
|
530
|
-
derivation_paths:
|
|
519
|
+
derivation_paths: list[DerivationRecord] = []
|
|
531
520
|
target_wallet = self.wallets[wallet_id]
|
|
532
521
|
last: Optional[uint32] = await self.puzzle_store.get_last_derivation_path_for_wallet(wallet_id)
|
|
533
|
-
unused: Optional[uint32] = await self.puzzle_store.
|
|
522
|
+
unused: Optional[uint32] = await self.puzzle_store.get_unused_derivation_path_for_wallet(wallet_id)
|
|
534
523
|
if unused is None:
|
|
535
524
|
# This handles the case where the database has entries but they have all been used
|
|
536
525
|
unused = await self.puzzle_store.get_last_derivation_path()
|
|
@@ -606,14 +595,14 @@ class WalletStateManager:
|
|
|
606
595
|
self.pending_tx_callback = callback
|
|
607
596
|
|
|
608
597
|
def state_changed(
|
|
609
|
-
self, state: str, wallet_id: Optional[int] = None, data_object: Optional[
|
|
598
|
+
self, state: str, wallet_id: Optional[int] = None, data_object: Optional[dict[str, Any]] = None
|
|
610
599
|
) -> None:
|
|
611
600
|
"""
|
|
612
601
|
Calls the callback if it's present.
|
|
613
602
|
"""
|
|
614
603
|
if self.state_changed_callback is None:
|
|
615
604
|
return None
|
|
616
|
-
change_data:
|
|
605
|
+
change_data: dict[str, Any] = {"state": state}
|
|
617
606
|
if wallet_id is not None:
|
|
618
607
|
change_data["wallet_id"] = wallet_id
|
|
619
608
|
if data_object is not None:
|
|
@@ -687,13 +676,13 @@ class WalletStateManager:
|
|
|
687
676
|
self._sync_target = None
|
|
688
677
|
|
|
689
678
|
async def get_confirmed_spendable_balance_for_wallet(
|
|
690
|
-
self, wallet_id: int, unspent_records: Optional[
|
|
679
|
+
self, wallet_id: int, unspent_records: Optional[set[WalletCoinRecord]] = None
|
|
691
680
|
) -> uint128:
|
|
692
681
|
"""
|
|
693
682
|
Returns the balance amount of all coins that are spendable.
|
|
694
683
|
"""
|
|
695
684
|
|
|
696
|
-
spendable:
|
|
685
|
+
spendable: set[WalletCoinRecord] = await self.get_spendable_coins_for_wallet(wallet_id, unspent_records)
|
|
697
686
|
|
|
698
687
|
spendable_amount: uint128 = uint128(0)
|
|
699
688
|
for record in spendable:
|
|
@@ -702,7 +691,7 @@ class WalletStateManager:
|
|
|
702
691
|
return spendable_amount
|
|
703
692
|
|
|
704
693
|
async def does_coin_belong_to_wallet(
|
|
705
|
-
self, coin: Coin, wallet_id: int, hint_dict:
|
|
694
|
+
self, coin: Coin, wallet_id: int, hint_dict: dict[bytes32, bytes32] = {}
|
|
706
695
|
) -> bool:
|
|
707
696
|
"""
|
|
708
697
|
Returns true if we have the key for this coin.
|
|
@@ -713,7 +702,7 @@ class WalletStateManager:
|
|
|
713
702
|
async def get_confirmed_balance_for_wallet(
|
|
714
703
|
self,
|
|
715
704
|
wallet_id: int,
|
|
716
|
-
unspent_coin_records: Optional[
|
|
705
|
+
unspent_coin_records: Optional[set[WalletCoinRecord]] = None,
|
|
717
706
|
) -> uint128:
|
|
718
707
|
"""
|
|
719
708
|
Returns the confirmed balance, including coinbase rewards that are not spendable.
|
|
@@ -728,13 +717,13 @@ class WalletStateManager:
|
|
|
728
717
|
return uint128(sum(cr.coin.amount for cr in unspent_coin_records))
|
|
729
718
|
|
|
730
719
|
async def get_unconfirmed_balance(
|
|
731
|
-
self, wallet_id: int, unspent_coin_records: Optional[
|
|
720
|
+
self, wallet_id: int, unspent_coin_records: Optional[set[WalletCoinRecord]] = None
|
|
732
721
|
) -> uint128:
|
|
733
722
|
"""
|
|
734
723
|
Returns the balance, including coinbase rewards that are not spendable, and unconfirmed
|
|
735
724
|
transactions.
|
|
736
725
|
"""
|
|
737
|
-
# This API should change so that get_balance_from_coin_records is called for
|
|
726
|
+
# This API should change so that get_balance_from_coin_records is called for set[WalletCoinRecord]
|
|
738
727
|
# and this method is called only for the unspent_coin_records==None case.
|
|
739
728
|
if unspent_coin_records is None:
|
|
740
729
|
wallet_type: WalletType = self.wallets[uint32(wallet_id)].type()
|
|
@@ -745,8 +734,8 @@ class WalletStateManager:
|
|
|
745
734
|
else:
|
|
746
735
|
unspent_coin_records = await self.coin_store.get_unspent_coins_for_wallet(wallet_id)
|
|
747
736
|
|
|
748
|
-
unconfirmed_tx:
|
|
749
|
-
all_unspent_coins:
|
|
737
|
+
unconfirmed_tx: list[TransactionRecord] = await self.tx_store.get_unconfirmed_for_wallet(wallet_id)
|
|
738
|
+
all_unspent_coins: set[Coin] = {cr.coin for cr in unspent_coin_records}
|
|
750
739
|
|
|
751
740
|
for record in unconfirmed_tx:
|
|
752
741
|
if record.type in CLAWBACK_INCOMING_TRANSACTION_TYPES:
|
|
@@ -767,11 +756,11 @@ class WalletStateManager:
|
|
|
767
756
|
|
|
768
757
|
return uint128(sum(coin.amount for coin in all_unspent_coins))
|
|
769
758
|
|
|
770
|
-
async def unconfirmed_removals_for_wallet(self, wallet_id: int) ->
|
|
759
|
+
async def unconfirmed_removals_for_wallet(self, wallet_id: int) -> dict[bytes32, Coin]:
|
|
771
760
|
"""
|
|
772
761
|
Returns new removals transactions that have not been confirmed yet.
|
|
773
762
|
"""
|
|
774
|
-
removals:
|
|
763
|
+
removals: dict[bytes32, Coin] = {}
|
|
775
764
|
unconfirmed_tx = await self.tx_store.get_unconfirmed_for_wallet(wallet_id)
|
|
776
765
|
for record in unconfirmed_tx:
|
|
777
766
|
if record.type in CLAWBACK_INCOMING_TRANSACTION_TYPES:
|
|
@@ -779,20 +768,21 @@ class WalletStateManager:
|
|
|
779
768
|
# That is reserved for when the action to actually claw a tx back or forward is initiated.
|
|
780
769
|
continue
|
|
781
770
|
for coin in record.removals:
|
|
782
|
-
|
|
783
|
-
|
|
771
|
+
if coin not in record.additions:
|
|
772
|
+
removals[coin.name()] = coin
|
|
773
|
+
trade_removals: dict[bytes32, WalletCoinRecord] = await self.trade_manager.get_locked_coins()
|
|
784
774
|
return {**removals, **{coin_id: cr.coin for coin_id, cr in trade_removals.items() if cr.wallet_id == wallet_id}}
|
|
785
775
|
|
|
786
776
|
async def determine_coin_type(
|
|
787
777
|
self, peer: WSChiaConnection, coin_state: CoinState, fork_height: Optional[uint32]
|
|
788
|
-
) ->
|
|
778
|
+
) -> tuple[Optional[WalletIdentifier], Optional[Streamable]]:
|
|
789
779
|
if coin_state.created_height is not None and (
|
|
790
780
|
self.is_pool_reward(uint32(coin_state.created_height), coin_state.coin)
|
|
791
781
|
or self.is_farmer_reward(uint32(coin_state.created_height), coin_state.coin)
|
|
792
782
|
):
|
|
793
783
|
return None, None
|
|
794
784
|
|
|
795
|
-
response:
|
|
785
|
+
response: list[CoinState] = await self.wallet_node.get_coin_state(
|
|
796
786
|
[coin_state.coin.parent_coin_info], peer=peer, fork_height=fork_height
|
|
797
787
|
)
|
|
798
788
|
if len(response) == 0:
|
|
@@ -891,7 +881,7 @@ class WalletStateManager:
|
|
|
891
881
|
return await self.handle_clawback(clawback_coin_data, coin_state, coin_spend, peer), clawback_coin_data
|
|
892
882
|
|
|
893
883
|
# Check if the coin is a VC
|
|
894
|
-
is_vc,
|
|
884
|
+
is_vc, _err_msg = VerifiedCredential.is_vc(uncurried)
|
|
895
885
|
if is_vc:
|
|
896
886
|
vc: VerifiedCredential = VerifiedCredential.get_next_from_coin_spend(coin_spend)
|
|
897
887
|
return await self.handle_vc(vc), vc
|
|
@@ -903,7 +893,7 @@ class WalletStateManager:
|
|
|
903
893
|
async def auto_claim_coins(self) -> None:
|
|
904
894
|
# Get unspent clawback coin
|
|
905
895
|
current_timestamp = self.blockchain.get_latest_timestamp()
|
|
906
|
-
clawback_coins:
|
|
896
|
+
clawback_coins: dict[Coin, ClawbackMetadata] = {}
|
|
907
897
|
tx_fee = uint64(self.config.get("auto_claim", {}).get("tx_fee", 0))
|
|
908
898
|
assert self.wallet_node.logged_in_fingerprint is not None
|
|
909
899
|
tx_config_loader: TXConfigLoader = TXConfigLoader.from_json_dict(self.config.get("auto_claim", {}))
|
|
@@ -936,22 +926,6 @@ class WalletStateManager:
|
|
|
936
926
|
clawback_coins[coin.coin] = metadata
|
|
937
927
|
if len(clawback_coins) >= self.config.get("auto_claim", {}).get("batch_size", 50):
|
|
938
928
|
await self.spend_clawback_coins(clawback_coins, tx_fee, action_scope)
|
|
939
|
-
async with action_scope.use() as interface:
|
|
940
|
-
# TODO: editing this is not ideal, action scopes should know what coins are spent
|
|
941
|
-
action_scope._config = dataclasses.replace(
|
|
942
|
-
action_scope._config,
|
|
943
|
-
tx_config=dataclasses.replace(
|
|
944
|
-
action_scope._config.tx_config,
|
|
945
|
-
excluded_coin_ids=[
|
|
946
|
-
*action_scope.config.tx_config.excluded_coin_ids,
|
|
947
|
-
*(
|
|
948
|
-
c.name()
|
|
949
|
-
for tx in interface.side_effects.transactions
|
|
950
|
-
for c in tx.removals
|
|
951
|
-
),
|
|
952
|
-
],
|
|
953
|
-
),
|
|
954
|
-
)
|
|
955
929
|
clawback_coins = {}
|
|
956
930
|
except Exception as e:
|
|
957
931
|
self.log.error(f"Failed to claim clawback coin {coin.coin.name().hex()}: %s", e)
|
|
@@ -960,14 +934,14 @@ class WalletStateManager:
|
|
|
960
934
|
|
|
961
935
|
async def spend_clawback_coins(
|
|
962
936
|
self,
|
|
963
|
-
clawback_coins:
|
|
937
|
+
clawback_coins: dict[Coin, ClawbackMetadata],
|
|
964
938
|
fee: uint64,
|
|
965
939
|
action_scope: WalletActionScope,
|
|
966
940
|
force: bool = False,
|
|
967
|
-
extra_conditions:
|
|
941
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
968
942
|
) -> None:
|
|
969
943
|
assert len(clawback_coins) > 0
|
|
970
|
-
coin_spends:
|
|
944
|
+
coin_spends: list[CoinSpend] = []
|
|
971
945
|
message: bytes32 = std_hash(b"".join([c.name() for c in clawback_coins.keys()]))
|
|
972
946
|
now: uint64 = uint64(int(time.time()))
|
|
973
947
|
derivation_record: Optional[DerivationRecord] = None
|
|
@@ -994,7 +968,7 @@ class WalletStateManager:
|
|
|
994
968
|
assert derivation_record is not None
|
|
995
969
|
amount = uint64(amount + coin.amount)
|
|
996
970
|
# Remove the clawback hint since it is unnecessary for the XCH coin
|
|
997
|
-
memos:
|
|
971
|
+
memos: list[bytes] = [] if len(incoming_tx.memos) == 0 else incoming_tx.memos[0][1][1:]
|
|
998
972
|
inner_puzzle: Program = self.main_wallet.puzzle_for_pk(derivation_record.pubkey)
|
|
999
973
|
inner_solution: Program = self.main_wallet.make_solution(
|
|
1000
974
|
primaries=[
|
|
@@ -1021,20 +995,29 @@ class WalletStateManager:
|
|
|
1021
995
|
spend_bundle = WalletSpendBundle(coin_spends, G2Element())
|
|
1022
996
|
if fee > 0:
|
|
1023
997
|
async with self.new_action_scope(action_scope.config.tx_config, push=False) as inner_action_scope:
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
998
|
+
async with action_scope.use() as interface:
|
|
999
|
+
async with inner_action_scope.use() as inner_interface:
|
|
1000
|
+
inner_interface.side_effects.selected_coins = interface.side_effects.selected_coins
|
|
1001
|
+
await self.main_wallet.create_tandem_xch_tx(
|
|
1002
|
+
fee,
|
|
1003
|
+
inner_action_scope,
|
|
1004
|
+
extra_conditions=(
|
|
1005
|
+
AssertCoinAnnouncement(asserted_id=coin_spends[0].coin.name(), asserted_msg=message),
|
|
1006
|
+
),
|
|
1007
|
+
)
|
|
1008
|
+
async with inner_action_scope.use() as inner_interface:
|
|
1009
|
+
# This should not be looked to for best practice.
|
|
1010
|
+
# Ideally, the two spend bundles can exist separately on each tx record until they are pushed.
|
|
1011
|
+
# This is not very supported behavior at the moment
|
|
1012
|
+
# so to avoid any potential backwards compatibility issues,
|
|
1013
|
+
# we're moving the spend bundle from this TX to the main
|
|
1014
|
+
interface.side_effects.transactions.extend(
|
|
1015
|
+
[
|
|
1016
|
+
dataclasses.replace(tx, spend_bundle=None)
|
|
1017
|
+
for tx in inner_interface.side_effects.transactions
|
|
1018
|
+
]
|
|
1019
|
+
)
|
|
1020
|
+
interface.side_effects.selected_coins.extend(inner_interface.side_effects.selected_coins)
|
|
1038
1021
|
spend_bundle = WalletSpendBundle.aggregate(
|
|
1039
1022
|
[
|
|
1040
1023
|
spend_bundle,
|
|
@@ -1068,7 +1051,7 @@ class WalletStateManager:
|
|
|
1068
1051
|
async with action_scope.use() as interface:
|
|
1069
1052
|
interface.side_effects.transactions.append(tx_record)
|
|
1070
1053
|
|
|
1071
|
-
async def filter_spam(self, new_coin_state:
|
|
1054
|
+
async def filter_spam(self, new_coin_state: list[CoinState]) -> list[CoinState]:
|
|
1072
1055
|
xch_spam_amount = self.config.get("xch_spam_amount", 1000000)
|
|
1073
1056
|
|
|
1074
1057
|
# No need to filter anything if the filter is set to 1 or 0 mojos
|
|
@@ -1079,8 +1062,8 @@ class WalletStateManager:
|
|
|
1079
1062
|
small_unspent_count = await self.coin_store.count_small_unspent(xch_spam_amount)
|
|
1080
1063
|
|
|
1081
1064
|
# if small_unspent_count > spam_filter_after_n_txs:
|
|
1082
|
-
filtered_cs:
|
|
1083
|
-
is_standard_wallet_phs:
|
|
1065
|
+
filtered_cs: list[CoinState] = []
|
|
1066
|
+
is_standard_wallet_phs: set[bytes32] = set()
|
|
1084
1067
|
|
|
1085
1068
|
for cs in new_coin_state:
|
|
1086
1069
|
# Only apply filter to new coins being sent to our wallet, that are very small
|
|
@@ -1113,7 +1096,7 @@ class WalletStateManager:
|
|
|
1113
1096
|
"""
|
|
1114
1097
|
Handle the new coin when it is a DAO CAT
|
|
1115
1098
|
"""
|
|
1116
|
-
|
|
1099
|
+
_mod_hash, tail_hash, _inner_puzzle = curried_args
|
|
1117
1100
|
asset_id: bytes32 = bytes32(bytes(tail_hash)[1:])
|
|
1118
1101
|
for wallet in self.wallets.values():
|
|
1119
1102
|
if wallet.type() == WalletType.DAO_CAT:
|
|
@@ -1278,7 +1261,7 @@ class WalletStateManager:
|
|
|
1278
1261
|
and launch_id == wallet.did_info.origin_coin.name()
|
|
1279
1262
|
and not wallet.did_info.sent_recovery_transaction
|
|
1280
1263
|
):
|
|
1281
|
-
await self.
|
|
1264
|
+
await self.delete_wallet(wallet.id())
|
|
1282
1265
|
removed_wallet_ids.append(wallet.id())
|
|
1283
1266
|
for remove_id in removed_wallet_ids:
|
|
1284
1267
|
self.wallets.pop(remove_id)
|
|
@@ -1313,34 +1296,44 @@ class WalletStateManager:
|
|
|
1313
1296
|
self.log.error("DID puzzle hash doesn't match, please check curried parameters.")
|
|
1314
1297
|
return None
|
|
1315
1298
|
# Create DID wallet
|
|
1316
|
-
response:
|
|
1299
|
+
response: list[CoinState] = await self.wallet_node.get_coin_state([launch_id], peer=peer)
|
|
1317
1300
|
if len(response) == 0:
|
|
1318
1301
|
self.log.warning(f"Could not find the launch coin with ID: {launch_id}")
|
|
1319
1302
|
return None
|
|
1320
1303
|
launch_coin: CoinState = response[0]
|
|
1321
1304
|
origin_coin = launch_coin.coin
|
|
1322
1305
|
|
|
1306
|
+
did_wallet_count = 0
|
|
1323
1307
|
for wallet in self.wallets.values():
|
|
1324
1308
|
if wallet.type() == WalletType.DECENTRALIZED_ID:
|
|
1325
1309
|
assert isinstance(wallet, DIDWallet)
|
|
1326
1310
|
assert wallet.did_info.origin_coin is not None
|
|
1327
1311
|
if origin_coin.name() == wallet.did_info.origin_coin.name():
|
|
1328
1312
|
return WalletIdentifier.create(wallet)
|
|
1313
|
+
did_wallet_count += 1
|
|
1329
1314
|
if coin_state.spent_height is not None:
|
|
1330
1315
|
# The first coin we received for DID wallet is spent.
|
|
1331
1316
|
# This means the wallet is in a resync process, skip the coin
|
|
1332
1317
|
return None
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1318
|
+
# check we aren't above the auto-add wallet limit
|
|
1319
|
+
limit = self.config.get("did_auto_add_limit", 10)
|
|
1320
|
+
if did_wallet_count < limit:
|
|
1321
|
+
did_wallet = await DIDWallet.create_new_did_wallet_from_coin_spend(
|
|
1322
|
+
self,
|
|
1323
|
+
self.main_wallet,
|
|
1324
|
+
launch_coin.coin,
|
|
1325
|
+
did_puzzle,
|
|
1326
|
+
coin_spend,
|
|
1327
|
+
f"DID {encode_puzzle_hash(launch_id, AddressType.DID.hrp(self.config))}",
|
|
1328
|
+
)
|
|
1329
|
+
wallet_identifier = WalletIdentifier.create(did_wallet)
|
|
1330
|
+
self.state_changed("wallet_created", wallet_identifier.id, {"did_id": did_wallet.get_my_DID()})
|
|
1331
|
+
return wallet_identifier
|
|
1332
|
+
# we are over the limit
|
|
1333
|
+
self.log.warning(
|
|
1334
|
+
f"You are at the max configured limit of {limit} DIDs. Ignoring received DID {launch_id.hex()}"
|
|
1340
1335
|
)
|
|
1341
|
-
|
|
1342
|
-
self.state_changed("wallet_created", wallet_identifier.id, {"did_id": did_wallet.get_my_DID()})
|
|
1343
|
-
return wallet_identifier
|
|
1336
|
+
return None
|
|
1344
1337
|
|
|
1345
1338
|
async def get_minter_did(self, launcher_coin: Coin, peer: WSChiaConnection) -> Optional[bytes32]:
|
|
1346
1339
|
# Get minter DID
|
|
@@ -1357,7 +1350,7 @@ class WalletStateManager:
|
|
|
1357
1350
|
minter_did = None
|
|
1358
1351
|
if minter_did is None:
|
|
1359
1352
|
# Check if the NFT is a bulk minting
|
|
1360
|
-
launcher_parent:
|
|
1353
|
+
launcher_parent: list[CoinState] = await self.wallet_node.get_coin_state(
|
|
1361
1354
|
[launcher_coin.parent_coin_info], peer=peer
|
|
1362
1355
|
)
|
|
1363
1356
|
assert (
|
|
@@ -1370,7 +1363,7 @@ class WalletStateManager:
|
|
|
1370
1363
|
launcher_parent[0].coin.parent_coin_info
|
|
1371
1364
|
) or self.constants.GENESIS_CHALLENGE[16:] in bytes(launcher_parent[0].coin.parent_coin_info):
|
|
1372
1365
|
return None
|
|
1373
|
-
did_coin:
|
|
1366
|
+
did_coin: list[CoinState] = await self.wallet_node.get_coin_state(
|
|
1374
1367
|
[launcher_parent[0].coin.parent_coin_info], peer=peer
|
|
1375
1368
|
)
|
|
1376
1369
|
assert did_coin is not None and len(did_coin) == 1 and did_coin[0].spent_height is not None
|
|
@@ -1378,7 +1371,7 @@ class WalletStateManager:
|
|
|
1378
1371
|
uncurried = uncurry_puzzle(did_spend.puzzle_reveal)
|
|
1379
1372
|
did_curried_args = match_did_puzzle(uncurried.mod, uncurried.args)
|
|
1380
1373
|
if did_curried_args is not None:
|
|
1381
|
-
|
|
1374
|
+
_p2_puzzle, _recovery_list_hash, _num_verification, singleton_struct, _metadata = did_curried_args
|
|
1382
1375
|
minter_did = bytes32(bytes(singleton_struct.rest().first())[1:])
|
|
1383
1376
|
return minter_did
|
|
1384
1377
|
|
|
@@ -1410,20 +1403,20 @@ class WalletStateManager:
|
|
|
1410
1403
|
) -> Optional[WalletIdentifier]:
|
|
1411
1404
|
(
|
|
1412
1405
|
# ; second hash
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1406
|
+
_SELF_HASH,
|
|
1407
|
+
_PROPOSAL_ID,
|
|
1408
|
+
_PROPOSED_PUZ_HASH,
|
|
1409
|
+
_YES_VOTES,
|
|
1410
|
+
_TOTAL_VOTES,
|
|
1418
1411
|
# ; first hash
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1412
|
+
_PROPOSAL_TIMER_MOD_HASH,
|
|
1413
|
+
_SINGLETON_MOD_HASH,
|
|
1414
|
+
_SINGLETON_LAUNCHER_PUZHASH,
|
|
1415
|
+
_CAT_MOD_HASH,
|
|
1416
|
+
_DAO_FINISHED_STATE_MOD_HASH,
|
|
1417
|
+
_TREASURY_MOD_HASH,
|
|
1418
|
+
_LOCKUP_SELF_HASH,
|
|
1419
|
+
_CAT_TAIL_HASH,
|
|
1427
1420
|
TREASURY_ID,
|
|
1428
1421
|
) = uncurried_args
|
|
1429
1422
|
for wallet in self.wallets.values():
|
|
@@ -1446,7 +1439,7 @@ class WalletStateManager:
|
|
|
1446
1439
|
raise ValueError("coin_state argument to handle_dao_finished_proposals cannot have created_height of None")
|
|
1447
1440
|
(
|
|
1448
1441
|
SINGLETON_STRUCT, # (SINGLETON_MOD_HASH, (SINGLETON_ID, LAUNCHER_PUZZLE_HASH))
|
|
1449
|
-
|
|
1442
|
+
_FINISHED_STATE_MOD_HASH,
|
|
1450
1443
|
) = uncurried_args
|
|
1451
1444
|
proposal_id = SINGLETON_STRUCT.rest().first().as_atom()
|
|
1452
1445
|
for wallet in self.wallets.values():
|
|
@@ -1486,7 +1479,7 @@ class WalletStateManager:
|
|
|
1486
1479
|
# P2 puzzle hash determines if we should ignore the NFT
|
|
1487
1480
|
uncurried_nft: UncurriedNFT = nft_data.uncurried_nft
|
|
1488
1481
|
old_p2_puzhash = uncurried_nft.p2_puzzle.get_tree_hash()
|
|
1489
|
-
|
|
1482
|
+
_metadata, new_p2_puzhash = get_metadata_and_phs(
|
|
1490
1483
|
uncurried_nft,
|
|
1491
1484
|
nft_data.parent_coin_spend.solution,
|
|
1492
1485
|
)
|
|
@@ -1500,19 +1493,19 @@ class WalletStateManager:
|
|
|
1500
1493
|
else:
|
|
1501
1494
|
new_did_id = _new_did_id
|
|
1502
1495
|
self.log.debug(
|
|
1503
|
-
"Handling NFT: %s
|
|
1496
|
+
"Handling NFT: %s, old DID:%s, new DID:%s, old P2:%s, new P2:%s",
|
|
1504
1497
|
nft_data.parent_coin_spend,
|
|
1505
1498
|
old_did_id,
|
|
1506
1499
|
new_did_id,
|
|
1507
1500
|
old_p2_puzhash,
|
|
1508
1501
|
new_p2_puzhash,
|
|
1509
1502
|
)
|
|
1510
|
-
new_derivation_record: Optional[
|
|
1511
|
-
|
|
1512
|
-
)
|
|
1513
|
-
old_derivation_record: Optional[
|
|
1514
|
-
|
|
1515
|
-
)
|
|
1503
|
+
new_derivation_record: Optional[
|
|
1504
|
+
DerivationRecord
|
|
1505
|
+
] = await self.puzzle_store.get_derivation_record_for_puzzle_hash(new_p2_puzhash)
|
|
1506
|
+
old_derivation_record: Optional[
|
|
1507
|
+
DerivationRecord
|
|
1508
|
+
] = await self.puzzle_store.get_derivation_record_for_puzzle_hash(old_p2_puzhash)
|
|
1516
1509
|
if new_derivation_record is None and old_derivation_record is None:
|
|
1517
1510
|
self.log.debug(
|
|
1518
1511
|
"Cannot find a P2 puzzle hash for NFT:%s, this NFT belongs to others.",
|
|
@@ -1543,7 +1536,7 @@ class WalletStateManager:
|
|
|
1543
1536
|
break
|
|
1544
1537
|
if is_empty and nft_wallet.did_id is not None and not has_did:
|
|
1545
1538
|
self.log.info(f"No NFT, deleting wallet {nft_wallet.did_id.hex()} ...")
|
|
1546
|
-
await self.
|
|
1539
|
+
await self.delete_wallet(nft_wallet.wallet_info.id)
|
|
1547
1540
|
self.wallets.pop(nft_wallet.wallet_info.id)
|
|
1548
1541
|
if nft_wallet.nft_wallet_info.did_id == new_did_id and new_derivation_record is not None:
|
|
1549
1542
|
self.log.info(
|
|
@@ -1585,9 +1578,9 @@ class WalletStateManager:
|
|
|
1585
1578
|
assert coin_state.created_height is not None
|
|
1586
1579
|
is_recipient: Optional[bool] = None
|
|
1587
1580
|
# Check if the wallet is the sender
|
|
1588
|
-
sender_derivation_record: Optional[
|
|
1589
|
-
|
|
1590
|
-
)
|
|
1581
|
+
sender_derivation_record: Optional[
|
|
1582
|
+
DerivationRecord
|
|
1583
|
+
] = await self.puzzle_store.get_derivation_record_for_puzzle_hash(metadata.sender_puzzle_hash)
|
|
1591
1584
|
# Check if the wallet is the recipient
|
|
1592
1585
|
recipient_derivation_record = await self.puzzle_store.get_derivation_record_for_puzzle_hash(
|
|
1593
1586
|
metadata.recipient_puzzle_hash
|
|
@@ -1694,14 +1687,13 @@ class WalletStateManager:
|
|
|
1694
1687
|
self.log.info(f"Found verified credential {vc.launcher_id.hex()}.")
|
|
1695
1688
|
for wallet_info in await self.get_all_wallet_info_entries(wallet_type=WalletType.VC):
|
|
1696
1689
|
return WalletIdentifier(wallet_info.id, WalletType.VC)
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
return WalletIdentifier(vc_wallet.id(), WalletType.VC) # pragma: no cover
|
|
1690
|
+
# Create a new VC wallet
|
|
1691
|
+
vc_wallet = await VCWallet.create_new_vc_wallet(self, self.main_wallet) # pragma: no cover
|
|
1692
|
+
return WalletIdentifier(vc_wallet.id(), WalletType.VC) # pragma: no cover
|
|
1701
1693
|
|
|
1702
1694
|
async def _add_coin_states(
|
|
1703
1695
|
self,
|
|
1704
|
-
coin_states:
|
|
1696
|
+
coin_states: list[CoinState],
|
|
1705
1697
|
peer: WSChiaConnection,
|
|
1706
1698
|
fork_height: Optional[uint32],
|
|
1707
1699
|
) -> None:
|
|
@@ -1715,7 +1707,7 @@ class WalletStateManager:
|
|
|
1715
1707
|
curr_h = last_change_height
|
|
1716
1708
|
|
|
1717
1709
|
trade_removals = await self.trade_manager.get_coins_of_interest()
|
|
1718
|
-
all_unconfirmed:
|
|
1710
|
+
all_unconfirmed: list[LightTransactionRecord] = await self.tx_store.get_all_unconfirmed()
|
|
1719
1711
|
used_up_to = -1
|
|
1720
1712
|
ph_to_index_cache: LRUCache[bytes32, uint32] = LRUCache(100)
|
|
1721
1713
|
|
|
@@ -1770,14 +1762,16 @@ class WalletStateManager:
|
|
|
1770
1762
|
# Confirm tx records for txs which we submitted for coins which aren't in our wallet
|
|
1771
1763
|
if coin_state.created_height is not None and coin_state.spent_height is not None:
|
|
1772
1764
|
all_unconfirmed = await self.tx_store.get_all_unconfirmed()
|
|
1773
|
-
tx_records_to_confirm:
|
|
1765
|
+
tx_records_to_confirm: list[LightTransactionRecord] = []
|
|
1774
1766
|
for out_tx_record in all_unconfirmed:
|
|
1775
1767
|
if coin_state.coin in out_tx_record.removals:
|
|
1776
1768
|
tx_records_to_confirm.append(out_tx_record)
|
|
1777
1769
|
|
|
1778
1770
|
if len(tx_records_to_confirm) > 0:
|
|
1779
|
-
for
|
|
1780
|
-
await self.tx_store.set_confirmed(
|
|
1771
|
+
for light_tx_record in tx_records_to_confirm:
|
|
1772
|
+
await self.tx_store.set_confirmed(
|
|
1773
|
+
light_tx_record.name, uint32(coin_state.spent_height)
|
|
1774
|
+
)
|
|
1781
1775
|
self.log.debug(f"No wallet for coin state: {coin_state}")
|
|
1782
1776
|
continue
|
|
1783
1777
|
|
|
@@ -1919,16 +1913,16 @@ class WalletStateManager:
|
|
|
1919
1913
|
|
|
1920
1914
|
# Reorg rollback adds reorged transactions so it's possible there is tx_record already
|
|
1921
1915
|
# Even though we are just adding coin record to the db (after reorg)
|
|
1922
|
-
tx_records:
|
|
1916
|
+
tx_records: list[LightTransactionRecord] = []
|
|
1923
1917
|
for out_tx_record in all_unconfirmed:
|
|
1924
1918
|
for rem_coin in out_tx_record.removals:
|
|
1925
1919
|
if rem_coin == coin_state.coin:
|
|
1926
1920
|
tx_records.append(out_tx_record)
|
|
1927
1921
|
|
|
1928
1922
|
if len(tx_records) > 0:
|
|
1929
|
-
for
|
|
1923
|
+
for light_record in tx_records:
|
|
1930
1924
|
await self.tx_store.set_confirmed(
|
|
1931
|
-
|
|
1925
|
+
light_record.name, uint32(coin_state.spent_height)
|
|
1932
1926
|
)
|
|
1933
1927
|
else:
|
|
1934
1928
|
tx_name = bytes(coin_state.coin.name())
|
|
@@ -1962,20 +1956,20 @@ class WalletStateManager:
|
|
|
1962
1956
|
await self.coin_store.set_spent(coin_name, uint32(coin_state.spent_height))
|
|
1963
1957
|
if record.coin_type == CoinType.CLAWBACK:
|
|
1964
1958
|
await self.interested_store.remove_interested_coin_id(coin_state.coin.name())
|
|
1965
|
-
confirmed_tx_records:
|
|
1959
|
+
confirmed_tx_records: list[LightTransactionRecord] = []
|
|
1966
1960
|
|
|
1967
|
-
for
|
|
1968
|
-
if
|
|
1969
|
-
for add_coin in
|
|
1961
|
+
for light_record in all_unconfirmed:
|
|
1962
|
+
if light_record.type in CLAWBACK_INCOMING_TRANSACTION_TYPES:
|
|
1963
|
+
for add_coin in light_record.additions:
|
|
1970
1964
|
if add_coin == coin_state.coin:
|
|
1971
|
-
confirmed_tx_records.append(
|
|
1965
|
+
confirmed_tx_records.append(light_record)
|
|
1972
1966
|
else:
|
|
1973
|
-
for rem_coin in
|
|
1967
|
+
for rem_coin in light_record.removals:
|
|
1974
1968
|
if rem_coin == coin_state.coin:
|
|
1975
|
-
confirmed_tx_records.append(
|
|
1969
|
+
confirmed_tx_records.append(light_record)
|
|
1976
1970
|
|
|
1977
|
-
for
|
|
1978
|
-
await self.tx_store.set_confirmed(
|
|
1971
|
+
for light_record in confirmed_tx_records:
|
|
1972
|
+
await self.tx_store.set_confirmed(light_record.name, uint32(coin_state.spent_height))
|
|
1979
1973
|
for unconfirmed_record in all_unconfirmed:
|
|
1980
1974
|
for rem_coin in unconfirmed_record.removals:
|
|
1981
1975
|
if rem_coin == coin_state.coin:
|
|
@@ -1984,7 +1978,7 @@ class WalletStateManager:
|
|
|
1984
1978
|
unconfirmed_record.name, uint32(coin_state.spent_height)
|
|
1985
1979
|
)
|
|
1986
1980
|
|
|
1987
|
-
if record.wallet_type in
|
|
1981
|
+
if record.wallet_type in {WalletType.POOLING_WALLET, WalletType.DAO}:
|
|
1988
1982
|
wallet_type_to_class = {WalletType.POOLING_WALLET: PoolWallet, WalletType.DAO: DAOWallet}
|
|
1989
1983
|
if coin_state.spent_height is not None and coin_state.coin.amount == uint64(1):
|
|
1990
1984
|
singleton_wallet: Union[PoolWallet, DAOWallet] = self.get_wallet(
|
|
@@ -2021,7 +2015,7 @@ class WalletStateManager:
|
|
|
2021
2015
|
curr_coin_state.coin.name(), uint32(curr_coin_state.spent_height)
|
|
2022
2016
|
)
|
|
2023
2017
|
await self.add_interested_coin_ids([new_singleton_coin.name()])
|
|
2024
|
-
new_coin_state:
|
|
2018
|
+
new_coin_state: list[CoinState] = await self.wallet_node.get_coin_state(
|
|
2025
2019
|
[coin_name], peer=peer, fork_height=fork_height
|
|
2026
2020
|
)
|
|
2027
2021
|
assert len(new_coin_state) == 1
|
|
@@ -2125,7 +2119,7 @@ class WalletStateManager:
|
|
|
2125
2119
|
|
|
2126
2120
|
async def add_coin_states(
|
|
2127
2121
|
self,
|
|
2128
|
-
coin_states:
|
|
2122
|
+
coin_states: list[CoinState],
|
|
2129
2123
|
peer: WSChiaConnection,
|
|
2130
2124
|
fork_height: Optional[uint32],
|
|
2131
2125
|
) -> bool:
|
|
@@ -2192,7 +2186,7 @@ class WalletStateManager:
|
|
|
2192
2186
|
return None
|
|
2193
2187
|
|
|
2194
2188
|
async def get_wallet_identifier_for_coin(
|
|
2195
|
-
self, coin: Coin, hint_dict:
|
|
2189
|
+
self, coin: Coin, hint_dict: dict[bytes32, bytes32] = {}
|
|
2196
2190
|
) -> Optional[WalletIdentifier]:
|
|
2197
2191
|
wallet_identifier = await self.puzzle_store.get_wallet_identifier_for_puzzle_hash(coin.puzzle_hash)
|
|
2198
2192
|
if (
|
|
@@ -2218,7 +2212,7 @@ class WalletStateManager:
|
|
|
2218
2212
|
self,
|
|
2219
2213
|
coin: Coin,
|
|
2220
2214
|
height: uint32,
|
|
2221
|
-
all_unconfirmed_transaction_records:
|
|
2215
|
+
all_unconfirmed_transaction_records: list[LightTransactionRecord],
|
|
2222
2216
|
wallet_id: uint32,
|
|
2223
2217
|
wallet_type: WalletType,
|
|
2224
2218
|
peer: WSChiaConnection,
|
|
@@ -2248,7 +2242,7 @@ class WalletStateManager:
|
|
|
2248
2242
|
coin_confirmed_transaction = False
|
|
2249
2243
|
if not coinbase:
|
|
2250
2244
|
for record in all_unconfirmed_transaction_records:
|
|
2251
|
-
if coin in record.additions
|
|
2245
|
+
if coin in record.additions:
|
|
2252
2246
|
await self.tx_store.set_confirmed(record.name, height)
|
|
2253
2247
|
coin_confirmed_transaction = True
|
|
2254
2248
|
break
|
|
@@ -2259,7 +2253,7 @@ class WalletStateManager:
|
|
|
2259
2253
|
# no matter if there is another TX updated.
|
|
2260
2254
|
clawback = parent_coin_record is not None and parent_coin_record.coin_type == CoinType.CLAWBACK
|
|
2261
2255
|
|
|
2262
|
-
if coinbase or clawback or not coin_confirmed_transaction and not change:
|
|
2256
|
+
if coinbase or clawback or (not coin_confirmed_transaction and not change):
|
|
2263
2257
|
tx_record = TransactionRecord(
|
|
2264
2258
|
confirmed_at_height=uint32(height),
|
|
2265
2259
|
created_at_time=await self.wallet_node.get_timestamp_for_height(height),
|
|
@@ -2298,13 +2292,13 @@ class WalletStateManager:
|
|
|
2298
2292
|
|
|
2299
2293
|
async def add_pending_transactions(
|
|
2300
2294
|
self,
|
|
2301
|
-
tx_records:
|
|
2295
|
+
tx_records: list[TransactionRecord],
|
|
2302
2296
|
push: bool = True,
|
|
2303
2297
|
merge_spends: bool = True,
|
|
2304
2298
|
sign: Optional[bool] = None,
|
|
2305
|
-
additional_signing_responses: Optional[
|
|
2306
|
-
extra_spends: Optional[
|
|
2307
|
-
) ->
|
|
2299
|
+
additional_signing_responses: Optional[list[SigningResponse]] = None,
|
|
2300
|
+
extra_spends: Optional[list[WalletSpendBundle]] = None,
|
|
2301
|
+
) -> list[TransactionRecord]:
|
|
2308
2302
|
"""
|
|
2309
2303
|
Add a list of transactions to be submitted to the full node.
|
|
2310
2304
|
Aggregates the `spend_bundle` property for each transaction onto the first transaction in the list.
|
|
@@ -2387,26 +2381,27 @@ class WalletStateManager:
|
|
|
2387
2381
|
if (
|
|
2388
2382
|
send_status != MempoolInclusionStatus.SUCCESS
|
|
2389
2383
|
and error
|
|
2390
|
-
and error not in
|
|
2384
|
+
and error not in {Err.INVALID_FEE_LOW_FEE, Err.INVALID_FEE_TOO_CLOSE_TO_ZERO}
|
|
2391
2385
|
):
|
|
2392
2386
|
coins_removed = tx.spend_bundle.removals()
|
|
2393
2387
|
trade_coins_removed = set()
|
|
2394
2388
|
trades = []
|
|
2395
2389
|
for removed_coin in coins_removed:
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
trades
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2390
|
+
trades_by_coin = await self.trade_manager.get_trades_by_coin(removed_coin)
|
|
2391
|
+
for trade in trades_by_coin:
|
|
2392
|
+
if trade is not None and trade.status in {
|
|
2393
|
+
TradeStatus.PENDING_CONFIRM.value,
|
|
2394
|
+
TradeStatus.PENDING_ACCEPT.value,
|
|
2395
|
+
TradeStatus.PENDING_CANCEL.value,
|
|
2396
|
+
}:
|
|
2397
|
+
if trade not in trades:
|
|
2398
|
+
trades.append(trade)
|
|
2399
|
+
# offer was tied to these coins, lets subscribe to them to get a confirmation to
|
|
2400
|
+
# cancel it if it's confirmed
|
|
2401
|
+
# we send transactions to multiple peers, and in cases when mempool gets
|
|
2402
|
+
# fragmented, it's safest to wait for confirmation from blockchain before setting
|
|
2403
|
+
# offer to failed
|
|
2404
|
+
trade_coins_removed.add(removed_coin.name())
|
|
2410
2405
|
if trades != [] and trade_coins_removed != set():
|
|
2411
2406
|
if not tx.is_valid():
|
|
2412
2407
|
# we've tried to send this transaction to a full node multiple times
|
|
@@ -2428,7 +2423,7 @@ class WalletStateManager:
|
|
|
2428
2423
|
else:
|
|
2429
2424
|
self.state_changed("tx_update", tx.wallet_id, {"transaction": tx})
|
|
2430
2425
|
|
|
2431
|
-
async def get_all_transactions(self, wallet_id: int) ->
|
|
2426
|
+
async def get_all_transactions(self, wallet_id: int) -> list[TransactionRecord]:
|
|
2432
2427
|
"""
|
|
2433
2428
|
Retrieves all confirmed and pending transactions
|
|
2434
2429
|
"""
|
|
@@ -2442,7 +2437,7 @@ class WalletStateManager:
|
|
|
2442
2437
|
timestamp: uint64 = await self.wallet_node.get_timestamp_for_height(wr.confirmed_block_height)
|
|
2443
2438
|
return wr.to_coin_record(timestamp)
|
|
2444
2439
|
|
|
2445
|
-
async def get_coin_records_by_coin_ids(self, **kwargs: Any) ->
|
|
2440
|
+
async def get_coin_records_by_coin_ids(self, **kwargs: Any) -> list[CoinRecord]:
|
|
2446
2441
|
result = await self.coin_store.get_coin_records(**kwargs)
|
|
2447
2442
|
return [await self.get_coin_record_by_wallet_record(record) for record in result.records]
|
|
2448
2443
|
|
|
@@ -2454,7 +2449,7 @@ class WalletStateManager:
|
|
|
2454
2449
|
wallet = self.wallets[wallet_id]
|
|
2455
2450
|
return wallet
|
|
2456
2451
|
|
|
2457
|
-
async def reorg_rollback(self, height: int) ->
|
|
2452
|
+
async def reorg_rollback(self, height: int) -> list[uint32]:
|
|
2458
2453
|
"""
|
|
2459
2454
|
Rolls back and updates the coin_store and transaction store. It's possible this height
|
|
2460
2455
|
is the tip, or even beyond the tip.
|
|
@@ -2464,21 +2459,21 @@ class WalletStateManager:
|
|
|
2464
2459
|
await self.coin_store.rollback_to_block(height)
|
|
2465
2460
|
await self.interested_store.rollback_to_block(height)
|
|
2466
2461
|
await self.dl_store.rollback_to_block(height)
|
|
2467
|
-
reorged:
|
|
2462
|
+
reorged: list[TransactionRecord] = await self.tx_store.get_transaction_above(height)
|
|
2468
2463
|
await self.tx_store.rollback_to_block(height)
|
|
2469
2464
|
for record in reorged:
|
|
2470
|
-
if TransactionType(record.type) in
|
|
2465
|
+
if TransactionType(record.type) in {
|
|
2471
2466
|
TransactionType.OUTGOING_TX,
|
|
2472
2467
|
TransactionType.OUTGOING_TRADE,
|
|
2473
2468
|
TransactionType.INCOMING_TRADE,
|
|
2474
2469
|
TransactionType.OUTGOING_CLAWBACK,
|
|
2475
2470
|
TransactionType.INCOMING_CLAWBACK_SEND,
|
|
2476
2471
|
TransactionType.INCOMING_CLAWBACK_RECEIVE,
|
|
2477
|
-
|
|
2472
|
+
}:
|
|
2478
2473
|
await self.tx_store.tx_reorged(record)
|
|
2479
2474
|
|
|
2480
2475
|
# Removes wallets that were created from a blockchain transaction which got reorged.
|
|
2481
|
-
remove_ids:
|
|
2476
|
+
remove_ids: list[uint32] = []
|
|
2482
2477
|
for wallet_id, wallet in self.wallets.items():
|
|
2483
2478
|
if wallet.type() == WalletType.POOLING_WALLET.value:
|
|
2484
2479
|
assert isinstance(wallet, PoolWallet)
|
|
@@ -2486,7 +2481,7 @@ class WalletStateManager:
|
|
|
2486
2481
|
if remove:
|
|
2487
2482
|
remove_ids.append(wallet_id)
|
|
2488
2483
|
for wallet_id in remove_ids:
|
|
2489
|
-
await self.
|
|
2484
|
+
await self.delete_wallet(wallet_id)
|
|
2490
2485
|
self.state_changed("wallet_removed", wallet_id)
|
|
2491
2486
|
|
|
2492
2487
|
return remove_ids
|
|
@@ -2497,12 +2492,12 @@ class WalletStateManager:
|
|
|
2497
2492
|
def unlink_db(self) -> None:
|
|
2498
2493
|
Path(self.db_path).unlink()
|
|
2499
2494
|
|
|
2500
|
-
async def get_all_wallet_info_entries(self, wallet_type: Optional[WalletType] = None) ->
|
|
2495
|
+
async def get_all_wallet_info_entries(self, wallet_type: Optional[WalletType] = None) -> list[WalletInfo]:
|
|
2501
2496
|
return await self.user_store.get_all_wallet_info_entries(wallet_type)
|
|
2502
2497
|
|
|
2503
2498
|
async def get_wallet_for_asset_id(self, asset_id: str) -> Optional[WalletProtocol[Any]]:
|
|
2504
2499
|
for wallet_id, wallet in self.wallets.items():
|
|
2505
|
-
if wallet.type() in
|
|
2500
|
+
if wallet.type() in {WalletType.CAT, WalletType.CRCAT}:
|
|
2506
2501
|
assert isinstance(wallet, CATWallet)
|
|
2507
2502
|
if wallet.get_asset_id() == asset_id:
|
|
2508
2503
|
return wallet
|
|
@@ -2543,8 +2538,8 @@ class WalletStateManager:
|
|
|
2543
2538
|
self.state_changed("wallet_created")
|
|
2544
2539
|
|
|
2545
2540
|
async def get_spendable_coins_for_wallet(
|
|
2546
|
-
self, wallet_id: int, records: Optional[
|
|
2547
|
-
) ->
|
|
2541
|
+
self, wallet_id: int, records: Optional[set[WalletCoinRecord]] = None
|
|
2542
|
+
) -> set[WalletCoinRecord]:
|
|
2548
2543
|
wallet_type = self.wallets[uint32(wallet_id)].type()
|
|
2549
2544
|
if records is None:
|
|
2550
2545
|
if wallet_type == WalletType.CRCAT:
|
|
@@ -2553,8 +2548,8 @@ class WalletStateManager:
|
|
|
2553
2548
|
records = await self.coin_store.get_unspent_coins_for_wallet(wallet_id)
|
|
2554
2549
|
|
|
2555
2550
|
# Coins that are currently part of a transaction
|
|
2556
|
-
unconfirmed_tx:
|
|
2557
|
-
removal_dict:
|
|
2551
|
+
unconfirmed_tx: list[TransactionRecord] = await self.tx_store.get_unconfirmed_for_wallet(wallet_id)
|
|
2552
|
+
removal_dict: dict[bytes32, Coin] = {}
|
|
2558
2553
|
for tx in unconfirmed_tx:
|
|
2559
2554
|
for coin in tx.removals:
|
|
2560
2555
|
# TODO, "if" might not be necessary once unconfirmed tx doesn't contain coins for other wallets
|
|
@@ -2562,7 +2557,7 @@ class WalletStateManager:
|
|
|
2562
2557
|
removal_dict[coin.name()] = coin
|
|
2563
2558
|
|
|
2564
2559
|
# Coins that are part of the trade
|
|
2565
|
-
offer_locked_coins:
|
|
2560
|
+
offer_locked_coins: dict[bytes32, WalletCoinRecord] = await self.trade_manager.get_locked_coins()
|
|
2566
2561
|
|
|
2567
2562
|
filtered = set()
|
|
2568
2563
|
for record in records:
|
|
@@ -2584,7 +2579,7 @@ class WalletStateManager:
|
|
|
2584
2579
|
if self.wallet_node.last_wallet_tx_resend_time < current_time - self.wallet_node.wallet_tx_resend_timeout_secs:
|
|
2585
2580
|
self.tx_pending_changed()
|
|
2586
2581
|
|
|
2587
|
-
async def add_interested_puzzle_hashes(self, puzzle_hashes:
|
|
2582
|
+
async def add_interested_puzzle_hashes(self, puzzle_hashes: list[bytes32], wallet_ids: list[int]) -> None:
|
|
2588
2583
|
# TODO: It's unclear if the intended use for this is that each puzzle hash should store all
|
|
2589
2584
|
# the elements of wallet_ids. It only stores one wallet_id per puzzle hash in the interested_store
|
|
2590
2585
|
# but the coin_cache keeps all wallet_ids for each puzzle hash
|
|
@@ -2599,7 +2594,7 @@ class WalletStateManager:
|
|
|
2599
2594
|
if len(puzzle_hashes) > 0:
|
|
2600
2595
|
await self.wallet_node.new_peak_queue.subscribe_to_puzzle_hashes(puzzle_hashes)
|
|
2601
2596
|
|
|
2602
|
-
async def add_interested_coin_ids(self, coin_ids:
|
|
2597
|
+
async def add_interested_coin_ids(self, coin_ids: list[bytes32], wallet_ids: list[int] = []) -> None:
|
|
2603
2598
|
# TODO: FIX: wallet_ids is sometimes populated unexpectedly when called from add_pending_transaction
|
|
2604
2599
|
for coin_id in coin_ids:
|
|
2605
2600
|
if coin_id in self.interested_coin_cache:
|
|
@@ -2614,14 +2609,14 @@ class WalletStateManager:
|
|
|
2614
2609
|
await self.wallet_node.new_peak_queue.subscribe_to_coin_ids(coin_ids)
|
|
2615
2610
|
|
|
2616
2611
|
async def delete_trade_transactions(self, trade_id: bytes32) -> None:
|
|
2617
|
-
txs:
|
|
2612
|
+
txs: list[TransactionRecord] = await self.tx_store.get_transactions_by_trade_id(trade_id)
|
|
2618
2613
|
for tx in txs:
|
|
2619
2614
|
await self.tx_store.delete_transaction_record(tx.name)
|
|
2620
2615
|
|
|
2621
2616
|
async def convert_puzzle_hash(self, wallet_id: uint32, puzzle_hash: bytes32) -> bytes32:
|
|
2622
2617
|
wallet = self.wallets[wallet_id]
|
|
2623
2618
|
# This should be general to wallets but for right now this is just for CATs so we'll add this if
|
|
2624
|
-
if wallet.type() in
|
|
2619
|
+
if wallet.type() in {WalletType.CAT.value, WalletType.CRCAT.value}:
|
|
2625
2620
|
assert isinstance(wallet, CATWallet)
|
|
2626
2621
|
return await wallet.convert_puzzle_hash(puzzle_hash)
|
|
2627
2622
|
|
|
@@ -2654,15 +2649,15 @@ class WalletStateManager:
|
|
|
2654
2649
|
async def path_hint_for_pubkey(self, pk: bytes) -> Optional[PathHint]:
|
|
2655
2650
|
return await self.main_wallet.path_hint_for_pubkey(pk)
|
|
2656
2651
|
|
|
2657
|
-
async def key_hints_for_pubkeys(self, pks:
|
|
2652
|
+
async def key_hints_for_pubkeys(self, pks: list[bytes]) -> KeyHints:
|
|
2658
2653
|
return KeyHints(
|
|
2659
2654
|
[sum_hint for pk in pks for sum_hint in (await self.sum_hint_for_pubkey(pk),) if sum_hint is not None],
|
|
2660
2655
|
[path_hint for pk in pks for path_hint in (await self.path_hint_for_pubkey(pk),) if path_hint is not None],
|
|
2661
2656
|
)
|
|
2662
2657
|
|
|
2663
|
-
async def gather_signing_info(self, coin_spends:
|
|
2664
|
-
pks:
|
|
2665
|
-
signing_targets:
|
|
2658
|
+
async def gather_signing_info(self, coin_spends: list[Spend]) -> SigningInstructions:
|
|
2659
|
+
pks: list[bytes] = []
|
|
2660
|
+
signing_targets: list[SigningTarget] = []
|
|
2666
2661
|
for coin_spend in coin_spends:
|
|
2667
2662
|
_coin_spend = coin_spend.as_coin_spend()
|
|
2668
2663
|
# Get AGG_SIG conditions
|
|
@@ -2685,10 +2680,10 @@ class WalletStateManager:
|
|
|
2685
2680
|
signing_targets,
|
|
2686
2681
|
)
|
|
2687
2682
|
|
|
2688
|
-
async def gather_signing_info_for_bundles(self, bundles:
|
|
2689
|
-
utxs:
|
|
2683
|
+
async def gather_signing_info_for_bundles(self, bundles: list[WalletSpendBundle]) -> list[UnsignedTransaction]:
|
|
2684
|
+
utxs: list[UnsignedTransaction] = []
|
|
2690
2685
|
for bundle in bundles:
|
|
2691
|
-
signer_protocol_spends:
|
|
2686
|
+
signer_protocol_spends: list[Spend] = [Spend.from_coin_spend(spend) for spend in bundle.coin_spends]
|
|
2692
2687
|
utxs.append(
|
|
2693
2688
|
UnsignedTransaction(
|
|
2694
2689
|
TransactionInfo(signer_protocol_spends), await self.gather_signing_info(signer_protocol_spends)
|
|
@@ -2697,21 +2692,21 @@ class WalletStateManager:
|
|
|
2697
2692
|
|
|
2698
2693
|
return utxs
|
|
2699
2694
|
|
|
2700
|
-
async def gather_signing_info_for_txs(self, txs:
|
|
2695
|
+
async def gather_signing_info_for_txs(self, txs: list[TransactionRecord]) -> list[UnsignedTransaction]:
|
|
2701
2696
|
return await self.gather_signing_info_for_bundles(
|
|
2702
2697
|
[tx.spend_bundle for tx in txs if tx.spend_bundle is not None]
|
|
2703
2698
|
)
|
|
2704
2699
|
|
|
2705
|
-
async def gather_signing_info_for_trades(self, offers:
|
|
2700
|
+
async def gather_signing_info_for_trades(self, offers: list[Offer]) -> list[UnsignedTransaction]:
|
|
2706
2701
|
return await self.gather_signing_info_for_bundles([offer._bundle for offer in offers])
|
|
2707
2702
|
|
|
2708
2703
|
async def execute_signing_instructions(
|
|
2709
2704
|
self, signing_instructions: SigningInstructions, partial_allowed: bool = False
|
|
2710
|
-
) ->
|
|
2705
|
+
) -> list[SigningResponse]:
|
|
2711
2706
|
return await self.main_wallet.execute_signing_instructions(signing_instructions, partial_allowed)
|
|
2712
2707
|
|
|
2713
2708
|
async def apply_signatures(
|
|
2714
|
-
self, spends:
|
|
2709
|
+
self, spends: list[Spend], signing_responses: list[SigningResponse]
|
|
2715
2710
|
) -> SignedTransaction:
|
|
2716
2711
|
return await self.main_wallet.apply_signatures(spends, signing_responses)
|
|
2717
2712
|
|
|
@@ -2725,17 +2720,17 @@ class WalletStateManager:
|
|
|
2725
2720
|
|
|
2726
2721
|
async def sign_transactions(
|
|
2727
2722
|
self,
|
|
2728
|
-
tx_records:
|
|
2729
|
-
additional_signing_responses:
|
|
2723
|
+
tx_records: list[TransactionRecord],
|
|
2724
|
+
additional_signing_responses: list[SigningResponse] = [],
|
|
2730
2725
|
partial_allowed: bool = False,
|
|
2731
|
-
) ->
|
|
2732
|
-
unsigned_txs:
|
|
2733
|
-
new_txs:
|
|
2726
|
+
) -> tuple[list[TransactionRecord], list[SigningResponse]]:
|
|
2727
|
+
unsigned_txs: list[UnsignedTransaction] = await self.gather_signing_info_for_txs(tx_records)
|
|
2728
|
+
new_txs: list[TransactionRecord] = []
|
|
2734
2729
|
all_signing_responses = additional_signing_responses.copy()
|
|
2735
2730
|
for unsigned_tx, tx in zip(
|
|
2736
2731
|
unsigned_txs, [tx_record for tx_record in tx_records if tx_record.spend_bundle is not None]
|
|
2737
2732
|
):
|
|
2738
|
-
signing_responses:
|
|
2733
|
+
signing_responses: list[SigningResponse] = await self.execute_signing_instructions(
|
|
2739
2734
|
unsigned_tx.signing_instructions, partial_allowed=partial_allowed
|
|
2740
2735
|
)
|
|
2741
2736
|
all_signing_responses.extend(signing_responses)
|
|
@@ -2751,15 +2746,15 @@ class WalletStateManager:
|
|
|
2751
2746
|
|
|
2752
2747
|
async def sign_offers(
|
|
2753
2748
|
self,
|
|
2754
|
-
offers:
|
|
2755
|
-
additional_signing_responses:
|
|
2749
|
+
offers: list[Offer],
|
|
2750
|
+
additional_signing_responses: list[SigningResponse] = [],
|
|
2756
2751
|
partial_allowed: bool = False,
|
|
2757
|
-
) ->
|
|
2758
|
-
unsigned_txs:
|
|
2759
|
-
new_offers:
|
|
2752
|
+
) -> tuple[list[Offer], list[SigningResponse]]:
|
|
2753
|
+
unsigned_txs: list[UnsignedTransaction] = await self.gather_signing_info_for_trades(offers)
|
|
2754
|
+
new_offers: list[Offer] = []
|
|
2760
2755
|
all_signing_responses = additional_signing_responses.copy()
|
|
2761
2756
|
for unsigned_tx, offer in zip(unsigned_txs, [offer for offer in offers]):
|
|
2762
|
-
signing_responses:
|
|
2757
|
+
signing_responses: list[SigningResponse] = await self.execute_signing_instructions(
|
|
2763
2758
|
unsigned_tx.signing_instructions, partial_allowed=partial_allowed
|
|
2764
2759
|
)
|
|
2765
2760
|
all_signing_responses.extend(signing_responses)
|
|
@@ -2774,12 +2769,12 @@ class WalletStateManager:
|
|
|
2774
2769
|
|
|
2775
2770
|
async def sign_bundle(
|
|
2776
2771
|
self,
|
|
2777
|
-
coin_spends:
|
|
2778
|
-
additional_signing_responses:
|
|
2772
|
+
coin_spends: list[CoinSpend],
|
|
2773
|
+
additional_signing_responses: list[SigningResponse] = [],
|
|
2779
2774
|
partial_allowed: bool = False,
|
|
2780
|
-
) ->
|
|
2775
|
+
) -> tuple[WalletSpendBundle, list[SigningResponse]]:
|
|
2781
2776
|
[unsigned_tx] = await self.gather_signing_info_for_bundles([WalletSpendBundle(coin_spends, G2Element())])
|
|
2782
|
-
signing_responses:
|
|
2777
|
+
signing_responses: list[SigningResponse] = await self.execute_signing_instructions(
|
|
2783
2778
|
unsigned_tx.signing_instructions, partial_allowed=partial_allowed
|
|
2784
2779
|
)
|
|
2785
2780
|
return (
|
|
@@ -2792,8 +2787,8 @@ class WalletStateManager:
|
|
|
2792
2787
|
signing_responses,
|
|
2793
2788
|
)
|
|
2794
2789
|
|
|
2795
|
-
async def submit_transactions(self, signed_txs:
|
|
2796
|
-
bundles:
|
|
2790
|
+
async def submit_transactions(self, signed_txs: list[SignedTransaction]) -> list[bytes32]:
|
|
2791
|
+
bundles: list[WalletSpendBundle] = [self.signed_tx_to_spendbundle(tx) for tx in signed_txs]
|
|
2797
2792
|
for bundle in bundles:
|
|
2798
2793
|
await self.wallet_node.push_tx(bundle)
|
|
2799
2794
|
return [bundle.name() for bundle in bundles]
|
|
@@ -2805,8 +2800,8 @@ class WalletStateManager:
|
|
|
2805
2800
|
push: bool = False,
|
|
2806
2801
|
merge_spends: bool = True,
|
|
2807
2802
|
sign: Optional[bool] = None,
|
|
2808
|
-
additional_signing_responses:
|
|
2809
|
-
extra_spends:
|
|
2803
|
+
additional_signing_responses: list[SigningResponse] = [],
|
|
2804
|
+
extra_spends: list[WalletSpendBundle] = [],
|
|
2810
2805
|
) -> AsyncIterator[WalletActionScope]:
|
|
2811
2806
|
async with new_wallet_action_scope(
|
|
2812
2807
|
self,
|
|
@@ -2818,3 +2813,7 @@ class WalletStateManager:
|
|
|
2818
2813
|
extra_spends=extra_spends,
|
|
2819
2814
|
) as action_scope:
|
|
2820
2815
|
yield action_scope
|
|
2816
|
+
|
|
2817
|
+
async def delete_wallet(self, wallet_id: uint32) -> None:
|
|
2818
|
+
await self.user_store.delete_wallet(wallet_id)
|
|
2819
|
+
await self.puzzle_store.delete_wallet(wallet_id)
|