chia-blockchain 2.5.1rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/__init__.py +10 -0
- chia/__main__.py +5 -0
- chia/_tests/README.md +53 -0
- chia/_tests/__init__.py +0 -0
- chia/_tests/blockchain/__init__.py +0 -0
- chia/_tests/blockchain/blockchain_test_utils.py +195 -0
- chia/_tests/blockchain/config.py +4 -0
- chia/_tests/blockchain/test_augmented_chain.py +145 -0
- chia/_tests/blockchain/test_blockchain.py +4202 -0
- chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
- chia/_tests/blockchain/test_build_chains.py +59 -0
- chia/_tests/blockchain/test_get_block_generator.py +72 -0
- chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
- chia/_tests/build-init-files.py +92 -0
- chia/_tests/build-job-matrix.py +204 -0
- chia/_tests/check_pytest_monitor_output.py +34 -0
- chia/_tests/check_sql_statements.py +72 -0
- chia/_tests/chia-start-sim +42 -0
- chia/_tests/clvm/__init__.py +0 -0
- chia/_tests/clvm/benchmark_costs.py +23 -0
- chia/_tests/clvm/coin_store.py +149 -0
- chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
- chia/_tests/clvm/test_clvm_step.py +37 -0
- chia/_tests/clvm/test_condition_codes.py +13 -0
- chia/_tests/clvm/test_curry_and_treehash.py +55 -0
- chia/_tests/clvm/test_message_conditions.py +184 -0
- chia/_tests/clvm/test_program.py +150 -0
- chia/_tests/clvm/test_puzzle_compression.py +143 -0
- chia/_tests/clvm/test_puzzle_drivers.py +45 -0
- chia/_tests/clvm/test_puzzles.py +242 -0
- chia/_tests/clvm/test_singletons.py +540 -0
- chia/_tests/clvm/test_spend_sim.py +181 -0
- chia/_tests/cmds/__init__.py +0 -0
- chia/_tests/cmds/cmd_test_utils.py +469 -0
- chia/_tests/cmds/config.py +3 -0
- chia/_tests/cmds/conftest.py +23 -0
- chia/_tests/cmds/test_click_types.py +200 -0
- chia/_tests/cmds/test_cmd_framework.py +620 -0
- chia/_tests/cmds/test_cmds_util.py +97 -0
- chia/_tests/cmds/test_daemon.py +92 -0
- chia/_tests/cmds/test_dev_gh.py +131 -0
- chia/_tests/cmds/test_farm_cmd.py +66 -0
- chia/_tests/cmds/test_show.py +116 -0
- chia/_tests/cmds/test_sim.py +207 -0
- chia/_tests/cmds/test_timelock_args.py +75 -0
- chia/_tests/cmds/test_tx_config_args.py +154 -0
- chia/_tests/cmds/testing_classes.py +59 -0
- chia/_tests/cmds/wallet/__init__.py +0 -0
- chia/_tests/cmds/wallet/test_consts.py +47 -0
- chia/_tests/cmds/wallet/test_dao.py +565 -0
- chia/_tests/cmds/wallet/test_did.py +403 -0
- chia/_tests/cmds/wallet/test_nft.py +471 -0
- chia/_tests/cmds/wallet/test_notifications.py +124 -0
- chia/_tests/cmds/wallet/test_offer.toffer +1 -0
- chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
- chia/_tests/cmds/wallet/test_vcs.py +400 -0
- chia/_tests/cmds/wallet/test_wallet.py +1125 -0
- chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
- chia/_tests/conftest.py +1419 -0
- chia/_tests/connection_utils.py +125 -0
- chia/_tests/core/__init__.py +0 -0
- chia/_tests/core/cmds/__init__.py +0 -0
- chia/_tests/core/cmds/test_beta.py +382 -0
- chia/_tests/core/cmds/test_keys.py +1734 -0
- chia/_tests/core/cmds/test_wallet.py +126 -0
- chia/_tests/core/config.py +3 -0
- chia/_tests/core/consensus/__init__.py +0 -0
- chia/_tests/core/consensus/test_block_creation.py +54 -0
- chia/_tests/core/consensus/test_pot_iterations.py +117 -0
- chia/_tests/core/custom_types/__init__.py +0 -0
- chia/_tests/core/custom_types/test_coin.py +107 -0
- chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
- chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
- chia/_tests/core/daemon/__init__.py +0 -0
- chia/_tests/core/daemon/config.py +4 -0
- chia/_tests/core/daemon/test_daemon.py +2128 -0
- chia/_tests/core/daemon/test_daemon_register.py +109 -0
- chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
- chia/_tests/core/data_layer/__init__.py +0 -0
- chia/_tests/core/data_layer/config.py +5 -0
- chia/_tests/core/data_layer/conftest.py +106 -0
- chia/_tests/core/data_layer/test_data_cli.py +56 -0
- chia/_tests/core/data_layer/test_data_layer.py +83 -0
- chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
- chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
- chia/_tests/core/data_layer/test_data_store.py +2424 -0
- chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
- chia/_tests/core/data_layer/test_plugin.py +91 -0
- chia/_tests/core/data_layer/util.py +233 -0
- chia/_tests/core/farmer/__init__.py +0 -0
- chia/_tests/core/farmer/config.py +3 -0
- chia/_tests/core/farmer/test_farmer_api.py +103 -0
- chia/_tests/core/full_node/__init__.py +0 -0
- chia/_tests/core/full_node/config.py +4 -0
- chia/_tests/core/full_node/dos/__init__.py +0 -0
- chia/_tests/core/full_node/dos/config.py +3 -0
- chia/_tests/core/full_node/full_sync/__init__.py +0 -0
- chia/_tests/core/full_node/full_sync/config.py +4 -0
- chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
- chia/_tests/core/full_node/ram_db.py +27 -0
- chia/_tests/core/full_node/stores/__init__.py +0 -0
- chia/_tests/core/full_node/stores/config.py +4 -0
- chia/_tests/core/full_node/stores/test_block_store.py +590 -0
- chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
- chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
- chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
- chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
- chia/_tests/core/full_node/test_address_manager.py +588 -0
- chia/_tests/core/full_node/test_block_height_map.py +556 -0
- chia/_tests/core/full_node/test_conditions.py +556 -0
- chia/_tests/core/full_node/test_full_node.py +2700 -0
- chia/_tests/core/full_node/test_generator_tools.py +82 -0
- chia/_tests/core/full_node/test_hint_management.py +104 -0
- chia/_tests/core/full_node/test_node_load.py +34 -0
- chia/_tests/core/full_node/test_performance.py +179 -0
- chia/_tests/core/full_node/test_subscriptions.py +492 -0
- chia/_tests/core/full_node/test_transactions.py +203 -0
- chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
- chia/_tests/core/large_block.py +2388 -0
- chia/_tests/core/make_block_generator.py +70 -0
- chia/_tests/core/mempool/__init__.py +0 -0
- chia/_tests/core/mempool/config.py +4 -0
- chia/_tests/core/mempool/test_mempool.py +3255 -0
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
- chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
- chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
- chia/_tests/core/mempool/test_mempool_performance.py +64 -0
- chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
- chia/_tests/core/node_height.py +28 -0
- chia/_tests/core/server/__init__.py +0 -0
- chia/_tests/core/server/config.py +3 -0
- chia/_tests/core/server/flood.py +84 -0
- chia/_tests/core/server/serve.py +135 -0
- chia/_tests/core/server/test_api_protocol.py +21 -0
- chia/_tests/core/server/test_capabilities.py +66 -0
- chia/_tests/core/server/test_dos.py +319 -0
- chia/_tests/core/server/test_event_loop.py +109 -0
- chia/_tests/core/server/test_loop.py +294 -0
- chia/_tests/core/server/test_node_discovery.py +73 -0
- chia/_tests/core/server/test_rate_limits.py +482 -0
- chia/_tests/core/server/test_server.py +226 -0
- chia/_tests/core/server/test_upnp.py +8 -0
- chia/_tests/core/services/__init__.py +0 -0
- chia/_tests/core/services/config.py +3 -0
- chia/_tests/core/services/test_services.py +188 -0
- chia/_tests/core/ssl/__init__.py +0 -0
- chia/_tests/core/ssl/config.py +3 -0
- chia/_tests/core/ssl/test_ssl.py +202 -0
- chia/_tests/core/test_coins.py +33 -0
- chia/_tests/core/test_cost_calculation.py +313 -0
- chia/_tests/core/test_crawler.py +175 -0
- chia/_tests/core/test_crawler_rpc.py +53 -0
- chia/_tests/core/test_daemon_rpc.py +24 -0
- chia/_tests/core/test_db_conversion.py +130 -0
- chia/_tests/core/test_db_validation.py +162 -0
- chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
- chia/_tests/core/test_filter.py +35 -0
- chia/_tests/core/test_full_node_rpc.py +768 -0
- chia/_tests/core/test_merkle_set.py +343 -0
- chia/_tests/core/test_program.py +47 -0
- chia/_tests/core/test_rpc_util.py +86 -0
- chia/_tests/core/test_seeder.py +420 -0
- chia/_tests/core/test_setproctitle.py +13 -0
- chia/_tests/core/util/__init__.py +0 -0
- chia/_tests/core/util/config.py +4 -0
- chia/_tests/core/util/test_block_cache.py +44 -0
- chia/_tests/core/util/test_cached_bls.py +57 -0
- chia/_tests/core/util/test_config.py +337 -0
- chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
- chia/_tests/core/util/test_files.py +391 -0
- chia/_tests/core/util/test_jsonify.py +146 -0
- chia/_tests/core/util/test_keychain.py +522 -0
- chia/_tests/core/util/test_keyring_wrapper.py +491 -0
- chia/_tests/core/util/test_lockfile.py +380 -0
- chia/_tests/core/util/test_log_exceptions.py +187 -0
- chia/_tests/core/util/test_lru_cache.py +56 -0
- chia/_tests/core/util/test_significant_bits.py +40 -0
- chia/_tests/core/util/test_streamable.py +883 -0
- chia/_tests/db/__init__.py +0 -0
- chia/_tests/db/test_db_wrapper.py +566 -0
- chia/_tests/environments/__init__.py +0 -0
- chia/_tests/environments/common.py +35 -0
- chia/_tests/environments/full_node.py +47 -0
- chia/_tests/environments/wallet.py +429 -0
- chia/_tests/ether.py +19 -0
- chia/_tests/farmer_harvester/__init__.py +0 -0
- chia/_tests/farmer_harvester/config.py +3 -0
- chia/_tests/farmer_harvester/test_farmer.py +1264 -0
- chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
- chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
- chia/_tests/fee_estimation/__init__.py +0 -0
- chia/_tests/fee_estimation/config.py +3 -0
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
- chia/_tests/generator/__init__.py +0 -0
- chia/_tests/generator/puzzles/__init__.py +0 -0
- chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
- chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
- chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
- chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
- chia/_tests/generator/test_compression.py +201 -0
- chia/_tests/generator/test_generator_types.py +44 -0
- chia/_tests/generator/test_rom.py +180 -0
- chia/_tests/plot_sync/__init__.py +0 -0
- chia/_tests/plot_sync/config.py +3 -0
- chia/_tests/plot_sync/test_delta.py +101 -0
- chia/_tests/plot_sync/test_plot_sync.py +618 -0
- chia/_tests/plot_sync/test_receiver.py +451 -0
- chia/_tests/plot_sync/test_sender.py +116 -0
- chia/_tests/plot_sync/test_sync_simulated.py +451 -0
- chia/_tests/plot_sync/util.py +68 -0
- chia/_tests/plotting/__init__.py +0 -0
- chia/_tests/plotting/config.py +3 -0
- chia/_tests/plotting/test_plot_manager.py +781 -0
- chia/_tests/plotting/util.py +12 -0
- chia/_tests/pools/__init__.py +0 -0
- chia/_tests/pools/config.py +5 -0
- chia/_tests/pools/test_pool_cli_parsing.py +128 -0
- chia/_tests/pools/test_pool_cmdline.py +1001 -0
- chia/_tests/pools/test_pool_config.py +42 -0
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
- chia/_tests/pools/test_pool_rpc.py +1123 -0
- chia/_tests/pools/test_pool_wallet.py +205 -0
- chia/_tests/pools/test_wallet_pool_store.py +161 -0
- chia/_tests/process_junit.py +348 -0
- chia/_tests/rpc/__init__.py +0 -0
- chia/_tests/rpc/test_rpc_client.py +138 -0
- chia/_tests/rpc/test_rpc_server.py +183 -0
- chia/_tests/simulation/__init__.py +0 -0
- chia/_tests/simulation/config.py +6 -0
- chia/_tests/simulation/test_simulation.py +501 -0
- chia/_tests/simulation/test_simulator.py +232 -0
- chia/_tests/simulation/test_start_simulator.py +107 -0
- chia/_tests/testconfig.py +13 -0
- chia/_tests/timelord/__init__.py +0 -0
- chia/_tests/timelord/config.py +3 -0
- chia/_tests/timelord/test_new_peak.py +437 -0
- chia/_tests/timelord/test_timelord.py +11 -0
- chia/_tests/tools/1315537.json +170 -0
- chia/_tests/tools/1315544.json +160 -0
- chia/_tests/tools/1315630.json +150 -0
- chia/_tests/tools/300000.json +105 -0
- chia/_tests/tools/442734.json +140 -0
- chia/_tests/tools/466212.json +130 -0
- chia/_tests/tools/__init__.py +0 -0
- chia/_tests/tools/config.py +5 -0
- chia/_tests/tools/test-blockchain-db.sqlite +0 -0
- chia/_tests/tools/test_full_sync.py +30 -0
- chia/_tests/tools/test_legacy_keyring.py +82 -0
- chia/_tests/tools/test_run_block.py +128 -0
- chia/_tests/tools/test_virtual_project.py +591 -0
- chia/_tests/util/__init__.py +0 -0
- chia/_tests/util/benchmark_cost.py +170 -0
- chia/_tests/util/benchmarks.py +153 -0
- chia/_tests/util/bip39_test_vectors.json +148 -0
- chia/_tests/util/blockchain.py +134 -0
- chia/_tests/util/blockchain_mock.py +132 -0
- chia/_tests/util/build_network_protocol_files.py +302 -0
- chia/_tests/util/clvm_generator.bin +0 -0
- chia/_tests/util/config.py +3 -0
- chia/_tests/util/constants.py +20 -0
- chia/_tests/util/db_connection.py +37 -0
- chia/_tests/util/full_sync.py +253 -0
- chia/_tests/util/gen_ssl_certs.py +114 -0
- chia/_tests/util/generator_tools_testing.py +45 -0
- chia/_tests/util/get_name_puzzle_conditions.py +52 -0
- chia/_tests/util/key_tool.py +36 -0
- chia/_tests/util/misc.py +675 -0
- chia/_tests/util/network_protocol_data.py +1072 -0
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +2701 -0
- chia/_tests/util/rpc.py +26 -0
- chia/_tests/util/run_block.py +163 -0
- chia/_tests/util/setup_nodes.py +481 -0
- chia/_tests/util/spend_sim.py +492 -0
- chia/_tests/util/split_managers.py +102 -0
- chia/_tests/util/temp_file.py +14 -0
- chia/_tests/util/test_action_scope.py +144 -0
- chia/_tests/util/test_async_pool.py +366 -0
- chia/_tests/util/test_build_job_matrix.py +42 -0
- chia/_tests/util/test_build_network_protocol_files.py +7 -0
- chia/_tests/util/test_chia_version.py +50 -0
- chia/_tests/util/test_collection.py +11 -0
- chia/_tests/util/test_condition_tools.py +229 -0
- chia/_tests/util/test_config.py +426 -0
- chia/_tests/util/test_dump_keyring.py +60 -0
- chia/_tests/util/test_errors.py +10 -0
- chia/_tests/util/test_full_block_utils.py +279 -0
- chia/_tests/util/test_installed.py +20 -0
- chia/_tests/util/test_limited_semaphore.py +53 -0
- chia/_tests/util/test_logging_filter.py +42 -0
- chia/_tests/util/test_misc.py +445 -0
- chia/_tests/util/test_network.py +73 -0
- chia/_tests/util/test_network_protocol_files.py +578 -0
- chia/_tests/util/test_network_protocol_json.py +267 -0
- chia/_tests/util/test_network_protocol_test.py +256 -0
- chia/_tests/util/test_paginator.py +71 -0
- chia/_tests/util/test_pprint.py +17 -0
- chia/_tests/util/test_priority_mutex.py +488 -0
- chia/_tests/util/test_recursive_replace.py +116 -0
- chia/_tests/util/test_replace_str_to_bytes.py +137 -0
- chia/_tests/util/test_service_groups.py +15 -0
- chia/_tests/util/test_ssl_check.py +31 -0
- chia/_tests/util/test_testnet_overrides.py +19 -0
- chia/_tests/util/test_tests_misc.py +38 -0
- chia/_tests/util/test_timing.py +37 -0
- chia/_tests/util/test_trusted_peer.py +51 -0
- chia/_tests/util/time_out_assert.py +191 -0
- chia/_tests/wallet/__init__.py +0 -0
- chia/_tests/wallet/cat_wallet/__init__.py +0 -0
- chia/_tests/wallet/cat_wallet/config.py +4 -0
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
- chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
- chia/_tests/wallet/clawback/__init__.py +0 -0
- chia/_tests/wallet/clawback/config.py +3 -0
- chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
- chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
- chia/_tests/wallet/config.py +4 -0
- chia/_tests/wallet/conftest.py +278 -0
- chia/_tests/wallet/dao_wallet/__init__.py +0 -0
- chia/_tests/wallet/dao_wallet/config.py +3 -0
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
- chia/_tests/wallet/db_wallet/__init__.py +0 -0
- chia/_tests/wallet/db_wallet/config.py +3 -0
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
- chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
- chia/_tests/wallet/did_wallet/__init__.py +0 -0
- chia/_tests/wallet/did_wallet/config.py +4 -0
- chia/_tests/wallet/did_wallet/test_did.py +2284 -0
- chia/_tests/wallet/nft_wallet/__init__.py +0 -0
- chia/_tests/wallet/nft_wallet/config.py +4 -0
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
- chia/_tests/wallet/rpc/__init__.py +0 -0
- chia/_tests/wallet/rpc/config.py +4 -0
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
- chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
- chia/_tests/wallet/simple_sync/__init__.py +0 -0
- chia/_tests/wallet/simple_sync/config.py +3 -0
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
- chia/_tests/wallet/sync/__init__.py +0 -0
- chia/_tests/wallet/sync/config.py +4 -0
- chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
- chia/_tests/wallet/test_address_type.py +189 -0
- chia/_tests/wallet/test_bech32m.py +45 -0
- chia/_tests/wallet/test_clvm_streamable.py +244 -0
- chia/_tests/wallet/test_coin_management.py +354 -0
- chia/_tests/wallet/test_coin_selection.py +588 -0
- chia/_tests/wallet/test_conditions.py +400 -0
- chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
- chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
- chia/_tests/wallet/test_nft_store.py +192 -0
- chia/_tests/wallet/test_notifications.py +196 -0
- chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
- chia/_tests/wallet/test_puzzle_store.py +132 -0
- chia/_tests/wallet/test_sign_coin_spends.py +159 -0
- chia/_tests/wallet/test_signer_protocol.py +947 -0
- chia/_tests/wallet/test_singleton.py +122 -0
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
- chia/_tests/wallet/test_singleton_store.py +152 -0
- chia/_tests/wallet/test_taproot.py +19 -0
- chia/_tests/wallet/test_transaction_store.py +945 -0
- chia/_tests/wallet/test_util.py +185 -0
- chia/_tests/wallet/test_wallet.py +2139 -0
- chia/_tests/wallet/test_wallet_action_scope.py +85 -0
- chia/_tests/wallet/test_wallet_blockchain.py +111 -0
- chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
- chia/_tests/wallet/test_wallet_interested_store.py +43 -0
- chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
- chia/_tests/wallet/test_wallet_node.py +780 -0
- chia/_tests/wallet/test_wallet_retry.py +95 -0
- chia/_tests/wallet/test_wallet_state_manager.py +259 -0
- chia/_tests/wallet/test_wallet_test_framework.py +275 -0
- chia/_tests/wallet/test_wallet_trade_store.py +218 -0
- chia/_tests/wallet/test_wallet_user_store.py +34 -0
- chia/_tests/wallet/test_wallet_utils.py +156 -0
- chia/_tests/wallet/vc_wallet/__init__.py +0 -0
- chia/_tests/wallet/vc_wallet/config.py +3 -0
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
- chia/_tests/wallet/wallet_block_tools.py +327 -0
- chia/_tests/weight_proof/__init__.py +0 -0
- chia/_tests/weight_proof/config.py +3 -0
- chia/_tests/weight_proof/test_weight_proof.py +528 -0
- chia/apis.py +19 -0
- chia/clvm/__init__.py +0 -0
- chia/cmds/__init__.py +0 -0
- chia/cmds/beta.py +184 -0
- chia/cmds/beta_funcs.py +137 -0
- chia/cmds/check_wallet_db.py +420 -0
- chia/cmds/chia.py +151 -0
- chia/cmds/cmd_classes.py +323 -0
- chia/cmds/cmd_helpers.py +242 -0
- chia/cmds/cmds_util.py +488 -0
- chia/cmds/coin_funcs.py +275 -0
- chia/cmds/coins.py +182 -0
- chia/cmds/completion.py +49 -0
- chia/cmds/configure.py +332 -0
- chia/cmds/dao.py +1064 -0
- chia/cmds/dao_funcs.py +598 -0
- chia/cmds/data.py +708 -0
- chia/cmds/data_funcs.py +385 -0
- chia/cmds/db.py +87 -0
- chia/cmds/db_backup_func.py +77 -0
- chia/cmds/db_upgrade_func.py +452 -0
- chia/cmds/db_validate_func.py +184 -0
- chia/cmds/dev.py +18 -0
- chia/cmds/farm.py +100 -0
- chia/cmds/farm_funcs.py +200 -0
- chia/cmds/gh.py +275 -0
- chia/cmds/init.py +63 -0
- chia/cmds/init_funcs.py +367 -0
- chia/cmds/installers.py +131 -0
- chia/cmds/keys.py +527 -0
- chia/cmds/keys_funcs.py +863 -0
- chia/cmds/netspace.py +50 -0
- chia/cmds/netspace_funcs.py +54 -0
- chia/cmds/options.py +32 -0
- chia/cmds/param_types.py +238 -0
- chia/cmds/passphrase.py +131 -0
- chia/cmds/passphrase_funcs.py +292 -0
- chia/cmds/peer.py +51 -0
- chia/cmds/peer_funcs.py +129 -0
- chia/cmds/plotnft.py +260 -0
- chia/cmds/plotnft_funcs.py +405 -0
- chia/cmds/plots.py +230 -0
- chia/cmds/plotters.py +18 -0
- chia/cmds/rpc.py +208 -0
- chia/cmds/show.py +72 -0
- chia/cmds/show_funcs.py +215 -0
- chia/cmds/signer.py +296 -0
- chia/cmds/sim.py +225 -0
- chia/cmds/sim_funcs.py +509 -0
- chia/cmds/start.py +24 -0
- chia/cmds/start_funcs.py +109 -0
- chia/cmds/stop.py +62 -0
- chia/cmds/units.py +9 -0
- chia/cmds/wallet.py +1901 -0
- chia/cmds/wallet_funcs.py +1874 -0
- chia/consensus/__init__.py +0 -0
- chia/consensus/block_body_validation.py +562 -0
- chia/consensus/block_creation.py +546 -0
- chia/consensus/block_header_validation.py +1059 -0
- chia/consensus/block_record.py +31 -0
- chia/consensus/block_rewards.py +53 -0
- chia/consensus/blockchain.py +1087 -0
- chia/consensus/blockchain_interface.py +56 -0
- chia/consensus/coinbase.py +30 -0
- chia/consensus/condition_costs.py +9 -0
- chia/consensus/constants.py +49 -0
- chia/consensus/cost_calculator.py +15 -0
- chia/consensus/default_constants.py +89 -0
- chia/consensus/deficit.py +55 -0
- chia/consensus/difficulty_adjustment.py +412 -0
- chia/consensus/find_fork_point.py +111 -0
- chia/consensus/full_block_to_block_record.py +167 -0
- chia/consensus/get_block_challenge.py +106 -0
- chia/consensus/get_block_generator.py +27 -0
- chia/consensus/make_sub_epoch_summary.py +210 -0
- chia/consensus/multiprocess_validation.py +268 -0
- chia/consensus/pos_quality.py +19 -0
- chia/consensus/pot_iterations.py +67 -0
- chia/consensus/puzzles/__init__.py +0 -0
- chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
- chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
- chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
- chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
- chia/consensus/vdf_info_computation.py +156 -0
- chia/daemon/__init__.py +0 -0
- chia/daemon/client.py +252 -0
- chia/daemon/keychain_proxy.py +502 -0
- chia/daemon/keychain_server.py +365 -0
- chia/daemon/server.py +1606 -0
- chia/daemon/windows_signal.py +56 -0
- chia/data_layer/__init__.py +0 -0
- chia/data_layer/data_layer.py +1291 -0
- chia/data_layer/data_layer_api.py +33 -0
- chia/data_layer/data_layer_errors.py +50 -0
- chia/data_layer/data_layer_server.py +170 -0
- chia/data_layer/data_layer_util.py +985 -0
- chia/data_layer/data_layer_wallet.py +1311 -0
- chia/data_layer/data_store.py +2267 -0
- chia/data_layer/dl_wallet_store.py +407 -0
- chia/data_layer/download_data.py +389 -0
- chia/data_layer/puzzles/__init__.py +0 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
- chia/data_layer/s3_plugin_config.yml +33 -0
- chia/data_layer/s3_plugin_service.py +468 -0
- chia/data_layer/util/__init__.py +0 -0
- chia/data_layer/util/benchmark.py +107 -0
- chia/data_layer/util/plugin.py +40 -0
- chia/farmer/__init__.py +0 -0
- chia/farmer/farmer.py +923 -0
- chia/farmer/farmer_api.py +820 -0
- chia/full_node/__init__.py +0 -0
- chia/full_node/bitcoin_fee_estimator.py +85 -0
- chia/full_node/block_height_map.py +271 -0
- chia/full_node/block_store.py +576 -0
- chia/full_node/bundle_tools.py +19 -0
- chia/full_node/coin_store.py +647 -0
- chia/full_node/fee_estimate.py +54 -0
- chia/full_node/fee_estimate_store.py +24 -0
- chia/full_node/fee_estimation.py +92 -0
- chia/full_node/fee_estimator.py +90 -0
- chia/full_node/fee_estimator_constants.py +38 -0
- chia/full_node/fee_estimator_interface.py +42 -0
- chia/full_node/fee_history.py +25 -0
- chia/full_node/fee_tracker.py +564 -0
- chia/full_node/full_node.py +3327 -0
- chia/full_node/full_node_api.py +2025 -0
- chia/full_node/full_node_store.py +1033 -0
- chia/full_node/hint_management.py +56 -0
- chia/full_node/hint_store.py +93 -0
- chia/full_node/mempool.py +589 -0
- chia/full_node/mempool_check_conditions.py +146 -0
- chia/full_node/mempool_manager.py +853 -0
- chia/full_node/pending_tx_cache.py +112 -0
- chia/full_node/puzzles/__init__.py +0 -0
- chia/full_node/puzzles/block_program_zero.clsp +14 -0
- chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
- chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
- chia/full_node/signage_point.py +16 -0
- chia/full_node/subscriptions.py +247 -0
- chia/full_node/sync_store.py +146 -0
- chia/full_node/tx_processing_queue.py +78 -0
- chia/full_node/util/__init__.py +0 -0
- chia/full_node/weight_proof.py +1720 -0
- chia/harvester/__init__.py +0 -0
- chia/harvester/harvester.py +272 -0
- chia/harvester/harvester_api.py +380 -0
- chia/introducer/__init__.py +0 -0
- chia/introducer/introducer.py +122 -0
- chia/introducer/introducer_api.py +70 -0
- chia/legacy/__init__.py +0 -0
- chia/legacy/keyring.py +155 -0
- chia/plot_sync/__init__.py +0 -0
- chia/plot_sync/delta.py +61 -0
- chia/plot_sync/exceptions.py +56 -0
- chia/plot_sync/receiver.py +386 -0
- chia/plot_sync/sender.py +340 -0
- chia/plot_sync/util.py +43 -0
- chia/plotters/__init__.py +0 -0
- chia/plotters/bladebit.py +388 -0
- chia/plotters/chiapos.py +63 -0
- chia/plotters/madmax.py +224 -0
- chia/plotters/plotters.py +577 -0
- chia/plotters/plotters_util.py +133 -0
- chia/plotting/__init__.py +0 -0
- chia/plotting/cache.py +213 -0
- chia/plotting/check_plots.py +283 -0
- chia/plotting/create_plots.py +278 -0
- chia/plotting/manager.py +436 -0
- chia/plotting/util.py +336 -0
- chia/pools/__init__.py +0 -0
- chia/pools/pool_config.py +110 -0
- chia/pools/pool_puzzles.py +459 -0
- chia/pools/pool_wallet.py +933 -0
- chia/pools/pool_wallet_info.py +118 -0
- chia/pools/puzzles/__init__.py +0 -0
- chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
- chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
- chia/protocols/__init__.py +0 -0
- chia/protocols/farmer_protocol.py +102 -0
- chia/protocols/full_node_protocol.py +219 -0
- chia/protocols/harvester_protocol.py +216 -0
- chia/protocols/introducer_protocol.py +25 -0
- chia/protocols/pool_protocol.py +177 -0
- chia/protocols/protocol_message_types.py +139 -0
- chia/protocols/protocol_state_machine.py +87 -0
- chia/protocols/protocol_timing.py +8 -0
- chia/protocols/shared_protocol.py +86 -0
- chia/protocols/timelord_protocol.py +93 -0
- chia/protocols/wallet_protocol.py +401 -0
- chia/py.typed +0 -0
- chia/rpc/__init__.py +0 -0
- chia/rpc/crawler_rpc_api.py +80 -0
- chia/rpc/data_layer_rpc_api.py +644 -0
- chia/rpc/data_layer_rpc_client.py +188 -0
- chia/rpc/data_layer_rpc_util.py +58 -0
- chia/rpc/farmer_rpc_api.py +365 -0
- chia/rpc/farmer_rpc_client.py +86 -0
- chia/rpc/full_node_rpc_api.py +959 -0
- chia/rpc/full_node_rpc_client.py +292 -0
- chia/rpc/harvester_rpc_api.py +141 -0
- chia/rpc/harvester_rpc_client.py +54 -0
- chia/rpc/rpc_client.py +164 -0
- chia/rpc/rpc_server.py +521 -0
- chia/rpc/timelord_rpc_api.py +32 -0
- chia/rpc/util.py +93 -0
- chia/rpc/wallet_request_types.py +904 -0
- chia/rpc/wallet_rpc_api.py +4943 -0
- chia/rpc/wallet_rpc_client.py +1814 -0
- chia/seeder/__init__.py +0 -0
- chia/seeder/crawl_store.py +425 -0
- chia/seeder/crawler.py +410 -0
- chia/seeder/crawler_api.py +135 -0
- chia/seeder/dns_server.py +593 -0
- chia/seeder/peer_record.py +146 -0
- chia/seeder/start_crawler.py +92 -0
- chia/server/__init__.py +0 -0
- chia/server/address_manager.py +658 -0
- chia/server/address_manager_store.py +237 -0
- chia/server/api_protocol.py +116 -0
- chia/server/capabilities.py +24 -0
- chia/server/chia_policy.py +346 -0
- chia/server/introducer_peers.py +76 -0
- chia/server/node_discovery.py +714 -0
- chia/server/outbound_message.py +33 -0
- chia/server/rate_limit_numbers.py +214 -0
- chia/server/rate_limits.py +153 -0
- chia/server/server.py +741 -0
- chia/server/signal_handlers.py +120 -0
- chia/server/ssl_context.py +32 -0
- chia/server/start_data_layer.py +151 -0
- chia/server/start_farmer.py +98 -0
- chia/server/start_full_node.py +112 -0
- chia/server/start_harvester.py +93 -0
- chia/server/start_introducer.py +81 -0
- chia/server/start_service.py +316 -0
- chia/server/start_timelord.py +89 -0
- chia/server/start_wallet.py +113 -0
- chia/server/upnp.py +118 -0
- chia/server/ws_connection.py +766 -0
- chia/simulator/__init__.py +0 -0
- chia/simulator/add_blocks_in_batches.py +54 -0
- chia/simulator/block_tools.py +2054 -0
- chia/simulator/full_node_simulator.py +794 -0
- chia/simulator/keyring.py +128 -0
- chia/simulator/setup_services.py +506 -0
- chia/simulator/simulator_constants.py +13 -0
- chia/simulator/simulator_full_node_rpc_api.py +99 -0
- chia/simulator/simulator_full_node_rpc_client.py +60 -0
- chia/simulator/simulator_protocol.py +29 -0
- chia/simulator/simulator_test_tools.py +164 -0
- chia/simulator/socket.py +24 -0
- chia/simulator/ssl_certs.py +114 -0
- chia/simulator/ssl_certs_1.py +697 -0
- chia/simulator/ssl_certs_10.py +697 -0
- chia/simulator/ssl_certs_2.py +697 -0
- chia/simulator/ssl_certs_3.py +697 -0
- chia/simulator/ssl_certs_4.py +697 -0
- chia/simulator/ssl_certs_5.py +697 -0
- chia/simulator/ssl_certs_6.py +697 -0
- chia/simulator/ssl_certs_7.py +697 -0
- chia/simulator/ssl_certs_8.py +697 -0
- chia/simulator/ssl_certs_9.py +697 -0
- chia/simulator/start_simulator.py +143 -0
- chia/simulator/wallet_tools.py +246 -0
- chia/ssl/__init__.py +0 -0
- chia/ssl/chia_ca.crt +19 -0
- chia/ssl/chia_ca.key +28 -0
- chia/ssl/create_ssl.py +249 -0
- chia/ssl/dst_root_ca.pem +20 -0
- chia/timelord/__init__.py +0 -0
- chia/timelord/iters_from_block.py +50 -0
- chia/timelord/timelord.py +1226 -0
- chia/timelord/timelord_api.py +138 -0
- chia/timelord/timelord_launcher.py +190 -0
- chia/timelord/timelord_state.py +244 -0
- chia/timelord/types.py +22 -0
- chia/types/__init__.py +0 -0
- chia/types/aliases.py +35 -0
- chia/types/block_protocol.py +20 -0
- chia/types/blockchain_format/__init__.py +0 -0
- chia/types/blockchain_format/classgroup.py +5 -0
- chia/types/blockchain_format/coin.py +28 -0
- chia/types/blockchain_format/foliage.py +8 -0
- chia/types/blockchain_format/pool_target.py +5 -0
- chia/types/blockchain_format/program.py +269 -0
- chia/types/blockchain_format/proof_of_space.py +135 -0
- chia/types/blockchain_format/reward_chain_block.py +6 -0
- chia/types/blockchain_format/serialized_program.py +5 -0
- chia/types/blockchain_format/sized_bytes.py +11 -0
- chia/types/blockchain_format/slots.py +9 -0
- chia/types/blockchain_format/sub_epoch_summary.py +5 -0
- chia/types/blockchain_format/tree_hash.py +72 -0
- chia/types/blockchain_format/vdf.py +86 -0
- chia/types/clvm_cost.py +13 -0
- chia/types/coin_record.py +43 -0
- chia/types/coin_spend.py +115 -0
- chia/types/condition_opcodes.py +73 -0
- chia/types/condition_with_args.py +16 -0
- chia/types/eligible_coin_spends.py +365 -0
- chia/types/end_of_slot_bundle.py +5 -0
- chia/types/fee_rate.py +38 -0
- chia/types/full_block.py +5 -0
- chia/types/generator_types.py +13 -0
- chia/types/header_block.py +5 -0
- chia/types/internal_mempool_item.py +18 -0
- chia/types/mempool_inclusion_status.py +9 -0
- chia/types/mempool_item.py +85 -0
- chia/types/mempool_submission_status.py +30 -0
- chia/types/mojos.py +7 -0
- chia/types/peer_info.py +64 -0
- chia/types/signing_mode.py +29 -0
- chia/types/spend_bundle.py +30 -0
- chia/types/spend_bundle_conditions.py +7 -0
- chia/types/transaction_queue_entry.py +55 -0
- chia/types/unfinished_block.py +5 -0
- chia/types/unfinished_header_block.py +37 -0
- chia/types/validation_state.py +14 -0
- chia/types/weight_proof.py +49 -0
- chia/util/__init__.py +0 -0
- chia/util/action_scope.py +168 -0
- chia/util/async_pool.py +226 -0
- chia/util/augmented_chain.py +134 -0
- chia/util/batches.py +42 -0
- chia/util/bech32m.py +126 -0
- chia/util/beta_metrics.py +119 -0
- chia/util/block_cache.py +56 -0
- chia/util/byte_types.py +12 -0
- chia/util/check_fork_next_block.py +33 -0
- chia/util/chia_logging.py +144 -0
- chia/util/chia_version.py +33 -0
- chia/util/collection.py +17 -0
- chia/util/condition_tools.py +201 -0
- chia/util/config.py +367 -0
- chia/util/cpu.py +22 -0
- chia/util/db_synchronous.py +23 -0
- chia/util/db_version.py +32 -0
- chia/util/db_wrapper.py +430 -0
- chia/util/default_root.py +27 -0
- chia/util/dump_keyring.py +93 -0
- chia/util/english.txt +2048 -0
- chia/util/errors.py +353 -0
- chia/util/file_keyring.py +469 -0
- chia/util/files.py +97 -0
- chia/util/full_block_utils.py +345 -0
- chia/util/generator_tools.py +72 -0
- chia/util/hash.py +31 -0
- chia/util/initial-config.yaml +694 -0
- chia/util/inline_executor.py +26 -0
- chia/util/ints.py +19 -0
- chia/util/ip_address.py +39 -0
- chia/util/json_util.py +37 -0
- chia/util/keychain.py +676 -0
- chia/util/keyring_wrapper.py +327 -0
- chia/util/limited_semaphore.py +41 -0
- chia/util/lock.py +49 -0
- chia/util/log_exceptions.py +32 -0
- chia/util/logging.py +36 -0
- chia/util/lru_cache.py +31 -0
- chia/util/math.py +20 -0
- chia/util/network.py +182 -0
- chia/util/paginator.py +48 -0
- chia/util/path.py +31 -0
- chia/util/permissions.py +20 -0
- chia/util/prev_transaction_block.py +21 -0
- chia/util/priority_mutex.py +95 -0
- chia/util/profiler.py +197 -0
- chia/util/recursive_replace.py +24 -0
- chia/util/safe_cancel_task.py +16 -0
- chia/util/service_groups.py +47 -0
- chia/util/setproctitle.py +22 -0
- chia/util/significant_bits.py +32 -0
- chia/util/ssl_check.py +213 -0
- chia/util/streamable.py +642 -0
- chia/util/task_referencer.py +59 -0
- chia/util/task_timing.py +382 -0
- chia/util/timing.py +67 -0
- chia/util/vdf_prover.py +30 -0
- chia/util/virtual_project_analysis.py +540 -0
- chia/util/ws_message.py +66 -0
- chia/wallet/__init__.py +0 -0
- chia/wallet/cat_wallet/__init__.py +0 -0
- chia/wallet/cat_wallet/cat_constants.py +75 -0
- chia/wallet/cat_wallet/cat_info.py +47 -0
- chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
- chia/wallet/cat_wallet/cat_utils.py +164 -0
- chia/wallet/cat_wallet/cat_wallet.py +855 -0
- chia/wallet/cat_wallet/dao_cat_info.py +28 -0
- chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
- chia/wallet/cat_wallet/lineage_store.py +74 -0
- chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
- chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
- chia/wallet/coin_selection.py +188 -0
- chia/wallet/conditions.py +1512 -0
- chia/wallet/dao_wallet/__init__.py +0 -0
- chia/wallet/dao_wallet/dao_info.py +61 -0
- chia/wallet/dao_wallet/dao_utils.py +811 -0
- chia/wallet/dao_wallet/dao_wallet.py +2119 -0
- chia/wallet/db_wallet/__init__.py +0 -0
- chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
- chia/wallet/derivation_record.py +30 -0
- chia/wallet/derive_keys.py +146 -0
- chia/wallet/did_wallet/__init__.py +0 -0
- chia/wallet/did_wallet/did_info.py +39 -0
- chia/wallet/did_wallet/did_wallet.py +1494 -0
- chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
- chia/wallet/did_wallet/puzzles/__init__.py +0 -0
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
- chia/wallet/driver_protocol.py +26 -0
- chia/wallet/key_val_store.py +55 -0
- chia/wallet/lineage_proof.py +58 -0
- chia/wallet/nft_wallet/__init__.py +0 -0
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
- chia/wallet/nft_wallet/nft_info.py +120 -0
- chia/wallet/nft_wallet/nft_puzzles.py +305 -0
- chia/wallet/nft_wallet/nft_wallet.py +1687 -0
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
- chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
- chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
- chia/wallet/nft_wallet/uncurry_nft.py +217 -0
- chia/wallet/notification_manager.py +117 -0
- chia/wallet/notification_store.py +178 -0
- chia/wallet/outer_puzzles.py +84 -0
- chia/wallet/payment.py +33 -0
- chia/wallet/puzzle_drivers.py +118 -0
- chia/wallet/puzzles/__init__.py +0 -0
- chia/wallet/puzzles/augmented_condition.clsp +13 -0
- chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
- chia/wallet/puzzles/clawback/__init__.py +0 -0
- chia/wallet/puzzles/clawback/drivers.py +188 -0
- chia/wallet/puzzles/clawback/metadata.py +38 -0
- chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
- chia/wallet/puzzles/condition_codes.clib +77 -0
- chia/wallet/puzzles/curry-and-treehash.clib +102 -0
- chia/wallet/puzzles/curry.clib +135 -0
- chia/wallet/puzzles/curry_by_index.clib +16 -0
- chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
- chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
- chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
- chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
- chia/wallet/puzzles/dao_finished_state.clsp +35 -0
- chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
- chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_lockup.clsp +288 -0
- chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
- chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal.clsp +377 -0
- chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_treasury.clsp +115 -0
- chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
- chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
- chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
- chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
- chia/wallet/puzzles/json.clib +25 -0
- chia/wallet/puzzles/load_clvm.py +161 -0
- chia/wallet/puzzles/merkle_utils.clib +18 -0
- chia/wallet/puzzles/notification.clsp +7 -0
- chia/wallet/puzzles/notification.clsp.hex +1 -0
- chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
- chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
- chia/wallet/puzzles/p2_conditions.clsp +3 -0
- chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
- chia/wallet/puzzles/p2_conditions.py +26 -0
- chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
- chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
- chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
- chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
- chia/wallet/puzzles/p2_parent.clsp +19 -0
- chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
- chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
- chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
- chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
- chia/wallet/puzzles/p2_singleton.clsp +30 -0
- chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
- chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/puzzle_utils.py +34 -0
- chia/wallet/puzzles/settlement_payments.clsp +49 -0
- chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
- chia/wallet/puzzles/sha256tree.clib +11 -0
- chia/wallet/puzzles/singleton_launcher.clsp +16 -0
- chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
- chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer.py +296 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
- chia/wallet/puzzles/singleton_truths.clib +21 -0
- chia/wallet/puzzles/tails.py +348 -0
- chia/wallet/puzzles/utility_macros.clib +48 -0
- chia/wallet/signer_protocol.py +125 -0
- chia/wallet/singleton.py +106 -0
- chia/wallet/singleton_record.py +30 -0
- chia/wallet/trade_manager.py +1102 -0
- chia/wallet/trade_record.py +67 -0
- chia/wallet/trading/__init__.py +0 -0
- chia/wallet/trading/offer.py +702 -0
- chia/wallet/trading/trade_status.py +13 -0
- chia/wallet/trading/trade_store.py +526 -0
- chia/wallet/transaction_record.py +158 -0
- chia/wallet/transaction_sorting.py +14 -0
- chia/wallet/uncurried_puzzle.py +17 -0
- chia/wallet/util/__init__.py +0 -0
- chia/wallet/util/address_type.py +55 -0
- chia/wallet/util/blind_signer_tl.py +164 -0
- chia/wallet/util/clvm_streamable.py +203 -0
- chia/wallet/util/compute_hints.py +66 -0
- chia/wallet/util/compute_memos.py +43 -0
- chia/wallet/util/curry_and_treehash.py +91 -0
- chia/wallet/util/debug_spend_bundle.py +232 -0
- chia/wallet/util/merkle_tree.py +100 -0
- chia/wallet/util/merkle_utils.py +102 -0
- chia/wallet/util/new_peak_queue.py +82 -0
- chia/wallet/util/notifications.py +12 -0
- chia/wallet/util/peer_request_cache.py +174 -0
- chia/wallet/util/pprint.py +39 -0
- chia/wallet/util/puzzle_compression.py +95 -0
- chia/wallet/util/puzzle_decorator.py +100 -0
- chia/wallet/util/puzzle_decorator_type.py +7 -0
- chia/wallet/util/query_filter.py +59 -0
- chia/wallet/util/transaction_type.py +23 -0
- chia/wallet/util/tx_config.py +158 -0
- chia/wallet/util/wallet_sync_utils.py +351 -0
- chia/wallet/util/wallet_types.py +72 -0
- chia/wallet/vc_wallet/__init__.py +0 -0
- chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
- chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
- chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
- chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_drivers.py +838 -0
- chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_store.py +263 -0
- chia/wallet/vc_wallet/vc_wallet.py +638 -0
- chia/wallet/wallet.py +698 -0
- chia/wallet/wallet_action_scope.py +96 -0
- chia/wallet/wallet_blockchain.py +244 -0
- chia/wallet/wallet_coin_record.py +72 -0
- chia/wallet/wallet_coin_store.py +351 -0
- chia/wallet/wallet_info.py +35 -0
- chia/wallet/wallet_interested_store.py +188 -0
- chia/wallet/wallet_nft_store.py +279 -0
- chia/wallet/wallet_node.py +1765 -0
- chia/wallet/wallet_node_api.py +207 -0
- chia/wallet/wallet_pool_store.py +119 -0
- chia/wallet/wallet_protocol.py +90 -0
- chia/wallet/wallet_puzzle_store.py +396 -0
- chia/wallet/wallet_retry_store.py +70 -0
- chia/wallet/wallet_singleton_store.py +259 -0
- chia/wallet/wallet_spend_bundle.py +25 -0
- chia/wallet/wallet_state_manager.py +2819 -0
- chia/wallet/wallet_transaction_store.py +496 -0
- chia/wallet/wallet_user_store.py +110 -0
- chia/wallet/wallet_weight_proof_handler.py +126 -0
- chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
- chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
- chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
- chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
- chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
- mozilla-ca/cacert.pem +3611 -0
|
@@ -0,0 +1,1874 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import pathlib
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
from collections.abc import Awaitable, Sequence
|
|
10
|
+
from datetime import datetime, timezone
|
|
11
|
+
from decimal import Decimal
|
|
12
|
+
from typing import Any, Callable, Optional, Union
|
|
13
|
+
|
|
14
|
+
from chia.cmds.cmds_util import (
|
|
15
|
+
CMDTXConfigLoader,
|
|
16
|
+
cli_confirm,
|
|
17
|
+
get_wallet_client,
|
|
18
|
+
transaction_status_msg,
|
|
19
|
+
transaction_submitted_msg,
|
|
20
|
+
)
|
|
21
|
+
from chia.cmds.param_types import CliAddress, CliAmount
|
|
22
|
+
from chia.cmds.peer_funcs import print_connections
|
|
23
|
+
from chia.cmds.units import units
|
|
24
|
+
from chia.rpc.wallet_request_types import (
|
|
25
|
+
CATSpendResponse,
|
|
26
|
+
GetNotifications,
|
|
27
|
+
SendTransactionResponse,
|
|
28
|
+
VCAddProofs,
|
|
29
|
+
VCGet,
|
|
30
|
+
VCGetList,
|
|
31
|
+
VCGetProofsForRoot,
|
|
32
|
+
VCMint,
|
|
33
|
+
VCRevoke,
|
|
34
|
+
VCSpend,
|
|
35
|
+
)
|
|
36
|
+
from chia.rpc.wallet_rpc_client import WalletRpcClient
|
|
37
|
+
from chia.types.blockchain_format.sized_bytes import bytes32
|
|
38
|
+
from chia.util.bech32m import bech32_decode, decode_puzzle_hash, encode_puzzle_hash
|
|
39
|
+
from chia.util.byte_types import hexstr_to_bytes
|
|
40
|
+
from chia.util.config import selected_network_address_prefix
|
|
41
|
+
from chia.util.ints import uint16, uint32, uint64
|
|
42
|
+
from chia.wallet.conditions import ConditionValidTimes, CreateCoinAnnouncement, CreatePuzzleAnnouncement
|
|
43
|
+
from chia.wallet.nft_wallet.nft_info import NFTInfo
|
|
44
|
+
from chia.wallet.outer_puzzles import AssetType
|
|
45
|
+
from chia.wallet.puzzle_drivers import PuzzleInfo
|
|
46
|
+
from chia.wallet.trade_record import TradeRecord
|
|
47
|
+
from chia.wallet.trading.offer import Offer
|
|
48
|
+
from chia.wallet.trading.trade_status import TradeStatus
|
|
49
|
+
from chia.wallet.transaction_record import TransactionRecord
|
|
50
|
+
from chia.wallet.transaction_sorting import SortKey
|
|
51
|
+
from chia.wallet.util.address_type import AddressType
|
|
52
|
+
from chia.wallet.util.puzzle_decorator_type import PuzzleDecoratorType
|
|
53
|
+
from chia.wallet.util.query_filter import HashFilter, TransactionTypeFilter
|
|
54
|
+
from chia.wallet.util.transaction_type import CLAWBACK_INCOMING_TRANSACTION_TYPES, TransactionType
|
|
55
|
+
from chia.wallet.util.wallet_types import WalletType
|
|
56
|
+
from chia.wallet.vc_wallet.vc_store import VCProofs
|
|
57
|
+
from chia.wallet.wallet_coin_store import GetCoinRecords
|
|
58
|
+
|
|
59
|
+
CATNameResolver = Callable[[bytes32], Awaitable[Optional[tuple[Optional[uint32], str]]]]
|
|
60
|
+
|
|
61
|
+
transaction_type_descriptions = {
|
|
62
|
+
TransactionType.INCOMING_TX: "received",
|
|
63
|
+
TransactionType.OUTGOING_TX: "sent",
|
|
64
|
+
TransactionType.COINBASE_REWARD: "rewarded",
|
|
65
|
+
TransactionType.FEE_REWARD: "rewarded",
|
|
66
|
+
TransactionType.INCOMING_TRADE: "received in trade",
|
|
67
|
+
TransactionType.OUTGOING_TRADE: "sent in trade",
|
|
68
|
+
TransactionType.INCOMING_CLAWBACK_RECEIVE: "received in clawback as recipient",
|
|
69
|
+
TransactionType.INCOMING_CLAWBACK_SEND: "received in clawback as sender",
|
|
70
|
+
TransactionType.OUTGOING_CLAWBACK: "claim/clawback",
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def transaction_description_from_type(tx: TransactionRecord) -> str:
|
|
75
|
+
return transaction_type_descriptions.get(TransactionType(tx.type), "(unknown reason)")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def print_transaction(
|
|
79
|
+
tx: TransactionRecord,
|
|
80
|
+
verbose: bool,
|
|
81
|
+
name: str,
|
|
82
|
+
address_prefix: str,
|
|
83
|
+
mojo_per_unit: int,
|
|
84
|
+
coin_record: Optional[dict[str, Any]] = None,
|
|
85
|
+
) -> None:
|
|
86
|
+
if verbose:
|
|
87
|
+
print(tx)
|
|
88
|
+
else:
|
|
89
|
+
chia_amount = Decimal(int(tx.amount)) / mojo_per_unit
|
|
90
|
+
to_address = encode_puzzle_hash(tx.to_puzzle_hash, address_prefix)
|
|
91
|
+
print(f"Transaction {tx.name}")
|
|
92
|
+
print(f"Status: {'Confirmed' if tx.confirmed else ('In mempool' if tx.is_in_mempool() else 'Pending')}")
|
|
93
|
+
description = transaction_description_from_type(tx)
|
|
94
|
+
print(f"Amount {description}: {chia_amount} {name}")
|
|
95
|
+
print(f"To address: {to_address}")
|
|
96
|
+
print("Created at:", datetime.fromtimestamp(tx.created_at_time).strftime("%Y-%m-%d %H:%M:%S"))
|
|
97
|
+
if coin_record is not None:
|
|
98
|
+
print(
|
|
99
|
+
"Recipient claimable time:",
|
|
100
|
+
datetime.fromtimestamp(tx.created_at_time + coin_record["metadata"]["time_lock"]).strftime(
|
|
101
|
+
"%Y-%m-%d %H:%M:%S"
|
|
102
|
+
),
|
|
103
|
+
)
|
|
104
|
+
print("")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_mojo_per_unit(wallet_type: WalletType) -> int:
|
|
108
|
+
mojo_per_unit: int
|
|
109
|
+
if wallet_type in {
|
|
110
|
+
WalletType.STANDARD_WALLET,
|
|
111
|
+
WalletType.POOLING_WALLET,
|
|
112
|
+
WalletType.DATA_LAYER,
|
|
113
|
+
WalletType.VC,
|
|
114
|
+
WalletType.DAO,
|
|
115
|
+
}:
|
|
116
|
+
mojo_per_unit = units["chia"]
|
|
117
|
+
elif wallet_type in {WalletType.CAT, WalletType.CRCAT}:
|
|
118
|
+
mojo_per_unit = units["cat"]
|
|
119
|
+
elif wallet_type in {WalletType.NFT, WalletType.DECENTRALIZED_ID, WalletType.DAO_CAT}:
|
|
120
|
+
mojo_per_unit = units["mojo"]
|
|
121
|
+
else:
|
|
122
|
+
raise LookupError(f"Operation is not supported for Wallet type {wallet_type.name}")
|
|
123
|
+
|
|
124
|
+
return mojo_per_unit
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
async def get_wallet_type(wallet_id: int, wallet_client: WalletRpcClient) -> WalletType:
|
|
128
|
+
summaries_response = await wallet_client.get_wallets()
|
|
129
|
+
for summary in summaries_response:
|
|
130
|
+
summary_id: int = summary["id"]
|
|
131
|
+
summary_type: int = summary["type"]
|
|
132
|
+
if wallet_id == summary_id:
|
|
133
|
+
return WalletType(summary_type)
|
|
134
|
+
|
|
135
|
+
raise LookupError(f"Wallet ID not found: {wallet_id}")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
async def get_unit_name_for_wallet_id(
|
|
139
|
+
config: dict[str, Any],
|
|
140
|
+
wallet_type: WalletType,
|
|
141
|
+
wallet_id: int,
|
|
142
|
+
wallet_client: WalletRpcClient,
|
|
143
|
+
) -> str:
|
|
144
|
+
if wallet_type in {
|
|
145
|
+
WalletType.STANDARD_WALLET,
|
|
146
|
+
WalletType.POOLING_WALLET,
|
|
147
|
+
WalletType.DATA_LAYER,
|
|
148
|
+
WalletType.VC,
|
|
149
|
+
}:
|
|
150
|
+
name: str = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"].upper()
|
|
151
|
+
elif wallet_type in {WalletType.CAT, WalletType.CRCAT}:
|
|
152
|
+
name = await wallet_client.get_cat_name(wallet_id=wallet_id)
|
|
153
|
+
else:
|
|
154
|
+
raise LookupError(f"Operation is not supported for Wallet type {wallet_type.name}")
|
|
155
|
+
|
|
156
|
+
return name
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
async def get_transaction(
|
|
160
|
+
*, root_path: pathlib.Path, wallet_rpc_port: Optional[int], fingerprint: Optional[int], tx_id: str, verbose: int
|
|
161
|
+
) -> None:
|
|
162
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fingerprint) as (wallet_client, fingerprint, config):
|
|
163
|
+
transaction_id = bytes32.from_hexstr(tx_id)
|
|
164
|
+
address_prefix = selected_network_address_prefix(config)
|
|
165
|
+
tx: TransactionRecord = await wallet_client.get_transaction(transaction_id=transaction_id)
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
wallet_type = await get_wallet_type(wallet_id=tx.wallet_id, wallet_client=wallet_client)
|
|
169
|
+
mojo_per_unit = get_mojo_per_unit(wallet_type=wallet_type)
|
|
170
|
+
name = await get_unit_name_for_wallet_id(
|
|
171
|
+
config=config,
|
|
172
|
+
wallet_type=wallet_type,
|
|
173
|
+
wallet_id=tx.wallet_id,
|
|
174
|
+
wallet_client=wallet_client,
|
|
175
|
+
)
|
|
176
|
+
except LookupError as e:
|
|
177
|
+
print(e.args[0])
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
print_transaction(
|
|
181
|
+
tx,
|
|
182
|
+
verbose=(verbose > 0),
|
|
183
|
+
name=name,
|
|
184
|
+
address_prefix=address_prefix,
|
|
185
|
+
mojo_per_unit=mojo_per_unit,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async def get_transactions(
|
|
190
|
+
*,
|
|
191
|
+
root_path: pathlib.Path,
|
|
192
|
+
wallet_rpc_port: Optional[int],
|
|
193
|
+
fp: Optional[int],
|
|
194
|
+
wallet_id: int,
|
|
195
|
+
verbose: int,
|
|
196
|
+
paginate: Optional[bool],
|
|
197
|
+
offset: int,
|
|
198
|
+
limit: int,
|
|
199
|
+
sort_key: SortKey,
|
|
200
|
+
reverse: bool,
|
|
201
|
+
clawback: bool,
|
|
202
|
+
) -> None:
|
|
203
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, config):
|
|
204
|
+
if paginate is None:
|
|
205
|
+
paginate = sys.stdout.isatty()
|
|
206
|
+
type_filter = (
|
|
207
|
+
None
|
|
208
|
+
if not clawback
|
|
209
|
+
else TransactionTypeFilter.include(
|
|
210
|
+
[TransactionType.INCOMING_CLAWBACK_RECEIVE, TransactionType.INCOMING_CLAWBACK_SEND]
|
|
211
|
+
)
|
|
212
|
+
)
|
|
213
|
+
txs: list[TransactionRecord] = await wallet_client.get_transactions(
|
|
214
|
+
wallet_id, start=offset, end=(offset + limit), sort_key=sort_key, reverse=reverse, type_filter=type_filter
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
address_prefix = selected_network_address_prefix(config)
|
|
218
|
+
if len(txs) == 0:
|
|
219
|
+
print("There are no transactions to this address")
|
|
220
|
+
|
|
221
|
+
try:
|
|
222
|
+
wallet_type = await get_wallet_type(wallet_id=wallet_id, wallet_client=wallet_client)
|
|
223
|
+
mojo_per_unit = get_mojo_per_unit(wallet_type=wallet_type)
|
|
224
|
+
name = await get_unit_name_for_wallet_id(
|
|
225
|
+
config=config,
|
|
226
|
+
wallet_type=wallet_type,
|
|
227
|
+
wallet_id=wallet_id,
|
|
228
|
+
wallet_client=wallet_client,
|
|
229
|
+
)
|
|
230
|
+
except LookupError as e:
|
|
231
|
+
print(e.args[0])
|
|
232
|
+
return
|
|
233
|
+
|
|
234
|
+
skipped = 0
|
|
235
|
+
num_per_screen = 5 if paginate else len(txs)
|
|
236
|
+
for i in range(0, len(txs), num_per_screen):
|
|
237
|
+
for j in range(0, num_per_screen):
|
|
238
|
+
if i + j + skipped >= len(txs):
|
|
239
|
+
break
|
|
240
|
+
coin_record: Optional[dict[str, Any]] = None
|
|
241
|
+
if txs[i + j + skipped].type in CLAWBACK_INCOMING_TRANSACTION_TYPES:
|
|
242
|
+
coin_records = await wallet_client.get_coin_records(
|
|
243
|
+
GetCoinRecords(coin_id_filter=HashFilter.include([txs[i + j + skipped].additions[0].name()]))
|
|
244
|
+
)
|
|
245
|
+
if len(coin_records["coin_records"]) > 0:
|
|
246
|
+
coin_record = coin_records["coin_records"][0]
|
|
247
|
+
else:
|
|
248
|
+
j -= 1
|
|
249
|
+
skipped += 1
|
|
250
|
+
continue
|
|
251
|
+
print_transaction(
|
|
252
|
+
txs[i + j + skipped],
|
|
253
|
+
verbose=(verbose > 0),
|
|
254
|
+
name=name,
|
|
255
|
+
address_prefix=address_prefix,
|
|
256
|
+
mojo_per_unit=mojo_per_unit,
|
|
257
|
+
coin_record=coin_record,
|
|
258
|
+
)
|
|
259
|
+
if i + num_per_screen >= len(txs):
|
|
260
|
+
return None
|
|
261
|
+
print("Press q to quit, or c to continue")
|
|
262
|
+
while True:
|
|
263
|
+
entered_key = sys.stdin.read(1)
|
|
264
|
+
if entered_key == "q":
|
|
265
|
+
return None
|
|
266
|
+
elif entered_key == "c":
|
|
267
|
+
break
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def check_unusual_transaction(amount: uint64, fee: uint64) -> bool:
|
|
271
|
+
return fee >= amount
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
async def send(
|
|
275
|
+
*,
|
|
276
|
+
root_path: pathlib.Path,
|
|
277
|
+
wallet_rpc_port: Optional[int],
|
|
278
|
+
fp: Optional[int],
|
|
279
|
+
wallet_id: int,
|
|
280
|
+
amount: CliAmount,
|
|
281
|
+
memo: Optional[str],
|
|
282
|
+
fee: uint64,
|
|
283
|
+
address: CliAddress,
|
|
284
|
+
override: bool,
|
|
285
|
+
min_coin_amount: CliAmount,
|
|
286
|
+
max_coin_amount: CliAmount,
|
|
287
|
+
excluded_coin_ids: Sequence[bytes32],
|
|
288
|
+
reuse_puzhash: Optional[bool],
|
|
289
|
+
clawback_time_lock: int,
|
|
290
|
+
push: bool,
|
|
291
|
+
condition_valid_times: ConditionValidTimes,
|
|
292
|
+
) -> list[TransactionRecord]:
|
|
293
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
294
|
+
if memo is None:
|
|
295
|
+
memos = None
|
|
296
|
+
else:
|
|
297
|
+
memos = [memo]
|
|
298
|
+
|
|
299
|
+
if clawback_time_lock < 0:
|
|
300
|
+
print("Clawback time lock seconds cannot be negative.")
|
|
301
|
+
return []
|
|
302
|
+
try:
|
|
303
|
+
typ = await get_wallet_type(wallet_id=wallet_id, wallet_client=wallet_client)
|
|
304
|
+
mojo_per_unit = get_mojo_per_unit(typ)
|
|
305
|
+
except LookupError:
|
|
306
|
+
print(f"Wallet id: {wallet_id} not found.")
|
|
307
|
+
return []
|
|
308
|
+
|
|
309
|
+
final_amount: uint64 = amount.convert_amount(mojo_per_unit)
|
|
310
|
+
|
|
311
|
+
if not override and check_unusual_transaction(final_amount, fee):
|
|
312
|
+
print(
|
|
313
|
+
f"A transaction of amount {final_amount / units['chia']} and fee {fee} is unusual.\n"
|
|
314
|
+
f"Pass in --override if you are sure you mean to do this."
|
|
315
|
+
)
|
|
316
|
+
return []
|
|
317
|
+
if final_amount == 0:
|
|
318
|
+
print("You can not send an empty transaction")
|
|
319
|
+
return []
|
|
320
|
+
|
|
321
|
+
if typ == WalletType.STANDARD_WALLET:
|
|
322
|
+
print("Submitting transaction...")
|
|
323
|
+
res: Union[CATSpendResponse, SendTransactionResponse] = await wallet_client.send_transaction(
|
|
324
|
+
wallet_id,
|
|
325
|
+
final_amount,
|
|
326
|
+
address.original_address,
|
|
327
|
+
CMDTXConfigLoader(
|
|
328
|
+
min_coin_amount=min_coin_amount,
|
|
329
|
+
max_coin_amount=max_coin_amount,
|
|
330
|
+
excluded_coin_ids=list(excluded_coin_ids),
|
|
331
|
+
reuse_puzhash=reuse_puzhash,
|
|
332
|
+
).to_tx_config(mojo_per_unit, config, fingerprint),
|
|
333
|
+
fee,
|
|
334
|
+
memos,
|
|
335
|
+
puzzle_decorator_override=(
|
|
336
|
+
[{"decorator": PuzzleDecoratorType.CLAWBACK.name, "clawback_timelock": clawback_time_lock}]
|
|
337
|
+
if clawback_time_lock > 0
|
|
338
|
+
else None
|
|
339
|
+
),
|
|
340
|
+
push=push,
|
|
341
|
+
timelock_info=condition_valid_times,
|
|
342
|
+
)
|
|
343
|
+
elif typ in {WalletType.CAT, WalletType.CRCAT}:
|
|
344
|
+
print("Submitting transaction...")
|
|
345
|
+
res = await wallet_client.cat_spend(
|
|
346
|
+
wallet_id,
|
|
347
|
+
CMDTXConfigLoader(
|
|
348
|
+
min_coin_amount=min_coin_amount,
|
|
349
|
+
max_coin_amount=max_coin_amount,
|
|
350
|
+
excluded_coin_ids=list(excluded_coin_ids),
|
|
351
|
+
reuse_puzhash=reuse_puzhash,
|
|
352
|
+
).to_tx_config(mojo_per_unit, config, fingerprint),
|
|
353
|
+
final_amount,
|
|
354
|
+
address.original_address,
|
|
355
|
+
fee,
|
|
356
|
+
memos,
|
|
357
|
+
push=push,
|
|
358
|
+
timelock_info=condition_valid_times,
|
|
359
|
+
)
|
|
360
|
+
else:
|
|
361
|
+
print("Only standard wallet and CAT wallets are supported")
|
|
362
|
+
return []
|
|
363
|
+
|
|
364
|
+
tx_id = res.transaction.name
|
|
365
|
+
if push:
|
|
366
|
+
start = time.time()
|
|
367
|
+
while time.time() - start < 10:
|
|
368
|
+
await asyncio.sleep(0.1)
|
|
369
|
+
tx = await wallet_client.get_transaction(tx_id)
|
|
370
|
+
if len(tx.sent_to) > 0:
|
|
371
|
+
print(transaction_submitted_msg(tx))
|
|
372
|
+
print(transaction_status_msg(fingerprint, tx_id))
|
|
373
|
+
return res.transactions
|
|
374
|
+
|
|
375
|
+
print("Transaction not yet submitted to nodes")
|
|
376
|
+
if push: # pragma: no cover
|
|
377
|
+
print(f"To get status, use command: chia wallet get_transaction -f {fingerprint} -tx 0x{tx_id}")
|
|
378
|
+
|
|
379
|
+
return res.transactions # pragma: no cover
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
async def get_address(
|
|
383
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], wallet_id: int, new_address: bool
|
|
384
|
+
) -> None:
|
|
385
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
386
|
+
res = await wallet_client.get_next_address(wallet_id, new_address)
|
|
387
|
+
print(res)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
async def delete_unconfirmed_transactions(
|
|
391
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], wallet_id: int
|
|
392
|
+
) -> None:
|
|
393
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, _):
|
|
394
|
+
await wallet_client.delete_unconfirmed_transactions(wallet_id)
|
|
395
|
+
print(f"Successfully deleted all unconfirmed transactions for wallet id {wallet_id} on key {fingerprint}")
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
async def get_derivation_index(root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int]) -> None:
|
|
399
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
400
|
+
res = await wallet_client.get_current_derivation_index()
|
|
401
|
+
print(f"Last derivation index: {res}")
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
async def update_derivation_index(
|
|
405
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], index: int
|
|
406
|
+
) -> None:
|
|
407
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
408
|
+
print("Updating derivation index... This may take a while.")
|
|
409
|
+
res = await wallet_client.extend_derivation_index(index)
|
|
410
|
+
print(f"Updated derivation index: {res}")
|
|
411
|
+
print("Your balances may take a while to update.")
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
async def add_token(
|
|
415
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], asset_id: bytes32, token_name: str
|
|
416
|
+
) -> None:
|
|
417
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, _):
|
|
418
|
+
existing_info: Optional[tuple[Optional[uint32], str]] = await wallet_client.cat_asset_id_to_name(asset_id)
|
|
419
|
+
if existing_info is None or existing_info[0] is None:
|
|
420
|
+
response = await wallet_client.create_wallet_for_existing_cat(asset_id)
|
|
421
|
+
wallet_id = response["wallet_id"]
|
|
422
|
+
await wallet_client.set_cat_name(wallet_id, token_name)
|
|
423
|
+
print(f"Successfully added {token_name} with wallet id {wallet_id} on key {fingerprint}")
|
|
424
|
+
else:
|
|
425
|
+
wallet_id, old_name = existing_info
|
|
426
|
+
await wallet_client.set_cat_name(wallet_id, token_name)
|
|
427
|
+
print(f"Successfully renamed {old_name} with wallet_id {wallet_id} on key {fingerprint} to {token_name}")
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
async def make_offer(
|
|
431
|
+
*,
|
|
432
|
+
root_path: pathlib.Path,
|
|
433
|
+
wallet_rpc_port: Optional[int],
|
|
434
|
+
fp: Optional[int],
|
|
435
|
+
fee: uint64,
|
|
436
|
+
offers: Sequence[str],
|
|
437
|
+
requests: Sequence[str],
|
|
438
|
+
filepath: pathlib.Path,
|
|
439
|
+
reuse_puzhash: Optional[bool],
|
|
440
|
+
condition_valid_times: ConditionValidTimes,
|
|
441
|
+
) -> None:
|
|
442
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
443
|
+
if offers == [] or requests == []:
|
|
444
|
+
print("Not creating offer: Must be offering and requesting at least one asset")
|
|
445
|
+
else:
|
|
446
|
+
offer_dict: dict[Union[uint32, str], int] = {}
|
|
447
|
+
driver_dict: dict[str, Any] = {}
|
|
448
|
+
printable_dict: dict[str, tuple[str, int, int]] = {} # dict[asset_name, tuple[amount, unit, multiplier]]
|
|
449
|
+
royalty_asset_dict: dict[Any, tuple[Any, uint16]] = {}
|
|
450
|
+
fungible_asset_dict: dict[Any, uint64] = {}
|
|
451
|
+
for item in [*offers, *requests]:
|
|
452
|
+
name, amount = tuple(item.split(":")[0:2])
|
|
453
|
+
try:
|
|
454
|
+
b32_id = bytes32.from_hexstr(name)
|
|
455
|
+
id: Union[uint32, str] = b32_id.hex()
|
|
456
|
+
result = await wallet_client.cat_asset_id_to_name(b32_id)
|
|
457
|
+
if result is not None:
|
|
458
|
+
name = result[1]
|
|
459
|
+
else:
|
|
460
|
+
name = "Unknown CAT"
|
|
461
|
+
unit = units["cat"]
|
|
462
|
+
if item in offers:
|
|
463
|
+
fungible_asset_dict[name] = uint64(abs(int(Decimal(amount) * unit)))
|
|
464
|
+
except ValueError:
|
|
465
|
+
try:
|
|
466
|
+
hrp, _ = bech32_decode(name)
|
|
467
|
+
if hrp == "nft":
|
|
468
|
+
coin_id = decode_puzzle_hash(name)
|
|
469
|
+
unit = 1
|
|
470
|
+
info = NFTInfo.from_json_dict((await wallet_client.get_nft_info(coin_id.hex()))["nft_info"])
|
|
471
|
+
id = info.launcher_id.hex()
|
|
472
|
+
assert isinstance(id, str)
|
|
473
|
+
if item in requests:
|
|
474
|
+
driver_dict[id] = {
|
|
475
|
+
"type": "singleton",
|
|
476
|
+
"launcher_id": "0x" + id,
|
|
477
|
+
"launcher_ph": "0x" + info.launcher_puzhash.hex(),
|
|
478
|
+
"also": {
|
|
479
|
+
"type": "metadata",
|
|
480
|
+
"metadata": info.chain_info,
|
|
481
|
+
"updater_hash": "0x" + info.updater_puzhash.hex(),
|
|
482
|
+
},
|
|
483
|
+
}
|
|
484
|
+
if info.supports_did:
|
|
485
|
+
assert info.royalty_puzzle_hash is not None
|
|
486
|
+
assert info.royalty_percentage is not None
|
|
487
|
+
driver_dict[id]["also"]["also"] = {
|
|
488
|
+
"type": "ownership",
|
|
489
|
+
"owner": "()",
|
|
490
|
+
"transfer_program": {
|
|
491
|
+
"type": "royalty transfer program",
|
|
492
|
+
"launcher_id": "0x" + info.launcher_id.hex(),
|
|
493
|
+
"royalty_address": "0x" + info.royalty_puzzle_hash.hex(),
|
|
494
|
+
"royalty_percentage": str(info.royalty_percentage),
|
|
495
|
+
},
|
|
496
|
+
}
|
|
497
|
+
royalty_asset_dict[name] = (
|
|
498
|
+
encode_puzzle_hash(info.royalty_puzzle_hash, AddressType.XCH.hrp(config)),
|
|
499
|
+
info.royalty_percentage,
|
|
500
|
+
)
|
|
501
|
+
else:
|
|
502
|
+
id = decode_puzzle_hash(name).hex()
|
|
503
|
+
assert hrp is not None
|
|
504
|
+
unit = units[hrp]
|
|
505
|
+
except ValueError:
|
|
506
|
+
id = uint32(int(name))
|
|
507
|
+
if id == 1:
|
|
508
|
+
name = "XCH"
|
|
509
|
+
unit = units["chia"]
|
|
510
|
+
else:
|
|
511
|
+
name = await wallet_client.get_cat_name(id)
|
|
512
|
+
unit = units["cat"]
|
|
513
|
+
if item in offers:
|
|
514
|
+
fungible_asset_dict[name] = uint64(abs(int(Decimal(amount) * unit)))
|
|
515
|
+
multiplier: int = -1 if item in offers else 1
|
|
516
|
+
printable_dict[name] = (amount, unit, multiplier)
|
|
517
|
+
if id in offer_dict:
|
|
518
|
+
print("Not creating offer: Cannot offer and request the same asset in a trade")
|
|
519
|
+
break
|
|
520
|
+
else:
|
|
521
|
+
offer_dict[id] = int(Decimal(amount) * unit) * multiplier
|
|
522
|
+
else:
|
|
523
|
+
print("Creating Offer")
|
|
524
|
+
print("--------------")
|
|
525
|
+
print()
|
|
526
|
+
print("OFFERING:")
|
|
527
|
+
for name, data in printable_dict.items():
|
|
528
|
+
amount, unit, multiplier = data
|
|
529
|
+
if multiplier < 0:
|
|
530
|
+
print(f" - {amount} {name} ({int(Decimal(amount) * unit)} mojos)")
|
|
531
|
+
print("REQUESTING:")
|
|
532
|
+
for name, data in printable_dict.items():
|
|
533
|
+
amount, unit, multiplier = data
|
|
534
|
+
if multiplier > 0:
|
|
535
|
+
print(f" - {amount} {name} ({int(Decimal(amount) * unit)} mojos)")
|
|
536
|
+
|
|
537
|
+
if fee > 0:
|
|
538
|
+
print()
|
|
539
|
+
print(f"Including Fees: {Decimal(fee) / units['chia']} XCH, {fee} mojos")
|
|
540
|
+
|
|
541
|
+
if royalty_asset_dict != {}:
|
|
542
|
+
royalty_summary: dict[Any, list[dict[str, Any]]] = await wallet_client.nft_calculate_royalties(
|
|
543
|
+
royalty_asset_dict, fungible_asset_dict
|
|
544
|
+
)
|
|
545
|
+
total_amounts_requested: dict[Any, int] = {}
|
|
546
|
+
print()
|
|
547
|
+
print("Royalties Summary:")
|
|
548
|
+
for nft_id, summaries in royalty_summary.items():
|
|
549
|
+
print(f" - For {nft_id}:")
|
|
550
|
+
for summary in summaries:
|
|
551
|
+
divisor = units["chia"] if summary["asset"] == "XCH" else units["cat"]
|
|
552
|
+
converted_amount = Decimal(summary["amount"]) / divisor
|
|
553
|
+
total_amounts_requested.setdefault(summary["asset"], fungible_asset_dict[summary["asset"]])
|
|
554
|
+
total_amounts_requested[summary["asset"]] += summary["amount"]
|
|
555
|
+
print(
|
|
556
|
+
f" - {converted_amount} {summary['asset']} ({summary['amount']} mojos) to {summary['address']}" # noqa
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
print()
|
|
560
|
+
print("Total Amounts Offered:")
|
|
561
|
+
for asset, requested_amount in total_amounts_requested.items():
|
|
562
|
+
divisor = units["chia"] if asset == "XCH" else units["cat"]
|
|
563
|
+
converted_amount = Decimal(requested_amount) / divisor
|
|
564
|
+
print(f" - {converted_amount} {asset} ({requested_amount} mojos)")
|
|
565
|
+
|
|
566
|
+
cli_confirm(
|
|
567
|
+
"\nOffers for NFTs will have royalties automatically added. "
|
|
568
|
+
"Are you sure you would like to continue? (y/n): ",
|
|
569
|
+
"Not creating offer...",
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
cli_confirm("Confirm (y/n): ", "Not creating offer...")
|
|
573
|
+
|
|
574
|
+
with filepath.open(mode="w") as file:
|
|
575
|
+
res = await wallet_client.create_offer_for_ids(
|
|
576
|
+
offer_dict,
|
|
577
|
+
driver_dict=driver_dict,
|
|
578
|
+
fee=fee,
|
|
579
|
+
tx_config=CMDTXConfigLoader(
|
|
580
|
+
reuse_puzhash=reuse_puzhash,
|
|
581
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
582
|
+
timelock_info=condition_valid_times,
|
|
583
|
+
)
|
|
584
|
+
if res.offer is not None:
|
|
585
|
+
file.write(res.offer.to_bech32())
|
|
586
|
+
print(f"Created offer with ID {res.trade_record.trade_id}")
|
|
587
|
+
print(
|
|
588
|
+
f"Use chia wallet get_offers --id "
|
|
589
|
+
f"{res.trade_record.trade_id} -f {fingerprint} to view status"
|
|
590
|
+
)
|
|
591
|
+
else:
|
|
592
|
+
print("Error creating offer")
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
def timestamp_to_time(timestamp: int) -> str:
|
|
596
|
+
return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
async def print_offer_summary(
|
|
600
|
+
cat_name_resolver: CATNameResolver, sum_dict: dict[str, int], has_fee: bool = False, network_xch: str = "XCH"
|
|
601
|
+
) -> None:
|
|
602
|
+
for asset_id, amount in sum_dict.items():
|
|
603
|
+
description: str = ""
|
|
604
|
+
unit: int = units["chia"]
|
|
605
|
+
wid: str = "1" if asset_id == "xch" else ""
|
|
606
|
+
mojo_amount: int = int(Decimal(amount))
|
|
607
|
+
name: str = network_xch
|
|
608
|
+
if asset_id != "xch":
|
|
609
|
+
name = asset_id
|
|
610
|
+
if asset_id == "unknown":
|
|
611
|
+
name = "Unknown"
|
|
612
|
+
unit = units["mojo"]
|
|
613
|
+
if has_fee:
|
|
614
|
+
description = " [Typically represents change returned from the included fee]"
|
|
615
|
+
else:
|
|
616
|
+
unit = units["cat"]
|
|
617
|
+
result = await cat_name_resolver(bytes32.from_hexstr(asset_id))
|
|
618
|
+
if result is not None:
|
|
619
|
+
wid = str(result[0])
|
|
620
|
+
name = result[1]
|
|
621
|
+
output: str = f" - {name}"
|
|
622
|
+
mojo_str: str = f"{mojo_amount} {'mojo' if mojo_amount == 1 else 'mojos'}"
|
|
623
|
+
if len(wid) > 0:
|
|
624
|
+
output += f" (Wallet ID: {wid})"
|
|
625
|
+
if unit == units["mojo"]:
|
|
626
|
+
output += f": {mojo_str}"
|
|
627
|
+
else:
|
|
628
|
+
output += f": {mojo_amount / unit} ({mojo_str})"
|
|
629
|
+
if len(description) > 0:
|
|
630
|
+
output += f" {description}"
|
|
631
|
+
print(output)
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
def format_timestamp_with_timezone(timestamp: int) -> str:
|
|
635
|
+
tzinfo = datetime.now(timezone.utc).astimezone().tzinfo
|
|
636
|
+
return datetime.fromtimestamp(timestamp, tz=tzinfo).strftime("%Y-%m-%d %H:%M %Z")
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
async def print_trade_record(record: TradeRecord, wallet_client: WalletRpcClient, summaries: bool = False) -> None:
|
|
640
|
+
print()
|
|
641
|
+
print(f"Record with id: {record.trade_id}")
|
|
642
|
+
print("---------------")
|
|
643
|
+
print(f"Created at: {timestamp_to_time(record.created_at_time)}")
|
|
644
|
+
print(f"Confirmed at: {record.confirmed_at_index if record.confirmed_at_index > 0 else 'Not confirmed'}")
|
|
645
|
+
print(f"Accepted at: {timestamp_to_time(record.accepted_at_time) if record.accepted_at_time else 'N/A'}")
|
|
646
|
+
print(f"Status: {TradeStatus(record.status).name}")
|
|
647
|
+
if summaries:
|
|
648
|
+
print("Summary:")
|
|
649
|
+
offer = Offer.from_bytes(record.offer)
|
|
650
|
+
offered, requested, _, _ = offer.summary()
|
|
651
|
+
outbound_balances: dict[str, int] = offer.get_pending_amounts()
|
|
652
|
+
fees: Decimal = Decimal(offer.fees())
|
|
653
|
+
cat_name_resolver = wallet_client.cat_asset_id_to_name
|
|
654
|
+
print(" OFFERED:")
|
|
655
|
+
await print_offer_summary(cat_name_resolver, offered)
|
|
656
|
+
print(" REQUESTED:")
|
|
657
|
+
await print_offer_summary(cat_name_resolver, requested)
|
|
658
|
+
print("Pending Outbound Balances:")
|
|
659
|
+
await print_offer_summary(cat_name_resolver, outbound_balances, has_fee=(fees > 0))
|
|
660
|
+
print(f"Included Fees: {fees / units['chia']} XCH, {fees} mojos")
|
|
661
|
+
print("Timelock information:")
|
|
662
|
+
if record.valid_times.min_time is not None:
|
|
663
|
+
print(f" - Not valid until {format_timestamp_with_timezone(record.valid_times.min_time)}")
|
|
664
|
+
if record.valid_times.min_height is not None:
|
|
665
|
+
print(f" - Not valid until height {record.valid_times.min_height}")
|
|
666
|
+
if record.valid_times.max_time is not None:
|
|
667
|
+
print(f" - Expires at {format_timestamp_with_timezone(record.valid_times.max_time)} (+/- 10 min)")
|
|
668
|
+
if record.valid_times.max_height is not None:
|
|
669
|
+
print(f" - Expires at height {record.valid_times.max_height} (wait ~10 blocks after to be reorg safe)")
|
|
670
|
+
print("---------------")
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
async def get_offers(
|
|
674
|
+
*,
|
|
675
|
+
root_path: pathlib.Path,
|
|
676
|
+
wallet_rpc_port: Optional[int],
|
|
677
|
+
fp: Optional[int],
|
|
678
|
+
offer_id: Optional[bytes32],
|
|
679
|
+
filepath: Optional[str],
|
|
680
|
+
exclude_my_offers: bool = False,
|
|
681
|
+
exclude_taken_offers: bool = False,
|
|
682
|
+
include_completed: bool = False,
|
|
683
|
+
summaries: bool = False,
|
|
684
|
+
reverse: bool = False,
|
|
685
|
+
sort_by_relevance: bool = True,
|
|
686
|
+
) -> None:
|
|
687
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
688
|
+
file_contents: bool = (filepath is not None) or summaries
|
|
689
|
+
records: list[TradeRecord] = []
|
|
690
|
+
if offer_id is None:
|
|
691
|
+
batch_size: int = 10
|
|
692
|
+
start: int = 0
|
|
693
|
+
end: int = start + batch_size
|
|
694
|
+
|
|
695
|
+
# Traverse offers page by page
|
|
696
|
+
while True:
|
|
697
|
+
new_records: list[TradeRecord] = await wallet_client.get_all_offers(
|
|
698
|
+
start,
|
|
699
|
+
end,
|
|
700
|
+
sort_key="RELEVANCE" if sort_by_relevance else "CONFIRMED_AT_HEIGHT",
|
|
701
|
+
reverse=reverse,
|
|
702
|
+
file_contents=file_contents,
|
|
703
|
+
exclude_my_offers=exclude_my_offers,
|
|
704
|
+
exclude_taken_offers=exclude_taken_offers,
|
|
705
|
+
include_completed=include_completed,
|
|
706
|
+
)
|
|
707
|
+
records.extend(new_records)
|
|
708
|
+
|
|
709
|
+
# If fewer records were returned than requested, we're done
|
|
710
|
+
if len(new_records) < batch_size:
|
|
711
|
+
break
|
|
712
|
+
|
|
713
|
+
start = end
|
|
714
|
+
end += batch_size
|
|
715
|
+
else:
|
|
716
|
+
records = [await wallet_client.get_offer(offer_id, file_contents)]
|
|
717
|
+
if filepath is not None:
|
|
718
|
+
with open(pathlib.Path(filepath), "w") as file:
|
|
719
|
+
file.write(Offer.from_bytes(records[0].offer).to_bech32())
|
|
720
|
+
file.close()
|
|
721
|
+
|
|
722
|
+
for record in records:
|
|
723
|
+
await print_trade_record(record, wallet_client, summaries=summaries)
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
async def take_offer(
|
|
727
|
+
root_path: pathlib.Path,
|
|
728
|
+
wallet_rpc_port: Optional[int],
|
|
729
|
+
fp: Optional[int],
|
|
730
|
+
fee: uint64,
|
|
731
|
+
file: str,
|
|
732
|
+
examine_only: bool,
|
|
733
|
+
push: bool,
|
|
734
|
+
condition_valid_times: ConditionValidTimes,
|
|
735
|
+
) -> list[TransactionRecord]:
|
|
736
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
737
|
+
if os.path.exists(file):
|
|
738
|
+
filepath = pathlib.Path(file)
|
|
739
|
+
with open(filepath) as ffile:
|
|
740
|
+
offer_hex: str = ffile.read()
|
|
741
|
+
ffile.close()
|
|
742
|
+
else:
|
|
743
|
+
offer_hex = file
|
|
744
|
+
|
|
745
|
+
try:
|
|
746
|
+
offer = Offer.from_bech32(offer_hex)
|
|
747
|
+
except ValueError:
|
|
748
|
+
print("Please enter a valid offer file or hex blob")
|
|
749
|
+
return []
|
|
750
|
+
|
|
751
|
+
offered, requested, _, _ = offer.summary()
|
|
752
|
+
cat_name_resolver = wallet_client.cat_asset_id_to_name
|
|
753
|
+
network_xch = AddressType.XCH.hrp(config).upper()
|
|
754
|
+
print("Summary:")
|
|
755
|
+
print(" OFFERED:")
|
|
756
|
+
await print_offer_summary(cat_name_resolver, offered, network_xch=network_xch)
|
|
757
|
+
print(" REQUESTED:")
|
|
758
|
+
await print_offer_summary(cat_name_resolver, requested, network_xch=network_xch)
|
|
759
|
+
|
|
760
|
+
print()
|
|
761
|
+
|
|
762
|
+
royalty_asset_dict: dict[Any, tuple[Any, uint16]] = {}
|
|
763
|
+
for royalty_asset_id in nft_coin_ids_supporting_royalties_from_offer(offer):
|
|
764
|
+
if royalty_asset_id.hex() in offered:
|
|
765
|
+
percentage, address = await get_nft_royalty_percentage_and_address(royalty_asset_id, wallet_client)
|
|
766
|
+
royalty_asset_dict[encode_puzzle_hash(royalty_asset_id, AddressType.NFT.hrp(config))] = (
|
|
767
|
+
encode_puzzle_hash(address, AddressType.XCH.hrp(config)),
|
|
768
|
+
percentage,
|
|
769
|
+
)
|
|
770
|
+
|
|
771
|
+
if royalty_asset_dict != {}:
|
|
772
|
+
fungible_asset_dict: dict[Any, uint64] = {}
|
|
773
|
+
for fungible_asset_id in fungible_assets_from_offer(offer):
|
|
774
|
+
fungible_asset_id_str = fungible_asset_id.hex() if fungible_asset_id is not None else "xch"
|
|
775
|
+
if fungible_asset_id_str in requested:
|
|
776
|
+
nft_royalty_currency: str = "Unknown CAT"
|
|
777
|
+
if fungible_asset_id is None:
|
|
778
|
+
nft_royalty_currency = network_xch
|
|
779
|
+
else:
|
|
780
|
+
result = await wallet_client.cat_asset_id_to_name(fungible_asset_id)
|
|
781
|
+
if result is not None:
|
|
782
|
+
nft_royalty_currency = result[1]
|
|
783
|
+
fungible_asset_dict[nft_royalty_currency] = uint64(requested[fungible_asset_id_str])
|
|
784
|
+
|
|
785
|
+
if fungible_asset_dict != {}:
|
|
786
|
+
royalty_summary: dict[Any, list[dict[str, Any]]] = await wallet_client.nft_calculate_royalties(
|
|
787
|
+
royalty_asset_dict, fungible_asset_dict
|
|
788
|
+
)
|
|
789
|
+
total_amounts_requested: dict[Any, int] = {}
|
|
790
|
+
print("Royalties Summary:")
|
|
791
|
+
for nft_id, summaries in royalty_summary.items():
|
|
792
|
+
print(f" - For {nft_id}:")
|
|
793
|
+
for summary in summaries:
|
|
794
|
+
divisor = units["chia"] if summary["asset"] == network_xch else units["cat"]
|
|
795
|
+
converted_amount = Decimal(summary["amount"]) / divisor
|
|
796
|
+
total_amounts_requested.setdefault(summary["asset"], fungible_asset_dict[summary["asset"]])
|
|
797
|
+
total_amounts_requested[summary["asset"]] += summary["amount"]
|
|
798
|
+
print(
|
|
799
|
+
f" - {converted_amount} {summary['asset']} ({summary['amount']} mojos) to {summary['address']}" # noqa
|
|
800
|
+
)
|
|
801
|
+
|
|
802
|
+
print()
|
|
803
|
+
print("Total Amounts Requested:")
|
|
804
|
+
for asset, amount in total_amounts_requested.items():
|
|
805
|
+
divisor = units["chia"] if asset == network_xch else units["cat"]
|
|
806
|
+
converted_amount = Decimal(amount) / divisor
|
|
807
|
+
print(f" - {converted_amount} {asset} ({amount} mojos)")
|
|
808
|
+
|
|
809
|
+
print(f"Included Fees: {Decimal(offer.fees()) / units['chia']} {network_xch}, {offer.fees()} mojos")
|
|
810
|
+
|
|
811
|
+
if not examine_only:
|
|
812
|
+
print()
|
|
813
|
+
cli_confirm("Would you like to take this offer? (y/n): ")
|
|
814
|
+
res = await wallet_client.take_offer(
|
|
815
|
+
offer,
|
|
816
|
+
fee=fee,
|
|
817
|
+
tx_config=CMDTXConfigLoader().to_tx_config(units["chia"], config, fingerprint),
|
|
818
|
+
push=push,
|
|
819
|
+
timelock_info=condition_valid_times,
|
|
820
|
+
)
|
|
821
|
+
if push:
|
|
822
|
+
print(f"Accepted offer with ID {res.trade_record.trade_id}")
|
|
823
|
+
print(
|
|
824
|
+
f"Use chia wallet get_offers --id {res.trade_record.trade_id} -f {fingerprint} to view its status"
|
|
825
|
+
)
|
|
826
|
+
|
|
827
|
+
return res.transactions
|
|
828
|
+
else:
|
|
829
|
+
return []
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
async def cancel_offer(
|
|
833
|
+
root_path: pathlib.Path,
|
|
834
|
+
wallet_rpc_port: Optional[int],
|
|
835
|
+
fp: Optional[int],
|
|
836
|
+
fee: uint64,
|
|
837
|
+
offer_id: bytes32,
|
|
838
|
+
secure: bool,
|
|
839
|
+
push: bool,
|
|
840
|
+
condition_valid_times: ConditionValidTimes,
|
|
841
|
+
) -> list[TransactionRecord]:
|
|
842
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
843
|
+
trade_record = await wallet_client.get_offer(offer_id, file_contents=True)
|
|
844
|
+
await print_trade_record(trade_record, wallet_client, summaries=True)
|
|
845
|
+
|
|
846
|
+
cli_confirm(f"Are you sure you wish to cancel offer with ID: {trade_record.trade_id}? (y/n): ")
|
|
847
|
+
res = await wallet_client.cancel_offer(
|
|
848
|
+
offer_id,
|
|
849
|
+
CMDTXConfigLoader().to_tx_config(units["chia"], config, fingerprint),
|
|
850
|
+
secure=secure,
|
|
851
|
+
fee=fee,
|
|
852
|
+
push=push,
|
|
853
|
+
timelock_info=condition_valid_times,
|
|
854
|
+
)
|
|
855
|
+
if push or not secure:
|
|
856
|
+
print(f"Cancelled offer with ID {trade_record.trade_id}")
|
|
857
|
+
if secure and push:
|
|
858
|
+
print(f"Use chia wallet get_offers --id {trade_record.trade_id} -f {fingerprint} to view cancel status")
|
|
859
|
+
|
|
860
|
+
return res.transactions
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def wallet_coin_unit(typ: WalletType, address_prefix: str) -> tuple[str, int]:
|
|
864
|
+
if typ in {WalletType.CAT, WalletType.CRCAT}:
|
|
865
|
+
return "", units["cat"]
|
|
866
|
+
if typ in {WalletType.STANDARD_WALLET, WalletType.POOLING_WALLET, WalletType.MULTI_SIG}:
|
|
867
|
+
return address_prefix, units["chia"]
|
|
868
|
+
return "", units["mojo"]
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
def print_balance(amount: int, scale: int, address_prefix: str, *, decimal_only: bool = False) -> str:
|
|
872
|
+
if decimal_only: # dont use scientific notation.
|
|
873
|
+
final_amount = f"{amount / scale:.12f}"
|
|
874
|
+
else:
|
|
875
|
+
final_amount = f"{amount / scale}"
|
|
876
|
+
ret = f"{final_amount} {address_prefix} "
|
|
877
|
+
if scale > 1:
|
|
878
|
+
ret += f"({amount} mojo)"
|
|
879
|
+
return ret
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
async def print_balances(
|
|
883
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], wallet_type: Optional[WalletType] = None
|
|
884
|
+
) -> None:
|
|
885
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
886
|
+
summaries_response = await wallet_client.get_wallets(wallet_type)
|
|
887
|
+
address_prefix = selected_network_address_prefix(config)
|
|
888
|
+
|
|
889
|
+
sync_response = await wallet_client.get_sync_status()
|
|
890
|
+
|
|
891
|
+
print(f"Wallet height: {(await wallet_client.get_height_info()).height}")
|
|
892
|
+
if sync_response.syncing:
|
|
893
|
+
print("Sync status: Syncing...")
|
|
894
|
+
elif sync_response.synced:
|
|
895
|
+
print("Sync status: Synced")
|
|
896
|
+
else:
|
|
897
|
+
print("Sync status: Not synced")
|
|
898
|
+
|
|
899
|
+
if not sync_response.syncing and sync_response.synced:
|
|
900
|
+
if len(summaries_response) == 0:
|
|
901
|
+
type_hint = " " if wallet_type is None else f" from type {wallet_type.name} "
|
|
902
|
+
print(f"\nNo wallets{type_hint}available for fingerprint: {fingerprint}")
|
|
903
|
+
else:
|
|
904
|
+
print(f"Balances, fingerprint: {fingerprint}")
|
|
905
|
+
for summary in summaries_response:
|
|
906
|
+
indent: str = " "
|
|
907
|
+
# asset_id currently contains both the asset ID and TAIL program bytes concatenated together.
|
|
908
|
+
# A future RPC update may split them apart, but for now we'll show the first 32 bytes (64 chars)
|
|
909
|
+
asset_id = summary["data"][:64]
|
|
910
|
+
wallet_id = summary["id"]
|
|
911
|
+
balances = await wallet_client.get_wallet_balance(wallet_id)
|
|
912
|
+
typ = WalletType(int(summary["type"]))
|
|
913
|
+
address_prefix, scale = wallet_coin_unit(typ, address_prefix)
|
|
914
|
+
total_balance: str = print_balance(balances["confirmed_wallet_balance"], scale, address_prefix)
|
|
915
|
+
unconfirmed_wallet_balance: str = print_balance(
|
|
916
|
+
balances["unconfirmed_wallet_balance"], scale, address_prefix
|
|
917
|
+
)
|
|
918
|
+
spendable_balance: str = print_balance(balances["spendable_balance"], scale, address_prefix)
|
|
919
|
+
my_did: Optional[str] = None
|
|
920
|
+
ljust = 23
|
|
921
|
+
if typ == WalletType.CRCAT:
|
|
922
|
+
ljust = 36
|
|
923
|
+
print()
|
|
924
|
+
print(f"{summary['name']}:")
|
|
925
|
+
print(f"{indent}{'-Total Balance:'.ljust(ljust)} {total_balance}")
|
|
926
|
+
if typ == WalletType.CRCAT:
|
|
927
|
+
print(
|
|
928
|
+
f"{indent}{'-Balance Pending VC Approval:'.ljust(ljust)} "
|
|
929
|
+
f"{print_balance(balances['pending_approval_balance'], scale, address_prefix)}"
|
|
930
|
+
)
|
|
931
|
+
print(f"{indent}{'-Pending Total Balance:'.ljust(ljust)} {unconfirmed_wallet_balance}")
|
|
932
|
+
print(f"{indent}{'-Spendable:'.ljust(ljust)} {spendable_balance}")
|
|
933
|
+
print(f"{indent}{'-Type:'.ljust(ljust)} {typ.name}")
|
|
934
|
+
if typ == WalletType.DECENTRALIZED_ID:
|
|
935
|
+
get_did_response = await wallet_client.get_did_id(wallet_id)
|
|
936
|
+
my_did = get_did_response["my_did"]
|
|
937
|
+
print(f"{indent}{'-DID ID:'.ljust(ljust)} {my_did}")
|
|
938
|
+
elif typ == WalletType.NFT:
|
|
939
|
+
get_did_response = await wallet_client.get_nft_wallet_did(wallet_id)
|
|
940
|
+
my_did = get_did_response["did_id"]
|
|
941
|
+
if my_did is not None and len(my_did) > 0:
|
|
942
|
+
print(f"{indent}{'-DID ID:'.ljust(ljust)} {my_did}")
|
|
943
|
+
elif typ == WalletType.DAO:
|
|
944
|
+
get_id_response = await wallet_client.dao_get_treasury_id(wallet_id)
|
|
945
|
+
treasury_id = get_id_response["treasury_id"][2:]
|
|
946
|
+
print(f"{indent}{'-Treasury ID:'.ljust(ljust)} {treasury_id}")
|
|
947
|
+
elif typ == WalletType.DAO_CAT:
|
|
948
|
+
cat_asset_id = summary["data"][32:96]
|
|
949
|
+
print(f"{indent}{'-Asset ID:'.ljust(ljust)} {cat_asset_id}")
|
|
950
|
+
elif len(asset_id) > 0:
|
|
951
|
+
print(f"{indent}{'-Asset ID:'.ljust(ljust)} {asset_id}")
|
|
952
|
+
print(f"{indent}{'-Wallet ID:'.ljust(ljust)} {wallet_id}")
|
|
953
|
+
|
|
954
|
+
print(" ")
|
|
955
|
+
trusted_peers: dict[str, str] = config["wallet"].get("trusted_peers", {})
|
|
956
|
+
trusted_cidrs: list[str] = config["wallet"].get("trusted_cidrs", [])
|
|
957
|
+
await print_connections(wallet_client, trusted_peers, trusted_cidrs)
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
async def create_did_wallet(
|
|
961
|
+
root_path: pathlib.Path,
|
|
962
|
+
wallet_rpc_port: Optional[int],
|
|
963
|
+
fp: Optional[int],
|
|
964
|
+
fee: uint64,
|
|
965
|
+
name: Optional[str],
|
|
966
|
+
amount: int,
|
|
967
|
+
push: bool,
|
|
968
|
+
condition_valid_times: ConditionValidTimes,
|
|
969
|
+
) -> list[TransactionRecord]:
|
|
970
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
971
|
+
try:
|
|
972
|
+
response = await wallet_client.create_new_did_wallet(
|
|
973
|
+
amount,
|
|
974
|
+
CMDTXConfigLoader().to_tx_config(units["chia"], config, fingerprint),
|
|
975
|
+
fee,
|
|
976
|
+
name,
|
|
977
|
+
push=push,
|
|
978
|
+
timelock_info=condition_valid_times,
|
|
979
|
+
)
|
|
980
|
+
wallet_id = response["wallet_id"]
|
|
981
|
+
my_did = response["my_did"]
|
|
982
|
+
print(f"Successfully created a DID wallet with name {name} and id {wallet_id} on key {fingerprint}")
|
|
983
|
+
print(f"Successfully created a DID {my_did} in the newly created DID wallet")
|
|
984
|
+
return [] # TODO: fix this endpoint to return transactions
|
|
985
|
+
except Exception as e:
|
|
986
|
+
print(f"Failed to create DID wallet: {e}")
|
|
987
|
+
return []
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
async def did_set_wallet_name(
|
|
991
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], wallet_id: int, name: str
|
|
992
|
+
) -> None:
|
|
993
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
994
|
+
try:
|
|
995
|
+
await wallet_client.did_set_wallet_name(wallet_id, name)
|
|
996
|
+
print(f"Successfully set a new name for DID wallet with id {wallet_id}: {name}")
|
|
997
|
+
except Exception as e:
|
|
998
|
+
print(f"Failed to set DID wallet name: {e}")
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
async def get_did(
|
|
1002
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], did_wallet_id: int
|
|
1003
|
+
) -> None:
|
|
1004
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1005
|
+
try:
|
|
1006
|
+
response = await wallet_client.get_did_id(did_wallet_id)
|
|
1007
|
+
my_did = response["my_did"]
|
|
1008
|
+
coin_id = response["coin_id"]
|
|
1009
|
+
print(f"{'DID:'.ljust(23)} {my_did}")
|
|
1010
|
+
print(f"{'Coin ID:'.ljust(23)} {coin_id}")
|
|
1011
|
+
except Exception as e:
|
|
1012
|
+
print(f"Failed to get DID: {e}")
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
async def get_did_info(
|
|
1016
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], coin_id: str, latest: bool
|
|
1017
|
+
) -> None:
|
|
1018
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1019
|
+
did_padding_length = 23
|
|
1020
|
+
try:
|
|
1021
|
+
response = await wallet_client.get_did_info(coin_id, latest)
|
|
1022
|
+
print(f"{'DID:'.ljust(did_padding_length)} {response['did_id']}")
|
|
1023
|
+
print(f"{'Coin ID:'.ljust(did_padding_length)} {response['latest_coin']}")
|
|
1024
|
+
print(f"{'Inner P2 Address:'.ljust(did_padding_length)} {response['p2_address']}")
|
|
1025
|
+
print(f"{'Public Key:'.ljust(did_padding_length)} {response['public_key']}")
|
|
1026
|
+
print(f"{'Launcher ID:'.ljust(did_padding_length)} {response['launcher_id']}")
|
|
1027
|
+
print(f"{'DID Metadata:'.ljust(did_padding_length)} {response['metadata']}")
|
|
1028
|
+
print(f"{'Recovery List Hash:'.ljust(did_padding_length)} {response['recovery_list_hash']}")
|
|
1029
|
+
print(f"{'Recovery Required Verifications:'.ljust(did_padding_length)} {response['num_verification']}")
|
|
1030
|
+
print(f"{'Last Spend Puzzle:'.ljust(did_padding_length)} {response['full_puzzle']}")
|
|
1031
|
+
print(f"{'Last Spend Solution:'.ljust(did_padding_length)} {response['solution']}")
|
|
1032
|
+
print(f"{'Last Spend Hints:'.ljust(did_padding_length)} {response['hints']}")
|
|
1033
|
+
|
|
1034
|
+
except Exception as e:
|
|
1035
|
+
print(f"Failed to get DID details: {e}")
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
async def update_did_metadata(
|
|
1039
|
+
root_path: pathlib.Path,
|
|
1040
|
+
wallet_rpc_port: Optional[int],
|
|
1041
|
+
fp: Optional[int],
|
|
1042
|
+
did_wallet_id: int,
|
|
1043
|
+
metadata: str,
|
|
1044
|
+
reuse_puzhash: bool,
|
|
1045
|
+
push: bool,
|
|
1046
|
+
condition_valid_times: ConditionValidTimes,
|
|
1047
|
+
) -> list[TransactionRecord]:
|
|
1048
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1049
|
+
try:
|
|
1050
|
+
response = await wallet_client.update_did_metadata(
|
|
1051
|
+
did_wallet_id,
|
|
1052
|
+
json.loads(metadata),
|
|
1053
|
+
tx_config=CMDTXConfigLoader(
|
|
1054
|
+
reuse_puzhash=reuse_puzhash,
|
|
1055
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1056
|
+
push=push,
|
|
1057
|
+
timelock_info=condition_valid_times,
|
|
1058
|
+
)
|
|
1059
|
+
if push:
|
|
1060
|
+
print(
|
|
1061
|
+
f"Successfully updated DID wallet ID: {response.wallet_id}, "
|
|
1062
|
+
f"Spend Bundle: {response.spend_bundle.to_json_dict()}"
|
|
1063
|
+
)
|
|
1064
|
+
return response.transactions
|
|
1065
|
+
except Exception as e:
|
|
1066
|
+
print(f"Failed to update DID metadata: {e}")
|
|
1067
|
+
return []
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
async def did_message_spend(
|
|
1071
|
+
root_path: pathlib.Path,
|
|
1072
|
+
wallet_rpc_port: Optional[int],
|
|
1073
|
+
fp: Optional[int],
|
|
1074
|
+
did_wallet_id: int,
|
|
1075
|
+
puzzle_announcements: list[str],
|
|
1076
|
+
coin_announcements: list[str],
|
|
1077
|
+
push: bool,
|
|
1078
|
+
condition_valid_times: ConditionValidTimes,
|
|
1079
|
+
) -> list[TransactionRecord]:
|
|
1080
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1081
|
+
try:
|
|
1082
|
+
response = await wallet_client.did_message_spend(
|
|
1083
|
+
did_wallet_id,
|
|
1084
|
+
CMDTXConfigLoader().to_tx_config(units["chia"], config, fingerprint),
|
|
1085
|
+
extra_conditions=(
|
|
1086
|
+
*(CreateCoinAnnouncement(hexstr_to_bytes(ca)) for ca in coin_announcements),
|
|
1087
|
+
*(CreatePuzzleAnnouncement(hexstr_to_bytes(pa)) for pa in puzzle_announcements),
|
|
1088
|
+
),
|
|
1089
|
+
push=push,
|
|
1090
|
+
timelock_info=condition_valid_times,
|
|
1091
|
+
)
|
|
1092
|
+
print(f"Message Spend Bundle: {response.spend_bundle.to_json_dict()}")
|
|
1093
|
+
return response.transactions
|
|
1094
|
+
except Exception as e:
|
|
1095
|
+
print(f"Failed to update DID metadata: {e}")
|
|
1096
|
+
return []
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
async def transfer_did(
|
|
1100
|
+
root_path: pathlib.Path,
|
|
1101
|
+
wallet_rpc_port: Optional[int],
|
|
1102
|
+
fp: Optional[int],
|
|
1103
|
+
did_wallet_id: int,
|
|
1104
|
+
fee: uint64,
|
|
1105
|
+
target_cli_address: CliAddress,
|
|
1106
|
+
with_recovery: bool,
|
|
1107
|
+
reuse_puzhash: Optional[bool],
|
|
1108
|
+
push: bool,
|
|
1109
|
+
condition_valid_times: ConditionValidTimes,
|
|
1110
|
+
) -> list[TransactionRecord]:
|
|
1111
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1112
|
+
try:
|
|
1113
|
+
target_address = target_cli_address.original_address
|
|
1114
|
+
response = await wallet_client.did_transfer_did(
|
|
1115
|
+
did_wallet_id,
|
|
1116
|
+
target_address,
|
|
1117
|
+
fee,
|
|
1118
|
+
with_recovery,
|
|
1119
|
+
tx_config=CMDTXConfigLoader(
|
|
1120
|
+
reuse_puzhash=reuse_puzhash,
|
|
1121
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1122
|
+
push=push,
|
|
1123
|
+
timelock_info=condition_valid_times,
|
|
1124
|
+
)
|
|
1125
|
+
if push:
|
|
1126
|
+
print(f"Successfully transferred DID to {target_address}")
|
|
1127
|
+
print(f"Transaction ID: {response.transaction_id.hex()}")
|
|
1128
|
+
print(f"Transaction: {response.transaction.to_json_dict_convenience(config)}")
|
|
1129
|
+
return response.transactions
|
|
1130
|
+
except Exception as e:
|
|
1131
|
+
print(f"Failed to transfer DID: {e}")
|
|
1132
|
+
return []
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
async def find_lost_did(
|
|
1136
|
+
*,
|
|
1137
|
+
root_path: pathlib.Path,
|
|
1138
|
+
wallet_rpc_port: Optional[int],
|
|
1139
|
+
fp: Optional[int],
|
|
1140
|
+
coin_id: str,
|
|
1141
|
+
metadata: Optional[Any],
|
|
1142
|
+
recovery_list_hash: Optional[str],
|
|
1143
|
+
num_verification: Optional[int],
|
|
1144
|
+
) -> None:
|
|
1145
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1146
|
+
try:
|
|
1147
|
+
response = await wallet_client.find_lost_did(
|
|
1148
|
+
coin_id,
|
|
1149
|
+
recovery_list_hash,
|
|
1150
|
+
metadata,
|
|
1151
|
+
num_verification,
|
|
1152
|
+
)
|
|
1153
|
+
if response["success"]:
|
|
1154
|
+
print(f"Successfully found lost DID {coin_id}, latest coin ID: {response['latest_coin_id']}")
|
|
1155
|
+
else:
|
|
1156
|
+
print(f"Cannot find lost DID {coin_id}: {response['error']}")
|
|
1157
|
+
except Exception as e:
|
|
1158
|
+
print(f"Failed to find lost DID: {e}")
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
async def create_nft_wallet(
|
|
1162
|
+
root_path: pathlib.Path,
|
|
1163
|
+
wallet_rpc_port: Optional[int],
|
|
1164
|
+
fp: Optional[int],
|
|
1165
|
+
did_id: Optional[CliAddress] = None,
|
|
1166
|
+
name: Optional[str] = None,
|
|
1167
|
+
) -> None:
|
|
1168
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, _):
|
|
1169
|
+
try:
|
|
1170
|
+
response = await wallet_client.create_new_nft_wallet(did_id.original_address if did_id else None, name)
|
|
1171
|
+
wallet_id = response["wallet_id"]
|
|
1172
|
+
print(f"Successfully created an NFT wallet with id {wallet_id} on key {fingerprint}")
|
|
1173
|
+
except Exception as e:
|
|
1174
|
+
print(f"Failed to create NFT wallet: {e}")
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
async def mint_nft(
|
|
1178
|
+
*,
|
|
1179
|
+
root_path: pathlib.Path,
|
|
1180
|
+
wallet_rpc_port: Optional[int],
|
|
1181
|
+
fp: Optional[int],
|
|
1182
|
+
wallet_id: int,
|
|
1183
|
+
royalty_cli_address: Optional[CliAddress],
|
|
1184
|
+
target_cli_address: Optional[CliAddress],
|
|
1185
|
+
no_did_ownership: bool,
|
|
1186
|
+
hash: str,
|
|
1187
|
+
uris: list[str],
|
|
1188
|
+
metadata_hash: Optional[str],
|
|
1189
|
+
metadata_uris: list[str],
|
|
1190
|
+
license_hash: Optional[str],
|
|
1191
|
+
license_uris: list[str],
|
|
1192
|
+
edition_total: Optional[int],
|
|
1193
|
+
edition_number: Optional[int],
|
|
1194
|
+
fee: uint64,
|
|
1195
|
+
royalty_percentage: int,
|
|
1196
|
+
reuse_puzhash: Optional[bool],
|
|
1197
|
+
push: bool,
|
|
1198
|
+
condition_valid_times: ConditionValidTimes,
|
|
1199
|
+
) -> list[TransactionRecord]:
|
|
1200
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1201
|
+
royalty_address = royalty_cli_address.validate_address_type(AddressType.XCH) if royalty_cli_address else None
|
|
1202
|
+
target_address = target_cli_address.validate_address_type(AddressType.XCH) if target_cli_address else None
|
|
1203
|
+
try:
|
|
1204
|
+
response = await wallet_client.get_nft_wallet_did(wallet_id)
|
|
1205
|
+
wallet_did = response["did_id"]
|
|
1206
|
+
wallet_has_did = wallet_did is not None
|
|
1207
|
+
did_id: Optional[str] = wallet_did
|
|
1208
|
+
# Handle the case when the user wants to disable DID ownership
|
|
1209
|
+
if no_did_ownership:
|
|
1210
|
+
if wallet_has_did:
|
|
1211
|
+
raise ValueError("Disabling DID ownership is not supported for this NFT wallet, it does have a DID")
|
|
1212
|
+
else:
|
|
1213
|
+
did_id = None
|
|
1214
|
+
else:
|
|
1215
|
+
if not wallet_has_did:
|
|
1216
|
+
did_id = ""
|
|
1217
|
+
|
|
1218
|
+
mint_response = await wallet_client.mint_nft(
|
|
1219
|
+
wallet_id,
|
|
1220
|
+
royalty_address,
|
|
1221
|
+
target_address,
|
|
1222
|
+
hash,
|
|
1223
|
+
uris,
|
|
1224
|
+
CMDTXConfigLoader(
|
|
1225
|
+
reuse_puzhash=reuse_puzhash,
|
|
1226
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1227
|
+
metadata_hash,
|
|
1228
|
+
metadata_uris,
|
|
1229
|
+
license_hash,
|
|
1230
|
+
license_uris,
|
|
1231
|
+
edition_total,
|
|
1232
|
+
edition_number,
|
|
1233
|
+
fee,
|
|
1234
|
+
royalty_percentage,
|
|
1235
|
+
did_id,
|
|
1236
|
+
push=push,
|
|
1237
|
+
timelock_info=condition_valid_times,
|
|
1238
|
+
)
|
|
1239
|
+
spend_bundle = mint_response.spend_bundle
|
|
1240
|
+
if push:
|
|
1241
|
+
print(f"NFT minted Successfully with spend bundle: {spend_bundle}")
|
|
1242
|
+
return mint_response.transactions
|
|
1243
|
+
except Exception as e:
|
|
1244
|
+
print(f"Failed to mint NFT: {e}")
|
|
1245
|
+
return []
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
async def add_uri_to_nft(
|
|
1249
|
+
*,
|
|
1250
|
+
root_path: pathlib.Path,
|
|
1251
|
+
wallet_rpc_port: Optional[int],
|
|
1252
|
+
fp: Optional[int],
|
|
1253
|
+
wallet_id: int,
|
|
1254
|
+
fee: uint64,
|
|
1255
|
+
nft_coin_id: str,
|
|
1256
|
+
uri: Optional[str],
|
|
1257
|
+
metadata_uri: Optional[str],
|
|
1258
|
+
license_uri: Optional[str],
|
|
1259
|
+
reuse_puzhash: Optional[bool],
|
|
1260
|
+
push: bool,
|
|
1261
|
+
condition_valid_times: ConditionValidTimes,
|
|
1262
|
+
) -> list[TransactionRecord]:
|
|
1263
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1264
|
+
try:
|
|
1265
|
+
if len([x for x in (uri, metadata_uri, license_uri) if x is not None]) > 1:
|
|
1266
|
+
raise ValueError("You must provide only one of the URI flags")
|
|
1267
|
+
if uri is not None and len(uri) > 0:
|
|
1268
|
+
key = "u"
|
|
1269
|
+
uri_value = uri
|
|
1270
|
+
elif metadata_uri is not None and len(metadata_uri) > 0:
|
|
1271
|
+
key = "mu"
|
|
1272
|
+
uri_value = metadata_uri
|
|
1273
|
+
elif license_uri is not None and len(license_uri) > 0:
|
|
1274
|
+
key = "lu"
|
|
1275
|
+
uri_value = license_uri
|
|
1276
|
+
else:
|
|
1277
|
+
raise ValueError("You must provide at least one of the URI flags")
|
|
1278
|
+
response = await wallet_client.add_uri_to_nft(
|
|
1279
|
+
wallet_id,
|
|
1280
|
+
nft_coin_id,
|
|
1281
|
+
key,
|
|
1282
|
+
uri_value,
|
|
1283
|
+
fee,
|
|
1284
|
+
tx_config=CMDTXConfigLoader(
|
|
1285
|
+
reuse_puzhash=reuse_puzhash,
|
|
1286
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1287
|
+
push=push,
|
|
1288
|
+
timelock_info=condition_valid_times,
|
|
1289
|
+
)
|
|
1290
|
+
spend_bundle = response.spend_bundle.to_json_dict()
|
|
1291
|
+
if push:
|
|
1292
|
+
print(f"URI added successfully with spend bundle: {spend_bundle}")
|
|
1293
|
+
return response.transactions
|
|
1294
|
+
except Exception as e:
|
|
1295
|
+
print(f"Failed to add URI to NFT: {e}")
|
|
1296
|
+
return []
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
async def transfer_nft(
|
|
1300
|
+
*,
|
|
1301
|
+
root_path: pathlib.Path,
|
|
1302
|
+
wallet_rpc_port: Optional[int],
|
|
1303
|
+
fp: Optional[int],
|
|
1304
|
+
wallet_id: int,
|
|
1305
|
+
fee: uint64,
|
|
1306
|
+
nft_coin_id: str,
|
|
1307
|
+
target_cli_address: CliAddress,
|
|
1308
|
+
reuse_puzhash: Optional[bool],
|
|
1309
|
+
push: bool,
|
|
1310
|
+
condition_valid_times: ConditionValidTimes,
|
|
1311
|
+
) -> list[TransactionRecord]:
|
|
1312
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1313
|
+
try:
|
|
1314
|
+
target_address = target_cli_address.validate_address_type(AddressType.XCH)
|
|
1315
|
+
response = await wallet_client.transfer_nft(
|
|
1316
|
+
wallet_id,
|
|
1317
|
+
nft_coin_id,
|
|
1318
|
+
target_address,
|
|
1319
|
+
fee,
|
|
1320
|
+
tx_config=CMDTXConfigLoader(
|
|
1321
|
+
reuse_puzhash=reuse_puzhash,
|
|
1322
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1323
|
+
push=push,
|
|
1324
|
+
timelock_info=condition_valid_times,
|
|
1325
|
+
)
|
|
1326
|
+
spend_bundle = response.spend_bundle.to_json_dict()
|
|
1327
|
+
if push:
|
|
1328
|
+
print("NFT transferred successfully")
|
|
1329
|
+
print(f"spend bundle: {spend_bundle}")
|
|
1330
|
+
return response.transactions
|
|
1331
|
+
except Exception as e:
|
|
1332
|
+
print(f"Failed to transfer NFT: {e}")
|
|
1333
|
+
return []
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
def print_nft_info(nft: NFTInfo, *, config: dict[str, Any]) -> None:
|
|
1337
|
+
indent: str = " "
|
|
1338
|
+
owner_did = None if nft.owner_did is None else encode_puzzle_hash(nft.owner_did, AddressType.DID.hrp(config))
|
|
1339
|
+
minter_did = None if nft.minter_did is None else encode_puzzle_hash(nft.minter_did, AddressType.DID.hrp(config))
|
|
1340
|
+
print()
|
|
1341
|
+
print(f"{'NFT identifier:'.ljust(26)} {encode_puzzle_hash(nft.launcher_id, AddressType.NFT.hrp(config))}")
|
|
1342
|
+
print(f"{'Launcher coin ID:'.ljust(26)} {nft.launcher_id}")
|
|
1343
|
+
print(f"{'Launcher puzhash:'.ljust(26)} {nft.launcher_puzhash}")
|
|
1344
|
+
print(f"{'Current NFT coin ID:'.ljust(26)} {nft.nft_coin_id}")
|
|
1345
|
+
print(f"{'On-chain data/info:'.ljust(26)} {nft.chain_info}")
|
|
1346
|
+
print(f"{'Owner DID:'.ljust(26)} {owner_did}")
|
|
1347
|
+
print(f"{'Minter DID:'.ljust(26)} {minter_did}")
|
|
1348
|
+
print(f"{'Royalty percentage:'.ljust(26)} {nft.royalty_percentage}")
|
|
1349
|
+
print(f"{'Royalty puzhash:'.ljust(26)} {nft.royalty_puzzle_hash}")
|
|
1350
|
+
print(f"{'NFT content hash:'.ljust(26)} {nft.data_hash.hex()}")
|
|
1351
|
+
print(f"{'Metadata hash:'.ljust(26)} {nft.metadata_hash.hex()}")
|
|
1352
|
+
print(f"{'License hash:'.ljust(26)} {nft.license_hash.hex()}")
|
|
1353
|
+
print(f"{'NFT edition total:'.ljust(26)} {nft.edition_total}")
|
|
1354
|
+
print(f"{'Current NFT number in the edition:'.ljust(26)} {nft.edition_number}")
|
|
1355
|
+
print(f"{'Metadata updater puzhash:'.ljust(26)} {nft.updater_puzhash}")
|
|
1356
|
+
print(f"{'NFT minting block height:'.ljust(26)} {nft.mint_height}")
|
|
1357
|
+
print(f"{'Inner puzzle supports DID:'.ljust(26)} {nft.supports_did}")
|
|
1358
|
+
print(f"{'NFT is pending for a transaction:'.ljust(26)} {nft.pending_transaction}")
|
|
1359
|
+
print()
|
|
1360
|
+
print("URIs:")
|
|
1361
|
+
for uri in nft.data_uris:
|
|
1362
|
+
print(f"{indent}{uri}")
|
|
1363
|
+
print()
|
|
1364
|
+
print("Metadata URIs:")
|
|
1365
|
+
for metadata_uri in nft.metadata_uris:
|
|
1366
|
+
print(f"{indent}{metadata_uri}")
|
|
1367
|
+
print()
|
|
1368
|
+
print("License URIs:")
|
|
1369
|
+
for license_uri in nft.license_uris:
|
|
1370
|
+
print(f"{indent}{license_uri}")
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
async def list_nfts(
|
|
1374
|
+
root_path: pathlib.Path,
|
|
1375
|
+
wallet_rpc_port: Optional[int],
|
|
1376
|
+
fp: Optional[int],
|
|
1377
|
+
wallet_id: int,
|
|
1378
|
+
num: int,
|
|
1379
|
+
start_index: int,
|
|
1380
|
+
) -> None:
|
|
1381
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1382
|
+
try:
|
|
1383
|
+
response = await wallet_client.list_nfts(wallet_id, num, start_index)
|
|
1384
|
+
nft_list = response["nft_list"]
|
|
1385
|
+
if len(nft_list) > 0:
|
|
1386
|
+
for n in nft_list:
|
|
1387
|
+
nft = NFTInfo.from_json_dict(n)
|
|
1388
|
+
print_nft_info(nft, config=config)
|
|
1389
|
+
else:
|
|
1390
|
+
print(f"No NFTs found for wallet with id {wallet_id} on key {fingerprint}")
|
|
1391
|
+
except Exception as e:
|
|
1392
|
+
print(f"Failed to list NFTs for wallet with id {wallet_id} on key {fingerprint}: {e}")
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
async def set_nft_did(
|
|
1396
|
+
*,
|
|
1397
|
+
root_path: pathlib.Path,
|
|
1398
|
+
wallet_rpc_port: Optional[int],
|
|
1399
|
+
fp: Optional[int],
|
|
1400
|
+
wallet_id: int,
|
|
1401
|
+
fee: uint64,
|
|
1402
|
+
nft_coin_id: str,
|
|
1403
|
+
did_id: str,
|
|
1404
|
+
reuse_puzhash: Optional[bool],
|
|
1405
|
+
push: bool,
|
|
1406
|
+
condition_valid_times: ConditionValidTimes,
|
|
1407
|
+
) -> list[TransactionRecord]:
|
|
1408
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1409
|
+
try:
|
|
1410
|
+
response = await wallet_client.set_nft_did(
|
|
1411
|
+
wallet_id,
|
|
1412
|
+
did_id,
|
|
1413
|
+
nft_coin_id,
|
|
1414
|
+
fee,
|
|
1415
|
+
tx_config=CMDTXConfigLoader(
|
|
1416
|
+
reuse_puzhash=reuse_puzhash,
|
|
1417
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1418
|
+
push=push,
|
|
1419
|
+
timelock_info=condition_valid_times,
|
|
1420
|
+
)
|
|
1421
|
+
spend_bundle = response.spend_bundle.to_json_dict()
|
|
1422
|
+
print(f"Transaction to set DID on NFT has been initiated with: {spend_bundle}")
|
|
1423
|
+
return response.transactions
|
|
1424
|
+
except Exception as e:
|
|
1425
|
+
print(f"Failed to set DID on NFT: {e}")
|
|
1426
|
+
return []
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
async def get_nft_info(
|
|
1430
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], nft_coin_id: str
|
|
1431
|
+
) -> None:
|
|
1432
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, config):
|
|
1433
|
+
try:
|
|
1434
|
+
response = await wallet_client.get_nft_info(nft_coin_id)
|
|
1435
|
+
nft_info = NFTInfo.from_json_dict(response["nft_info"])
|
|
1436
|
+
print_nft_info(nft_info, config=config)
|
|
1437
|
+
except Exception as e:
|
|
1438
|
+
print(f"Failed to get NFT info: {e}")
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
async def get_nft_royalty_percentage_and_address(
|
|
1442
|
+
nft_coin_id: bytes32, wallet_client: WalletRpcClient
|
|
1443
|
+
) -> tuple[uint16, bytes32]:
|
|
1444
|
+
info = NFTInfo.from_json_dict((await wallet_client.get_nft_info(nft_coin_id.hex()))["nft_info"])
|
|
1445
|
+
assert info.royalty_puzzle_hash is not None
|
|
1446
|
+
percentage = uint16(info.royalty_percentage) if info.royalty_percentage is not None else 0
|
|
1447
|
+
return uint16(percentage), info.royalty_puzzle_hash
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
def calculate_nft_royalty_amount(
|
|
1451
|
+
offered: dict[str, Any], requested: dict[str, Any], nft_coin_id: bytes32, nft_royalty_percentage: int
|
|
1452
|
+
) -> tuple[str, int, int]:
|
|
1453
|
+
nft_asset_id = nft_coin_id.hex()
|
|
1454
|
+
amount_dict: dict[str, Any] = requested if nft_asset_id in offered else offered
|
|
1455
|
+
amounts: list[tuple[str, int]] = list(amount_dict.items())
|
|
1456
|
+
|
|
1457
|
+
if len(amounts) != 1 or not isinstance(amounts[0][1], int):
|
|
1458
|
+
raise ValueError("Royalty enabled NFTs only support offering/requesting one NFT for one currency")
|
|
1459
|
+
|
|
1460
|
+
royalty_amount: uint64 = uint64(amounts[0][1] * nft_royalty_percentage / 10000)
|
|
1461
|
+
royalty_asset_id = amounts[0][0]
|
|
1462
|
+
total_amount_requested = (requested[royalty_asset_id] if amount_dict == requested else 0) + royalty_amount
|
|
1463
|
+
return royalty_asset_id, royalty_amount, total_amount_requested
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
def driver_dict_asset_is_nft_supporting_royalties(driver_dict: dict[bytes32, PuzzleInfo], asset_id: bytes32) -> bool:
|
|
1467
|
+
asset_dict: PuzzleInfo = driver_dict[asset_id]
|
|
1468
|
+
return asset_dict.check_type(
|
|
1469
|
+
[
|
|
1470
|
+
AssetType.SINGLETON.value,
|
|
1471
|
+
AssetType.METADATA.value,
|
|
1472
|
+
AssetType.OWNERSHIP.value,
|
|
1473
|
+
]
|
|
1474
|
+
)
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
def driver_dict_asset_is_fungible(driver_dict: dict[bytes32, PuzzleInfo], asset_id: bytes32) -> bool:
|
|
1478
|
+
asset_dict: PuzzleInfo = driver_dict[asset_id]
|
|
1479
|
+
return not asset_dict.check_type(
|
|
1480
|
+
[
|
|
1481
|
+
AssetType.SINGLETON.value,
|
|
1482
|
+
]
|
|
1483
|
+
)
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
def nft_coin_ids_supporting_royalties_from_offer(offer: Offer) -> list[bytes32]:
|
|
1487
|
+
return [
|
|
1488
|
+
key for key in offer.driver_dict.keys() if driver_dict_asset_is_nft_supporting_royalties(offer.driver_dict, key)
|
|
1489
|
+
]
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
def fungible_assets_from_offer(offer: Offer) -> list[Optional[bytes32]]:
|
|
1493
|
+
return [
|
|
1494
|
+
asset for asset in offer.arbitrage() if asset is None or driver_dict_asset_is_fungible(offer.driver_dict, asset)
|
|
1495
|
+
]
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
async def send_notification(
|
|
1499
|
+
root_path: pathlib.Path,
|
|
1500
|
+
wallet_rpc_port: Optional[int],
|
|
1501
|
+
fp: Optional[int],
|
|
1502
|
+
fee: uint64,
|
|
1503
|
+
address: CliAddress,
|
|
1504
|
+
message: bytes,
|
|
1505
|
+
cli_amount: CliAmount,
|
|
1506
|
+
push: bool,
|
|
1507
|
+
condition_valid_times: ConditionValidTimes,
|
|
1508
|
+
) -> list[TransactionRecord]:
|
|
1509
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, _):
|
|
1510
|
+
amount: uint64 = cli_amount.convert_amount(units["chia"])
|
|
1511
|
+
|
|
1512
|
+
tx = await wallet_client.send_notification(
|
|
1513
|
+
address.puzzle_hash,
|
|
1514
|
+
message,
|
|
1515
|
+
amount,
|
|
1516
|
+
fee,
|
|
1517
|
+
push=push,
|
|
1518
|
+
timelock_info=condition_valid_times,
|
|
1519
|
+
)
|
|
1520
|
+
|
|
1521
|
+
if push:
|
|
1522
|
+
print("Notification sent successfully.")
|
|
1523
|
+
print(f"To get status, use command: chia wallet get_transaction -f {fingerprint} -tx 0x{tx.name}")
|
|
1524
|
+
return [tx]
|
|
1525
|
+
|
|
1526
|
+
|
|
1527
|
+
async def get_notifications(
|
|
1528
|
+
root_path: pathlib.Path,
|
|
1529
|
+
wallet_rpc_port: Optional[int],
|
|
1530
|
+
fp: Optional[int],
|
|
1531
|
+
ids: Optional[Sequence[bytes32]],
|
|
1532
|
+
start: Optional[int],
|
|
1533
|
+
end: Optional[int],
|
|
1534
|
+
) -> None:
|
|
1535
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1536
|
+
if ids is not None:
|
|
1537
|
+
ids = None if len(ids) == 0 else list(ids)
|
|
1538
|
+
response = await wallet_client.get_notifications(
|
|
1539
|
+
GetNotifications(ids=ids, start=uint32.construct_optional(start), end=uint32.construct_optional(end))
|
|
1540
|
+
)
|
|
1541
|
+
for notification in response.notifications:
|
|
1542
|
+
print("")
|
|
1543
|
+
print(f"ID: {notification.id.hex()}")
|
|
1544
|
+
print(f"message: {notification.message.decode('utf-8')}")
|
|
1545
|
+
print(f"amount: {notification.amount}")
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
async def delete_notifications(
|
|
1549
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], ids: Sequence[bytes32], delete_all: bool
|
|
1550
|
+
) -> None:
|
|
1551
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1552
|
+
if delete_all:
|
|
1553
|
+
print(f"Success: {await wallet_client.delete_notifications()}")
|
|
1554
|
+
else:
|
|
1555
|
+
print(f"Success: {await wallet_client.delete_notifications(ids=list(ids))}")
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
async def sign_message(
|
|
1559
|
+
*,
|
|
1560
|
+
root_path: pathlib.Path,
|
|
1561
|
+
wallet_rpc_port: Optional[int],
|
|
1562
|
+
fp: Optional[int],
|
|
1563
|
+
addr_type: AddressType,
|
|
1564
|
+
message: str,
|
|
1565
|
+
address: Optional[CliAddress] = None,
|
|
1566
|
+
did_id: Optional[CliAddress] = None,
|
|
1567
|
+
nft_id: Optional[CliAddress] = None,
|
|
1568
|
+
) -> None:
|
|
1569
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1570
|
+
if addr_type == AddressType.XCH:
|
|
1571
|
+
if address is None:
|
|
1572
|
+
print("Address is required for XCH address type.")
|
|
1573
|
+
return
|
|
1574
|
+
pubkey, signature, signing_mode = await wallet_client.sign_message_by_address(
|
|
1575
|
+
address.original_address, message
|
|
1576
|
+
)
|
|
1577
|
+
elif addr_type == AddressType.DID:
|
|
1578
|
+
if did_id is None:
|
|
1579
|
+
print("DID id is required for DID address type.")
|
|
1580
|
+
return
|
|
1581
|
+
pubkey, signature, signing_mode = await wallet_client.sign_message_by_id(did_id.original_address, message)
|
|
1582
|
+
elif addr_type == AddressType.NFT:
|
|
1583
|
+
if nft_id is None:
|
|
1584
|
+
print("NFT id is required for NFT address type.")
|
|
1585
|
+
return
|
|
1586
|
+
pubkey, signature, signing_mode = await wallet_client.sign_message_by_id(nft_id.original_address, message)
|
|
1587
|
+
else:
|
|
1588
|
+
print("Invalid wallet type.")
|
|
1589
|
+
return
|
|
1590
|
+
print("")
|
|
1591
|
+
print(f"Message: {message}")
|
|
1592
|
+
print(f"Public Key: {pubkey}")
|
|
1593
|
+
print(f"Signature: {signature}")
|
|
1594
|
+
print(f"Signing Mode: {signing_mode}")
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
async def spend_clawback(
|
|
1598
|
+
*,
|
|
1599
|
+
root_path: pathlib.Path,
|
|
1600
|
+
wallet_rpc_port: Optional[int],
|
|
1601
|
+
fp: Optional[int],
|
|
1602
|
+
fee: uint64,
|
|
1603
|
+
tx_ids_str: str,
|
|
1604
|
+
force: bool = False,
|
|
1605
|
+
push: bool,
|
|
1606
|
+
condition_valid_times: ConditionValidTimes,
|
|
1607
|
+
) -> list[TransactionRecord]:
|
|
1608
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1609
|
+
tx_ids = []
|
|
1610
|
+
for tid in tx_ids_str.split(","):
|
|
1611
|
+
tx_ids.append(bytes32.from_hexstr(tid))
|
|
1612
|
+
if len(tx_ids) == 0:
|
|
1613
|
+
print("Transaction ID is required.")
|
|
1614
|
+
return []
|
|
1615
|
+
if fee < 0:
|
|
1616
|
+
print("Batch fee cannot be negative.")
|
|
1617
|
+
return []
|
|
1618
|
+
response = await wallet_client.spend_clawback_coins(
|
|
1619
|
+
tx_ids,
|
|
1620
|
+
fee,
|
|
1621
|
+
force,
|
|
1622
|
+
push=push,
|
|
1623
|
+
timelock_info=condition_valid_times,
|
|
1624
|
+
)
|
|
1625
|
+
print(str(response))
|
|
1626
|
+
return [TransactionRecord.from_json_dict_convenience(tx) for tx in response["transactions"]]
|
|
1627
|
+
|
|
1628
|
+
|
|
1629
|
+
async def mint_vc(
|
|
1630
|
+
root_path: pathlib.Path,
|
|
1631
|
+
wallet_rpc_port: Optional[int],
|
|
1632
|
+
fp: Optional[int],
|
|
1633
|
+
did: CliAddress,
|
|
1634
|
+
fee: uint64,
|
|
1635
|
+
target_address: Optional[CliAddress],
|
|
1636
|
+
push: bool,
|
|
1637
|
+
condition_valid_times: ConditionValidTimes,
|
|
1638
|
+
) -> list[TransactionRecord]:
|
|
1639
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1640
|
+
res = await wallet_client.vc_mint(
|
|
1641
|
+
VCMint(
|
|
1642
|
+
did_id=did.validate_address_type(AddressType.DID),
|
|
1643
|
+
target_address=target_address.validate_address_type(AddressType.XCH) if target_address else None,
|
|
1644
|
+
fee=fee,
|
|
1645
|
+
push=push,
|
|
1646
|
+
),
|
|
1647
|
+
CMDTXConfigLoader().to_tx_config(units["chia"], config, fingerprint),
|
|
1648
|
+
timelock_info=condition_valid_times,
|
|
1649
|
+
)
|
|
1650
|
+
|
|
1651
|
+
if push:
|
|
1652
|
+
print(f"New VC with launcher ID minted: {res.vc_record.vc.launcher_id.hex()}")
|
|
1653
|
+
print("Relevant TX records:")
|
|
1654
|
+
print("")
|
|
1655
|
+
for tx in res.transactions:
|
|
1656
|
+
print_transaction(
|
|
1657
|
+
tx,
|
|
1658
|
+
verbose=False,
|
|
1659
|
+
name="XCH",
|
|
1660
|
+
address_prefix=selected_network_address_prefix(config),
|
|
1661
|
+
mojo_per_unit=get_mojo_per_unit(wallet_type=WalletType.STANDARD_WALLET),
|
|
1662
|
+
)
|
|
1663
|
+
return res.transactions
|
|
1664
|
+
|
|
1665
|
+
|
|
1666
|
+
async def get_vcs(
|
|
1667
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], start: int, count: int
|
|
1668
|
+
) -> None:
|
|
1669
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, config):
|
|
1670
|
+
get_list_response = await wallet_client.vc_get_list(VCGetList(uint32(start), uint32(count)))
|
|
1671
|
+
print("Proofs:")
|
|
1672
|
+
for hash, proof_dict in get_list_response.proof_dict.items():
|
|
1673
|
+
if proof_dict is not None:
|
|
1674
|
+
print(f"- {hash}")
|
|
1675
|
+
for proof in proof_dict:
|
|
1676
|
+
print(f" - {proof}")
|
|
1677
|
+
for record in get_list_response.vc_records:
|
|
1678
|
+
print("")
|
|
1679
|
+
print(f"Launcher ID: {record.vc.launcher_id.hex()}")
|
|
1680
|
+
print(f"Coin ID: {record.vc.coin.name().hex()}")
|
|
1681
|
+
print(
|
|
1682
|
+
f"Inner Address:"
|
|
1683
|
+
f" {encode_puzzle_hash(record.vc.inner_puzzle_hash, selected_network_address_prefix(config))}"
|
|
1684
|
+
)
|
|
1685
|
+
if record.vc.proof_hash is None:
|
|
1686
|
+
pass
|
|
1687
|
+
else:
|
|
1688
|
+
print(f"Proof Hash: {record.vc.proof_hash.hex()}")
|
|
1689
|
+
|
|
1690
|
+
|
|
1691
|
+
async def spend_vc(
|
|
1692
|
+
*,
|
|
1693
|
+
root_path: pathlib.Path,
|
|
1694
|
+
wallet_rpc_port: Optional[int],
|
|
1695
|
+
fp: Optional[int],
|
|
1696
|
+
vc_id: bytes32,
|
|
1697
|
+
fee: uint64,
|
|
1698
|
+
new_puzhash: Optional[bytes32],
|
|
1699
|
+
new_proof_hash: str,
|
|
1700
|
+
reuse_puzhash: bool,
|
|
1701
|
+
push: bool,
|
|
1702
|
+
condition_valid_times: ConditionValidTimes,
|
|
1703
|
+
) -> list[TransactionRecord]:
|
|
1704
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1705
|
+
txs = (
|
|
1706
|
+
await wallet_client.vc_spend(
|
|
1707
|
+
VCSpend(
|
|
1708
|
+
vc_id=vc_id,
|
|
1709
|
+
new_puzhash=new_puzhash,
|
|
1710
|
+
new_proof_hash=bytes32.from_hexstr(new_proof_hash),
|
|
1711
|
+
fee=fee,
|
|
1712
|
+
push=push,
|
|
1713
|
+
),
|
|
1714
|
+
tx_config=CMDTXConfigLoader(
|
|
1715
|
+
reuse_puzhash=reuse_puzhash,
|
|
1716
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1717
|
+
timelock_info=condition_valid_times,
|
|
1718
|
+
)
|
|
1719
|
+
).transactions
|
|
1720
|
+
|
|
1721
|
+
if push:
|
|
1722
|
+
print("Proofs successfully updated!")
|
|
1723
|
+
print("Relevant TX records:")
|
|
1724
|
+
print("")
|
|
1725
|
+
for tx in txs:
|
|
1726
|
+
print_transaction(
|
|
1727
|
+
tx,
|
|
1728
|
+
verbose=False,
|
|
1729
|
+
name="XCH",
|
|
1730
|
+
address_prefix=selected_network_address_prefix(config),
|
|
1731
|
+
mojo_per_unit=get_mojo_per_unit(wallet_type=WalletType.STANDARD_WALLET),
|
|
1732
|
+
)
|
|
1733
|
+
return txs
|
|
1734
|
+
|
|
1735
|
+
|
|
1736
|
+
async def add_proof_reveal(
|
|
1737
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], proofs: Sequence[str], root_only: bool
|
|
1738
|
+
) -> None:
|
|
1739
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1740
|
+
if len(proofs) == 0:
|
|
1741
|
+
print("Must specify at least one proof")
|
|
1742
|
+
return
|
|
1743
|
+
|
|
1744
|
+
proof_dict: dict[str, str] = {proof: "1" for proof in proofs}
|
|
1745
|
+
if root_only:
|
|
1746
|
+
print(f"Proof Hash: {VCProofs(proof_dict).root()}")
|
|
1747
|
+
return
|
|
1748
|
+
else:
|
|
1749
|
+
await wallet_client.vc_add_proofs(VCAddProofs.from_json_dict({"proofs": proof_dict}))
|
|
1750
|
+
print("Proofs added to DB successfully!")
|
|
1751
|
+
return
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
async def get_proofs_for_root(
|
|
1755
|
+
root_path: pathlib.Path, wallet_rpc_port: Optional[int], fp: Optional[int], proof_hash: str
|
|
1756
|
+
) -> None:
|
|
1757
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, _, _):
|
|
1758
|
+
proof_dict: dict[str, str] = (
|
|
1759
|
+
(await wallet_client.vc_get_proofs_for_root(VCGetProofsForRoot(bytes32.from_hexstr(proof_hash))))
|
|
1760
|
+
.to_vc_proofs()
|
|
1761
|
+
.key_value_pairs
|
|
1762
|
+
)
|
|
1763
|
+
print("Proofs:")
|
|
1764
|
+
for proof in proof_dict:
|
|
1765
|
+
print(f" - {proof}")
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
async def revoke_vc(
|
|
1769
|
+
root_path: pathlib.Path,
|
|
1770
|
+
wallet_rpc_port: Optional[int],
|
|
1771
|
+
fp: Optional[int],
|
|
1772
|
+
parent_coin_id: Optional[bytes32],
|
|
1773
|
+
vc_id: Optional[bytes32],
|
|
1774
|
+
fee: uint64,
|
|
1775
|
+
reuse_puzhash: bool,
|
|
1776
|
+
push: bool,
|
|
1777
|
+
condition_valid_times: ConditionValidTimes,
|
|
1778
|
+
) -> list[TransactionRecord]:
|
|
1779
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
|
|
1780
|
+
if parent_coin_id is None:
|
|
1781
|
+
if vc_id is None:
|
|
1782
|
+
print("Must specify either --parent-coin-id or --vc-id")
|
|
1783
|
+
return []
|
|
1784
|
+
record = (await wallet_client.vc_get(VCGet(vc_id))).vc_record
|
|
1785
|
+
if record is None:
|
|
1786
|
+
print(f"Cannot find a VC with ID {vc_id.hex()}")
|
|
1787
|
+
return []
|
|
1788
|
+
parent_id: bytes32 = bytes32(record.vc.coin.parent_coin_info)
|
|
1789
|
+
else:
|
|
1790
|
+
parent_id = parent_coin_id
|
|
1791
|
+
txs = (
|
|
1792
|
+
await wallet_client.vc_revoke(
|
|
1793
|
+
VCRevoke(
|
|
1794
|
+
vc_parent_id=parent_id,
|
|
1795
|
+
fee=fee,
|
|
1796
|
+
push=push,
|
|
1797
|
+
),
|
|
1798
|
+
tx_config=CMDTXConfigLoader(
|
|
1799
|
+
reuse_puzhash=reuse_puzhash,
|
|
1800
|
+
).to_tx_config(units["chia"], config, fingerprint),
|
|
1801
|
+
timelock_info=condition_valid_times,
|
|
1802
|
+
)
|
|
1803
|
+
).transactions
|
|
1804
|
+
|
|
1805
|
+
if push:
|
|
1806
|
+
print("VC successfully revoked!")
|
|
1807
|
+
print("Relevant TX records:")
|
|
1808
|
+
print("")
|
|
1809
|
+
for tx in txs:
|
|
1810
|
+
print_transaction(
|
|
1811
|
+
tx,
|
|
1812
|
+
verbose=False,
|
|
1813
|
+
name="XCH",
|
|
1814
|
+
address_prefix=selected_network_address_prefix(config),
|
|
1815
|
+
mojo_per_unit=get_mojo_per_unit(wallet_type=WalletType.STANDARD_WALLET),
|
|
1816
|
+
)
|
|
1817
|
+
return txs
|
|
1818
|
+
|
|
1819
|
+
|
|
1820
|
+
async def approve_r_cats(
|
|
1821
|
+
root_path: pathlib.Path,
|
|
1822
|
+
wallet_rpc_port: Optional[int],
|
|
1823
|
+
fingerprint: int,
|
|
1824
|
+
wallet_id: uint32,
|
|
1825
|
+
min_amount_to_claim: CliAmount,
|
|
1826
|
+
fee: uint64,
|
|
1827
|
+
min_coin_amount: CliAmount,
|
|
1828
|
+
max_coin_amount: CliAmount,
|
|
1829
|
+
reuse: bool,
|
|
1830
|
+
push: bool,
|
|
1831
|
+
condition_valid_times: ConditionValidTimes,
|
|
1832
|
+
) -> list[TransactionRecord]:
|
|
1833
|
+
async with get_wallet_client(root_path, wallet_rpc_port, fingerprint) as (wallet_client, fingerprint, config):
|
|
1834
|
+
if wallet_client is None:
|
|
1835
|
+
return
|
|
1836
|
+
txs = await wallet_client.crcat_approve_pending(
|
|
1837
|
+
wallet_id=wallet_id,
|
|
1838
|
+
min_amount_to_claim=min_amount_to_claim.convert_amount(units["cat"]),
|
|
1839
|
+
fee=fee,
|
|
1840
|
+
tx_config=CMDTXConfigLoader(
|
|
1841
|
+
min_coin_amount=min_coin_amount,
|
|
1842
|
+
max_coin_amount=max_coin_amount,
|
|
1843
|
+
reuse_puzhash=reuse,
|
|
1844
|
+
).to_tx_config(units["cat"], config, fingerprint),
|
|
1845
|
+
push=push,
|
|
1846
|
+
timelock_info=condition_valid_times,
|
|
1847
|
+
)
|
|
1848
|
+
|
|
1849
|
+
if push:
|
|
1850
|
+
print("VC successfully approved R-CATs!")
|
|
1851
|
+
print("Relevant TX records:")
|
|
1852
|
+
print("")
|
|
1853
|
+
for tx in txs:
|
|
1854
|
+
try:
|
|
1855
|
+
wallet_type = await get_wallet_type(wallet_id=tx.wallet_id, wallet_client=wallet_client)
|
|
1856
|
+
mojo_per_unit = get_mojo_per_unit(wallet_type=wallet_type)
|
|
1857
|
+
name = await get_unit_name_for_wallet_id(
|
|
1858
|
+
config=config,
|
|
1859
|
+
wallet_type=wallet_type,
|
|
1860
|
+
wallet_id=tx.wallet_id,
|
|
1861
|
+
wallet_client=wallet_client,
|
|
1862
|
+
)
|
|
1863
|
+
except LookupError as e:
|
|
1864
|
+
print(e.args[0])
|
|
1865
|
+
return txs
|
|
1866
|
+
|
|
1867
|
+
print_transaction(
|
|
1868
|
+
tx,
|
|
1869
|
+
verbose=False,
|
|
1870
|
+
name=name,
|
|
1871
|
+
address_prefix=selected_network_address_prefix(config),
|
|
1872
|
+
mojo_per_unit=mojo_per_unit,
|
|
1873
|
+
)
|
|
1874
|
+
return txs
|