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
|
@@ -7,15 +7,15 @@ import logging
|
|
|
7
7
|
import multiprocessing.context
|
|
8
8
|
import time
|
|
9
9
|
import traceback
|
|
10
|
-
from collections.abc import AsyncIterator
|
|
10
|
+
from collections.abc import AsyncIterator, Callable
|
|
11
11
|
from contextlib import asynccontextmanager
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import TYPE_CHECKING, Any,
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
|
|
14
14
|
|
|
15
15
|
import aiosqlite
|
|
16
|
-
from chia_rs import AugSchemeMPL, CoinSpend, CoinState, ConsensusConstants, G1Element, G2Element, PrivateKey
|
|
16
|
+
from chia_rs import AugSchemeMPL, CoinRecord, CoinSpend, CoinState, ConsensusConstants, G1Element, G2Element, PrivateKey
|
|
17
17
|
from chia_rs.sized_bytes import bytes32
|
|
18
|
-
from chia_rs.sized_ints import uint16, uint32, uint64, uint128
|
|
18
|
+
from chia_rs.sized_ints import uint8, uint16, uint32, uint64, uint128
|
|
19
19
|
|
|
20
20
|
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
|
|
21
21
|
from chia.consensus.coinbase import farmer_parent_id, pool_parent_id
|
|
@@ -33,8 +33,7 @@ from chia.rpc.rpc_server import StateChangedProtocol
|
|
|
33
33
|
from chia.server.server import ChiaServer
|
|
34
34
|
from chia.server.ws_connection import WSChiaConnection
|
|
35
35
|
from chia.types.blockchain_format.coin import Coin
|
|
36
|
-
from chia.types.blockchain_format.program import
|
|
37
|
-
from chia.types.coin_record import CoinRecord
|
|
36
|
+
from chia.types.blockchain_format.program import Program
|
|
38
37
|
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
|
39
38
|
from chia.util.bech32m import encode_puzzle_hash
|
|
40
39
|
from chia.util.db_synchronous import db_synchronous_on
|
|
@@ -60,10 +59,12 @@ from chia.wallet.conditions import (
|
|
|
60
59
|
from chia.wallet.db_wallet.db_wallet_puzzles import MIRROR_PUZZLE_HASH
|
|
61
60
|
from chia.wallet.derivation_record import DerivationRecord
|
|
62
61
|
from chia.wallet.derive_keys import (
|
|
62
|
+
MAX_POOL_WALLETS,
|
|
63
63
|
_derive_path,
|
|
64
64
|
_derive_pk_unhardened,
|
|
65
65
|
master_pk_to_wallet_pk_unhardened,
|
|
66
66
|
master_pk_to_wallet_pk_unhardened_intermediate,
|
|
67
|
+
master_sk_to_singleton_owner_sk,
|
|
67
68
|
master_sk_to_wallet_sk,
|
|
68
69
|
master_sk_to_wallet_sk_intermediate,
|
|
69
70
|
master_sk_to_wallet_sk_unhardened,
|
|
@@ -105,7 +106,7 @@ from chia.wallet.util.compute_hints import compute_spend_hints_and_additions
|
|
|
105
106
|
from chia.wallet.util.compute_memos import compute_memos
|
|
106
107
|
from chia.wallet.util.curry_and_treehash import NIL_TREEHASH
|
|
107
108
|
from chia.wallet.util.puzzle_decorator import PuzzleDecoratorManager
|
|
108
|
-
from chia.wallet.util.query_filter import HashFilter
|
|
109
|
+
from chia.wallet.util.query_filter import FilterMode, HashFilter
|
|
109
110
|
from chia.wallet.util.transaction_type import CLAWBACK_INCOMING_TRANSACTION_TYPES, TransactionType
|
|
110
111
|
from chia.wallet.util.tx_config import TXConfig, TXConfigLoader
|
|
111
112
|
from chia.wallet.util.wallet_sync_utils import (
|
|
@@ -123,7 +124,7 @@ from chia.wallet.wallet import Wallet
|
|
|
123
124
|
from chia.wallet.wallet_action_scope import WalletActionScope, new_wallet_action_scope
|
|
124
125
|
from chia.wallet.wallet_blockchain import WalletBlockchain
|
|
125
126
|
from chia.wallet.wallet_coin_record import MetadataTypes, WalletCoinRecord
|
|
126
|
-
from chia.wallet.wallet_coin_store import WalletCoinStore
|
|
127
|
+
from chia.wallet.wallet_coin_store import CoinRecordOrder, WalletCoinStore
|
|
127
128
|
from chia.wallet.wallet_info import WalletInfo
|
|
128
129
|
from chia.wallet.wallet_interested_store import WalletInterestedStore
|
|
129
130
|
from chia.wallet.wallet_nft_store import WalletNftStore
|
|
@@ -165,16 +166,16 @@ class WalletStateManager:
|
|
|
165
166
|
log: logging.Logger
|
|
166
167
|
|
|
167
168
|
# TODO Don't allow user to send tx until wallet is synced
|
|
168
|
-
_sync_target:
|
|
169
|
+
_sync_target: uint32 | None
|
|
169
170
|
|
|
170
|
-
state_changed_callback:
|
|
171
|
-
pending_tx_callback:
|
|
171
|
+
state_changed_callback: StateChangedProtocol | None = None
|
|
172
|
+
pending_tx_callback: PendingTxCallback | None
|
|
172
173
|
db_path: Path
|
|
173
174
|
db_wrapper: DBWrapper2
|
|
174
175
|
|
|
175
176
|
main_wallet: Wallet
|
|
176
177
|
wallets: dict[uint32, WalletProtocol[Any]]
|
|
177
|
-
private_key:
|
|
178
|
+
private_key: PrivateKey | None
|
|
178
179
|
root_pubkey: G1Element
|
|
179
180
|
|
|
180
181
|
trade_manager: TradeManager
|
|
@@ -196,14 +197,14 @@ class WalletStateManager:
|
|
|
196
197
|
|
|
197
198
|
@staticmethod
|
|
198
199
|
async def create(
|
|
199
|
-
private_key:
|
|
200
|
+
private_key: PrivateKey | None,
|
|
200
201
|
config: dict[str, Any],
|
|
201
202
|
db_path: Path,
|
|
202
203
|
constants: ConsensusConstants,
|
|
203
204
|
server: ChiaServer,
|
|
204
205
|
root_path: Path,
|
|
205
206
|
wallet_node: WalletNode,
|
|
206
|
-
root_pubkey:
|
|
207
|
+
root_pubkey: G1Element | None = None,
|
|
207
208
|
) -> WalletStateManager:
|
|
208
209
|
self = WalletStateManager()
|
|
209
210
|
|
|
@@ -214,7 +215,7 @@ class WalletStateManager:
|
|
|
214
215
|
self.log = logging.getLogger(__name__)
|
|
215
216
|
self.lock = asyncio.Lock()
|
|
216
217
|
self.log.debug(f"Starting in db path: {db_path}")
|
|
217
|
-
sql_log_path:
|
|
218
|
+
sql_log_path: Path | None = None
|
|
218
219
|
if self.config.get("log_sqlite_cmds", False):
|
|
219
220
|
sql_log_path = path_from_root(self.root_path, "log/wallet_sql.log")
|
|
220
221
|
self.log.info(f"logging SQL commands to {sql_log_path}")
|
|
@@ -280,7 +281,7 @@ class WalletStateManager:
|
|
|
280
281
|
AssetType.CAT: CATWallet,
|
|
281
282
|
}
|
|
282
283
|
|
|
283
|
-
wallet:
|
|
284
|
+
wallet: WalletProtocol[Any] | None = None
|
|
284
285
|
for wallet_info in await self.get_all_wallet_info_entries():
|
|
285
286
|
wallet_type = WalletType(wallet_info.type)
|
|
286
287
|
if wallet_type == WalletType.STANDARD_WALLET:
|
|
@@ -367,9 +368,13 @@ class WalletStateManager:
|
|
|
367
368
|
return self.private_key
|
|
368
369
|
|
|
369
370
|
def get_wallet(self, id: uint32, required_type: type[TWalletType]) -> TWalletType:
|
|
371
|
+
if id not in self.wallets:
|
|
372
|
+
raise ValueError(f"Wallet with id {id} does not exist")
|
|
373
|
+
|
|
370
374
|
wallet = self.wallets[id]
|
|
375
|
+
|
|
371
376
|
if not isinstance(wallet, required_type):
|
|
372
|
-
raise
|
|
377
|
+
raise ValueError(
|
|
373
378
|
f"wallet id {id} is of type {type(wallet).__name__} but type {required_type.__name__} is required",
|
|
374
379
|
)
|
|
375
380
|
|
|
@@ -389,9 +394,9 @@ class WalletStateManager:
|
|
|
389
394
|
self,
|
|
390
395
|
from_zero: bool = False,
|
|
391
396
|
mark_existing_as_used: bool = True,
|
|
392
|
-
up_to_index:
|
|
393
|
-
num_additional_phs:
|
|
394
|
-
previous_result:
|
|
397
|
+
up_to_index: uint32 | None = None,
|
|
398
|
+
num_additional_phs: int | None = None,
|
|
399
|
+
previous_result: CreateMorePuzzleHashesResult | None = None,
|
|
395
400
|
_commit_previous_result: bool = True,
|
|
396
401
|
) -> CreateMorePuzzleHashesResult:
|
|
397
402
|
"""
|
|
@@ -408,8 +413,8 @@ class WalletStateManager:
|
|
|
408
413
|
if _commit_previous_result:
|
|
409
414
|
await previous_result.commit(self)
|
|
410
415
|
targets = list(self.wallets.keys())
|
|
411
|
-
self.log.debug("Target wallets to generate puzzle hashes for: %
|
|
412
|
-
unused:
|
|
416
|
+
self.log.debug("Target wallets to generate puzzle hashes for: %r", targets)
|
|
417
|
+
unused: uint32 | None = (
|
|
413
418
|
up_to_index if up_to_index is not None else await self.puzzle_store.get_unused_derivation_path()
|
|
414
419
|
)
|
|
415
420
|
if unused is None:
|
|
@@ -439,7 +444,7 @@ class WalletStateManager:
|
|
|
439
444
|
if from_zero:
|
|
440
445
|
start_index_by_wallet[wallet_id] = 0
|
|
441
446
|
continue
|
|
442
|
-
last:
|
|
447
|
+
last: uint32 | None = await self.puzzle_store.get_last_derivation_path_for_wallet(wallet_id)
|
|
443
448
|
if last is not None:
|
|
444
449
|
if last >= last_index:
|
|
445
450
|
self.log.debug(f"Nothing to create for for wallet_id: {wallet_id}, index: {last_index}")
|
|
@@ -490,7 +495,7 @@ class WalletStateManager:
|
|
|
490
495
|
)
|
|
491
496
|
self.log.info(f"Start: {creating_msg}")
|
|
492
497
|
for index in range(start_index, last_index + 1):
|
|
493
|
-
pubkey:
|
|
498
|
+
pubkey: G1Element | None = hardened_keys.get(index)
|
|
494
499
|
if pubkey is not None:
|
|
495
500
|
# Hardened
|
|
496
501
|
puzzlehash: bytes32 = target_wallet.puzzle_hash_for_pk(pubkey)
|
|
@@ -540,8 +545,8 @@ class WalletStateManager:
|
|
|
540
545
|
async def update_wallet_puzzle_hashes(self, wallet_id: uint32) -> None:
|
|
541
546
|
derivation_paths: list[DerivationRecord] = []
|
|
542
547
|
target_wallet = self.wallets[wallet_id]
|
|
543
|
-
last:
|
|
544
|
-
unused:
|
|
548
|
+
last: uint32 | None = await self.puzzle_store.get_last_derivation_path_for_wallet(wallet_id)
|
|
549
|
+
unused: uint32 | None = await self.puzzle_store.get_unused_derivation_path_for_wallet(wallet_id)
|
|
545
550
|
if unused is None:
|
|
546
551
|
# This handles the case where the database has entries but they have all been used
|
|
547
552
|
unused = await self.puzzle_store.get_last_derivation_path()
|
|
@@ -571,7 +576,7 @@ class WalletStateManager:
|
|
|
571
576
|
wallet_id: uint32,
|
|
572
577
|
*,
|
|
573
578
|
hardened: bool = False,
|
|
574
|
-
previous_result:
|
|
579
|
+
previous_result: GetUnusedDerivationRecordResult | None = None,
|
|
575
580
|
) -> GetUnusedDerivationRecordResult:
|
|
576
581
|
"""
|
|
577
582
|
Creates a puzzle hash for the given wallet, and then makes more puzzle hashes
|
|
@@ -582,13 +587,13 @@ class WalletStateManager:
|
|
|
582
587
|
async with self.puzzle_hash_db_writer():
|
|
583
588
|
if previous_result is not None:
|
|
584
589
|
await previous_result.commit(self)
|
|
585
|
-
create_more_puzzle_hashes_result:
|
|
590
|
+
create_more_puzzle_hashes_result: CreateMorePuzzleHashesResult | None = (
|
|
586
591
|
previous_result.create_more_puzzle_hashes_result
|
|
587
592
|
)
|
|
588
593
|
else:
|
|
589
594
|
create_more_puzzle_hashes_result = None
|
|
590
595
|
# If we have no unused public keys, we will create new ones
|
|
591
|
-
unused:
|
|
596
|
+
unused: uint32 | None = await self.puzzle_store.get_unused_derivation_path()
|
|
592
597
|
if unused is None:
|
|
593
598
|
self.log.debug("No unused paths, generate more ")
|
|
594
599
|
create_more_puzzle_hashes_result = await self.create_more_puzzle_hashes(
|
|
@@ -600,7 +605,7 @@ class WalletStateManager:
|
|
|
600
605
|
assert unused is not None
|
|
601
606
|
|
|
602
607
|
self.log.debug("Fetching derivation record for: %s %s %s", unused, wallet_id, hardened)
|
|
603
|
-
record:
|
|
608
|
+
record: DerivationRecord | None = await self.puzzle_store.get_derivation_record(
|
|
604
609
|
unused, wallet_id, hardened
|
|
605
610
|
)
|
|
606
611
|
if record is None:
|
|
@@ -625,10 +630,10 @@ class WalletStateManager:
|
|
|
625
630
|
await result.commit(self)
|
|
626
631
|
return result.record
|
|
627
632
|
|
|
628
|
-
async def get_current_derivation_record_for_wallet(self, wallet_id: uint32) ->
|
|
633
|
+
async def get_current_derivation_record_for_wallet(self, wallet_id: uint32) -> DerivationRecord | None:
|
|
629
634
|
async with self.puzzle_store.lock:
|
|
630
635
|
# If we have no unused public keys, we will create new ones
|
|
631
|
-
current:
|
|
636
|
+
current: DerivationRecord | None = await self.puzzle_store.get_current_derivation_record_for_wallet(
|
|
632
637
|
wallet_id
|
|
633
638
|
)
|
|
634
639
|
return current
|
|
@@ -646,7 +651,7 @@ class WalletStateManager:
|
|
|
646
651
|
self.pending_tx_callback = callback
|
|
647
652
|
|
|
648
653
|
def state_changed(
|
|
649
|
-
self, state: str, wallet_id:
|
|
654
|
+
self, state: str, wallet_id: int | None = None, data_object: dict[str, Any] | None = None
|
|
650
655
|
) -> None:
|
|
651
656
|
"""
|
|
652
657
|
Calls the callback if it's present.
|
|
@@ -669,7 +674,7 @@ class WalletStateManager:
|
|
|
669
674
|
|
|
670
675
|
self.pending_tx_callback()
|
|
671
676
|
|
|
672
|
-
async def synced(self, block_is_current_at:
|
|
677
|
+
async def synced(self, block_is_current_at: int | None = None) -> bool:
|
|
673
678
|
if block_is_current_at is None:
|
|
674
679
|
block_is_current_at = int(time.time() - 60 * 5)
|
|
675
680
|
if len(self.server.get_connections(NodeType.FULL_NODE)) == 0:
|
|
@@ -697,7 +702,7 @@ class WalletStateManager:
|
|
|
697
702
|
return self._sync_target is not None
|
|
698
703
|
|
|
699
704
|
@property
|
|
700
|
-
def sync_target(self) ->
|
|
705
|
+
def sync_target(self) -> uint32 | None:
|
|
701
706
|
return self._sync_target
|
|
702
707
|
|
|
703
708
|
@asynccontextmanager
|
|
@@ -727,7 +732,7 @@ class WalletStateManager:
|
|
|
727
732
|
self._sync_target = None
|
|
728
733
|
|
|
729
734
|
async def get_confirmed_spendable_balance_for_wallet(
|
|
730
|
-
self, wallet_id: int, unspent_records:
|
|
735
|
+
self, wallet_id: int, unspent_records: set[WalletCoinRecord] | None = None
|
|
731
736
|
) -> uint128:
|
|
732
737
|
"""
|
|
733
738
|
Returns the balance amount of all coins that are spendable.
|
|
@@ -753,7 +758,7 @@ class WalletStateManager:
|
|
|
753
758
|
async def get_confirmed_balance_for_wallet(
|
|
754
759
|
self,
|
|
755
760
|
wallet_id: int,
|
|
756
|
-
unspent_coin_records:
|
|
761
|
+
unspent_coin_records: set[WalletCoinRecord] | None = None,
|
|
757
762
|
) -> uint128:
|
|
758
763
|
"""
|
|
759
764
|
Returns the confirmed balance, including coinbase rewards that are not spendable.
|
|
@@ -768,7 +773,7 @@ class WalletStateManager:
|
|
|
768
773
|
return uint128(sum(cr.coin.amount for cr in unspent_coin_records))
|
|
769
774
|
|
|
770
775
|
async def get_unconfirmed_balance(
|
|
771
|
-
self, wallet_id: int, unspent_coin_records:
|
|
776
|
+
self, wallet_id: int, unspent_coin_records: set[WalletCoinRecord] | None = None
|
|
772
777
|
) -> uint128:
|
|
773
778
|
"""
|
|
774
779
|
Returns the balance, including coinbase rewards that are not spendable, and unconfirmed
|
|
@@ -825,8 +830,8 @@ class WalletStateManager:
|
|
|
825
830
|
return {**removals, **{coin_id: cr.coin for coin_id, cr in trade_removals.items() if cr.wallet_id == wallet_id}}
|
|
826
831
|
|
|
827
832
|
async def determine_coin_type(
|
|
828
|
-
self, peer: WSChiaConnection, coin_state: CoinState, fork_height:
|
|
829
|
-
) -> tuple[
|
|
833
|
+
self, peer: WSChiaConnection, coin_state: CoinState, fork_height: uint32 | None
|
|
834
|
+
) -> tuple[WalletIdentifier | None, Streamable | None]:
|
|
830
835
|
if coin_state.created_height is not None and (
|
|
831
836
|
self.is_pool_reward(uint32(coin_state.created_height), coin_state.coin)
|
|
832
837
|
or self.is_farmer_reward(uint32(coin_state.created_height), coin_state.coin)
|
|
@@ -883,7 +888,7 @@ class WalletStateManager:
|
|
|
883
888
|
p2_puzzle, recovery_list_hash, num_verification, singleton_struct, metadata = did_curried_args
|
|
884
889
|
did_data: DIDCoinData = DIDCoinData(
|
|
885
890
|
p2_puzzle,
|
|
886
|
-
bytes32(recovery_list_hash.as_atom()) if recovery_list_hash != Program.
|
|
891
|
+
bytes32(recovery_list_hash.as_atom()) if recovery_list_hash != Program.NIL else None,
|
|
887
892
|
uint16(num_verification.as_int()),
|
|
888
893
|
singleton_struct,
|
|
889
894
|
metadata,
|
|
@@ -964,7 +969,7 @@ class WalletStateManager:
|
|
|
964
969
|
coin_spends: list[CoinSpend] = []
|
|
965
970
|
message: bytes32 = std_hash(b"".join([c.name() for c in clawback_coins.keys()]))
|
|
966
971
|
now: uint64 = uint64(time.time())
|
|
967
|
-
derivation_record:
|
|
972
|
+
derivation_record: DerivationRecord | None = None
|
|
968
973
|
amount: uint64 = uint64(0)
|
|
969
974
|
for coin, metadata in clawback_coins.items():
|
|
970
975
|
try:
|
|
@@ -1113,8 +1118,8 @@ class WalletStateManager:
|
|
|
1113
1118
|
coin_state: CoinState,
|
|
1114
1119
|
coin_spend: CoinSpend,
|
|
1115
1120
|
peer: WSChiaConnection,
|
|
1116
|
-
fork_height:
|
|
1117
|
-
) ->
|
|
1121
|
+
fork_height: uint32 | None,
|
|
1122
|
+
) -> WalletIdentifier | None:
|
|
1118
1123
|
"""
|
|
1119
1124
|
Handle the new coin when it is a CAT
|
|
1120
1125
|
:param parent_data: Parent CAT coin uncurried metadata
|
|
@@ -1210,7 +1215,7 @@ class WalletStateManager:
|
|
|
1210
1215
|
cat_wallet: CATWallet = await CRCATWallet.get_or_create_wallet_for_cat(
|
|
1211
1216
|
self,
|
|
1212
1217
|
self.main_wallet,
|
|
1213
|
-
crcat.tail_hash
|
|
1218
|
+
crcat.tail_hash,
|
|
1214
1219
|
authorized_providers=crcat.authorized_providers,
|
|
1215
1220
|
proofs_checker=ProofsChecker.from_program(uncurry_puzzle(crcat.proofs_checker)),
|
|
1216
1221
|
)
|
|
@@ -1218,20 +1223,20 @@ class WalletStateManager:
|
|
|
1218
1223
|
cat_wallet = await RCATWallet.get_or_create_wallet_for_cat(
|
|
1219
1224
|
self,
|
|
1220
1225
|
self.main_wallet,
|
|
1221
|
-
parent_data.tail_program_hash
|
|
1226
|
+
parent_data.tail_program_hash,
|
|
1222
1227
|
# too complicated for mypy but semantics guarantee this not to be None
|
|
1223
1228
|
hidden_puzzle_hash=revocation_layer_match[0], # type: ignore[index]
|
|
1224
1229
|
)
|
|
1225
1230
|
else:
|
|
1226
1231
|
cat_wallet = await CATWallet.get_or_create_wallet_for_cat(
|
|
1227
|
-
self, self.main_wallet, parent_data.tail_program_hash
|
|
1232
|
+
self, self.main_wallet, parent_data.tail_program_hash
|
|
1228
1233
|
)
|
|
1229
1234
|
return WalletIdentifier.create(cat_wallet)
|
|
1230
1235
|
else:
|
|
1231
1236
|
# Found unacknowledged CAT, save it in the database.
|
|
1232
1237
|
await self.interested_store.add_unacknowledged_token(
|
|
1233
1238
|
asset_id,
|
|
1234
|
-
CATWallet.default_wallet_name_for_unknown_cat(asset_id
|
|
1239
|
+
CATWallet.default_wallet_name_for_unknown_cat(asset_id),
|
|
1235
1240
|
None if parent_coin_state.spent_height is None else uint32(parent_coin_state.spent_height),
|
|
1236
1241
|
parent_coin_state.coin.puzzle_hash,
|
|
1237
1242
|
)
|
|
@@ -1250,7 +1255,7 @@ class WalletStateManager:
|
|
|
1250
1255
|
coin_state: CoinState,
|
|
1251
1256
|
coin_spend: CoinSpend,
|
|
1252
1257
|
peer: WSChiaConnection,
|
|
1253
|
-
) ->
|
|
1258
|
+
) -> WalletIdentifier | None:
|
|
1254
1259
|
"""
|
|
1255
1260
|
Handle the new coin when it is a DID
|
|
1256
1261
|
:param parent_data: Curried data of the DID coin
|
|
@@ -1309,7 +1314,7 @@ class WalletStateManager:
|
|
|
1309
1314
|
)
|
|
1310
1315
|
alt_did_puzzle_empty_recovery = DID_INNERPUZ_MOD.curry(
|
|
1311
1316
|
our_inner_puzzle,
|
|
1312
|
-
NIL,
|
|
1317
|
+
Program.NIL,
|
|
1313
1318
|
uint64(0),
|
|
1314
1319
|
parent_data.singleton_struct,
|
|
1315
1320
|
parent_data.metadata,
|
|
@@ -1367,12 +1372,12 @@ class WalletStateManager:
|
|
|
1367
1372
|
)
|
|
1368
1373
|
return None
|
|
1369
1374
|
|
|
1370
|
-
async def get_minter_did(self, launcher_coin: Coin, peer: WSChiaConnection) ->
|
|
1375
|
+
async def get_minter_did(self, launcher_coin: Coin, peer: WSChiaConnection) -> bytes32 | None:
|
|
1371
1376
|
# Get minter DID
|
|
1372
1377
|
eve_coin = (await self.wallet_node.fetch_children(launcher_coin.name(), peer=peer))[0]
|
|
1373
1378
|
eve_coin_spend = await fetch_coin_spend_for_coin_state(eve_coin, peer)
|
|
1374
1379
|
eve_full_puzzle: Program = Program.from_bytes(bytes(eve_coin_spend.puzzle_reveal))
|
|
1375
|
-
eve_uncurried_nft:
|
|
1380
|
+
eve_uncurried_nft: UncurriedNFT | None = UncurriedNFT.uncurry(*eve_full_puzzle.uncurry())
|
|
1376
1381
|
if eve_uncurried_nft is None:
|
|
1377
1382
|
raise ValueError("Couldn't get minter DID for NFT")
|
|
1378
1383
|
if not eve_uncurried_nft.supports_did:
|
|
@@ -1410,7 +1415,7 @@ class WalletStateManager:
|
|
|
1410
1415
|
async def handle_nft(
|
|
1411
1416
|
self,
|
|
1412
1417
|
nft_data: NFTCoinData,
|
|
1413
|
-
) ->
|
|
1418
|
+
) -> WalletIdentifier | None:
|
|
1414
1419
|
"""
|
|
1415
1420
|
Handle the new coin when it is a NFT
|
|
1416
1421
|
:param nft_data: all necessary data to process a NFT coin
|
|
@@ -1418,7 +1423,7 @@ class WalletStateManager:
|
|
|
1418
1423
|
"""
|
|
1419
1424
|
wallet_identifier = None
|
|
1420
1425
|
# DID ID determines which NFT wallet should process the NFT
|
|
1421
|
-
new_did_id:
|
|
1426
|
+
new_did_id: bytes32 | None = None
|
|
1422
1427
|
old_did_id = None
|
|
1423
1428
|
# P2 puzzle hash determines if we should ignore the NFT
|
|
1424
1429
|
uncurried_nft: UncurriedNFT = nft_data.uncurried_nft
|
|
@@ -1446,12 +1451,12 @@ class WalletStateManager:
|
|
|
1446
1451
|
old_p2_puzhash,
|
|
1447
1452
|
new_p2_puzhash,
|
|
1448
1453
|
)
|
|
1449
|
-
new_derivation_record:
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
old_derivation_record:
|
|
1453
|
-
|
|
1454
|
-
|
|
1454
|
+
new_derivation_record: DerivationRecord | None = await self.puzzle_store.get_derivation_record_for_puzzle_hash(
|
|
1455
|
+
new_p2_puzhash
|
|
1456
|
+
)
|
|
1457
|
+
old_derivation_record: DerivationRecord | None = await self.puzzle_store.get_derivation_record_for_puzzle_hash(
|
|
1458
|
+
old_p2_puzhash
|
|
1459
|
+
)
|
|
1455
1460
|
if new_derivation_record is None and old_derivation_record is None:
|
|
1456
1461
|
self.log.debug(
|
|
1457
1462
|
"Cannot find a P2 puzzle hash for NFT:%s, this NFT belongs to others.",
|
|
@@ -1511,7 +1516,7 @@ class WalletStateManager:
|
|
|
1511
1516
|
coin_state: CoinState,
|
|
1512
1517
|
coin_spend: CoinSpend,
|
|
1513
1518
|
peer: WSChiaConnection,
|
|
1514
|
-
) ->
|
|
1519
|
+
) -> WalletIdentifier | None:
|
|
1515
1520
|
"""
|
|
1516
1521
|
Handle Clawback coins
|
|
1517
1522
|
:param metadata: Clawback metadata for spending the merkle coin
|
|
@@ -1522,11 +1527,11 @@ class WalletStateManager:
|
|
|
1522
1527
|
"""
|
|
1523
1528
|
# Record metadata
|
|
1524
1529
|
assert coin_state.created_height is not None
|
|
1525
|
-
is_recipient:
|
|
1530
|
+
is_recipient: bool | None = None
|
|
1526
1531
|
# Check if the wallet is the sender
|
|
1527
|
-
sender_derivation_record:
|
|
1528
|
-
DerivationRecord
|
|
1529
|
-
|
|
1532
|
+
sender_derivation_record: (
|
|
1533
|
+
DerivationRecord | None
|
|
1534
|
+
) = await self.puzzle_store.get_derivation_record_for_puzzle_hash(metadata.sender_puzzle_hash)
|
|
1530
1535
|
# Check if the wallet is the recipient
|
|
1531
1536
|
recipient_derivation_record = await self.puzzle_store.get_derivation_record_for_puzzle_hash(
|
|
1532
1537
|
metadata.recipient_puzzle_hash
|
|
@@ -1623,9 +1628,9 @@ class WalletStateManager:
|
|
|
1623
1628
|
await self.tx_store.add_transaction_record(tx_record)
|
|
1624
1629
|
return None
|
|
1625
1630
|
|
|
1626
|
-
async def handle_vc(self, vc: VerifiedCredential) ->
|
|
1631
|
+
async def handle_vc(self, vc: VerifiedCredential) -> WalletIdentifier | None:
|
|
1627
1632
|
# Check the ownership
|
|
1628
|
-
derivation_record:
|
|
1633
|
+
derivation_record: DerivationRecord | None = await self.puzzle_store.get_derivation_record_for_puzzle_hash(
|
|
1629
1634
|
vc.inner_puzzle_hash
|
|
1630
1635
|
)
|
|
1631
1636
|
if derivation_record is None:
|
|
@@ -1644,7 +1649,7 @@ class WalletStateManager:
|
|
|
1644
1649
|
self,
|
|
1645
1650
|
coin_states: list[CoinState],
|
|
1646
1651
|
peer: WSChiaConnection,
|
|
1647
|
-
fork_height:
|
|
1652
|
+
fork_height: uint32 | None,
|
|
1648
1653
|
) -> None:
|
|
1649
1654
|
# TODO: add comment about what this method does
|
|
1650
1655
|
# Input states should already be sorted by cs_height, with reorgs at the beginning
|
|
@@ -1676,7 +1681,7 @@ class WalletStateManager:
|
|
|
1676
1681
|
await self.retry_store.remove_state(coin_state)
|
|
1677
1682
|
|
|
1678
1683
|
wallet_identifier = await self.get_wallet_identifier_for_puzzle_hash(coin_state.coin.puzzle_hash)
|
|
1679
|
-
coin_data:
|
|
1684
|
+
coin_data: Streamable | None = None
|
|
1680
1685
|
# If we already have this coin, & it was spent & confirmed at the same heights, then return (done)
|
|
1681
1686
|
if local_record is not None:
|
|
1682
1687
|
local_spent = None
|
|
@@ -1781,7 +1786,7 @@ class WalletStateManager:
|
|
|
1781
1786
|
)
|
|
1782
1787
|
await self.coin_store.add_coin_record(record)
|
|
1783
1788
|
# Coin first received
|
|
1784
|
-
parent_coin_record:
|
|
1789
|
+
parent_coin_record: WalletCoinRecord | None = await self.coin_store.get_coin_record(
|
|
1785
1790
|
coin_state.coin.parent_coin_info
|
|
1786
1791
|
)
|
|
1787
1792
|
if (
|
|
@@ -1826,8 +1831,8 @@ class WalletStateManager:
|
|
|
1826
1831
|
fee = 0
|
|
1827
1832
|
|
|
1828
1833
|
to_puzzle_hash = None
|
|
1829
|
-
coin_spend:
|
|
1830
|
-
clawback_metadata:
|
|
1834
|
+
coin_spend: CoinSpend | None = None
|
|
1835
|
+
clawback_metadata: ClawbackMetadata | None = None
|
|
1831
1836
|
# Find coin that doesn't belong to us
|
|
1832
1837
|
amount = 0
|
|
1833
1838
|
for coin in additions:
|
|
@@ -2072,7 +2077,7 @@ class WalletStateManager:
|
|
|
2072
2077
|
self,
|
|
2073
2078
|
coin_states: list[CoinState],
|
|
2074
2079
|
peer: WSChiaConnection,
|
|
2075
|
-
fork_height:
|
|
2080
|
+
fork_height: uint32 | None,
|
|
2076
2081
|
) -> bool:
|
|
2077
2082
|
try:
|
|
2078
2083
|
await self._add_coin_states(coin_states, peer, fork_height)
|
|
@@ -2122,7 +2127,7 @@ class WalletStateManager:
|
|
|
2122
2127
|
return True
|
|
2123
2128
|
return False
|
|
2124
2129
|
|
|
2125
|
-
async def get_wallet_identifier_for_puzzle_hash(self, puzzle_hash: bytes32) ->
|
|
2130
|
+
async def get_wallet_identifier_for_puzzle_hash(self, puzzle_hash: bytes32) -> WalletIdentifier | None:
|
|
2126
2131
|
wallet_identifier = await self.puzzle_store.get_wallet_identifier_for_puzzle_hash(puzzle_hash)
|
|
2127
2132
|
if wallet_identifier is not None:
|
|
2128
2133
|
return wallet_identifier
|
|
@@ -2138,7 +2143,7 @@ class WalletStateManager:
|
|
|
2138
2143
|
|
|
2139
2144
|
async def get_wallet_identifier_for_coin(
|
|
2140
2145
|
self, coin: Coin, hint_dict: dict[bytes32, bytes32] = {}
|
|
2141
|
-
) ->
|
|
2146
|
+
) -> WalletIdentifier | None:
|
|
2142
2147
|
wallet_identifier = await self.puzzle_store.get_wallet_identifier_for_puzzle_hash(coin.puzzle_hash)
|
|
2143
2148
|
if (
|
|
2144
2149
|
wallet_identifier is None
|
|
@@ -2153,7 +2158,7 @@ class WalletStateManager:
|
|
|
2153
2158
|
|
|
2154
2159
|
return wallet_identifier
|
|
2155
2160
|
|
|
2156
|
-
async def get_wallet_identifier_for_hinted_coin(self, coin: Coin, hint: bytes32) ->
|
|
2161
|
+
async def get_wallet_identifier_for_hinted_coin(self, coin: Coin, hint: bytes32) -> WalletIdentifier | None:
|
|
2157
2162
|
for wallet in self.wallets.values():
|
|
2158
2163
|
if await wallet.match_hinted_coin(coin, hint):
|
|
2159
2164
|
return WalletIdentifier(wallet.id(), wallet.type())
|
|
@@ -2168,7 +2173,7 @@ class WalletStateManager:
|
|
|
2168
2173
|
wallet_type: WalletType,
|
|
2169
2174
|
peer: WSChiaConnection,
|
|
2170
2175
|
coin_name: bytes32,
|
|
2171
|
-
coin_data:
|
|
2176
|
+
coin_data: object | None,
|
|
2172
2177
|
) -> None:
|
|
2173
2178
|
"""
|
|
2174
2179
|
Adding coin to DB
|
|
@@ -2198,7 +2203,7 @@ class WalletStateManager:
|
|
|
2198
2203
|
coin_confirmed_transaction = True
|
|
2199
2204
|
break
|
|
2200
2205
|
|
|
2201
|
-
parent_coin_record:
|
|
2206
|
+
parent_coin_record: WalletCoinRecord | None = await self.coin_store.get_coin_record(coin.parent_coin_info)
|
|
2202
2207
|
change = parent_coin_record is not None and wallet_type.value == parent_coin_record.wallet_type
|
|
2203
2208
|
# If the coin is from a Clawback spent, we want to add the INCOMING_TX,
|
|
2204
2209
|
# no matter if there is another TX updated.
|
|
@@ -2246,9 +2251,9 @@ class WalletStateManager:
|
|
|
2246
2251
|
tx_records: list[TransactionRecord],
|
|
2247
2252
|
push: bool = True,
|
|
2248
2253
|
merge_spends: bool = True,
|
|
2249
|
-
sign:
|
|
2250
|
-
additional_signing_responses:
|
|
2251
|
-
extra_spends:
|
|
2254
|
+
sign: bool | None = None,
|
|
2255
|
+
additional_signing_responses: list[SigningResponse] | None = None,
|
|
2256
|
+
extra_spends: list[WalletSpendBundle] | None = None,
|
|
2252
2257
|
singleton_records: list[SingletonRecord] = [],
|
|
2253
2258
|
) -> list[TransactionRecord]:
|
|
2254
2259
|
"""
|
|
@@ -2321,7 +2326,7 @@ class WalletStateManager:
|
|
|
2321
2326
|
spendbundle_id: bytes32,
|
|
2322
2327
|
name: str,
|
|
2323
2328
|
send_status: MempoolInclusionStatus,
|
|
2324
|
-
error:
|
|
2329
|
+
error: Err | None,
|
|
2325
2330
|
) -> None:
|
|
2326
2331
|
"""
|
|
2327
2332
|
Full node received our transaction, no need to keep it in queue anymore, unless there was an error
|
|
@@ -2329,7 +2334,7 @@ class WalletStateManager:
|
|
|
2329
2334
|
|
|
2330
2335
|
updated = await self.tx_store.increment_sent(spendbundle_id, name, send_status, error)
|
|
2331
2336
|
if updated:
|
|
2332
|
-
tx:
|
|
2337
|
+
tx: TransactionRecord | None = await self.get_transaction(spendbundle_id)
|
|
2333
2338
|
if tx is not None and tx.spend_bundle is not None:
|
|
2334
2339
|
self.log.info("Checking if we need to cancel trade for tx: %s", tx.name)
|
|
2335
2340
|
# we're only interested in errors that are not temporary
|
|
@@ -2385,7 +2390,7 @@ class WalletStateManager:
|
|
|
2385
2390
|
records = await self.tx_store.get_all_transactions_for_wallet(wallet_id)
|
|
2386
2391
|
return records
|
|
2387
2392
|
|
|
2388
|
-
async def get_transaction(self, tx_id: bytes32) ->
|
|
2393
|
+
async def get_transaction(self, tx_id: bytes32) -> TransactionRecord | None:
|
|
2389
2394
|
return await self.tx_store.get_transaction_record(tx_id)
|
|
2390
2395
|
|
|
2391
2396
|
async def get_coin_record_by_wallet_record(self, wr: WalletCoinRecord) -> CoinRecord:
|
|
@@ -2396,7 +2401,7 @@ class WalletStateManager:
|
|
|
2396
2401
|
result = await self.coin_store.get_coin_records(**kwargs)
|
|
2397
2402
|
return [await self.get_coin_record_by_wallet_record(record) for record in result.records]
|
|
2398
2403
|
|
|
2399
|
-
async def get_wallet_for_coin(self, coin_id: bytes32) ->
|
|
2404
|
+
async def get_wallet_for_coin(self, coin_id: bytes32) -> WalletProtocol[Any] | None:
|
|
2400
2405
|
coin_record = await self.coin_store.get_coin_record(coin_id)
|
|
2401
2406
|
if coin_record is None:
|
|
2402
2407
|
return None
|
|
@@ -2448,10 +2453,10 @@ class WalletStateManager:
|
|
|
2448
2453
|
def unlink_db(self) -> None:
|
|
2449
2454
|
Path(self.db_path).unlink()
|
|
2450
2455
|
|
|
2451
|
-
async def get_all_wallet_info_entries(self, wallet_type:
|
|
2456
|
+
async def get_all_wallet_info_entries(self, wallet_type: WalletType | None = None) -> list[WalletInfo]:
|
|
2452
2457
|
return await self.user_store.get_all_wallet_info_entries(wallet_type)
|
|
2453
2458
|
|
|
2454
|
-
async def get_wallet_for_asset_id(self, asset_id:
|
|
2459
|
+
async def get_wallet_for_asset_id(self, asset_id: bytes32) -> WalletProtocol[Any] | None:
|
|
2455
2460
|
for wallet_id, wallet in self.wallets.items():
|
|
2456
2461
|
if wallet.type() in {WalletType.CAT, WalletType.CRCAT, WalletType.RCAT}:
|
|
2457
2462
|
assert isinstance(wallet, CATWallet)
|
|
@@ -2459,16 +2464,16 @@ class WalletStateManager:
|
|
|
2459
2464
|
return wallet
|
|
2460
2465
|
elif wallet.type() == WalletType.DATA_LAYER:
|
|
2461
2466
|
assert isinstance(wallet, DataLayerWallet)
|
|
2462
|
-
if await wallet.get_latest_singleton(
|
|
2467
|
+
if await wallet.get_latest_singleton(asset_id) is not None:
|
|
2463
2468
|
return wallet
|
|
2464
2469
|
elif wallet.type() == WalletType.NFT:
|
|
2465
2470
|
assert isinstance(wallet, NFTWallet)
|
|
2466
|
-
nft_coin = await self.nft_store.get_nft_by_id(
|
|
2471
|
+
nft_coin = await self.nft_store.get_nft_by_id(asset_id, wallet_id)
|
|
2467
2472
|
if nft_coin:
|
|
2468
2473
|
return wallet
|
|
2469
2474
|
return None
|
|
2470
2475
|
|
|
2471
|
-
async def get_wallet_for_puzzle_info(self, puzzle_driver: PuzzleInfo) ->
|
|
2476
|
+
async def get_wallet_for_puzzle_info(self, puzzle_driver: PuzzleInfo) -> WalletProtocol[Any] | None:
|
|
2472
2477
|
for wallet in self.wallets.values():
|
|
2473
2478
|
match_function = getattr(wallet, "match_puzzle_info", None)
|
|
2474
2479
|
if match_function is not None and callable(match_function):
|
|
@@ -2476,7 +2481,7 @@ class WalletStateManager:
|
|
|
2476
2481
|
return wallet
|
|
2477
2482
|
return None
|
|
2478
2483
|
|
|
2479
|
-
async def create_wallet_for_puzzle_info(self, puzzle_driver: PuzzleInfo, name:
|
|
2484
|
+
async def create_wallet_for_puzzle_info(self, puzzle_driver: PuzzleInfo, name: str | None = None) -> None:
|
|
2480
2485
|
if AssetType(puzzle_driver.type()) in self.asset_to_wallet_map:
|
|
2481
2486
|
await self.asset_to_wallet_map[AssetType(puzzle_driver.type())].create_from_puzzle_info(
|
|
2482
2487
|
self,
|
|
@@ -2495,10 +2500,29 @@ class WalletStateManager:
|
|
|
2495
2500
|
await result.commit(self)
|
|
2496
2501
|
self.state_changed("wallet_created")
|
|
2497
2502
|
|
|
2503
|
+
async def unconfirmed_additions_or_removals_for_wallet(
|
|
2504
|
+
self, *, wallet_id: uint32, get: Literal["additions", "removals"]
|
|
2505
|
+
) -> set[Coin]:
|
|
2506
|
+
unconfirmed_tx: list[TransactionRecord] = await self.tx_store.get_unconfirmed_for_wallet(wallet_id)
|
|
2507
|
+
return_set: set[Coin] = set()
|
|
2508
|
+
for tx in unconfirmed_tx:
|
|
2509
|
+
hint_dict = tx.hint_dict()
|
|
2510
|
+
checked_set = tx.removals if get == "removals" else tx.additions
|
|
2511
|
+
for coin in checked_set:
|
|
2512
|
+
if await self.does_coin_belong_to_wallet(coin, wallet_id, hint_dict):
|
|
2513
|
+
return_set.add(coin)
|
|
2514
|
+
|
|
2515
|
+
return return_set
|
|
2516
|
+
|
|
2498
2517
|
async def get_spendable_coins_for_wallet(
|
|
2499
|
-
self,
|
|
2518
|
+
self,
|
|
2519
|
+
wallet_id: int,
|
|
2520
|
+
records: set[WalletCoinRecord] | None = None,
|
|
2521
|
+
pending_removals: set[bytes32] | None = None,
|
|
2522
|
+
in_one_block: bool = False,
|
|
2500
2523
|
) -> set[WalletCoinRecord]:
|
|
2501
|
-
|
|
2524
|
+
wallet = self.wallets[uint32(wallet_id)]
|
|
2525
|
+
wallet_type = wallet.type()
|
|
2502
2526
|
if records is None:
|
|
2503
2527
|
if wallet_type == WalletType.CRCAT:
|
|
2504
2528
|
records = await self.coin_store.get_unspent_coins_for_wallet(wallet_id, CoinType.CRCAT)
|
|
@@ -2506,25 +2530,30 @@ class WalletStateManager:
|
|
|
2506
2530
|
records = await self.coin_store.get_unspent_coins_for_wallet(wallet_id)
|
|
2507
2531
|
|
|
2508
2532
|
# Coins that are currently part of a transaction
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2533
|
+
if pending_removals is None:
|
|
2534
|
+
pending_removals = {
|
|
2535
|
+
coin.name()
|
|
2536
|
+
for coin in await self.unconfirmed_additions_or_removals_for_wallet(
|
|
2537
|
+
wallet_id=uint32(wallet_id), get="removals"
|
|
2538
|
+
)
|
|
2539
|
+
}
|
|
2516
2540
|
|
|
2517
2541
|
# Coins that are part of the trade
|
|
2518
2542
|
offer_locked_coins: dict[bytes32, WalletCoinRecord] = await self.trade_manager.get_locked_coins()
|
|
2519
2543
|
|
|
2520
2544
|
filtered = set()
|
|
2521
2545
|
for record in records:
|
|
2522
|
-
if record.coin.name() in offer_locked_coins:
|
|
2546
|
+
if record.coin.name() in {*offer_locked_coins.keys(), *pending_removals}:
|
|
2523
2547
|
continue
|
|
2524
|
-
if
|
|
2548
|
+
if hasattr(wallet, "is_coin_spendable") and not await wallet.is_coin_spendable(record):
|
|
2525
2549
|
continue
|
|
2526
2550
|
filtered.add(record)
|
|
2527
2551
|
|
|
2552
|
+
if hasattr(wallet, "max_send_quantity") and in_one_block:
|
|
2553
|
+
filtered_as_list = list(filtered)
|
|
2554
|
+
filtered_as_list.sort(reverse=True, key=lambda rec: rec.coin.amount)
|
|
2555
|
+
return set(filtered_as_list[0 : min(len(filtered_as_list), wallet.max_send_quantity)])
|
|
2556
|
+
|
|
2528
2557
|
return filtered
|
|
2529
2558
|
|
|
2530
2559
|
async def new_peak(self, height: uint32) -> None:
|
|
@@ -2601,10 +2630,10 @@ class WalletStateManager:
|
|
|
2601
2630
|
|
|
2602
2631
|
return vc_wallet
|
|
2603
2632
|
|
|
2604
|
-
async def sum_hint_for_pubkey(self, pk: bytes) ->
|
|
2633
|
+
async def sum_hint_for_pubkey(self, pk: bytes) -> SumHint | None:
|
|
2605
2634
|
return await self.main_wallet.sum_hint_for_pubkey(pk)
|
|
2606
2635
|
|
|
2607
|
-
async def path_hint_for_pubkey(self, pk: bytes) ->
|
|
2636
|
+
async def path_hint_for_pubkey(self, pk: bytes) -> PathHint | None:
|
|
2608
2637
|
return await self.main_wallet.path_hint_for_pubkey(pk)
|
|
2609
2638
|
|
|
2610
2639
|
async def key_hints_for_pubkeys(self, pks: list[bytes]) -> KeyHints:
|
|
@@ -2757,10 +2786,10 @@ class WalletStateManager:
|
|
|
2757
2786
|
tx_config: TXConfig,
|
|
2758
2787
|
push: bool = False,
|
|
2759
2788
|
merge_spends: bool = True,
|
|
2760
|
-
sign:
|
|
2789
|
+
sign: bool | None = None,
|
|
2761
2790
|
additional_signing_responses: list[SigningResponse] = [],
|
|
2762
2791
|
extra_spends: list[WalletSpendBundle] = [],
|
|
2763
|
-
puzzle_for_pk:
|
|
2792
|
+
puzzle_for_pk: Callable[[G1Element], Program] | None = None,
|
|
2764
2793
|
) -> AsyncIterator[WalletActionScope]:
|
|
2765
2794
|
async with new_wallet_action_scope(
|
|
2766
2795
|
self,
|
|
@@ -2780,3 +2809,200 @@ class WalletStateManager:
|
|
|
2780
2809
|
|
|
2781
2810
|
def encode_puzzle_hash(self, puzzle_hash: bytes32) -> str:
|
|
2782
2811
|
return encode_puzzle_hash(puzzle_hash, AddressType.XCH.hrp(self.config))
|
|
2812
|
+
|
|
2813
|
+
def new_outgoing_transaction(
|
|
2814
|
+
self,
|
|
2815
|
+
*,
|
|
2816
|
+
wallet_id: uint32,
|
|
2817
|
+
puzzle_hash: bytes32,
|
|
2818
|
+
amount: uint64,
|
|
2819
|
+
fee: uint64,
|
|
2820
|
+
spend_bundle: WalletSpendBundle,
|
|
2821
|
+
additions: list[Coin],
|
|
2822
|
+
removals: list[Coin],
|
|
2823
|
+
name: bytes32,
|
|
2824
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
2825
|
+
trade_id: bytes32 | None = None,
|
|
2826
|
+
) -> TransactionRecord:
|
|
2827
|
+
return TransactionRecord(
|
|
2828
|
+
confirmed_at_height=uint32(0),
|
|
2829
|
+
created_at_time=uint64(time.time()),
|
|
2830
|
+
to_puzzle_hash=puzzle_hash,
|
|
2831
|
+
to_address=self.encode_puzzle_hash(puzzle_hash),
|
|
2832
|
+
amount=amount,
|
|
2833
|
+
fee_amount=fee,
|
|
2834
|
+
confirmed=False,
|
|
2835
|
+
sent=uint32(0),
|
|
2836
|
+
spend_bundle=spend_bundle,
|
|
2837
|
+
additions=additions,
|
|
2838
|
+
removals=removals,
|
|
2839
|
+
wallet_id=wallet_id,
|
|
2840
|
+
sent_to=[],
|
|
2841
|
+
trade_id=trade_id,
|
|
2842
|
+
type=uint32(TransactionType.OUTGOING_TX.value),
|
|
2843
|
+
name=name,
|
|
2844
|
+
memos=compute_memos(spend_bundle),
|
|
2845
|
+
valid_times=parse_timelock_info(extra_conditions),
|
|
2846
|
+
)
|
|
2847
|
+
|
|
2848
|
+
async def split_coins(
|
|
2849
|
+
self,
|
|
2850
|
+
*,
|
|
2851
|
+
action_scope: WalletActionScope,
|
|
2852
|
+
wallet_id: uint32,
|
|
2853
|
+
target_coin_id: bytes32,
|
|
2854
|
+
amount_per_coin: uint64,
|
|
2855
|
+
number_of_coins: uint16,
|
|
2856
|
+
fee: uint64,
|
|
2857
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
2858
|
+
) -> None:
|
|
2859
|
+
optional_coin = await self.coin_store.get_coin_record(target_coin_id)
|
|
2860
|
+
if optional_coin is None:
|
|
2861
|
+
raise ValueError(f"Could not find coin with ID {target_coin_id}")
|
|
2862
|
+
else:
|
|
2863
|
+
coin = optional_coin.coin
|
|
2864
|
+
|
|
2865
|
+
total_amount = amount_per_coin * number_of_coins
|
|
2866
|
+
|
|
2867
|
+
if coin.amount < total_amount:
|
|
2868
|
+
raise ValueError(f"Coin amount: {coin.amount} is less than the total amount of the split: {total_amount}.")
|
|
2869
|
+
|
|
2870
|
+
if wallet_id not in self.wallets:
|
|
2871
|
+
raise ValueError(f"Wallet with ID {wallet_id} does not exist")
|
|
2872
|
+
wallet = self.wallets[wallet_id]
|
|
2873
|
+
if not isinstance(wallet, (Wallet, CATWallet)):
|
|
2874
|
+
raise ValueError("Cannot split coins from non-fungible wallet types")
|
|
2875
|
+
|
|
2876
|
+
outputs = [
|
|
2877
|
+
CreateCoin(
|
|
2878
|
+
await action_scope.get_puzzle_hash(self, override_reuse_puzhash_with=False),
|
|
2879
|
+
amount_per_coin,
|
|
2880
|
+
)
|
|
2881
|
+
for _ in range(number_of_coins)
|
|
2882
|
+
]
|
|
2883
|
+
|
|
2884
|
+
if wallet.type() == WalletType.STANDARD_WALLET and coin.amount < total_amount + fee:
|
|
2885
|
+
async with action_scope.use() as interface:
|
|
2886
|
+
interface.side_effects.selected_coins.append(coin)
|
|
2887
|
+
coins = await wallet.select_coins(
|
|
2888
|
+
uint64(total_amount + fee - coin.amount),
|
|
2889
|
+
action_scope,
|
|
2890
|
+
)
|
|
2891
|
+
coins.add(coin)
|
|
2892
|
+
else:
|
|
2893
|
+
coins = {coin}
|
|
2894
|
+
|
|
2895
|
+
await wallet.generate_signed_transaction(
|
|
2896
|
+
[output.amount for output in outputs],
|
|
2897
|
+
[output.puzzle_hash for output in outputs],
|
|
2898
|
+
action_scope,
|
|
2899
|
+
fee,
|
|
2900
|
+
coins=coins,
|
|
2901
|
+
extra_conditions=extra_conditions,
|
|
2902
|
+
)
|
|
2903
|
+
|
|
2904
|
+
async def combine_coins(
|
|
2905
|
+
self,
|
|
2906
|
+
*,
|
|
2907
|
+
action_scope: WalletActionScope,
|
|
2908
|
+
wallet_id: uint32,
|
|
2909
|
+
number_of_coins: uint16,
|
|
2910
|
+
largest_first: bool,
|
|
2911
|
+
coin_num_limit: uint16,
|
|
2912
|
+
fee: uint64,
|
|
2913
|
+
target_coin_amount: uint64 | None = None,
|
|
2914
|
+
target_coin_ids: list[bytes32] | None = None,
|
|
2915
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
2916
|
+
) -> None:
|
|
2917
|
+
if wallet_id not in self.wallets:
|
|
2918
|
+
raise ValueError(f"Wallet with ID {wallet_id} does not exist")
|
|
2919
|
+
wallet = self.wallets[wallet_id]
|
|
2920
|
+
if not isinstance(wallet, (Wallet, CATWallet)):
|
|
2921
|
+
raise ValueError("Cannot combine coins from non-fungible wallet types")
|
|
2922
|
+
|
|
2923
|
+
coins: list[Coin] = []
|
|
2924
|
+
|
|
2925
|
+
# First get the coin IDs specified
|
|
2926
|
+
if target_coin_ids is not None:
|
|
2927
|
+
coins.extend(
|
|
2928
|
+
cr.coin
|
|
2929
|
+
for cr in (
|
|
2930
|
+
await self.coin_store.get_coin_records(
|
|
2931
|
+
wallet_id=wallet_id,
|
|
2932
|
+
coin_id_filter=HashFilter(target_coin_ids, mode=uint8(FilterMode.include.value)),
|
|
2933
|
+
)
|
|
2934
|
+
).records
|
|
2935
|
+
)
|
|
2936
|
+
|
|
2937
|
+
async with action_scope.use() as interface:
|
|
2938
|
+
interface.side_effects.selected_coins.extend(coins)
|
|
2939
|
+
|
|
2940
|
+
# Next let's select enough coins to meet the target + fee if there is one
|
|
2941
|
+
fungible_amount_needed = uint64(0) if target_coin_amount is None else target_coin_amount
|
|
2942
|
+
if isinstance(wallet, Wallet):
|
|
2943
|
+
fungible_amount_needed = uint64(fungible_amount_needed + fee)
|
|
2944
|
+
amount_selected = sum(c.amount for c in coins)
|
|
2945
|
+
if amount_selected < fungible_amount_needed: # implicit fungible_amount_needed > 0 here
|
|
2946
|
+
coins.extend(
|
|
2947
|
+
await wallet.select_coins(
|
|
2948
|
+
amount=uint64(fungible_amount_needed - amount_selected), action_scope=action_scope
|
|
2949
|
+
)
|
|
2950
|
+
)
|
|
2951
|
+
|
|
2952
|
+
if len(coins) > number_of_coins:
|
|
2953
|
+
raise ValueError(
|
|
2954
|
+
f"Options specified cannot be met without selecting more coins than specified: {len(coins)}"
|
|
2955
|
+
)
|
|
2956
|
+
|
|
2957
|
+
# Now let's select enough coins to get to the target number to combine
|
|
2958
|
+
if len(coins) < number_of_coins:
|
|
2959
|
+
async with action_scope.use() as interface:
|
|
2960
|
+
coins.extend(
|
|
2961
|
+
cr.coin
|
|
2962
|
+
for cr in (
|
|
2963
|
+
await self.coin_store.get_coin_records(
|
|
2964
|
+
wallet_id=wallet_id,
|
|
2965
|
+
limit=uint32(number_of_coins - len(coins)),
|
|
2966
|
+
order=CoinRecordOrder.amount,
|
|
2967
|
+
coin_id_filter=HashFilter(
|
|
2968
|
+
[c.name() for c in interface.side_effects.selected_coins],
|
|
2969
|
+
mode=uint8(FilterMode.exclude.value),
|
|
2970
|
+
),
|
|
2971
|
+
reverse=largest_first,
|
|
2972
|
+
)
|
|
2973
|
+
).records
|
|
2974
|
+
)
|
|
2975
|
+
|
|
2976
|
+
async with action_scope.use() as interface:
|
|
2977
|
+
interface.side_effects.selected_coins.extend(coins)
|
|
2978
|
+
|
|
2979
|
+
primary_output_amount = (
|
|
2980
|
+
uint64(sum(c.amount for c in coins)) if target_coin_amount is None else target_coin_amount
|
|
2981
|
+
)
|
|
2982
|
+
if isinstance(wallet, Wallet):
|
|
2983
|
+
primary_output_amount = uint64(primary_output_amount - fee)
|
|
2984
|
+
|
|
2985
|
+
await wallet.generate_signed_transaction(
|
|
2986
|
+
[primary_output_amount],
|
|
2987
|
+
[await action_scope.get_puzzle_hash(self)],
|
|
2988
|
+
action_scope,
|
|
2989
|
+
fee,
|
|
2990
|
+
coins=set(coins),
|
|
2991
|
+
extra_conditions=extra_conditions,
|
|
2992
|
+
)
|
|
2993
|
+
|
|
2994
|
+
def new_pool_wallet_pubkey(self) -> G1Element:
|
|
2995
|
+
# We assign a pseudo unique id to each pool wallet, so that each one gets its own deterministic
|
|
2996
|
+
# owner and auth keys. The public keys will go on the blockchain, and the private keys can be found
|
|
2997
|
+
# using the root SK and trying each index from zero. The indexes are not fully unique though,
|
|
2998
|
+
# because the PoolWallet is not created until the tx gets confirmed on chain. Therefore if we
|
|
2999
|
+
# make multiple pool wallets at the same time, they will have the same ID.
|
|
3000
|
+
max_pwi = 1
|
|
3001
|
+
for _, wallet in self.wallets.items():
|
|
3002
|
+
if wallet.type() == WalletType.POOLING_WALLET:
|
|
3003
|
+
max_pwi += 1
|
|
3004
|
+
|
|
3005
|
+
if max_pwi + 1 >= (MAX_POOL_WALLETS - 1):
|
|
3006
|
+
raise ValueError(f"Too many pool wallets ({max_pwi}), cannot create any more on this key.")
|
|
3007
|
+
|
|
3008
|
+
return master_sk_to_singleton_owner_sk(self.get_master_private_key(), uint32(max_pwi)).get_g1()
|