chia-blockchain 2.5.4rc2__py3-none-any.whl → 2.5.5__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 +529 -69
- chia/_tests/core/mempool/test_mempool_performance.py +3 -2
- chia/_tests/core/mempool/test_singleton_fast_forward.py +61 -132
- 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 +153 -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 +47 -45
- 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.5.dist-info}/METADATA +7 -7
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.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.5.dist-info}/LICENSE +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.dist-info}/entry_points.txt +0 -0
|
@@ -1,104 +1,105 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import random
|
|
5
|
-
from typing import Any
|
|
3
|
+
from typing import Optional, cast
|
|
6
4
|
|
|
7
5
|
import pytest
|
|
8
6
|
from chia_rs.sized_bytes import bytes32
|
|
9
7
|
from chia_rs.sized_ints import uint16, uint32, uint64
|
|
10
8
|
|
|
11
|
-
from chia._tests.
|
|
12
|
-
from chia._tests.util.time_out_assert import time_out_assert
|
|
13
|
-
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
|
|
14
|
-
from chia.rpc.full_node_rpc_client import FullNodeRpcClient
|
|
15
|
-
from chia.rpc.wallet_rpc_api import WalletRpcApi
|
|
16
|
-
from chia.rpc.wallet_rpc_client import WalletRpcClient
|
|
17
|
-
from chia.simulator.full_node_simulator import FullNodeSimulator
|
|
18
|
-
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
|
|
9
|
+
from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework
|
|
10
|
+
from chia._tests.util.time_out_assert import time_out_assert
|
|
19
11
|
from chia.types.blockchain_format.program import Program
|
|
20
|
-
from chia.types.peer_info import PeerInfo
|
|
21
12
|
from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
|
|
22
13
|
from chia.wallet.did_wallet.did_wallet import DIDWallet
|
|
23
14
|
from chia.wallet.nft_wallet.nft_wallet import NFTWallet
|
|
24
15
|
from chia.wallet.nft_wallet.uncurry_nft import UncurriedNFT
|
|
16
|
+
from chia.wallet.transaction_record import TransactionRecord
|
|
25
17
|
from chia.wallet.util.address_type import AddressType
|
|
26
|
-
from chia.wallet.
|
|
18
|
+
from chia.wallet.wallet_request_types import NFTGetNFTs, NFTMintBulk, NFTMintMetadata, PushTransactions
|
|
27
19
|
|
|
28
20
|
|
|
29
21
|
async def nft_count(wallet: NFTWallet) -> int:
|
|
30
22
|
return await wallet.get_nft_count()
|
|
31
23
|
|
|
32
24
|
|
|
33
|
-
@pytest.mark.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
)
|
|
25
|
+
@pytest.mark.limit_consensus_modes
|
|
26
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
27
|
+
@pytest.mark.parametrize("with_did", [True, False])
|
|
37
28
|
@pytest.mark.anyio
|
|
38
|
-
async def
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
56
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
57
|
-
}
|
|
58
|
-
else:
|
|
59
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
60
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
61
|
-
|
|
62
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
63
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
64
|
-
|
|
65
|
-
# for _ in range(1, num_blocks):
|
|
66
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
|
|
67
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
68
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
69
|
-
|
|
70
|
-
await time_out_assert(30, wallet_0.get_unconfirmed_balance, funds)
|
|
71
|
-
await time_out_assert(30, wallet_0.get_confirmed_balance, funds)
|
|
72
|
-
|
|
73
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
29
|
+
async def test_nft_mint(wallet_environments: WalletTestFramework, with_did: bool) -> None:
|
|
30
|
+
env_0 = wallet_environments.environments[0]
|
|
31
|
+
env_1 = wallet_environments.environments[1]
|
|
32
|
+
wallet_0 = env_0.xch_wallet
|
|
33
|
+
wallet_1 = env_1.xch_wallet
|
|
34
|
+
env_0.wallet_aliases = {
|
|
35
|
+
"xch": 1,
|
|
36
|
+
"did": 2,
|
|
37
|
+
"nft": 3,
|
|
38
|
+
}
|
|
39
|
+
env_1.wallet_aliases = {
|
|
40
|
+
"xch": 1,
|
|
41
|
+
"nft": 2,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
45
|
+
ph_0 = await action_scope.get_puzzle_hash(env_0.wallet_state_manager)
|
|
74
46
|
did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
75
|
-
|
|
47
|
+
env_0.wallet_state_manager, wallet_0, uint64(1), action_scope
|
|
76
48
|
)
|
|
77
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
78
|
-
await time_out_assert(30, wallet_0.get_pending_change_balance, 0)
|
|
79
49
|
|
|
80
50
|
hex_did_id = did_wallet.get_my_DID()
|
|
81
51
|
did_id = bytes32.fromhex(hex_did_id)
|
|
82
52
|
|
|
83
|
-
await
|
|
84
|
-
|
|
85
|
-
nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
|
|
86
|
-
wallet_node_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
|
|
53
|
+
nft_wallet_0 = await NFTWallet.create_new_nft_wallet(
|
|
54
|
+
env_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
|
|
87
55
|
)
|
|
88
56
|
|
|
89
|
-
|
|
90
|
-
|
|
57
|
+
nft_wallet_1 = await NFTWallet.create_new_nft_wallet(env_1.wallet_state_manager, wallet_1, name="NFT WALLET 2")
|
|
58
|
+
|
|
59
|
+
await wallet_environments.process_pending_states(
|
|
60
|
+
[
|
|
61
|
+
WalletStateTransition(
|
|
62
|
+
pre_block_balance_updates={
|
|
63
|
+
"xch": {
|
|
64
|
+
"set_remainder": True,
|
|
65
|
+
},
|
|
66
|
+
"did": {
|
|
67
|
+
"init": True,
|
|
68
|
+
"set_remainder": True,
|
|
69
|
+
},
|
|
70
|
+
"nft": {
|
|
71
|
+
"init": True,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
post_block_balance_updates={
|
|
75
|
+
"xch": {
|
|
76
|
+
"set_remainder": True,
|
|
77
|
+
},
|
|
78
|
+
"did": {
|
|
79
|
+
"set_remainder": True,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
),
|
|
83
|
+
WalletStateTransition(
|
|
84
|
+
pre_block_balance_updates={
|
|
85
|
+
"nft": {
|
|
86
|
+
"init": True,
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
post_block_balance_updates={},
|
|
90
|
+
),
|
|
91
|
+
]
|
|
91
92
|
)
|
|
92
93
|
|
|
93
94
|
royalty_pc = uint16(300)
|
|
94
|
-
royalty_addr =
|
|
95
|
+
royalty_addr = ph_0
|
|
95
96
|
|
|
96
97
|
mint_total = 10
|
|
97
98
|
fee = uint64(100)
|
|
98
99
|
metadata_list = [
|
|
99
100
|
{
|
|
100
101
|
"program": Program.to(
|
|
101
|
-
[("u", ["https://www.chia.net/img/branding/chia-logo.svg"]), ("h", bytes32.
|
|
102
|
+
[("u", ["https://www.chia.net/img/branding/chia-logo.svg"]), ("h", bytes32.zeros.hex())]
|
|
102
103
|
),
|
|
103
104
|
"royalty_pc": royalty_pc,
|
|
104
105
|
"royalty_ph": royalty_addr,
|
|
@@ -106,31 +107,87 @@ async def test_nft_mint_from_did(
|
|
|
106
107
|
for x in range(mint_total)
|
|
107
108
|
]
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
110
|
+
async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
111
|
+
target_list = [await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager) for x in range(mint_total)]
|
|
112
|
+
|
|
113
|
+
async with nft_wallet_0.wallet_state_manager.new_action_scope(
|
|
114
|
+
wallet_environments.tx_config, push=True
|
|
115
|
+
) as action_scope:
|
|
116
|
+
if with_did:
|
|
117
|
+
await nft_wallet_0.mint_from_did(
|
|
118
|
+
metadata_list,
|
|
119
|
+
action_scope,
|
|
120
|
+
target_list=target_list,
|
|
121
|
+
mint_number_start=1,
|
|
122
|
+
mint_total=mint_total,
|
|
123
|
+
fee=fee,
|
|
124
|
+
)
|
|
125
|
+
else:
|
|
126
|
+
await nft_wallet_0.mint_from_xch(
|
|
127
|
+
metadata_list,
|
|
128
|
+
action_scope,
|
|
129
|
+
target_list=target_list,
|
|
130
|
+
mint_number_start=1,
|
|
131
|
+
mint_total=mint_total,
|
|
132
|
+
fee=fee,
|
|
124
133
|
)
|
|
125
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
126
|
-
|
|
127
|
-
await time_out_assert(30, nft_count, mint_total, nft_wallet_taker)
|
|
128
|
-
await time_out_assert(30, nft_count, 0, nft_wallet_maker)
|
|
129
134
|
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
await wallet_environments.process_pending_states(
|
|
136
|
+
[
|
|
137
|
+
WalletStateTransition(
|
|
138
|
+
pre_block_balance_updates={
|
|
139
|
+
"xch": {
|
|
140
|
+
"unconfirmed_wallet_balance": -fee - mint_total,
|
|
141
|
+
"<=#spendable_balance": -fee - mint_total,
|
|
142
|
+
"<=#max_send_amount": -fee - mint_total,
|
|
143
|
+
">=#pending_change": 1,
|
|
144
|
+
"pending_coin_removal_count": 1,
|
|
145
|
+
},
|
|
146
|
+
"did": {
|
|
147
|
+
"spendable_balance": -1,
|
|
148
|
+
"max_send_amount": -1,
|
|
149
|
+
"pending_change": 1,
|
|
150
|
+
"pending_coin_removal_count": 1,
|
|
151
|
+
}
|
|
152
|
+
if with_did
|
|
153
|
+
else {},
|
|
154
|
+
"nft": {
|
|
155
|
+
"pending_coin_removal_count": mint_total,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
post_block_balance_updates={
|
|
159
|
+
"xch": {
|
|
160
|
+
"confirmed_wallet_balance": -fee - mint_total,
|
|
161
|
+
">=#spendable_balance": 1,
|
|
162
|
+
">=#max_send_amount": 1,
|
|
163
|
+
"<=#pending_change": -1,
|
|
164
|
+
"pending_coin_removal_count": -1,
|
|
165
|
+
},
|
|
166
|
+
"did": {
|
|
167
|
+
"spendable_balance": 1,
|
|
168
|
+
"max_send_amount": 1,
|
|
169
|
+
"pending_change": -1,
|
|
170
|
+
"pending_coin_removal_count": -1,
|
|
171
|
+
}
|
|
172
|
+
if with_did
|
|
173
|
+
else {},
|
|
174
|
+
"nft": {
|
|
175
|
+
"pending_coin_removal_count": -mint_total,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
),
|
|
179
|
+
WalletStateTransition(
|
|
180
|
+
pre_block_balance_updates={},
|
|
181
|
+
post_block_balance_updates={
|
|
182
|
+
"nft": {
|
|
183
|
+
"unspent_coin_count": mint_total,
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
),
|
|
187
|
+
]
|
|
188
|
+
)
|
|
132
189
|
|
|
133
|
-
nfts = await
|
|
190
|
+
nfts = await nft_wallet_1.get_current_nfts()
|
|
134
191
|
matched_data = dict(zip(target_list, metadata_list))
|
|
135
192
|
|
|
136
193
|
# Check targets and metadata entries match in the final nfts
|
|
@@ -142,839 +199,303 @@ async def test_nft_mint_from_did(
|
|
|
142
199
|
inner_ph = inner_args.at("rrrf").get_tree_hash()
|
|
143
200
|
meta = unft.metadata.at("rfr").as_atom()
|
|
144
201
|
# check that the target puzzle hashes of transferred nfts matches the metadata entry
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
202
|
+
prog: Program = cast(Program, matched_data[inner_ph]["program"])
|
|
203
|
+
assert prog.at("rfr").as_atom() == meta
|
|
204
|
+
if with_did:
|
|
205
|
+
# Check the did is set for each nft
|
|
206
|
+
assert nft.minter_did == did_id
|
|
207
|
+
else:
|
|
208
|
+
assert nft.minter_did is None
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@pytest.mark.limit_consensus_modes
|
|
212
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
213
|
+
@pytest.mark.parametrize("zero_royalties", [True, False])
|
|
214
|
+
@pytest.mark.parametrize("with_did", [True, False])
|
|
154
215
|
@pytest.mark.anyio
|
|
155
|
-
async def
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if trusted:
|
|
176
|
-
wallet_node_maker.config["trusted_peers"] = {
|
|
177
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
178
|
-
}
|
|
179
|
-
wallet_node_taker.config["trusted_peers"] = {
|
|
180
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
181
|
-
}
|
|
182
|
-
else:
|
|
183
|
-
wallet_node_maker.config["trusted_peers"] = {}
|
|
184
|
-
wallet_node_taker.config["trusted_peers"] = {}
|
|
185
|
-
|
|
186
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
187
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
188
|
-
|
|
189
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
|
|
190
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_taker))
|
|
191
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
192
|
-
|
|
193
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
194
|
-
|
|
195
|
-
await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
|
|
196
|
-
await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
|
|
197
|
-
await time_out_assert(30, wallet_taker.get_unconfirmed_balance, funds)
|
|
198
|
-
await time_out_assert(30, wallet_taker.get_confirmed_balance, funds)
|
|
199
|
-
|
|
200
|
-
api_maker = WalletRpcApi(wallet_node_maker)
|
|
201
|
-
api_taker = WalletRpcApi(wallet_node_taker)
|
|
202
|
-
config = bt.config
|
|
203
|
-
|
|
204
|
-
assert wallet_services[0].rpc_server is not None
|
|
205
|
-
assert full_node_service.rpc_server is not None
|
|
206
|
-
|
|
207
|
-
async with contextlib.AsyncExitStack() as exit_stack:
|
|
208
|
-
client = await exit_stack.enter_async_context(
|
|
209
|
-
WalletRpcClient.create_as_context(
|
|
210
|
-
self_hostname,
|
|
211
|
-
wallet_services[0].rpc_server.listen_port,
|
|
212
|
-
wallet_services[0].root_path,
|
|
213
|
-
wallet_services[0].config,
|
|
214
|
-
)
|
|
216
|
+
async def test_nft_mint_rpc(wallet_environments: WalletTestFramework, zero_royalties: bool, with_did: bool) -> None:
|
|
217
|
+
env_0 = wallet_environments.environments[0]
|
|
218
|
+
env_1 = wallet_environments.environments[1]
|
|
219
|
+
wallet_0 = env_0.xch_wallet
|
|
220
|
+
env_0.wallet_aliases = {
|
|
221
|
+
"xch": 1,
|
|
222
|
+
"did": 2,
|
|
223
|
+
"nft": 3,
|
|
224
|
+
}
|
|
225
|
+
env_1.wallet_aliases = {
|
|
226
|
+
"xch": 1,
|
|
227
|
+
"nft": 2,
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async with env_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
231
|
+
ph_1 = await action_scope.get_puzzle_hash(env_1.wallet_state_manager)
|
|
232
|
+
|
|
233
|
+
async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
234
|
+
did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
235
|
+
env_0.wallet_state_manager, wallet_0, uint64(1), action_scope
|
|
215
236
|
)
|
|
216
|
-
client_node = await exit_stack.enter_async_context(
|
|
217
|
-
FullNodeRpcClient.create_as_context(
|
|
218
|
-
self_hostname,
|
|
219
|
-
full_node_service.rpc_server.listen_port,
|
|
220
|
-
full_node_service.root_path,
|
|
221
|
-
full_node_service.config,
|
|
222
|
-
)
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
226
|
-
did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
227
|
-
wallet_node_maker.wallet_state_manager, wallet_maker, uint64(1), action_scope
|
|
228
|
-
)
|
|
229
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
230
237
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
"hash": bytes32.random(seeded_random).hex(),
|
|
254
|
-
"uris": [f"https://data.com/{i}"],
|
|
255
|
-
"meta_hash": bytes32.random(seeded_random).hex(),
|
|
256
|
-
"meta_uris": [f"https://meatadata.com/{i}"],
|
|
257
|
-
"license_hash": bytes32.random(seeded_random).hex(),
|
|
258
|
-
"license_uris": [f"https://license.com/{i}"],
|
|
259
|
-
"edition_number": i + 1,
|
|
260
|
-
"edition_total": n,
|
|
261
|
-
}
|
|
262
|
-
for i in range(n)
|
|
238
|
+
await wallet_environments.process_pending_states(
|
|
239
|
+
[
|
|
240
|
+
WalletStateTransition(
|
|
241
|
+
pre_block_balance_updates={
|
|
242
|
+
"xch": {
|
|
243
|
+
"set_remainder": True,
|
|
244
|
+
},
|
|
245
|
+
"did": {
|
|
246
|
+
"init": True,
|
|
247
|
+
"set_remainder": True,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
post_block_balance_updates={
|
|
251
|
+
"xch": {
|
|
252
|
+
"set_remainder": True,
|
|
253
|
+
},
|
|
254
|
+
"did": {
|
|
255
|
+
"set_remainder": True,
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
),
|
|
259
|
+
WalletStateTransition(),
|
|
263
260
|
]
|
|
264
|
-
|
|
265
|
-
royalty_address = encode_puzzle_hash(bytes32.random(seeded_random), "xch")
|
|
266
|
-
royalty_percentage = 300
|
|
267
|
-
fee = 100
|
|
268
|
-
required_amount = n + (fee * n)
|
|
269
|
-
xch_coins = await client.select_coins(
|
|
270
|
-
amount=required_amount, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=wallet_maker.id()
|
|
271
|
-
)
|
|
272
|
-
funding_coin = xch_coins[0]
|
|
273
|
-
assert funding_coin.amount >= required_amount
|
|
274
|
-
funding_coin_dict = xch_coins[0].to_json_dict()
|
|
275
|
-
chunk = 5
|
|
276
|
-
next_coin = funding_coin
|
|
277
|
-
did_coin = (
|
|
278
|
-
await client.select_coins(amount=1, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=2)
|
|
279
|
-
)[0]
|
|
280
|
-
did_lineage_parent = None
|
|
281
|
-
spends = []
|
|
282
|
-
nft_ids = set()
|
|
283
|
-
for i in range(0, n, chunk):
|
|
284
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
|
|
285
|
-
resp = await client.nft_mint_bulk(
|
|
286
|
-
wallet_id=nft_wallet_maker["wallet_id"],
|
|
287
|
-
metadata_list=metadata_list[i : i + chunk],
|
|
288
|
-
target_list=target_list[i : i + chunk],
|
|
289
|
-
royalty_percentage=royalty_percentage,
|
|
290
|
-
royalty_address=royalty_address,
|
|
291
|
-
mint_number_start=i + 1,
|
|
292
|
-
mint_total=n,
|
|
293
|
-
xch_coins=[next_coin.to_json_dict()],
|
|
294
|
-
xch_change_target=funding_coin_dict["puzzle_hash"],
|
|
295
|
-
did_coin=did_coin.to_json_dict(),
|
|
296
|
-
did_lineage_parent=did_lineage_parent,
|
|
297
|
-
mint_from_did=True,
|
|
298
|
-
fee=fee,
|
|
299
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
300
|
-
)
|
|
301
|
-
sb = resp.spend_bundle
|
|
302
|
-
did_lineage_parent = next(cn for cn in sb.removals() if cn.name() == did_coin.name()).parent_coin_info.hex()
|
|
303
|
-
did_coin = next(
|
|
304
|
-
cn for cn in sb.additions() if (cn.parent_coin_info == did_coin.name()) and (cn.amount == 1)
|
|
305
|
-
)
|
|
306
|
-
spends.append(sb)
|
|
307
|
-
xch_adds = [c for c in sb.additions() if c.puzzle_hash == funding_coin.puzzle_hash]
|
|
308
|
-
assert len(xch_adds) == 1
|
|
309
|
-
next_coin = xch_adds[0]
|
|
310
|
-
for nft_id in resp.nft_id_list:
|
|
311
|
-
nft_ids.add(decode_puzzle_hash(nft_id))
|
|
312
|
-
for sb in spends:
|
|
313
|
-
push_resp = await client_node.push_tx(sb)
|
|
314
|
-
assert push_resp["success"]
|
|
315
|
-
await full_node_api.process_spend_bundles([sb])
|
|
316
|
-
|
|
317
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
318
|
-
|
|
319
|
-
async def get_taker_nfts() -> int:
|
|
320
|
-
return int((await api_taker.nft_count_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["count"])
|
|
321
|
-
|
|
322
|
-
# We are using a long time out here because it can take a long time for the NFTs to show up
|
|
323
|
-
# Even with only 10 NFTs it regularly takes longer than 30-40s for them to be found
|
|
324
|
-
await time_out_assert(60, get_taker_nfts, n)
|
|
261
|
+
)
|
|
325
262
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
for nft in nfts:
|
|
329
|
-
edition_num = nft.edition_number
|
|
330
|
-
meta_dict = metadata_list[edition_num - 1]
|
|
331
|
-
assert meta_dict["hash"] == nft.data_hash.hex()
|
|
332
|
-
assert meta_dict["uris"] == nft.data_uris
|
|
333
|
-
assert meta_dict["meta_hash"] == nft.metadata_hash.hex()
|
|
334
|
-
assert meta_dict["meta_uris"] == nft.metadata_uris
|
|
335
|
-
assert meta_dict["license_hash"] == nft.license_hash.hex()
|
|
336
|
-
assert meta_dict["license_uris"] == nft.license_uris
|
|
337
|
-
assert meta_dict["edition_number"] == nft.edition_number
|
|
338
|
-
assert meta_dict["edition_total"] == nft.edition_total
|
|
339
|
-
assert nft.launcher_id in nft_ids
|
|
263
|
+
hex_did_id = did_wallet_maker.get_my_DID()
|
|
264
|
+
hmr_did_id = encode_puzzle_hash(bytes32.from_hexstr(hex_did_id), AddressType.DID.hrp(env_0.node.config))
|
|
340
265
|
|
|
266
|
+
nft_wallet_maker = await env_0.rpc_client.create_new_nft_wallet(name="NFT WALLET 1", did_id=hmr_did_id)
|
|
341
267
|
|
|
342
|
-
|
|
343
|
-
"trusted",
|
|
344
|
-
[True, False],
|
|
345
|
-
)
|
|
346
|
-
@pytest.mark.anyio
|
|
347
|
-
async def test_nft_mint_from_did_rpc_no_royalties(
|
|
348
|
-
two_wallet_nodes_services: SimulatorsAndWalletsServices,
|
|
349
|
-
trusted: Any,
|
|
350
|
-
self_hostname: str,
|
|
351
|
-
seeded_random: random.Random,
|
|
352
|
-
) -> None:
|
|
353
|
-
[full_node_service], wallet_services, bt = two_wallet_nodes_services
|
|
354
|
-
full_node_api: FullNodeSimulator = full_node_service._api
|
|
355
|
-
full_node_server = full_node_api.server
|
|
356
|
-
wallet_node_maker = wallet_services[0]._node
|
|
357
|
-
wallet_node_taker = wallet_services[1]._node
|
|
358
|
-
server_0 = wallet_node_maker.server
|
|
359
|
-
server_1 = wallet_node_taker.server
|
|
360
|
-
wallet_maker = wallet_node_maker.wallet_state_manager.main_wallet
|
|
361
|
-
wallet_taker = wallet_node_taker.wallet_state_manager.main_wallet
|
|
268
|
+
await env_1.rpc_client.create_new_nft_wallet(name="NFT WALLET 2", did_id=None)
|
|
362
269
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
ph_token = bytes32.random(seeded_random)
|
|
270
|
+
await env_0.change_balances({"nft": {"init": True}})
|
|
271
|
+
await env_1.change_balances({"nft": {"init": True}})
|
|
366
272
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
273
|
+
n = 10
|
|
274
|
+
chunk = 5
|
|
275
|
+
metadata_list = [
|
|
276
|
+
{
|
|
277
|
+
"hash": bytes([i] * 32).hex(),
|
|
278
|
+
"uris": [f"https://data.com/{i}"],
|
|
279
|
+
"meta_hash": bytes([i] * 32).hex(),
|
|
280
|
+
"meta_uris": [f"https://meatadata.com/{i}"],
|
|
281
|
+
"license_hash": bytes([i] * 32).hex(),
|
|
282
|
+
"license_uris": [f"https://license.com/{i}"],
|
|
283
|
+
"edition_number": i + 1,
|
|
284
|
+
"edition_total": n,
|
|
373
285
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
await
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
assert wallet_services[0].rpc_server is not None
|
|
397
|
-
assert full_node_service.rpc_server is not None
|
|
398
|
-
|
|
399
|
-
async with contextlib.AsyncExitStack() as exit_stack:
|
|
400
|
-
client = await exit_stack.enter_async_context(
|
|
401
|
-
WalletRpcClient.create_as_context(
|
|
402
|
-
self_hostname,
|
|
403
|
-
wallet_services[0].rpc_server.listen_port,
|
|
404
|
-
wallet_services[0].root_path,
|
|
405
|
-
wallet_services[0].config,
|
|
406
|
-
)
|
|
407
|
-
)
|
|
408
|
-
client_node = await exit_stack.enter_async_context(
|
|
409
|
-
FullNodeRpcClient.create_as_context(
|
|
410
|
-
self_hostname,
|
|
411
|
-
full_node_service.rpc_server.listen_port,
|
|
412
|
-
full_node_service.root_path,
|
|
413
|
-
full_node_service.config,
|
|
414
|
-
)
|
|
415
|
-
)
|
|
416
|
-
|
|
417
|
-
async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
418
|
-
did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
419
|
-
wallet_node_maker.wallet_state_manager, wallet_maker, uint64(1), action_scope
|
|
420
|
-
)
|
|
421
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
422
|
-
|
|
423
|
-
await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
|
|
424
|
-
await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds - 1)
|
|
425
|
-
await time_out_assert(30, wallet_maker.get_confirmed_balance, funds - 1)
|
|
426
|
-
|
|
427
|
-
hex_did_id = did_wallet_maker.get_my_DID()
|
|
428
|
-
hmr_did_id = encode_puzzle_hash(bytes32.from_hexstr(hex_did_id), AddressType.DID.hrp(config))
|
|
429
|
-
|
|
430
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
|
|
431
|
-
|
|
432
|
-
nft_wallet_maker = await api_maker.create_new_wallet(
|
|
433
|
-
dict(wallet_type="nft_wallet", name="NFT WALLET 1", did_id=hmr_did_id)
|
|
434
|
-
)
|
|
435
|
-
assert isinstance(nft_wallet_maker, dict)
|
|
436
|
-
assert nft_wallet_maker.get("success")
|
|
437
|
-
|
|
438
|
-
nft_wallet_taker = await api_taker.create_new_wallet(dict(wallet_type="nft_wallet", name="NFT WALLET 2"))
|
|
439
|
-
|
|
440
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
441
|
-
|
|
442
|
-
n = 10
|
|
443
|
-
metadata_list = [
|
|
444
|
-
{
|
|
445
|
-
"hash": bytes32.random(seeded_random).hex(),
|
|
446
|
-
"uris": [f"https://data.com/{i}"],
|
|
447
|
-
"meta_hash": bytes32.random(seeded_random).hex(),
|
|
448
|
-
"meta_uris": [f"https://meatadata.com/{i}"],
|
|
449
|
-
"license_hash": bytes32.random(seeded_random).hex(),
|
|
450
|
-
"license_uris": [f"https://license.com/{i}"],
|
|
451
|
-
"edition_number": i + 1,
|
|
452
|
-
"edition_total": n,
|
|
453
|
-
}
|
|
454
|
-
for i in range(n)
|
|
455
|
-
]
|
|
456
|
-
target_list = [encode_puzzle_hash((ph_taker), "xch") for x in range(n)]
|
|
457
|
-
royalty_address = None
|
|
458
|
-
royalty_percentage = None
|
|
459
|
-
required_amount = n
|
|
460
|
-
xch_coins = await client.select_coins(
|
|
461
|
-
amount=required_amount, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=wallet_maker.id()
|
|
286
|
+
for i in range(n)
|
|
287
|
+
]
|
|
288
|
+
target_list = [encode_puzzle_hash(ph_1, "xch") for x in range(n)]
|
|
289
|
+
royalty_address = None if zero_royalties else encode_puzzle_hash(bytes32.zeros, "xch")
|
|
290
|
+
royalty_percentage = None if zero_royalties else 300
|
|
291
|
+
fee = 100
|
|
292
|
+
num_chunks = int(n / chunk) + (1 if n % chunk > 0 else 0)
|
|
293
|
+
required_amount = n + (fee * num_chunks)
|
|
294
|
+
xch_coins = await env_0.rpc_client.select_coins(
|
|
295
|
+
amount=required_amount,
|
|
296
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config,
|
|
297
|
+
wallet_id=wallet_0.id(),
|
|
298
|
+
)
|
|
299
|
+
funding_coin = xch_coins[0]
|
|
300
|
+
assert funding_coin.amount >= required_amount
|
|
301
|
+
funding_coin_dict = xch_coins[0].to_json_dict()
|
|
302
|
+
next_coin = funding_coin
|
|
303
|
+
did_coin = (
|
|
304
|
+
await env_0.rpc_client.select_coins(
|
|
305
|
+
amount=1,
|
|
306
|
+
coin_selection_config=wallet_environments.tx_config.coin_selection_config,
|
|
307
|
+
wallet_id=env_0.wallet_aliases["did"],
|
|
462
308
|
)
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
)[0]
|
|
471
|
-
did_lineage_parent = None
|
|
472
|
-
spends = []
|
|
473
|
-
|
|
474
|
-
for i in range(0, n, chunk):
|
|
475
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
|
|
476
|
-
resp = await client.nft_mint_bulk(
|
|
309
|
+
)[0]
|
|
310
|
+
did_lineage_parent: Optional[bytes32] = None
|
|
311
|
+
txs: list[TransactionRecord] = []
|
|
312
|
+
nft_ids = set()
|
|
313
|
+
for i in range(0, n, chunk):
|
|
314
|
+
resp = await env_0.rpc_client.nft_mint_bulk(
|
|
315
|
+
NFTMintBulk(
|
|
477
316
|
wallet_id=nft_wallet_maker["wallet_id"],
|
|
478
|
-
metadata_list=metadata_list[i : i + chunk],
|
|
317
|
+
metadata_list=[NFTMintMetadata.from_json_dict(metadata) for metadata in metadata_list[i : i + chunk]],
|
|
479
318
|
target_list=target_list[i : i + chunk],
|
|
480
|
-
royalty_percentage=royalty_percentage,
|
|
319
|
+
royalty_percentage=uint16.construct_optional(royalty_percentage),
|
|
481
320
|
royalty_address=royalty_address,
|
|
482
|
-
mint_number_start=i + 1,
|
|
483
|
-
mint_total=n,
|
|
484
|
-
xch_coins=[next_coin
|
|
321
|
+
mint_number_start=uint16(i + 1),
|
|
322
|
+
mint_total=uint16(n),
|
|
323
|
+
xch_coins=[next_coin],
|
|
485
324
|
xch_change_target=funding_coin_dict["puzzle_hash"],
|
|
486
|
-
did_coin=did_coin
|
|
487
|
-
did_lineage_parent=did_lineage_parent,
|
|
488
|
-
mint_from_did=
|
|
489
|
-
|
|
490
|
-
)
|
|
491
|
-
|
|
492
|
-
|
|
325
|
+
did_coin=did_coin if with_did else None,
|
|
326
|
+
did_lineage_parent=did_lineage_parent if with_did else None,
|
|
327
|
+
mint_from_did=with_did,
|
|
328
|
+
fee=uint64(fee),
|
|
329
|
+
),
|
|
330
|
+
tx_config=wallet_environments.tx_config,
|
|
331
|
+
)
|
|
332
|
+
if with_did:
|
|
333
|
+
did_lineage_parent = next(
|
|
334
|
+
cn
|
|
335
|
+
for tx in resp.transactions
|
|
336
|
+
if tx.spend_bundle is not None
|
|
337
|
+
for cn in tx.spend_bundle.removals()
|
|
338
|
+
if cn.name() == did_coin.name()
|
|
339
|
+
).parent_coin_info
|
|
493
340
|
did_coin = next(
|
|
494
|
-
cn
|
|
341
|
+
cn
|
|
342
|
+
for tx in resp.transactions
|
|
343
|
+
if tx.spend_bundle is not None
|
|
344
|
+
for cn in tx.spend_bundle.additions()
|
|
345
|
+
if (cn.parent_coin_info == did_coin.name()) and (cn.amount == 1)
|
|
495
346
|
)
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
async def get_taker_nfts() -> int:
|
|
509
|
-
return int((await api_taker.nft_count_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["count"])
|
|
510
|
-
|
|
511
|
-
await time_out_assert(60, get_taker_nfts, n)
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
@pytest.mark.parametrize(
|
|
515
|
-
"trusted",
|
|
516
|
-
[True, False],
|
|
517
|
-
)
|
|
518
|
-
@pytest.mark.anyio
|
|
519
|
-
async def test_nft_mint_from_did_multiple_xch(
|
|
520
|
-
self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
|
|
521
|
-
) -> None:
|
|
522
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
523
|
-
full_node_api: FullNodeSimulator = full_nodes[0]
|
|
524
|
-
full_node_server = full_node_api.server
|
|
525
|
-
wallet_node_0, server_0 = wallets[0]
|
|
526
|
-
wallet_node_1, server_1 = wallets[1]
|
|
527
|
-
wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
|
|
528
|
-
wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
|
|
529
|
-
ph_maker = await wallet_maker.get_new_puzzlehash()
|
|
530
|
-
ph_taker = await wallet_taker.get_new_puzzlehash()
|
|
531
|
-
ph_token = bytes32.random(seeded_random)
|
|
532
|
-
|
|
533
|
-
if trusted:
|
|
534
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
535
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
536
|
-
}
|
|
537
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
538
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
539
|
-
}
|
|
540
|
-
else:
|
|
541
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
542
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
543
|
-
|
|
544
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
545
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
546
|
-
|
|
547
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
|
|
548
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
549
|
-
|
|
550
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
551
|
-
|
|
552
|
-
await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
|
|
553
|
-
await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
|
|
554
|
-
|
|
555
|
-
async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
556
|
-
did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
557
|
-
wallet_node_0.wallet_state_manager, wallet_maker, uint64(1), action_scope
|
|
558
|
-
)
|
|
559
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
560
|
-
await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
|
|
561
|
-
|
|
562
|
-
hex_did_id = did_wallet.get_my_DID()
|
|
563
|
-
did_id = bytes32.fromhex(hex_did_id)
|
|
564
|
-
|
|
565
|
-
await time_out_assert(5, did_wallet.get_confirmed_balance, 1)
|
|
566
|
-
|
|
567
|
-
nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
|
|
568
|
-
wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1", did_id=did_id
|
|
569
|
-
)
|
|
347
|
+
txs.extend(resp.transactions)
|
|
348
|
+
xch_adds = [
|
|
349
|
+
c
|
|
350
|
+
for tx in resp.transactions
|
|
351
|
+
if tx.spend_bundle is not None
|
|
352
|
+
for c in tx.spend_bundle.additions()
|
|
353
|
+
if c.puzzle_hash == funding_coin.puzzle_hash
|
|
354
|
+
]
|
|
355
|
+
assert len(xch_adds) == 1
|
|
356
|
+
next_coin = xch_adds[0]
|
|
357
|
+
for nft_id in resp.nft_id_list:
|
|
358
|
+
nft_ids.add(decode_puzzle_hash(nft_id))
|
|
570
359
|
|
|
571
|
-
|
|
572
|
-
wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
|
|
573
|
-
)
|
|
360
|
+
await env_0.rpc_client.push_transactions(PushTransactions(transactions=txs), wallet_environments.tx_config)
|
|
574
361
|
|
|
575
|
-
|
|
576
|
-
metadata = Program.to(
|
|
362
|
+
await wallet_environments.process_pending_states(
|
|
577
363
|
[
|
|
578
|
-
(
|
|
579
|
-
|
|
364
|
+
WalletStateTransition(
|
|
365
|
+
pre_block_balance_updates={
|
|
366
|
+
"xch": {
|
|
367
|
+
"unconfirmed_wallet_balance": -(fee * num_chunks) - n,
|
|
368
|
+
"<=#spendable_balance": -(fee * num_chunks) - n,
|
|
369
|
+
"<=#max_send_amount": -(fee * num_chunks) - n,
|
|
370
|
+
">=#pending_change": 1,
|
|
371
|
+
"pending_coin_removal_count": num_chunks,
|
|
372
|
+
},
|
|
373
|
+
"did": {
|
|
374
|
+
"spendable_balance": -1,
|
|
375
|
+
"max_send_amount": -1,
|
|
376
|
+
# 2 here feels a bit weird but I'm not sure it's necessarily incorrect
|
|
377
|
+
"pending_change": 2,
|
|
378
|
+
"pending_coin_removal_count": 2,
|
|
379
|
+
}
|
|
380
|
+
if with_did
|
|
381
|
+
else {},
|
|
382
|
+
"nft": {
|
|
383
|
+
"pending_coin_removal_count": n,
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
post_block_balance_updates={
|
|
387
|
+
"xch": {
|
|
388
|
+
"confirmed_wallet_balance": -(fee * num_chunks) - n,
|
|
389
|
+
">=#spendable_balance": 1,
|
|
390
|
+
">=#max_send_amount": 1,
|
|
391
|
+
"<=#pending_change": -1,
|
|
392
|
+
"pending_coin_removal_count": -num_chunks,
|
|
393
|
+
},
|
|
394
|
+
"did": {
|
|
395
|
+
"spendable_balance": 1,
|
|
396
|
+
"max_send_amount": 1,
|
|
397
|
+
"pending_change": -2,
|
|
398
|
+
"pending_coin_removal_count": -2,
|
|
399
|
+
}
|
|
400
|
+
if with_did
|
|
401
|
+
else {},
|
|
402
|
+
"nft": {
|
|
403
|
+
"pending_coin_removal_count": -n,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
),
|
|
407
|
+
WalletStateTransition(
|
|
408
|
+
pre_block_balance_updates={},
|
|
409
|
+
post_block_balance_updates={
|
|
410
|
+
"nft": {
|
|
411
|
+
"unspent_coin_count": n,
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
),
|
|
580
415
|
]
|
|
581
416
|
)
|
|
582
|
-
royalty_pc = uint16(300)
|
|
583
|
-
royalty_addr = ph_maker
|
|
584
|
-
|
|
585
|
-
mint_total = 1
|
|
586
|
-
fee = uint64(100)
|
|
587
|
-
metadata_list = [
|
|
588
|
-
{"program": metadata, "royalty_pc": royalty_pc, "royalty_ph": royalty_addr} for x in range(mint_total)
|
|
589
|
-
]
|
|
590
|
-
|
|
591
|
-
# Grab two coins for testing that we can create a bulk minting with more than 1 xch coin
|
|
592
|
-
async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
|
|
593
|
-
xch_coins_1 = await wallet_maker.select_coins(amount=10000, action_scope=action_scope)
|
|
594
|
-
xch_coins_2 = await wallet_maker.select_coins(
|
|
595
|
-
amount=10000,
|
|
596
|
-
action_scope=action_scope,
|
|
597
|
-
)
|
|
598
|
-
xch_coins = xch_coins_1.union(xch_coins_2)
|
|
599
|
-
|
|
600
|
-
target_list = [ph_taker for x in range(mint_total)]
|
|
601
417
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
)
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
# confirm that the spend uses the right amount of xch
|
|
622
|
-
expected_xch_bal = funds - fee - mint_total - 1
|
|
623
|
-
await time_out_assert(30, wallet_maker.get_confirmed_balance, expected_xch_bal)
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
@pytest.mark.parametrize(
|
|
627
|
-
"trusted",
|
|
628
|
-
[True, False],
|
|
629
|
-
)
|
|
418
|
+
# check NFT edition numbers
|
|
419
|
+
nfts = [nft for nft in (await env_1.rpc_client.list_nfts(NFTGetNFTs(uint32(env_1.wallet_aliases["nft"])))).nft_list]
|
|
420
|
+
for nft in nfts:
|
|
421
|
+
edition_num = nft.edition_number
|
|
422
|
+
meta_dict = metadata_list[edition_num - 1]
|
|
423
|
+
assert meta_dict["hash"] == nft.data_hash.hex()
|
|
424
|
+
assert meta_dict["uris"] == nft.data_uris
|
|
425
|
+
assert meta_dict["meta_hash"] == nft.metadata_hash.hex()
|
|
426
|
+
assert meta_dict["meta_uris"] == nft.metadata_uris
|
|
427
|
+
assert meta_dict["license_hash"] == nft.license_hash.hex()
|
|
428
|
+
assert meta_dict["license_uris"] == nft.license_uris
|
|
429
|
+
assert meta_dict["edition_number"] == nft.edition_number
|
|
430
|
+
assert meta_dict["edition_total"] == nft.edition_total
|
|
431
|
+
assert nft.launcher_id in nft_ids
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
@pytest.mark.limit_consensus_modes
|
|
435
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
436
|
+
@pytest.mark.parametrize("with_did", [True, False])
|
|
630
437
|
@pytest.mark.anyio
|
|
631
|
-
async def
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
649
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
650
|
-
}
|
|
651
|
-
else:
|
|
652
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
653
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
654
|
-
|
|
655
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
656
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
657
|
-
|
|
658
|
-
# for _ in range(1, num_blocks):
|
|
659
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
|
|
660
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
661
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
662
|
-
|
|
663
|
-
await time_out_assert(30, wallet_0.get_unconfirmed_balance, funds)
|
|
664
|
-
await time_out_assert(30, wallet_0.get_confirmed_balance, funds)
|
|
665
|
-
|
|
666
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
438
|
+
async def test_nft_mint_multiple_xch(wallet_environments: WalletTestFramework, with_did: bool) -> None:
|
|
439
|
+
env_0 = wallet_environments.environments[0]
|
|
440
|
+
env_1 = wallet_environments.environments[1]
|
|
441
|
+
wallet_0 = env_0.xch_wallet
|
|
442
|
+
wallet_1 = env_1.xch_wallet
|
|
443
|
+
env_0.wallet_aliases = {
|
|
444
|
+
"xch": 1,
|
|
445
|
+
"did": 2,
|
|
446
|
+
"nft": 3,
|
|
447
|
+
}
|
|
448
|
+
env_1.wallet_aliases = {
|
|
449
|
+
"xch": 1,
|
|
450
|
+
"nft": 2,
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
454
|
+
ph_0 = await action_scope.get_puzzle_hash(env_0.wallet_state_manager)
|
|
667
455
|
did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
668
|
-
|
|
456
|
+
env_0.wallet_state_manager, wallet_0, uint64(1), action_scope
|
|
669
457
|
)
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
hex_did_id = did_wallet.get_my_DID()
|
|
674
|
-
did_id = bytes32.fromhex(hex_did_id)
|
|
675
|
-
|
|
676
|
-
await time_out_assert(5, did_wallet.get_confirmed_balance, 1)
|
|
677
|
-
|
|
678
|
-
nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
|
|
679
|
-
wallet_node_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
|
|
680
|
-
)
|
|
681
|
-
|
|
682
|
-
nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
|
|
683
|
-
wallet_node_1.wallet_state_manager, wallet_1, name="NFT WALLET 2"
|
|
684
|
-
)
|
|
685
|
-
|
|
686
|
-
royalty_pc = uint16(300)
|
|
687
|
-
royalty_addr = ph_maker
|
|
458
|
+
async with env_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
459
|
+
ph_1 = await action_scope.get_puzzle_hash(env_1.wallet_state_manager)
|
|
688
460
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
461
|
+
await wallet_environments.process_pending_states(
|
|
462
|
+
[
|
|
463
|
+
WalletStateTransition(
|
|
464
|
+
pre_block_balance_updates={
|
|
465
|
+
"xch": {
|
|
466
|
+
"set_remainder": True,
|
|
467
|
+
},
|
|
468
|
+
"did": {
|
|
469
|
+
"init": True,
|
|
470
|
+
"set_remainder": True,
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
post_block_balance_updates={
|
|
474
|
+
"xch": {
|
|
475
|
+
"set_remainder": True,
|
|
476
|
+
},
|
|
477
|
+
"did": {
|
|
478
|
+
"set_remainder": True,
|
|
479
|
+
},
|
|
480
|
+
},
|
|
695
481
|
),
|
|
696
|
-
|
|
697
|
-
"royalty_ph": royalty_addr,
|
|
698
|
-
}
|
|
699
|
-
for x in range(mint_total)
|
|
700
|
-
]
|
|
701
|
-
|
|
702
|
-
target_list = [(await wallet_1.get_new_puzzlehash()) for x in range(mint_total)]
|
|
703
|
-
|
|
704
|
-
async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
705
|
-
await nft_wallet_maker.mint_from_xch(
|
|
706
|
-
metadata_list,
|
|
707
|
-
action_scope,
|
|
708
|
-
target_list=target_list,
|
|
709
|
-
mint_number_start=1,
|
|
710
|
-
mint_total=mint_total,
|
|
711
|
-
fee=fee,
|
|
712
|
-
)
|
|
713
|
-
|
|
714
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
715
|
-
|
|
716
|
-
await time_out_assert(30, nft_count, mint_total, nft_wallet_taker)
|
|
717
|
-
await time_out_assert(30, nft_count, 0, nft_wallet_maker)
|
|
718
|
-
|
|
719
|
-
expected_xch_bal = funds - fee - mint_total - 1
|
|
720
|
-
await time_out_assert(30, wallet_0.get_confirmed_balance, expected_xch_bal)
|
|
721
|
-
|
|
722
|
-
nfts = await nft_wallet_taker.get_current_nfts()
|
|
723
|
-
matched_data = dict(zip(target_list, metadata_list))
|
|
724
|
-
|
|
725
|
-
# Check targets and metadata entries match in the final nfts
|
|
726
|
-
for nft in nfts:
|
|
727
|
-
mod, args = nft.full_puzzle.uncurry()
|
|
728
|
-
unft = UncurriedNFT.uncurry(mod, args)
|
|
729
|
-
assert isinstance(unft, UncurriedNFT)
|
|
730
|
-
inner_args = unft.inner_puzzle.uncurry()[1]
|
|
731
|
-
inner_ph = inner_args.at("rrrf").get_tree_hash()
|
|
732
|
-
meta = unft.metadata.at("rfr").as_atom()
|
|
733
|
-
# check that the target puzzle hashes of transferred nfts matches the metadata entry
|
|
734
|
-
assert matched_data[inner_ph]["program"].at("rfr").as_atom() == meta
|
|
735
|
-
assert not nft.minter_did
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
@pytest.mark.parametrize(
|
|
739
|
-
"trusted",
|
|
740
|
-
[True, False],
|
|
741
|
-
)
|
|
742
|
-
@pytest.mark.anyio
|
|
743
|
-
async def test_nft_mint_from_xch_rpc(
|
|
744
|
-
two_wallet_nodes_services: SimulatorsAndWalletsServices,
|
|
745
|
-
trusted: Any,
|
|
746
|
-
self_hostname: str,
|
|
747
|
-
seeded_random: random.Random,
|
|
748
|
-
) -> None:
|
|
749
|
-
[full_node_service], wallet_services, bt = two_wallet_nodes_services
|
|
750
|
-
full_node_api: FullNodeSimulator = full_node_service._api
|
|
751
|
-
full_node_server = full_node_api.server
|
|
752
|
-
wallet_node_maker = wallet_services[0]._node
|
|
753
|
-
wallet_node_taker = wallet_services[1]._node
|
|
754
|
-
server_0 = wallet_node_maker.server
|
|
755
|
-
server_1 = wallet_node_taker.server
|
|
756
|
-
wallet_maker = wallet_node_maker.wallet_state_manager.main_wallet
|
|
757
|
-
wallet_taker = wallet_node_taker.wallet_state_manager.main_wallet
|
|
758
|
-
|
|
759
|
-
ph_maker = await wallet_maker.get_new_puzzlehash()
|
|
760
|
-
ph_taker = await wallet_taker.get_new_puzzlehash()
|
|
761
|
-
ph_token = bytes32.random(seeded_random)
|
|
762
|
-
|
|
763
|
-
if trusted:
|
|
764
|
-
wallet_node_maker.config["trusted_peers"] = {
|
|
765
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
766
|
-
}
|
|
767
|
-
wallet_node_taker.config["trusted_peers"] = {
|
|
768
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
769
|
-
}
|
|
770
|
-
else:
|
|
771
|
-
wallet_node_maker.config["trusted_peers"] = {}
|
|
772
|
-
wallet_node_taker.config["trusted_peers"] = {}
|
|
773
|
-
|
|
774
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
775
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
776
|
-
|
|
777
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
|
|
778
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_taker))
|
|
779
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
780
|
-
|
|
781
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
782
|
-
|
|
783
|
-
await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
|
|
784
|
-
await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
|
|
785
|
-
await time_out_assert(30, wallet_taker.get_unconfirmed_balance, funds)
|
|
786
|
-
await time_out_assert(30, wallet_taker.get_confirmed_balance, funds)
|
|
787
|
-
|
|
788
|
-
api_maker = WalletRpcApi(wallet_node_maker)
|
|
789
|
-
api_taker = WalletRpcApi(wallet_node_taker)
|
|
790
|
-
config = bt.config
|
|
791
|
-
|
|
792
|
-
assert wallet_services[0].rpc_server is not None
|
|
793
|
-
assert full_node_service.rpc_server is not None
|
|
794
|
-
|
|
795
|
-
async with contextlib.AsyncExitStack() as exit_stack:
|
|
796
|
-
client = await exit_stack.enter_async_context(
|
|
797
|
-
WalletRpcClient.create_as_context(
|
|
798
|
-
self_hostname,
|
|
799
|
-
wallet_services[0].rpc_server.listen_port,
|
|
800
|
-
wallet_services[0].root_path,
|
|
801
|
-
wallet_services[0].config,
|
|
802
|
-
)
|
|
803
|
-
)
|
|
804
|
-
client_node = await exit_stack.enter_async_context(
|
|
805
|
-
FullNodeRpcClient.create_as_context(
|
|
806
|
-
self_hostname,
|
|
807
|
-
full_node_service.rpc_server.listen_port,
|
|
808
|
-
full_node_service.root_path,
|
|
809
|
-
full_node_service.config,
|
|
810
|
-
)
|
|
811
|
-
)
|
|
812
|
-
|
|
813
|
-
async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
814
|
-
did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
815
|
-
wallet_node_maker.wallet_state_manager, wallet_maker, uint64(1), action_scope
|
|
816
|
-
)
|
|
817
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
818
|
-
|
|
819
|
-
await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
|
|
820
|
-
await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds - 1)
|
|
821
|
-
await time_out_assert(30, wallet_maker.get_confirmed_balance, funds - 1)
|
|
822
|
-
|
|
823
|
-
hex_did_id = did_wallet_maker.get_my_DID()
|
|
824
|
-
hmr_did_id = encode_puzzle_hash(bytes32.from_hexstr(hex_did_id), AddressType.DID.hrp(config))
|
|
825
|
-
|
|
826
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
|
|
827
|
-
|
|
828
|
-
nft_wallet_maker = await api_maker.create_new_wallet(
|
|
829
|
-
dict(wallet_type="nft_wallet", name="NFT WALLET 1", did_id=hmr_did_id)
|
|
830
|
-
)
|
|
831
|
-
assert isinstance(nft_wallet_maker, dict)
|
|
832
|
-
assert nft_wallet_maker.get("success")
|
|
833
|
-
|
|
834
|
-
nft_wallet_taker = await api_taker.create_new_wallet(dict(wallet_type="nft_wallet", name="NFT WALLET 2"))
|
|
835
|
-
|
|
836
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
837
|
-
|
|
838
|
-
n = 10
|
|
839
|
-
metadata_list = [
|
|
840
|
-
{
|
|
841
|
-
"hash": bytes32.random(seeded_random).hex(),
|
|
842
|
-
"uris": [f"https://data.com/{i}"],
|
|
843
|
-
"meta_hash": bytes32.random(seeded_random).hex(),
|
|
844
|
-
"meta_uris": [f"https://meatadata.com/{i}"],
|
|
845
|
-
"license_hash": bytes32.random(seeded_random).hex(),
|
|
846
|
-
"license_uris": [f"https://license.com/{i}"],
|
|
847
|
-
"edition_number": i + 1,
|
|
848
|
-
"edition_total": n,
|
|
849
|
-
}
|
|
850
|
-
for i in range(n)
|
|
482
|
+
WalletStateTransition(),
|
|
851
483
|
]
|
|
852
|
-
|
|
853
|
-
royalty_address = encode_puzzle_hash(bytes32.random(seeded_random), "xch")
|
|
854
|
-
royalty_percentage = 300
|
|
855
|
-
fee = 100
|
|
856
|
-
required_amount = n + (fee * n)
|
|
857
|
-
xch_coins = await client.select_coins(
|
|
858
|
-
amount=required_amount, coin_selection_config=DEFAULT_COIN_SELECTION_CONFIG, wallet_id=wallet_maker.id()
|
|
859
|
-
)
|
|
860
|
-
funding_coin = xch_coins[0]
|
|
861
|
-
assert funding_coin.amount >= required_amount
|
|
862
|
-
funding_coin_dict = xch_coins[0].to_json_dict()
|
|
863
|
-
chunk = 5
|
|
864
|
-
next_coin = funding_coin
|
|
865
|
-
spends = []
|
|
866
|
-
|
|
867
|
-
for i in range(0, n, chunk):
|
|
868
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_maker, timeout=20)
|
|
869
|
-
resp = await client.nft_mint_bulk(
|
|
870
|
-
wallet_id=nft_wallet_maker["wallet_id"],
|
|
871
|
-
metadata_list=metadata_list[i : i + chunk],
|
|
872
|
-
target_list=target_list[i : i + chunk],
|
|
873
|
-
royalty_percentage=royalty_percentage,
|
|
874
|
-
royalty_address=royalty_address,
|
|
875
|
-
mint_number_start=i + 1,
|
|
876
|
-
mint_total=n,
|
|
877
|
-
xch_coins=[next_coin.to_json_dict()],
|
|
878
|
-
xch_change_target=funding_coin_dict["puzzle_hash"],
|
|
879
|
-
mint_from_did=False,
|
|
880
|
-
fee=fee,
|
|
881
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
882
|
-
)
|
|
883
|
-
sb = resp.spend_bundle
|
|
884
|
-
spends.append(sb)
|
|
885
|
-
xch_adds = [c for c in sb.additions() if c.puzzle_hash == funding_coin.puzzle_hash]
|
|
886
|
-
assert len(xch_adds) == 1
|
|
887
|
-
next_coin = xch_adds[0]
|
|
888
|
-
|
|
889
|
-
for sb in spends:
|
|
890
|
-
push_resp = await client_node.push_tx(sb)
|
|
891
|
-
assert push_resp["success"]
|
|
892
|
-
await full_node_api.process_spend_bundles([sb])
|
|
893
|
-
|
|
894
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
895
|
-
|
|
896
|
-
async def get_taker_nfts() -> int:
|
|
897
|
-
return int((await api_taker.nft_count_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["count"])
|
|
898
|
-
|
|
899
|
-
# We are using a long time out here because it can take a long time for the NFTs to show up
|
|
900
|
-
# Even with only 10 NFTs it regularly takes longer than 30-40s for them to be found
|
|
901
|
-
await time_out_assert(60, get_taker_nfts, n)
|
|
902
|
-
|
|
903
|
-
# check NFT edition numbers
|
|
904
|
-
nfts = (await api_taker.nft_get_nfts({"wallet_id": nft_wallet_taker["wallet_id"]}))["nft_list"]
|
|
905
|
-
for nft in nfts:
|
|
906
|
-
edition_num = nft.edition_number
|
|
907
|
-
meta_dict = metadata_list[edition_num - 1]
|
|
908
|
-
assert meta_dict["hash"] == nft.data_hash.hex()
|
|
909
|
-
assert meta_dict["uris"] == nft.data_uris
|
|
910
|
-
assert meta_dict["meta_hash"] == nft.metadata_hash.hex()
|
|
911
|
-
assert meta_dict["meta_uris"] == nft.metadata_uris
|
|
912
|
-
assert meta_dict["license_hash"] == nft.license_hash.hex()
|
|
913
|
-
assert meta_dict["license_uris"] == nft.license_uris
|
|
914
|
-
assert meta_dict["edition_number"] == nft.edition_number
|
|
915
|
-
assert meta_dict["edition_total"] == nft.edition_total
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
@pytest.mark.parametrize(
|
|
919
|
-
"trusted",
|
|
920
|
-
[True, False],
|
|
921
|
-
)
|
|
922
|
-
@pytest.mark.anyio
|
|
923
|
-
async def test_nft_mint_from_xch_multiple_xch(
|
|
924
|
-
self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
|
|
925
|
-
) -> None:
|
|
926
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
927
|
-
full_node_api: FullNodeSimulator = full_nodes[0]
|
|
928
|
-
full_node_server = full_node_api.server
|
|
929
|
-
wallet_node_0, server_0 = wallets[0]
|
|
930
|
-
wallet_node_1, server_1 = wallets[1]
|
|
931
|
-
wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
|
|
932
|
-
wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
|
|
933
|
-
ph_maker = await wallet_maker.get_new_puzzlehash()
|
|
934
|
-
ph_taker = await wallet_taker.get_new_puzzlehash()
|
|
935
|
-
ph_token = bytes32.random(seeded_random)
|
|
936
|
-
|
|
937
|
-
if trusted:
|
|
938
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
939
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
940
|
-
}
|
|
941
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
942
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
943
|
-
}
|
|
944
|
-
else:
|
|
945
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
946
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
947
|
-
|
|
948
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
949
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
950
|
-
|
|
951
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
|
|
952
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
|
953
|
-
|
|
954
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
955
|
-
|
|
956
|
-
await time_out_assert(30, wallet_maker.get_unconfirmed_balance, funds)
|
|
957
|
-
await time_out_assert(30, wallet_maker.get_confirmed_balance, funds)
|
|
958
|
-
|
|
959
|
-
async with wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
960
|
-
did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
961
|
-
wallet_node_0.wallet_state_manager, wallet_maker, uint64(1), action_scope
|
|
962
|
-
)
|
|
963
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
964
|
-
await time_out_assert(30, wallet_maker.get_pending_change_balance, 0)
|
|
484
|
+
)
|
|
965
485
|
|
|
966
486
|
hex_did_id = did_wallet.get_my_DID()
|
|
967
487
|
did_id = bytes32.fromhex(hex_did_id)
|
|
968
488
|
|
|
969
489
|
await time_out_assert(5, did_wallet.get_confirmed_balance, 1)
|
|
970
490
|
|
|
971
|
-
|
|
972
|
-
|
|
491
|
+
nft_wallet_0 = await NFTWallet.create_new_nft_wallet(
|
|
492
|
+
env_0.wallet_state_manager, wallet_0, name="NFT WALLET 1", did_id=did_id
|
|
973
493
|
)
|
|
974
494
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
)
|
|
495
|
+
await NFTWallet.create_new_nft_wallet(wallet_1.wallet_state_manager, wallet_1, name="NFT WALLET 2")
|
|
496
|
+
|
|
497
|
+
await env_0.change_balances({"nft": {"init": True}})
|
|
498
|
+
await env_1.change_balances({"nft": {"init": True}})
|
|
978
499
|
|
|
979
500
|
# construct sample metadata
|
|
980
501
|
metadata = Program.to(
|
|
@@ -984,7 +505,7 @@ async def test_nft_mint_from_xch_multiple_xch(
|
|
|
984
505
|
]
|
|
985
506
|
)
|
|
986
507
|
royalty_pc = uint16(300)
|
|
987
|
-
royalty_addr =
|
|
508
|
+
royalty_addr = ph_0
|
|
988
509
|
|
|
989
510
|
mint_total = 1
|
|
990
511
|
fee = uint64(100)
|
|
@@ -993,32 +514,90 @@ async def test_nft_mint_from_xch_multiple_xch(
|
|
|
993
514
|
]
|
|
994
515
|
|
|
995
516
|
# Grab two coins for testing that we can create a bulk minting with more than 1 xch coin
|
|
996
|
-
async with
|
|
997
|
-
xch_coins_1 = await
|
|
998
|
-
xch_coins_2 = await
|
|
999
|
-
amount=10000,
|
|
517
|
+
async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=False) as action_scope:
|
|
518
|
+
xch_coins_1 = await wallet_0.select_coins(amount=uint64(10000), action_scope=action_scope)
|
|
519
|
+
xch_coins_2 = await wallet_0.select_coins(
|
|
520
|
+
amount=uint64(10000),
|
|
1000
521
|
action_scope=action_scope,
|
|
1001
522
|
)
|
|
1002
523
|
xch_coins = xch_coins_1.union(xch_coins_2)
|
|
1003
524
|
|
|
1004
|
-
target_list = [
|
|
1005
|
-
|
|
1006
|
-
async with
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
525
|
+
target_list = [ph_1 for x in range(mint_total)]
|
|
526
|
+
|
|
527
|
+
async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
528
|
+
if with_did:
|
|
529
|
+
await nft_wallet_0.mint_from_did(
|
|
530
|
+
metadata_list,
|
|
531
|
+
action_scope,
|
|
532
|
+
target_list=target_list,
|
|
533
|
+
mint_number_start=1,
|
|
534
|
+
mint_total=mint_total,
|
|
535
|
+
xch_coins=xch_coins,
|
|
536
|
+
fee=fee,
|
|
537
|
+
)
|
|
538
|
+
else:
|
|
539
|
+
await nft_wallet_0.mint_from_xch(
|
|
540
|
+
metadata_list,
|
|
541
|
+
action_scope,
|
|
542
|
+
target_list=target_list,
|
|
543
|
+
mint_number_start=1,
|
|
544
|
+
mint_total=mint_total,
|
|
545
|
+
xch_coins=xch_coins,
|
|
546
|
+
fee=fee,
|
|
547
|
+
)
|
|
1021
548
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
549
|
+
await wallet_environments.process_pending_states(
|
|
550
|
+
[
|
|
551
|
+
WalletStateTransition(
|
|
552
|
+
pre_block_balance_updates={
|
|
553
|
+
"xch": {
|
|
554
|
+
"unconfirmed_wallet_balance": -fee - mint_total,
|
|
555
|
+
"<=#spendable_balance": -fee - mint_total,
|
|
556
|
+
"<=#max_send_amount": -fee - mint_total,
|
|
557
|
+
">=#pending_change": 1,
|
|
558
|
+
"pending_coin_removal_count": 2,
|
|
559
|
+
},
|
|
560
|
+
"did": {
|
|
561
|
+
"spendable_balance": -1,
|
|
562
|
+
"max_send_amount": -1,
|
|
563
|
+
"pending_change": 1,
|
|
564
|
+
"pending_coin_removal_count": 1,
|
|
565
|
+
}
|
|
566
|
+
if with_did
|
|
567
|
+
else {},
|
|
568
|
+
"nft": {
|
|
569
|
+
"pending_coin_removal_count": mint_total,
|
|
570
|
+
},
|
|
571
|
+
},
|
|
572
|
+
post_block_balance_updates={
|
|
573
|
+
"xch": {
|
|
574
|
+
"confirmed_wallet_balance": -fee - mint_total,
|
|
575
|
+
">=#spendable_balance": 1,
|
|
576
|
+
">=#max_send_amount": 1,
|
|
577
|
+
"<=#pending_change": -1,
|
|
578
|
+
"pending_coin_removal_count": -2,
|
|
579
|
+
"unspent_coin_count": -1, # The two coins get combined for change
|
|
580
|
+
},
|
|
581
|
+
"did": {
|
|
582
|
+
"spendable_balance": 1,
|
|
583
|
+
"max_send_amount": 1,
|
|
584
|
+
"pending_change": -1,
|
|
585
|
+
"pending_coin_removal_count": -1,
|
|
586
|
+
}
|
|
587
|
+
if with_did
|
|
588
|
+
else {},
|
|
589
|
+
"nft": {
|
|
590
|
+
"pending_coin_removal_count": -mint_total,
|
|
591
|
+
},
|
|
592
|
+
},
|
|
593
|
+
),
|
|
594
|
+
WalletStateTransition(
|
|
595
|
+
pre_block_balance_updates={},
|
|
596
|
+
post_block_balance_updates={
|
|
597
|
+
"nft": {
|
|
598
|
+
"unspent_coin_count": mint_total,
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
),
|
|
602
|
+
]
|
|
603
|
+
)
|