chia-blockchain 2.5.4rc2__py3-none-any.whl → 2.5.5rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/_tests/blockchain/blockchain_test_utils.py +2 -3
- chia/_tests/blockchain/test_augmented_chain.py +2 -3
- chia/_tests/blockchain/test_blockchain.py +261 -44
- chia/_tests/blockchain/test_blockchain_transactions.py +4 -3
- chia/_tests/blockchain/test_build_chains.py +197 -1
- chia/_tests/blockchain/test_get_block_generator.py +1 -1
- chia/_tests/blockchain/test_lookup_fork_chain.py +1 -1
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +3 -4
- chia/_tests/clvm/test_message_conditions.py +2 -2
- chia/_tests/clvm/test_puzzle_compression.py +2 -3
- chia/_tests/clvm/test_puzzles.py +1 -2
- chia/_tests/clvm/test_singletons.py +2 -3
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +30 -25
- chia/_tests/cmds/test_dev_gh.py +1 -1
- chia/_tests/cmds/test_farm_cmd.py +1 -1
- chia/_tests/cmds/test_show.py +1 -2
- chia/_tests/cmds/wallet/test_did.py +101 -56
- chia/_tests/cmds/wallet/test_nft.py +109 -84
- chia/_tests/cmds/wallet/test_notifications.py +1 -1
- chia/_tests/cmds/wallet/test_offer.toffer +1 -1
- chia/_tests/cmds/wallet/test_vcs.py +8 -8
- chia/_tests/cmds/wallet/test_wallet.py +100 -46
- chia/_tests/conftest.py +31 -20
- chia/_tests/connection_utils.py +1 -1
- chia/_tests/core/consensus/stores/__init__.py +0 -0
- chia/_tests/core/consensus/stores/test_coin_store_protocol.py +40 -0
- chia/_tests/core/consensus/test_block_creation.py +2 -31
- chia/_tests/core/consensus/test_pot_iterations.py +38 -3
- chia/_tests/core/custom_types/test_proof_of_space.py +154 -26
- chia/_tests/core/custom_types/test_spend_bundle.py +2 -3
- chia/_tests/core/daemon/test_daemon.py +80 -0
- chia/_tests/core/data_layer/test_data_layer.py +1 -1
- chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
- chia/_tests/core/data_layer/test_data_rpc.py +14 -10
- chia/_tests/core/data_layer/test_data_store.py +5 -5
- chia/_tests/core/farmer/test_farmer_api.py +2 -2
- chia/_tests/core/full_node/full_sync/test_full_sync.py +446 -406
- chia/_tests/core/full_node/ram_db.py +3 -1
- chia/_tests/core/full_node/stores/test_block_store.py +28 -16
- chia/_tests/core/full_node/stores/test_coin_store.py +277 -185
- chia/_tests/core/full_node/stores/test_full_node_store.py +11 -4
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_address_manager.py +200 -27
- chia/_tests/core/full_node/test_block_height_map.py +2 -2
- chia/_tests/core/full_node/test_conditions.py +7 -6
- chia/_tests/core/full_node/test_full_node.py +456 -40
- chia/_tests/core/full_node/test_generator_tools.py +32 -2
- chia/_tests/core/full_node/test_hint_management.py +1 -1
- chia/_tests/core/full_node/test_node_load.py +20 -21
- chia/_tests/core/full_node/test_performance.py +3 -4
- chia/_tests/core/full_node/test_prev_tx_block.py +43 -0
- chia/_tests/core/full_node/test_subscriptions.py +1 -2
- chia/_tests/core/full_node/test_transactions.py +9 -5
- chia/_tests/core/full_node/test_tx_processing_queue.py +1 -2
- chia/_tests/core/large_block.py +1 -2
- chia/_tests/core/make_block_generator.py +3 -4
- chia/_tests/core/mempool/test_mempool.py +36 -86
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
- chia/_tests/core/mempool/test_mempool_item_queries.py +1 -3
- chia/_tests/core/mempool/test_mempool_manager.py +421 -69
- chia/_tests/core/mempool/test_mempool_performance.py +3 -2
- chia/_tests/core/mempool/test_singleton_fast_forward.py +60 -131
- chia/_tests/core/server/flood.py +1 -1
- chia/_tests/core/server/test_dos.py +1 -1
- chia/_tests/core/server/test_node_discovery.py +41 -27
- chia/_tests/core/server/test_rate_limits.py +1 -1
- chia/_tests/core/server/test_server.py +1 -1
- chia/_tests/core/services/test_services.py +5 -5
- chia/_tests/core/ssl/test_ssl.py +1 -1
- chia/_tests/core/test_cost_calculation.py +6 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_crawler_rpc.py +1 -1
- chia/_tests/core/test_db_conversion.py +3 -1
- chia/_tests/core/test_db_validation.py +5 -3
- chia/_tests/core/test_farmer_harvester_rpc.py +15 -15
- chia/_tests/core/test_filter.py +4 -1
- chia/_tests/core/test_full_node_rpc.py +99 -82
- chia/_tests/core/test_program.py +2 -2
- chia/_tests/core/util/test_block_cache.py +1 -1
- chia/_tests/core/util/test_keychain.py +2 -2
- chia/_tests/core/util/test_lockfile.py +1 -1
- chia/_tests/core/util/test_log_exceptions.py +5 -5
- chia/_tests/core/util/test_streamable.py +81 -22
- chia/_tests/db/test_db_wrapper.py +1 -3
- chia/_tests/environments/wallet.py +5 -5
- chia/_tests/farmer_harvester/test_farmer.py +9 -7
- chia/_tests/farmer_harvester/test_farmer_harvester.py +11 -4
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +15 -9
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -2
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +7 -5
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
- chia/_tests/generator/test_compression.py +1 -2
- chia/_tests/generator/test_rom.py +8 -4
- chia/_tests/plot_sync/test_plot_sync.py +3 -3
- chia/_tests/plot_sync/test_receiver.py +3 -3
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +3 -3
- chia/_tests/plot_sync/util.py +2 -2
- chia/_tests/pools/test_pool_cmdline.py +48 -21
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +2 -3
- chia/_tests/pools/test_pool_rpc.py +237 -105
- chia/_tests/pools/test_pool_wallet.py +11 -2
- chia/_tests/pools/test_wallet_pool_store.py +5 -4
- chia/_tests/rpc/test_rpc_client.py +1 -1
- chia/_tests/simulation/test_simulation.py +13 -8
- chia/_tests/simulation/test_simulator.py +2 -2
- chia/_tests/timelord/test_new_peak.py +191 -47
- chia/_tests/timelord/test_timelord.py +1 -1
- chia/_tests/tools/test_full_sync.py +0 -2
- chia/_tests/tools/test_run_block.py +3 -1
- chia/_tests/util/benchmark_cost.py +3 -3
- chia/_tests/util/benchmarks.py +2 -2
- chia/_tests/util/blockchain.py +11 -5
- chia/_tests/util/blockchain_mock.py +1 -4
- chia/_tests/util/coin_store.py +29 -0
- chia/_tests/util/constants.py +2 -18
- chia/_tests/util/full_sync.py +3 -3
- chia/_tests/util/generator_tools_testing.py +2 -3
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +33 -31
- chia/_tests/util/network_protocol_data.py +19 -17
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +3 -1
- chia/_tests/util/run_block.py +2 -2
- chia/_tests/util/setup_nodes.py +7 -7
- chia/_tests/util/spend_sim.py +47 -55
- chia/_tests/util/test_condition_tools.py +5 -4
- chia/_tests/util/test_config.py +2 -2
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +12 -14
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_paginator.py +4 -4
- chia/_tests/util/test_priority_mutex.py +2 -2
- chia/_tests/util/test_replace_str_to_bytes.py +15 -5
- chia/_tests/util/test_ssl_check.py +1 -1
- chia/_tests/util/test_testnet_overrides.py +13 -3
- chia/_tests/util/time_out_assert.py +4 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -2
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +352 -432
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +3 -6
- chia/_tests/wallet/cat_wallet/test_trades.py +53 -77
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -1
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +3 -3
- chia/_tests/wallet/clawback/test_clawback_metadata.py +4 -2
- chia/_tests/wallet/conftest.py +11 -12
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +11 -4
- chia/_tests/wallet/db_wallet/test_dl_offers.py +433 -130
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +3 -3
- chia/_tests/wallet/did_wallet/test_did.py +2132 -2000
- chia/_tests/wallet/nft_wallet/config.py +1 -1
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1610 -742
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +486 -907
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +4 -4
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +517 -294
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +133 -62
- chia/_tests/wallet/rpc/test_wallet_rpc.py +495 -265
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +10 -6
- chia/_tests/wallet/sync/test_wallet_sync.py +89 -60
- chia/_tests/wallet/test_clvm_casts.py +88 -0
- chia/_tests/wallet/test_coin_management.py +1 -1
- chia/_tests/wallet/test_coin_selection.py +1 -1
- chia/_tests/wallet/test_conditions.py +1 -1
- chia/_tests/wallet/test_new_wallet_protocol.py +13 -11
- chia/_tests/wallet/test_notifications.py +5 -3
- chia/_tests/wallet/test_sign_coin_spends.py +6 -6
- chia/_tests/wallet/test_signer_protocol.py +13 -12
- chia/_tests/wallet/test_singleton.py +1 -1
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +5 -7
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +108 -29
- chia/_tests/wallet/test_wallet_action_scope.py +9 -2
- chia/_tests/wallet/test_wallet_blockchain.py +2 -3
- chia/_tests/wallet/test_wallet_key_val_store.py +1 -2
- chia/_tests/wallet/test_wallet_node.py +2 -4
- chia/_tests/wallet/test_wallet_retry.py +4 -2
- chia/_tests/wallet/test_wallet_state_manager.py +191 -5
- chia/_tests/wallet/test_wallet_test_framework.py +1 -1
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +8 -8
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -12
- chia/_tests/wallet/wallet_block_tools.py +6 -6
- chia/_tests/weight_proof/test_weight_proof.py +10 -48
- chia/apis.py +1 -1
- chia/cmds/beta.py +1 -1
- chia/cmds/chia.py +9 -9
- chia/cmds/cmd_classes.py +12 -11
- chia/cmds/cmd_helpers.py +1 -1
- chia/cmds/cmds_util.py +12 -9
- chia/cmds/coin_funcs.py +2 -2
- chia/cmds/configure.py +2 -2
- chia/cmds/data.py +0 -2
- chia/cmds/data_funcs.py +1 -1
- chia/cmds/db_validate_func.py +1 -2
- chia/cmds/dev/__init__.py +0 -0
- chia/cmds/dev/data.py +273 -0
- chia/cmds/{gh.py → dev/gh.py} +5 -5
- chia/cmds/dev/main.py +22 -0
- chia/cmds/dev/mempool.py +78 -0
- chia/cmds/dev/mempool_funcs.py +63 -0
- chia/cmds/farm_funcs.py +5 -4
- chia/cmds/init_funcs.py +11 -11
- chia/cmds/keys.py +2 -2
- chia/cmds/keys_funcs.py +4 -4
- chia/cmds/netspace_funcs.py +1 -1
- chia/cmds/peer_funcs.py +2 -2
- chia/cmds/plotnft_funcs.py +72 -26
- chia/cmds/rpc.py +1 -1
- chia/cmds/show_funcs.py +5 -5
- chia/cmds/signer.py +8 -7
- chia/cmds/sim_funcs.py +8 -9
- chia/cmds/wallet.py +2 -2
- chia/cmds/wallet_funcs.py +165 -131
- chia/{util → consensus}/augmented_chain.py +1 -2
- chia/consensus/block_body_validation.py +54 -40
- chia/consensus/block_creation.py +42 -76
- chia/consensus/block_header_validation.py +32 -26
- chia/consensus/block_record.py +0 -3
- chia/consensus/blockchain.py +23 -32
- chia/consensus/blockchain_interface.py +1 -5
- chia/consensus/check_time_locks.py +57 -0
- chia/consensus/coin_store_protocol.py +151 -0
- chia/consensus/coinbase.py +0 -6
- chia/consensus/condition_costs.py +4 -0
- chia/{util → consensus}/condition_tools.py +4 -5
- chia/consensus/cost_calculator.py +1 -1
- chia/consensus/default_constants.py +32 -9
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +1 -2
- chia/consensus/find_fork_point.py +1 -3
- chia/consensus/full_block_to_block_record.py +1 -6
- chia/{util → consensus}/generator_tools.py +1 -3
- chia/consensus/get_block_challenge.py +30 -7
- chia/consensus/make_sub_epoch_summary.py +1 -5
- chia/consensus/multiprocess_validation.py +21 -20
- chia/consensus/pot_iterations.py +74 -13
- chia/{util → consensus}/prev_transaction_block.py +1 -1
- chia/consensus/vdf_info_computation.py +1 -3
- chia/daemon/keychain_proxy.py +5 -5
- chia/daemon/server.py +22 -5
- chia/data_layer/data_layer.py +92 -51
- chia/{rpc → data_layer}/data_layer_rpc_api.py +1 -1
- chia/{rpc → data_layer}/data_layer_rpc_util.py +3 -6
- chia/data_layer/data_layer_util.py +4 -6
- chia/data_layer/data_layer_wallet.py +42 -69
- chia/data_layer/dl_wallet_store.py +12 -6
- chia/data_layer/download_data.py +3 -3
- chia/data_layer/s3_plugin_service.py +0 -1
- chia/farmer/farmer.py +3 -4
- chia/farmer/farmer_api.py +11 -7
- chia/{rpc → farmer}/farmer_rpc_client.py +1 -1
- chia/full_node/block_height_map.py +7 -6
- chia/full_node/block_store.py +5 -7
- chia/full_node/bundle_tools.py +1 -2
- chia/full_node/coin_store.py +143 -124
- chia/{types → full_node}/eligible_coin_spends.py +39 -70
- chia/full_node/fee_estimator.py +1 -1
- chia/full_node/fee_estimator_interface.py +0 -8
- chia/full_node/fee_tracker.py +25 -25
- chia/full_node/full_node.py +70 -53
- chia/full_node/full_node_api.py +57 -40
- chia/{rpc → full_node}/full_node_rpc_api.py +87 -8
- chia/{rpc → full_node}/full_node_rpc_client.py +7 -6
- chia/full_node/full_node_store.py +23 -8
- chia/full_node/mempool.py +206 -53
- chia/full_node/mempool_check_conditions.py +20 -63
- chia/full_node/mempool_manager.py +26 -40
- chia/full_node/subscriptions.py +1 -3
- chia/full_node/tx_processing_queue.py +50 -3
- chia/full_node/weight_proof.py +46 -37
- chia/harvester/harvester.py +1 -1
- chia/harvester/harvester_api.py +22 -7
- chia/introducer/introducer.py +1 -1
- chia/introducer/introducer_api.py +1 -1
- chia/plot_sync/exceptions.py +1 -1
- chia/plot_sync/receiver.py +1 -1
- chia/plot_sync/sender.py +2 -2
- chia/pools/pool_puzzles.py +13 -18
- chia/pools/pool_wallet.py +23 -46
- chia/protocols/farmer_protocol.py +11 -3
- chia/protocols/full_node_protocol.py +1 -4
- chia/protocols/harvester_protocol.py +3 -3
- chia/protocols/pool_protocol.py +1 -2
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +1 -3
- chia/protocols/wallet_protocol.py +3 -3
- chia/rpc/rpc_client.py +7 -8
- chia/rpc/rpc_server.py +3 -3
- chia/rpc/util.py +3 -1
- chia/seeder/crawler.py +1 -1
- chia/seeder/crawler_api.py +1 -1
- chia/seeder/dns_server.py +2 -0
- chia/seeder/start_crawler.py +3 -3
- chia/server/address_manager.py +286 -38
- chia/server/address_manager_store.py +0 -215
- chia/{types → server}/aliases.py +7 -7
- chia/server/api_protocol.py +1 -1
- chia/server/chia_policy.py +1 -1
- chia/server/node_discovery.py +76 -113
- chia/server/rate_limits.py +1 -1
- chia/server/resolve_peer_info.py +43 -0
- chia/server/server.py +5 -5
- chia/server/start_data_layer.py +4 -4
- chia/server/start_farmer.py +5 -4
- chia/server/start_full_node.py +5 -4
- chia/server/start_harvester.py +7 -5
- chia/server/start_introducer.py +2 -2
- chia/server/start_service.py +1 -1
- chia/server/start_timelord.py +7 -5
- chia/server/start_wallet.py +7 -5
- chia/server/ws_connection.py +1 -1
- chia/simulator/add_blocks_in_batches.py +2 -2
- chia/simulator/block_tools.py +245 -201
- chia/simulator/full_node_simulator.py +38 -10
- chia/simulator/setup_services.py +12 -12
- chia/simulator/simulator_full_node_rpc_api.py +2 -2
- chia/simulator/simulator_full_node_rpc_client.py +2 -2
- chia/simulator/simulator_test_tools.py +2 -2
- chia/simulator/start_simulator.py +1 -1
- chia/simulator/wallet_tools.py +10 -18
- chia/ssl/create_ssl.py +1 -1
- chia/timelord/iters_from_block.py +14 -14
- chia/timelord/timelord.py +15 -11
- chia/timelord/timelord_api.py +14 -2
- chia/timelord/timelord_state.py +20 -14
- chia/types/blockchain_format/program.py +53 -10
- chia/types/blockchain_format/proof_of_space.py +73 -19
- chia/types/coin_spend.py +3 -56
- chia/types/generator_types.py +28 -0
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +12 -7
- chia/types/unfinished_header_block.py +1 -2
- chia/types/validation_state.py +1 -2
- chia/types/weight_proof.py +1 -3
- chia/util/action_scope.py +3 -3
- chia/util/block_cache.py +1 -2
- chia/util/byte_types.py +1 -1
- chia/util/casts.py +21 -0
- chia/util/config.py +0 -37
- chia/util/db_wrapper.py +8 -1
- chia/util/errors.py +3 -2
- chia/util/initial-config.yaml +21 -5
- chia/util/keychain.py +6 -7
- chia/util/keyring_wrapper.py +5 -5
- chia/util/limited_semaphore.py +1 -1
- chia/util/priority_mutex.py +1 -1
- chia/util/streamable.py +63 -5
- chia/util/task_timing.py +1 -1
- chia/util/virtual_project_analysis.py +1 -1
- chia/wallet/cat_wallet/cat_info.py +7 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +9 -5
- chia/wallet/cat_wallet/cat_utils.py +1 -1
- chia/wallet/cat_wallet/cat_wallet.py +44 -36
- chia/wallet/cat_wallet/lineage_store.py +7 -0
- chia/wallet/cat_wallet/r_cat_wallet.py +274 -0
- chia/wallet/conditions.py +5 -10
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -4
- chia/wallet/derivation_record.py +33 -0
- chia/wallet/derive_keys.py +3 -3
- chia/wallet/did_wallet/did_info.py +12 -3
- chia/wallet/did_wallet/did_wallet.py +132 -101
- chia/wallet/did_wallet/did_wallet_puzzles.py +9 -9
- chia/wallet/driver_protocol.py +3 -1
- chia/{types/spend_bundle.py → wallet/estimate_fees.py} +2 -7
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/nft_puzzle_utils.py +1 -1
- chia/wallet/nft_wallet/nft_wallet.py +69 -112
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +6 -4
- chia/wallet/nft_wallet/transfer_program_puzzle.py +4 -2
- chia/wallet/nft_wallet/uncurry_nft.py +4 -6
- chia/wallet/notification_manager.py +2 -3
- chia/wallet/outer_puzzles.py +7 -2
- chia/wallet/puzzle_drivers.py +1 -1
- chia/wallet/puzzles/clawback/drivers.py +5 -4
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -1
- chia/wallet/puzzles/singleton_top_layer.py +2 -1
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +2 -1
- chia/wallet/puzzles/tails.py +1 -3
- chia/wallet/signer_protocol.py +5 -6
- chia/wallet/singleton.py +5 -4
- chia/wallet/singleton_record.py +1 -1
- chia/wallet/trade_manager.py +18 -20
- chia/wallet/trade_record.py +3 -6
- chia/wallet/trading/offer.py +12 -13
- chia/wallet/uncurried_puzzle.py +2 -2
- chia/wallet/util/compute_additions.py +58 -0
- chia/wallet/util/compute_hints.py +3 -3
- chia/wallet/util/compute_memos.py +4 -4
- chia/wallet/util/curry_and_treehash.py +2 -1
- chia/wallet/util/debug_spend_bundle.py +1 -1
- chia/wallet/util/merkle_tree.py +1 -1
- chia/wallet/util/peer_request_cache.py +1 -2
- chia/wallet/util/tx_config.py +3 -8
- chia/wallet/util/wallet_sync_utils.py +10 -5
- chia/wallet/util/wallet_types.py +1 -0
- chia/wallet/vc_wallet/cr_cat_drivers.py +17 -18
- chia/wallet/vc_wallet/cr_cat_wallet.py +30 -28
- chia/wallet/vc_wallet/cr_outer_puzzle.py +5 -3
- chia/wallet/vc_wallet/vc_drivers.py +50 -8
- chia/wallet/vc_wallet/vc_store.py +3 -5
- chia/wallet/vc_wallet/vc_wallet.py +15 -22
- chia/wallet/wallet.py +36 -46
- chia/wallet/wallet_action_scope.py +73 -4
- chia/wallet/wallet_blockchain.py +1 -3
- chia/wallet/wallet_interested_store.py +1 -1
- chia/wallet/wallet_nft_store.py +3 -3
- chia/wallet/wallet_node.py +17 -16
- chia/wallet/wallet_node_api.py +4 -5
- chia/wallet/wallet_pool_store.py +1 -1
- chia/wallet/wallet_protocol.py +2 -0
- chia/wallet/wallet_puzzle_store.py +1 -1
- chia/{rpc → wallet}/wallet_request_types.py +670 -81
- chia/{rpc → wallet}/wallet_rpc_api.py +735 -766
- chia/{rpc → wallet}/wallet_rpc_client.py +268 -420
- chia/wallet/wallet_singleton_store.py +8 -7
- chia/wallet/wallet_spend_bundle.py +4 -3
- chia/wallet/wallet_state_manager.py +320 -191
- chia/wallet/wallet_weight_proof_handler.py +1 -2
- chia/wallet/wsm_apis.py +98 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/METADATA +7 -7
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/RECORD +443 -436
- mozilla-ca/cacert.pem +3 -165
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +0 -145
- chia/cmds/dev.py +0 -18
- chia/types/blockchain_format/slots.py +0 -9
- chia/types/blockchain_format/sub_epoch_summary.py +0 -5
- chia/types/end_of_slot_bundle.py +0 -5
- chia/types/full_block.py +0 -5
- chia/types/header_block.py +0 -5
- chia/types/spend_bundle_conditions.py +0 -7
- chia/types/transaction_queue_entry.py +0 -56
- chia/types/unfinished_block.py +0 -5
- /chia/cmds/{installers.py → dev/installers.py} +0 -0
- /chia/cmds/{sim.py → dev/sim.py} +0 -0
- /chia/{util → cmds}/dump_keyring.py +0 -0
- /chia/{full_node → consensus}/signage_point.py +0 -0
- /chia/{rpc → data_layer}/data_layer_rpc_client.py +0 -0
- /chia/{rpc → farmer}/farmer_rpc_api.py +0 -0
- /chia/{util → full_node}/full_block_utils.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_api.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_client.py +0 -0
- /chia/{full_node → protocols}/fee_estimate.py +0 -0
- /chia/{server → protocols}/outbound_message.py +0 -0
- /chia/{rpc → seeder}/crawler_rpc_api.py +0 -0
- /chia/{util → simulator}/vdf_prover.py +0 -0
- /chia/{util → ssl}/ssl_check.py +0 -0
- /chia/{rpc → timelord}/timelord_rpc_api.py +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/LICENSE +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5rc2.dist-info}/entry_points.txt +0 -0
|
@@ -10,15 +10,16 @@ import traceback
|
|
|
10
10
|
from collections.abc import AsyncIterator
|
|
11
11
|
from contextlib import asynccontextmanager
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar,
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, cast
|
|
14
14
|
|
|
15
15
|
import aiosqlite
|
|
16
|
-
from chia_rs import AugSchemeMPL, ConsensusConstants, G1Element, G2Element, PrivateKey
|
|
16
|
+
from chia_rs import AugSchemeMPL, CoinSpend, CoinState, ConsensusConstants, G1Element, G2Element, PrivateKey
|
|
17
17
|
from chia_rs.sized_bytes import bytes32
|
|
18
18
|
from chia_rs.sized_ints import 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
|
|
22
|
+
from chia.consensus.condition_tools import conditions_dict_for_solution, pkm_pairs_for_conditions_dict
|
|
22
23
|
from chia.data_layer.data_layer_wallet import DataLayerWallet
|
|
23
24
|
from chia.data_layer.dl_wallet_store import DataLayerStore
|
|
24
25
|
from chia.data_layer.singleton_record import SingletonRecord
|
|
@@ -27,20 +28,17 @@ from chia.pools.pool_puzzles import (
|
|
|
27
28
|
solution_to_pool_state,
|
|
28
29
|
)
|
|
29
30
|
from chia.pools.pool_wallet import PoolWallet
|
|
30
|
-
from chia.protocols.
|
|
31
|
+
from chia.protocols.outbound_message import NodeType
|
|
31
32
|
from chia.rpc.rpc_server import StateChangedProtocol
|
|
32
|
-
from chia.server.outbound_message import NodeType
|
|
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 Program
|
|
36
|
+
from chia.types.blockchain_format.program import NIL, Program
|
|
37
37
|
from chia.types.coin_record import CoinRecord
|
|
38
|
-
from chia.types.coin_spend import CoinSpend, compute_additions
|
|
39
38
|
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
|
40
39
|
from chia.util.bech32m import encode_puzzle_hash
|
|
41
|
-
from chia.util.condition_tools import conditions_dict_for_solution, pkm_pairs_for_conditions_dict
|
|
42
40
|
from chia.util.db_synchronous import db_synchronous_on
|
|
43
|
-
from chia.util.db_wrapper import DBWrapper2
|
|
41
|
+
from chia.util.db_wrapper import DBWrapper2, PurposefulAbort
|
|
44
42
|
from chia.util.errors import Err
|
|
45
43
|
from chia.util.hash import std_hash
|
|
46
44
|
from chia.util.lru_cache import LRUCache
|
|
@@ -50,6 +48,7 @@ from chia.wallet.cat_wallet.cat_constants import DEFAULT_CATS
|
|
|
50
48
|
from chia.wallet.cat_wallet.cat_info import CATCoinData, CATInfo, CRCATInfo
|
|
51
49
|
from chia.wallet.cat_wallet.cat_utils import CAT_MOD, CAT_MOD_HASH, construct_cat_puzzle, match_cat_puzzle
|
|
52
50
|
from chia.wallet.cat_wallet.cat_wallet import CATWallet
|
|
51
|
+
from chia.wallet.cat_wallet.r_cat_wallet import RCATWallet
|
|
53
52
|
from chia.wallet.conditions import (
|
|
54
53
|
AssertCoinAnnouncement,
|
|
55
54
|
Condition,
|
|
@@ -101,6 +100,7 @@ from chia.wallet.trading.trade_status import TradeStatus
|
|
|
101
100
|
from chia.wallet.transaction_record import LightTransactionRecord, TransactionRecord
|
|
102
101
|
from chia.wallet.uncurried_puzzle import uncurry_puzzle
|
|
103
102
|
from chia.wallet.util.address_type import AddressType
|
|
103
|
+
from chia.wallet.util.compute_additions import compute_additions
|
|
104
104
|
from chia.wallet.util.compute_hints import compute_spend_hints_and_additions
|
|
105
105
|
from chia.wallet.util.compute_memos import compute_memos
|
|
106
106
|
from chia.wallet.util.curry_and_treehash import NIL_TREEHASH
|
|
@@ -116,7 +116,7 @@ from chia.wallet.util.wallet_sync_utils import (
|
|
|
116
116
|
from chia.wallet.util.wallet_types import CoinType, WalletIdentifier, WalletType
|
|
117
117
|
from chia.wallet.vc_wallet.cr_cat_drivers import CRCAT, ProofsChecker, construct_pending_approval_state
|
|
118
118
|
from chia.wallet.vc_wallet.cr_cat_wallet import CRCATWallet
|
|
119
|
-
from chia.wallet.vc_wallet.vc_drivers import VerifiedCredential
|
|
119
|
+
from chia.wallet.vc_wallet.vc_drivers import VerifiedCredential, match_revocation_layer
|
|
120
120
|
from chia.wallet.vc_wallet.vc_store import VCStore
|
|
121
121
|
from chia.wallet.vc_wallet.vc_wallet import VCWallet
|
|
122
122
|
from chia.wallet.wallet import Wallet
|
|
@@ -134,6 +134,7 @@ from chia.wallet.wallet_retry_store import WalletRetryStore
|
|
|
134
134
|
from chia.wallet.wallet_spend_bundle import WalletSpendBundle
|
|
135
135
|
from chia.wallet.wallet_transaction_store import WalletTransactionStore
|
|
136
136
|
from chia.wallet.wallet_user_store import WalletUserStore
|
|
137
|
+
from chia.wallet.wsm_apis import CreateMorePuzzleHashesResult, GetUnusedDerivationRecordResult
|
|
137
138
|
|
|
138
139
|
TWalletType = TypeVar("TWalletType", bound=WalletProtocol[Any])
|
|
139
140
|
|
|
@@ -327,6 +328,12 @@ class WalletStateManager:
|
|
|
327
328
|
self.main_wallet,
|
|
328
329
|
wallet_info,
|
|
329
330
|
)
|
|
331
|
+
elif wallet_type == WalletType.RCAT:
|
|
332
|
+
wallet = await RCATWallet.create(
|
|
333
|
+
self,
|
|
334
|
+
self.main_wallet,
|
|
335
|
+
wallet_info,
|
|
336
|
+
)
|
|
330
337
|
if wallet is not None:
|
|
331
338
|
self.wallets[wallet_info.id] = wallet
|
|
332
339
|
|
|
@@ -368,130 +375,167 @@ class WalletStateManager:
|
|
|
368
375
|
|
|
369
376
|
return wallet
|
|
370
377
|
|
|
378
|
+
@asynccontextmanager
|
|
379
|
+
async def puzzle_hash_db_writer(self) -> AsyncIterator[None]:
|
|
380
|
+
async with self.db_wrapper.writer():
|
|
381
|
+
old_cache = self.puzzle_store.last_wallet_derivation_index.copy()
|
|
382
|
+
try:
|
|
383
|
+
yield
|
|
384
|
+
except Exception:
|
|
385
|
+
self.puzzle_store.last_wallet_derivation_index = old_cache
|
|
386
|
+
raise
|
|
387
|
+
|
|
371
388
|
async def create_more_puzzle_hashes(
|
|
372
389
|
self,
|
|
373
390
|
from_zero: bool = False,
|
|
374
391
|
mark_existing_as_used: bool = True,
|
|
375
392
|
up_to_index: Optional[uint32] = None,
|
|
376
393
|
num_additional_phs: Optional[int] = None,
|
|
377
|
-
|
|
394
|
+
previous_result: Optional[CreateMorePuzzleHashesResult] = None,
|
|
395
|
+
_commit_previous_result: bool = True,
|
|
396
|
+
) -> CreateMorePuzzleHashesResult:
|
|
378
397
|
"""
|
|
379
398
|
For all wallets in the user store, generates the first few puzzle hashes so
|
|
380
399
|
that we can restore the wallet from only the private keys.
|
|
381
400
|
"""
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
unused =
|
|
401
|
+
try:
|
|
402
|
+
async with self.puzzle_hash_db_writer():
|
|
403
|
+
if previous_result is not None:
|
|
404
|
+
if previous_result.mark_existing_as_used is not mark_existing_as_used:
|
|
405
|
+
raise ValueError(
|
|
406
|
+
"Called `create_more_puzzle_hashes` with a previous result and different configuration"
|
|
407
|
+
)
|
|
408
|
+
if _commit_previous_result:
|
|
409
|
+
await previous_result.commit(self)
|
|
410
|
+
targets = list(self.wallets.keys())
|
|
411
|
+
self.log.debug("Target wallets to generate puzzle hashes for: %s", repr(targets))
|
|
412
|
+
unused: Optional[uint32] = (
|
|
413
|
+
up_to_index if up_to_index is not None else await self.puzzle_store.get_unused_derivation_path()
|
|
414
|
+
)
|
|
415
|
+
if unused is None:
|
|
416
|
+
# This handles the case where the database has entries but they have all been used
|
|
417
|
+
unused = await self.puzzle_store.get_last_derivation_path()
|
|
418
|
+
self.log.debug("Tried finding unused: %s", unused)
|
|
419
|
+
if unused is None:
|
|
420
|
+
# This handles the case where the database is empty
|
|
421
|
+
unused = uint32(0)
|
|
422
|
+
else:
|
|
423
|
+
# The first unused will be the one after the last used one we got above
|
|
424
|
+
unused = uint32(unused + 1)
|
|
425
|
+
|
|
426
|
+
self.log.debug(f"Requested to generate puzzle hashes to at least index {unused}")
|
|
427
|
+
start_t = time.time()
|
|
428
|
+
to_generate = num_additional_phs if num_additional_phs is not None else self.initial_num_public_keys
|
|
429
|
+
|
|
430
|
+
# iterate all wallets that need derived keys and establish the start
|
|
431
|
+
# index for all of them
|
|
432
|
+
start_index_by_wallet: dict[uint32, int] = {}
|
|
433
|
+
last_index = unused + to_generate
|
|
434
|
+
for wallet_id in targets:
|
|
435
|
+
target_wallet = self.wallets[wallet_id]
|
|
436
|
+
if not target_wallet.require_derivation_paths():
|
|
437
|
+
self.log.debug("Skipping wallet %s as no derivation paths required", wallet_id)
|
|
438
|
+
continue
|
|
439
|
+
if from_zero:
|
|
440
|
+
start_index_by_wallet[wallet_id] = 0
|
|
441
|
+
continue
|
|
442
|
+
last: Optional[uint32] = await self.puzzle_store.get_last_derivation_path_for_wallet(wallet_id)
|
|
443
|
+
if last is not None:
|
|
444
|
+
if last >= last_index:
|
|
445
|
+
self.log.debug(f"Nothing to create for for wallet_id: {wallet_id}, index: {last_index}")
|
|
446
|
+
continue
|
|
447
|
+
start_index_by_wallet[wallet_id] = last
|
|
448
|
+
else:
|
|
449
|
+
start_index_by_wallet[wallet_id] = 0
|
|
450
|
+
|
|
451
|
+
if len(start_index_by_wallet) == 0:
|
|
452
|
+
raise PurposefulAbort(
|
|
453
|
+
CreateMorePuzzleHashesResult(
|
|
454
|
+
derivation_paths=[] if previous_result is None else previous_result.derivation_paths,
|
|
455
|
+
mark_existing_as_used=mark_existing_as_used,
|
|
456
|
+
unused=unused,
|
|
457
|
+
new_unhardened_keys=False,
|
|
458
|
+
last_index=last_index,
|
|
459
|
+
)
|
|
460
|
+
)
|
|
394
461
|
|
|
395
|
-
|
|
396
|
-
start_t = time.time()
|
|
397
|
-
to_generate = num_additional_phs if num_additional_phs is not None else self.initial_num_public_keys
|
|
398
|
-
|
|
399
|
-
# iterate all wallets that need derived keys and establish the start
|
|
400
|
-
# index for all of them
|
|
401
|
-
start_index_by_wallet: dict[uint32, int] = {}
|
|
402
|
-
last_index = unused + to_generate
|
|
403
|
-
for wallet_id in targets:
|
|
404
|
-
target_wallet = self.wallets[wallet_id]
|
|
405
|
-
if not target_wallet.require_derivation_paths():
|
|
406
|
-
self.log.debug("Skipping wallet %s as no derivation paths required", wallet_id)
|
|
407
|
-
continue
|
|
408
|
-
if from_zero:
|
|
409
|
-
start_index_by_wallet[wallet_id] = 0
|
|
410
|
-
continue
|
|
411
|
-
last: Optional[uint32] = await self.puzzle_store.get_last_derivation_path_for_wallet(wallet_id)
|
|
412
|
-
if last is not None:
|
|
413
|
-
if last + 1 >= last_index:
|
|
414
|
-
self.log.debug(f"Nothing to create for for wallet_id: {wallet_id}, index: {last_index}")
|
|
415
|
-
continue
|
|
416
|
-
start_index_by_wallet[wallet_id] = last + 1
|
|
417
|
-
else:
|
|
418
|
-
start_index_by_wallet[wallet_id] = 0
|
|
462
|
+
lowest_start_index = min(start_index_by_wallet.values())
|
|
419
463
|
|
|
420
|
-
|
|
421
|
-
|
|
464
|
+
# now derive the keysfrom lowest_start_index to last_index
|
|
465
|
+
# these maps derivation index to public key
|
|
466
|
+
hardened_keys: dict[int, G1Element] = {}
|
|
467
|
+
unhardened_keys: dict[int, G1Element] = {}
|
|
422
468
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
# now derive the keysfrom lowest_start_index to last_index
|
|
426
|
-
# these maps derivation index to public key
|
|
427
|
-
hardened_keys: dict[int, G1Element] = {}
|
|
428
|
-
unhardened_keys: dict[int, G1Element] = {}
|
|
429
|
-
|
|
430
|
-
if self.private_key is not None:
|
|
431
|
-
# Hardened
|
|
432
|
-
intermediate_sk = master_sk_to_wallet_sk_intermediate(self.private_key)
|
|
433
|
-
for index in range(lowest_start_index, last_index):
|
|
434
|
-
hardened_keys[index] = _derive_path(intermediate_sk, [index]).get_g1()
|
|
435
|
-
|
|
436
|
-
# Unhardened
|
|
437
|
-
intermediate_pk_un = master_pk_to_wallet_pk_unhardened_intermediate(self.root_pubkey)
|
|
438
|
-
for index in range(lowest_start_index, last_index):
|
|
439
|
-
unhardened_keys[index] = _derive_pk_unhardened(intermediate_pk_un, [index])
|
|
440
|
-
|
|
441
|
-
for wallet_id, start_index in start_index_by_wallet.items():
|
|
442
|
-
target_wallet = self.wallets[wallet_id]
|
|
443
|
-
assert target_wallet.type() != WalletType.POOLING_WALLET
|
|
444
|
-
assert start_index < last_index
|
|
445
|
-
|
|
446
|
-
derivation_paths: list[DerivationRecord] = []
|
|
447
|
-
creating_msg = f"Creating puzzle hashes from {start_index} to {last_index - 1} for wallet_id: {wallet_id}"
|
|
448
|
-
self.log.info(f"Start: {creating_msg}")
|
|
449
|
-
for index in range(start_index, last_index):
|
|
450
|
-
pubkey: Optional[G1Element] = hardened_keys.get(index)
|
|
451
|
-
if pubkey is not None:
|
|
469
|
+
if self.private_key is not None:
|
|
452
470
|
# Hardened
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
uint32(index),
|
|
458
|
-
puzzlehash,
|
|
459
|
-
pubkey,
|
|
460
|
-
target_wallet.type(),
|
|
461
|
-
uint32(target_wallet.id()),
|
|
462
|
-
True,
|
|
463
|
-
)
|
|
464
|
-
)
|
|
471
|
+
intermediate_sk = master_sk_to_wallet_sk_intermediate(self.private_key)
|
|
472
|
+
for index in range(lowest_start_index, last_index + 1):
|
|
473
|
+
hardened_keys[index] = _derive_path(intermediate_sk, [index]).get_g1()
|
|
474
|
+
|
|
465
475
|
# Unhardened
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
476
|
+
intermediate_pk_un = master_pk_to_wallet_pk_unhardened_intermediate(self.root_pubkey)
|
|
477
|
+
for index in range(lowest_start_index, last_index + 1):
|
|
478
|
+
unhardened_keys[index] = _derive_pk_unhardened(intermediate_pk_un, [index])
|
|
479
|
+
|
|
480
|
+
derivation_paths: list[DerivationRecord] = (
|
|
481
|
+
[] if previous_result is None else previous_result.derivation_paths
|
|
471
482
|
)
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
False,
|
|
483
|
+
for wallet_id, start_index in start_index_by_wallet.items():
|
|
484
|
+
target_wallet = self.wallets[wallet_id]
|
|
485
|
+
assert target_wallet.type() != WalletType.POOLING_WALLET
|
|
486
|
+
assert start_index < last_index
|
|
487
|
+
|
|
488
|
+
creating_msg = (
|
|
489
|
+
f"Creating puzzle hashes from {start_index} to {last_index} for wallet_id: {wallet_id}"
|
|
480
490
|
)
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
491
|
+
self.log.info(f"Start: {creating_msg}")
|
|
492
|
+
for index in range(start_index, last_index + 1):
|
|
493
|
+
pubkey: Optional[G1Element] = hardened_keys.get(index)
|
|
494
|
+
if pubkey is not None:
|
|
495
|
+
# Hardened
|
|
496
|
+
puzzlehash: bytes32 = target_wallet.puzzle_hash_for_pk(pubkey)
|
|
497
|
+
self.log.debug(
|
|
498
|
+
f"Puzzle at index {index} wallet ID {wallet_id} puzzle hash {puzzlehash.hex()}"
|
|
499
|
+
)
|
|
500
|
+
derivation_paths.append(
|
|
501
|
+
DerivationRecord(
|
|
502
|
+
uint32(index),
|
|
503
|
+
puzzlehash,
|
|
504
|
+
pubkey,
|
|
505
|
+
target_wallet.type(),
|
|
506
|
+
uint32(target_wallet.id()),
|
|
507
|
+
True,
|
|
508
|
+
)
|
|
509
|
+
)
|
|
510
|
+
# Unhardened
|
|
511
|
+
pubkey = unhardened_keys.get(index)
|
|
512
|
+
assert pubkey is not None
|
|
513
|
+
puzzlehash_unhardened: bytes32 = target_wallet.puzzle_hash_for_pk(pubkey)
|
|
514
|
+
self.log.debug(
|
|
515
|
+
f"Puzzle at index {index} wallet ID {wallet_id} puzzle hash {puzzlehash_unhardened.hex()}"
|
|
516
|
+
)
|
|
517
|
+
derivation_paths.append(
|
|
518
|
+
DerivationRecord(
|
|
519
|
+
uint32(index),
|
|
520
|
+
puzzlehash_unhardened,
|
|
521
|
+
pubkey,
|
|
522
|
+
target_wallet.type(),
|
|
523
|
+
uint32(target_wallet.id()),
|
|
524
|
+
False,
|
|
525
|
+
)
|
|
526
|
+
)
|
|
527
|
+
self.log.info(f"Done: {creating_msg} Time: {time.time() - start_t} seconds")
|
|
528
|
+
raise PurposefulAbort(
|
|
529
|
+
CreateMorePuzzleHashesResult(
|
|
530
|
+
derivation_paths=derivation_paths,
|
|
531
|
+
mark_existing_as_used=mark_existing_as_used,
|
|
532
|
+
unused=unused,
|
|
533
|
+
new_unhardened_keys=(len(hardened_keys) > 0),
|
|
534
|
+
last_index=last_index,
|
|
488
535
|
)
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
if mark_existing_as_used and unused > 0 and len(unhardened_keys) > 0:
|
|
493
|
-
self.log.info(f"Updating last used derivation index: {unused - 1}")
|
|
494
|
-
await self.puzzle_store.set_used_up_to(uint32(unused - 1))
|
|
536
|
+
)
|
|
537
|
+
except PurposefulAbort as e:
|
|
538
|
+
return cast(CreateMorePuzzleHashesResult, e.obj)
|
|
495
539
|
|
|
496
540
|
async def update_wallet_puzzle_hashes(self, wallet_id: uint32) -> None:
|
|
497
541
|
derivation_paths: list[DerivationRecord] = []
|
|
@@ -522,35 +566,64 @@ class WalletStateManager:
|
|
|
522
566
|
)
|
|
523
567
|
await self.puzzle_store.add_derivation_paths(derivation_paths)
|
|
524
568
|
|
|
525
|
-
async def
|
|
569
|
+
async def _get_unused_derivation_record(
|
|
570
|
+
self,
|
|
571
|
+
wallet_id: uint32,
|
|
572
|
+
*,
|
|
573
|
+
hardened: bool = False,
|
|
574
|
+
previous_result: Optional[GetUnusedDerivationRecordResult] = None,
|
|
575
|
+
) -> GetUnusedDerivationRecordResult:
|
|
526
576
|
"""
|
|
527
577
|
Creates a puzzle hash for the given wallet, and then makes more puzzle hashes
|
|
528
578
|
for every wallet to ensure we always have more in the database. Never reusue the
|
|
529
579
|
same public key more than once (for privacy).
|
|
530
580
|
"""
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
581
|
+
try:
|
|
582
|
+
async with self.puzzle_hash_db_writer():
|
|
583
|
+
if previous_result is not None:
|
|
584
|
+
await previous_result.commit(self)
|
|
585
|
+
create_more_puzzle_hashes_result: Optional[CreateMorePuzzleHashesResult] = (
|
|
586
|
+
previous_result.create_more_puzzle_hashes_result
|
|
587
|
+
)
|
|
588
|
+
else:
|
|
589
|
+
create_more_puzzle_hashes_result = None
|
|
590
|
+
# If we have no unused public keys, we will create new ones
|
|
591
|
+
unused: Optional[uint32] = await self.puzzle_store.get_unused_derivation_path()
|
|
592
|
+
if unused is None:
|
|
593
|
+
self.log.debug("No unused paths, generate more ")
|
|
594
|
+
create_more_puzzle_hashes_result = await self.create_more_puzzle_hashes(
|
|
595
|
+
previous_result=create_more_puzzle_hashes_result, _commit_previous_result=False
|
|
596
|
+
)
|
|
597
|
+
await create_more_puzzle_hashes_result.commit(self)
|
|
598
|
+
# Now we must have unused public keys
|
|
599
|
+
unused = await self.puzzle_store.get_unused_derivation_path()
|
|
600
|
+
assert unused is not None
|
|
601
|
+
|
|
602
|
+
self.log.debug("Fetching derivation record for: %s %s %s", unused, wallet_id, hardened)
|
|
603
|
+
record: Optional[DerivationRecord] = await self.puzzle_store.get_derivation_record(
|
|
604
|
+
unused, wallet_id, hardened
|
|
605
|
+
)
|
|
606
|
+
if record is None:
|
|
607
|
+
raise ValueError(f"Missing derivation '{unused}' for wallet id '{wallet_id}' (hardened={hardened})")
|
|
608
|
+
|
|
609
|
+
# Set this key to used so we never use it again
|
|
610
|
+
await self.puzzle_store.set_used_up_to(record.index)
|
|
547
611
|
|
|
548
|
-
|
|
549
|
-
|
|
612
|
+
# Create more puzzle hashes / keys
|
|
613
|
+
create_more_puzzle_hashes_result = await self.create_more_puzzle_hashes(
|
|
614
|
+
previous_result=create_more_puzzle_hashes_result,
|
|
615
|
+
up_to_index=record.index,
|
|
616
|
+
_commit_previous_result=False,
|
|
617
|
+
)
|
|
618
|
+
await create_more_puzzle_hashes_result.commit(self)
|
|
619
|
+
raise PurposefulAbort(GetUnusedDerivationRecordResult(record, create_more_puzzle_hashes_result))
|
|
620
|
+
except PurposefulAbort as e:
|
|
621
|
+
return cast(GetUnusedDerivationRecordResult, e.obj)
|
|
550
622
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
623
|
+
async def get_unused_derivation_record(self, wallet_id: uint32, *, hardened: bool = False) -> DerivationRecord:
|
|
624
|
+
result = await self._get_unused_derivation_record(wallet_id, hardened=hardened)
|
|
625
|
+
await result.commit(self)
|
|
626
|
+
return result.record
|
|
554
627
|
|
|
555
628
|
async def get_current_derivation_record_for_wallet(self, wallet_id: uint32) -> Optional[DerivationRecord]:
|
|
556
629
|
async with self.puzzle_store.lock:
|
|
@@ -810,7 +883,7 @@ class WalletStateManager:
|
|
|
810
883
|
p2_puzzle, recovery_list_hash, num_verification, singleton_struct, metadata = did_curried_args
|
|
811
884
|
did_data: DIDCoinData = DIDCoinData(
|
|
812
885
|
p2_puzzle,
|
|
813
|
-
bytes32(recovery_list_hash.as_atom()),
|
|
886
|
+
bytes32(recovery_list_hash.as_atom()) if recovery_list_hash != Program.to(None) else None,
|
|
814
887
|
uint16(num_verification.as_int()),
|
|
815
888
|
singleton_struct,
|
|
816
889
|
metadata,
|
|
@@ -834,32 +907,35 @@ class WalletStateManager:
|
|
|
834
907
|
|
|
835
908
|
return None, None
|
|
836
909
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
current_timestamp = self.blockchain.get_latest_timestamp()
|
|
840
|
-
clawback_coins: dict[Coin, ClawbackMetadata] = {}
|
|
841
|
-
tx_fee = uint64(self.config.get("auto_claim", {}).get("tx_fee", 0))
|
|
842
|
-
assert self.wallet_node.logged_in_fingerprint is not None
|
|
910
|
+
@property
|
|
911
|
+
def tx_config(self) -> TXConfig:
|
|
843
912
|
tx_config_loader: TXConfigLoader = TXConfigLoader.from_json_dict(self.config.get("auto_claim", {}))
|
|
844
913
|
if tx_config_loader.min_coin_amount is None:
|
|
845
914
|
tx_config_loader = tx_config_loader.override(
|
|
846
915
|
min_coin_amount=self.config.get("auto_claim", {}).get("min_amount"),
|
|
847
916
|
)
|
|
848
|
-
|
|
917
|
+
assert self.wallet_node.logged_in_fingerprint is not None
|
|
918
|
+
return tx_config_loader.autofill(
|
|
849
919
|
constants=self.constants,
|
|
850
920
|
config=self.config,
|
|
851
921
|
logged_in_fingerprint=self.wallet_node.logged_in_fingerprint,
|
|
852
922
|
)
|
|
923
|
+
|
|
924
|
+
async def auto_claim_coins(self) -> None:
|
|
925
|
+
# Get unspent clawback coin
|
|
926
|
+
current_timestamp = self.blockchain.get_latest_timestamp()
|
|
927
|
+
clawback_coins: dict[Coin, ClawbackMetadata] = {}
|
|
928
|
+
tx_fee = uint64(self.config.get("auto_claim", {}).get("tx_fee", 0))
|
|
853
929
|
unspent_coins = await self.coin_store.get_coin_records(
|
|
854
930
|
coin_type=CoinType.CLAWBACK,
|
|
855
931
|
wallet_type=WalletType.STANDARD_WALLET,
|
|
856
932
|
spent_range=UInt32Range(stop=uint32(0)),
|
|
857
933
|
amount_range=UInt64Range(
|
|
858
|
-
start=tx_config.coin_selection_config.min_coin_amount,
|
|
859
|
-
stop=tx_config.coin_selection_config.max_coin_amount,
|
|
934
|
+
start=self.tx_config.coin_selection_config.min_coin_amount,
|
|
935
|
+
stop=self.tx_config.coin_selection_config.max_coin_amount,
|
|
860
936
|
),
|
|
861
937
|
)
|
|
862
|
-
async with self.new_action_scope(tx_config, push=True) as action_scope:
|
|
938
|
+
async with self.new_action_scope(self.tx_config, push=True) as action_scope:
|
|
863
939
|
for coin in unspent_coins.records:
|
|
864
940
|
try:
|
|
865
941
|
metadata: MetadataTypes = coin.parsed_metadata()
|
|
@@ -1058,19 +1134,28 @@ class WalletStateManager:
|
|
|
1058
1134
|
our_inner_puzzle: Program = self.main_wallet.puzzle_for_pk(derivation_record.pubkey)
|
|
1059
1135
|
asset_id: bytes32 = parent_data.tail_program_hash
|
|
1060
1136
|
cat_puzzle = construct_cat_puzzle(CAT_MOD, asset_id, our_inner_puzzle, CAT_MOD_HASH)
|
|
1061
|
-
|
|
1137
|
+
wallet_type: type[CATWallet] = CATWallet
|
|
1062
1138
|
if cat_puzzle.get_tree_hash() != coin_state.coin.puzzle_hash:
|
|
1063
|
-
# Check if it is a
|
|
1064
|
-
|
|
1065
|
-
|
|
1139
|
+
# Check if it is a special type of CAT
|
|
1140
|
+
uncurried_puzzle_reveal = uncurry_puzzle(coin_spend.puzzle_reveal)
|
|
1141
|
+
if uncurried_puzzle_reveal.mod != CAT_MOD:
|
|
1142
|
+
return None
|
|
1143
|
+
revocation_layer_match = match_revocation_layer(uncurry_puzzle(uncurried_puzzle_reveal.args.at("rrf")))
|
|
1144
|
+
if revocation_layer_match is not None:
|
|
1145
|
+
wallet_type = RCATWallet
|
|
1066
1146
|
else:
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
# Since CRCAT wallet doesn't have derivation path, every CRCAT will go through this code path
|
|
1070
|
-
crcat: CRCAT = next(
|
|
1071
|
-
crc for crc in CRCAT.get_next_from_coin_spend(coin_spend) if crc.coin == coin_state.coin
|
|
1072
|
-
)
|
|
1147
|
+
try:
|
|
1148
|
+
next_crcats = CRCAT.get_next_from_coin_spend(coin_spend)
|
|
1073
1149
|
|
|
1150
|
+
except ValueError:
|
|
1151
|
+
return None
|
|
1152
|
+
|
|
1153
|
+
crcat = next(crc for crc in next_crcats if crc.coin == coin_state.coin)
|
|
1154
|
+
|
|
1155
|
+
wallet_type = CRCATWallet
|
|
1156
|
+
if wallet_type is CRCATWallet:
|
|
1157
|
+
assert crcat # mypy doesn't get the semantics
|
|
1158
|
+
# Since CRCAT wallet doesn't have derivation path, every CRCAT will go through this code path
|
|
1074
1159
|
# Make sure we control the inner puzzle or we control it if it's wrapped in the pending state
|
|
1075
1160
|
if (
|
|
1076
1161
|
await self.puzzle_store.get_derivation_record_for_puzzle_hash(crcat.inner_puzzle_hash) is None
|
|
@@ -1089,30 +1174,53 @@ class WalletStateManager:
|
|
|
1089
1174
|
if crcat_info.limitations_program_hash == asset_id:
|
|
1090
1175
|
return WalletIdentifier(wallet_info.id, WalletType(wallet_info.type))
|
|
1091
1176
|
|
|
1092
|
-
|
|
1177
|
+
if wallet_type in {CRCATWallet, RCATWallet}:
|
|
1178
|
+
# We didn't find a matching alt-CAT wallet, but maybe we have a matching CAT wallet that we can convert
|
|
1093
1179
|
for wallet_info in await self.get_all_wallet_info_entries(wallet_type=WalletType.CAT):
|
|
1094
1180
|
cat_info: CATInfo = CATInfo.from_bytes(bytes.fromhex(wallet_info.data))
|
|
1095
1181
|
found_cat_wallet = self.wallets[wallet_info.id]
|
|
1096
1182
|
assert isinstance(found_cat_wallet, CATWallet)
|
|
1097
|
-
if cat_info.limitations_program_hash ==
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1183
|
+
if cat_info.limitations_program_hash == asset_id:
|
|
1184
|
+
if wallet_type is CRCATWallet:
|
|
1185
|
+
assert crcat # again, mypy isn't this smart
|
|
1186
|
+
await CRCATWallet.convert_to_cr(
|
|
1187
|
+
found_cat_wallet,
|
|
1188
|
+
crcat.authorized_providers,
|
|
1189
|
+
ProofsChecker.from_program(uncurry_puzzle(crcat.proofs_checker)),
|
|
1190
|
+
)
|
|
1191
|
+
self.state_changed("converted cat wallet to cr", wallet_info.id)
|
|
1192
|
+
return WalletIdentifier(wallet_info.id, WalletType(WalletType.CRCAT))
|
|
1193
|
+
elif wallet_type is RCATWallet:
|
|
1194
|
+
success = await RCATWallet.convert_to_revocable(
|
|
1195
|
+
found_cat_wallet,
|
|
1196
|
+
# too complicated for mypy but semantics guarantee this not to be None
|
|
1197
|
+
hidden_puzzle_hash=revocation_layer_match[0], # type: ignore[index]
|
|
1198
|
+
)
|
|
1199
|
+
if success:
|
|
1200
|
+
self.state_changed("converted cat wallet to revocable", wallet_info.id)
|
|
1201
|
+
return WalletIdentifier(wallet_info.id, WalletType(WalletType.CRCAT))
|
|
1202
|
+
else:
|
|
1203
|
+
return None
|
|
1204
|
+
|
|
1105
1205
|
if parent_data.tail_program_hash.hex() in self.default_cats or self.config.get(
|
|
1106
1206
|
"automatically_add_unknown_cats", False
|
|
1107
1207
|
):
|
|
1108
|
-
if
|
|
1109
|
-
cat_wallet:
|
|
1208
|
+
if wallet_type is CRCATWallet:
|
|
1209
|
+
cat_wallet: CATWallet = await CRCATWallet.get_or_create_wallet_for_cat(
|
|
1110
1210
|
self,
|
|
1111
1211
|
self.main_wallet,
|
|
1112
1212
|
crcat.tail_hash.hex(),
|
|
1113
1213
|
authorized_providers=crcat.authorized_providers,
|
|
1114
1214
|
proofs_checker=ProofsChecker.from_program(uncurry_puzzle(crcat.proofs_checker)),
|
|
1115
1215
|
)
|
|
1216
|
+
elif wallet_type is RCATWallet:
|
|
1217
|
+
cat_wallet = await RCATWallet.get_or_create_wallet_for_cat(
|
|
1218
|
+
self,
|
|
1219
|
+
self.main_wallet,
|
|
1220
|
+
parent_data.tail_program_hash.hex(),
|
|
1221
|
+
# too complicated for mypy but semantics guarantee this not to be None
|
|
1222
|
+
hidden_puzzle_hash=revocation_layer_match[0], # type: ignore[index]
|
|
1223
|
+
)
|
|
1116
1224
|
else:
|
|
1117
1225
|
cat_wallet = await CATWallet.get_or_create_wallet_for_cat(
|
|
1118
1226
|
self, self.main_wallet, parent_data.tail_program_hash.hex()
|
|
@@ -1198,11 +1306,23 @@ class WalletStateManager:
|
|
|
1198
1306
|
parent_data.singleton_struct,
|
|
1199
1307
|
parent_data.metadata,
|
|
1200
1308
|
)
|
|
1309
|
+
alt_did_puzzle_empty_recovery = DID_INNERPUZ_MOD.curry(
|
|
1310
|
+
our_inner_puzzle,
|
|
1311
|
+
NIL,
|
|
1312
|
+
uint64(0),
|
|
1313
|
+
parent_data.singleton_struct,
|
|
1314
|
+
parent_data.metadata,
|
|
1315
|
+
)
|
|
1316
|
+
|
|
1201
1317
|
full_puzzle_empty_recovery = create_singleton_puzzle(did_puzzle_empty_recovery, launch_id)
|
|
1318
|
+
alt_full_puzzle_empty_recovery = create_singleton_puzzle(alt_did_puzzle_empty_recovery, launch_id)
|
|
1202
1319
|
if full_puzzle.get_tree_hash() != coin_state.coin.puzzle_hash:
|
|
1203
1320
|
if full_puzzle_empty_recovery.get_tree_hash() == coin_state.coin.puzzle_hash:
|
|
1204
1321
|
did_puzzle = did_puzzle_empty_recovery
|
|
1205
1322
|
self.log.info("DID recovery list was reset by the previous owner.")
|
|
1323
|
+
elif alt_full_puzzle_empty_recovery.get_tree_hash() == coin_state.coin.puzzle_hash:
|
|
1324
|
+
did_puzzle = alt_did_puzzle_empty_recovery
|
|
1325
|
+
self.log.info("DID recovery list was reset by the previous owner.")
|
|
1206
1326
|
else:
|
|
1207
1327
|
self.log.error("DID puzzle hash doesn't match, please check curried parameters.")
|
|
1208
1328
|
return None
|
|
@@ -1256,7 +1376,7 @@ class WalletStateManager:
|
|
|
1256
1376
|
raise ValueError("Couldn't get minter DID for NFT")
|
|
1257
1377
|
if not eve_uncurried_nft.supports_did:
|
|
1258
1378
|
return None
|
|
1259
|
-
minter_did = get_new_owner_did(eve_uncurried_nft, eve_coin_spend.solution
|
|
1379
|
+
minter_did = get_new_owner_did(eve_uncurried_nft, Program.from_serialized(eve_coin_spend.solution))
|
|
1260
1380
|
if minter_did == b"":
|
|
1261
1381
|
minter_did = None
|
|
1262
1382
|
if minter_did is None:
|
|
@@ -1307,7 +1427,7 @@ class WalletStateManager:
|
|
|
1307
1427
|
nft_data.parent_coin_spend.solution,
|
|
1308
1428
|
)
|
|
1309
1429
|
if uncurried_nft.supports_did:
|
|
1310
|
-
_new_did_id = get_new_owner_did(uncurried_nft, nft_data.parent_coin_spend.solution
|
|
1430
|
+
_new_did_id = get_new_owner_did(uncurried_nft, Program.from_serialized(nft_data.parent_coin_spend.solution))
|
|
1311
1431
|
old_did_id = uncurried_nft.owner_did
|
|
1312
1432
|
if _new_did_id is None:
|
|
1313
1433
|
new_did_id = old_did_id
|
|
@@ -1810,9 +1930,10 @@ class WalletStateManager:
|
|
|
1810
1930
|
|
|
1811
1931
|
while curr_coin_state.spent_height is not None:
|
|
1812
1932
|
cs: CoinSpend = await fetch_coin_spend_for_coin_state(curr_coin_state, peer)
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1933
|
+
async with self.new_action_scope(self.tx_config, push=True) as action_scope:
|
|
1934
|
+
success = await singleton_wallet.apply_state_transition(
|
|
1935
|
+
cs, uint32(curr_coin_state.spent_height), action_scope
|
|
1936
|
+
)
|
|
1816
1937
|
if not success:
|
|
1817
1938
|
break
|
|
1818
1939
|
new_singleton_coin = get_most_recent_singleton_coin_from_coin_spend(cs)
|
|
@@ -1901,14 +2022,16 @@ class WalletStateManager:
|
|
|
1901
2022
|
self.log.debug("solution_to_pool_state returned None, ignore and continue")
|
|
1902
2023
|
continue
|
|
1903
2024
|
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
2025
|
+
async with self.new_action_scope(self.tx_config, push=True) as action_scope:
|
|
2026
|
+
pool_wallet = await PoolWallet.create(
|
|
2027
|
+
self,
|
|
2028
|
+
action_scope,
|
|
2029
|
+
self.main_wallet,
|
|
2030
|
+
child.coin.name(),
|
|
2031
|
+
[launcher_spend],
|
|
2032
|
+
uint32(child.spent_height),
|
|
2033
|
+
name="pool_wallet",
|
|
2034
|
+
)
|
|
1912
2035
|
launcher_spend_additions = compute_additions(launcher_spend)
|
|
1913
2036
|
assert len(launcher_spend_additions) == 1
|
|
1914
2037
|
coin_added = launcher_spend_additions[0]
|
|
@@ -1971,7 +2094,7 @@ class WalletStateManager:
|
|
|
1971
2094
|
):
|
|
1972
2095
|
# Optimization to avoid the computation below. Any coin that has a different amount is not a pool reward
|
|
1973
2096
|
return False
|
|
1974
|
-
for i in range(
|
|
2097
|
+
for i in range(30):
|
|
1975
2098
|
try_height = created_height - i
|
|
1976
2099
|
if try_height < 0:
|
|
1977
2100
|
break
|
|
@@ -1984,7 +2107,7 @@ class WalletStateManager:
|
|
|
1984
2107
|
if coin.amount < calculate_base_farmer_reward(created_height):
|
|
1985
2108
|
# Optimization to avoid the computation below. Any coin less than this base amount cannot be farmer reward
|
|
1986
2109
|
return False
|
|
1987
|
-
for i in range(
|
|
2110
|
+
for i in range(30):
|
|
1988
2111
|
try_height = created_height - i
|
|
1989
2112
|
if try_height < 0:
|
|
1990
2113
|
break
|
|
@@ -2107,7 +2230,8 @@ class WalletStateManager:
|
|
|
2107
2230
|
|
|
2108
2231
|
await self.wallets[wallet_id].coin_added(coin, height, peer, coin_data)
|
|
2109
2232
|
|
|
2110
|
-
await self.create_more_puzzle_hashes()
|
|
2233
|
+
result = await self.create_more_puzzle_hashes()
|
|
2234
|
+
await result.commit(self)
|
|
2111
2235
|
|
|
2112
2236
|
async def add_pending_transactions(
|
|
2113
2237
|
self,
|
|
@@ -2300,7 +2424,8 @@ class WalletStateManager:
|
|
|
2300
2424
|
for wallet_id, wallet in self.wallets.items():
|
|
2301
2425
|
if wallet.type() == WalletType.POOLING_WALLET.value:
|
|
2302
2426
|
assert isinstance(wallet, PoolWallet)
|
|
2303
|
-
|
|
2427
|
+
async with self.new_action_scope(self.tx_config, push=True) as action_scope:
|
|
2428
|
+
remove: bool = await wallet.rewind(height, action_scope)
|
|
2304
2429
|
if remove:
|
|
2305
2430
|
remove_ids.append(wallet_id)
|
|
2306
2431
|
for wallet_id in remove_ids:
|
|
@@ -2320,7 +2445,7 @@ class WalletStateManager:
|
|
|
2320
2445
|
|
|
2321
2446
|
async def get_wallet_for_asset_id(self, asset_id: str) -> Optional[WalletProtocol[Any]]:
|
|
2322
2447
|
for wallet_id, wallet in self.wallets.items():
|
|
2323
|
-
if wallet.type() in {WalletType.CAT, WalletType.CRCAT}:
|
|
2448
|
+
if wallet.type() in {WalletType.CAT, WalletType.CRCAT, WalletType.RCAT}:
|
|
2324
2449
|
assert isinstance(wallet, CATWallet)
|
|
2325
2450
|
if wallet.get_asset_id() == asset_id:
|
|
2326
2451
|
return wallet
|
|
@@ -2352,12 +2477,14 @@ class WalletStateManager:
|
|
|
2352
2477
|
name,
|
|
2353
2478
|
potential_subclasses={
|
|
2354
2479
|
AssetType.CR: CRCATWallet,
|
|
2480
|
+
AssetType.REVOCATION_LAYER: RCATWallet,
|
|
2355
2481
|
},
|
|
2356
2482
|
)
|
|
2357
2483
|
|
|
2358
2484
|
async def add_new_wallet(self, wallet: WalletProtocol[Any]) -> None:
|
|
2359
2485
|
self.wallets[wallet.id()] = wallet
|
|
2360
|
-
await self.create_more_puzzle_hashes()
|
|
2486
|
+
result = await self.create_more_puzzle_hashes()
|
|
2487
|
+
await result.commit(self)
|
|
2361
2488
|
self.state_changed("wallet_created")
|
|
2362
2489
|
|
|
2363
2490
|
async def get_spendable_coins_for_wallet(
|
|
@@ -2439,7 +2566,7 @@ class WalletStateManager:
|
|
|
2439
2566
|
async def convert_puzzle_hash(self, wallet_id: uint32, puzzle_hash: bytes32) -> bytes32:
|
|
2440
2567
|
wallet = self.wallets[wallet_id]
|
|
2441
2568
|
# This should be general to wallets but for right now this is just for CATs so we'll add this if
|
|
2442
|
-
if wallet.type() in {WalletType.CAT.value, WalletType.CRCAT.value}:
|
|
2569
|
+
if wallet.type() in {WalletType.CAT.value, WalletType.CRCAT.value, WalletType.RCAT.value}:
|
|
2443
2570
|
assert isinstance(wallet, CATWallet)
|
|
2444
2571
|
return await wallet.convert_puzzle_hash(puzzle_hash)
|
|
2445
2572
|
|
|
@@ -2485,8 +2612,8 @@ class WalletStateManager:
|
|
|
2485
2612
|
_coin_spend = coin_spend.as_coin_spend()
|
|
2486
2613
|
# Get AGG_SIG conditions
|
|
2487
2614
|
conditions_dict = conditions_dict_for_solution(
|
|
2488
|
-
_coin_spend.puzzle_reveal
|
|
2489
|
-
_coin_spend.solution
|
|
2615
|
+
Program.from_serialized(_coin_spend.puzzle_reveal),
|
|
2616
|
+
Program.from_serialized(_coin_spend.solution),
|
|
2490
2617
|
self.constants.MAX_BLOCK_COST_CLVM,
|
|
2491
2618
|
)
|
|
2492
2619
|
# Create signature
|
|
@@ -2625,6 +2752,7 @@ class WalletStateManager:
|
|
|
2625
2752
|
sign: Optional[bool] = None,
|
|
2626
2753
|
additional_signing_responses: list[SigningResponse] = [],
|
|
2627
2754
|
extra_spends: list[WalletSpendBundle] = [],
|
|
2755
|
+
puzzle_for_pk: Optional[Callable[[G1Element], Program]] = None,
|
|
2628
2756
|
) -> AsyncIterator[WalletActionScope]:
|
|
2629
2757
|
async with new_wallet_action_scope(
|
|
2630
2758
|
self,
|
|
@@ -2634,6 +2762,7 @@ class WalletStateManager:
|
|
|
2634
2762
|
sign=sign,
|
|
2635
2763
|
additional_signing_responses=additional_signing_responses,
|
|
2636
2764
|
extra_spends=extra_spends,
|
|
2765
|
+
puzzle_for_pk=puzzle_for_pk,
|
|
2637
2766
|
) as action_scope:
|
|
2638
2767
|
yield action_scope
|
|
2639
2768
|
|