diff --git a/chia/data_layer/data_layer_wallet.py b/chia/data_layer/data_layer_wallet.py index cbeeb527d9..b64e01b269 100644 --- a/chia/data_layer/data_layer_wallet.py +++ b/chia/data_layer/data_layer_wallet.py @@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Set, Tupl from blspy import G1Element, G2Element from clvm.EvalError import EvalError -from typing_extensions import final +from typing_extensions import Unpack, final from chia.consensus.block_record import BlockRecord from chia.data_layer.data_layer_errors import LauncherCoinNotFoundError, OfferIntegrityError @@ -56,6 +56,7 @@ from chia.wallet.util.wallet_types import WalletType from chia.wallet.wallet import Wallet from chia.wallet.wallet_coin_record import WalletCoinRecord from chia.wallet.wallet_info import WalletInfo +from chia.wallet.wallet_protocol import GSTOptionalArgs, WalletProtocol if TYPE_CHECKING: from chia.wallet.wallet_state_manager import WalletStateManager @@ -106,8 +107,6 @@ class Mirror: @final class DataLayerWallet: if TYPE_CHECKING: - from chia.wallet.wallet_protocol import WalletProtocol - _protocol_check: ClassVar[WalletProtocol] = cast("DataLayerWallet", None) wallet_state_manager: WalletStateManager @@ -627,13 +626,15 @@ class DataLayerWallet: coin_announcements_to_consume: Optional[Set[Announcement]] = None, puzzle_announcements_to_consume: Optional[Set[Announcement]] = None, ignore_max_send_amount: bool = False, # ignored - # This wallet only - launcher_id: Optional[bytes32] = None, - new_root_hash: Optional[bytes32] = None, - sign: bool = True, # This only prevent signing of THIS wallet's part of the tx (fee will still be signed) - add_pending_singleton: bool = True, - announce_new_state: bool = False, + **kwargs: Unpack[GSTOptionalArgs], ) -> List[TransactionRecord]: + launcher_id: Optional[bytes32] = kwargs.get("launcher_id", None) + new_root_hash: Optional[bytes32] = kwargs.get("new_root_hash", None) + sign: bool = kwargs.get( + "sign", True + ) # This only prevent signing of THIS wallet's part of the tx (fee will still be signed) + add_pending_singleton: bool = kwargs.get("add_pending_singleton", True) + announce_new_state: bool = kwargs.get("announce_new_state", False) # Figure out the launcher ID if len(coins) == 0: if launcher_id is None: diff --git a/chia/pools/pool_wallet.py b/chia/pools/pool_wallet.py index 217bceee59..052fd22919 100644 --- a/chia/pools/pool_wallet.py +++ b/chia/pools/pool_wallet.py @@ -681,11 +681,11 @@ class PoolWallet: amount, genesis_launcher_puz.get_tree_hash(), fee, - launcher_parent.name(), coins, None, False, announcement_set, + origin_id=launcher_parent.name(), ) assert create_launcher_tx_record is not None and create_launcher_tx_record.spend_bundle is not None diff --git a/chia/wallet/cat_wallet/cat_wallet.py b/chia/wallet/cat_wallet/cat_wallet.py index 66041ce12c..2468828d21 100644 --- a/chia/wallet/cat_wallet/cat_wallet.py +++ b/chia/wallet/cat_wallet/cat_wallet.py @@ -8,6 +8,7 @@ from secrets import token_bytes from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Set, Tuple, cast from blspy import AugSchemeMPL, G1Element, G2Element +from typing_extensions import Unpack from chia.consensus.cost_calculator import NPCResult from chia.full_node.bundle_tools import simple_solution_generator @@ -56,6 +57,7 @@ from chia.wallet.util.wallet_types import WalletType from chia.wallet.wallet import Wallet from chia.wallet.wallet_coin_record import WalletCoinRecord from chia.wallet.wallet_info import WalletInfo +from chia.wallet.wallet_protocol import GSTOptionalArgs, WalletProtocol if TYPE_CHECKING: from chia.wallet.wallet_state_manager import WalletStateManager @@ -69,8 +71,6 @@ QUOTED_MOD_HASH = calculate_hash_of_quoted_mod_hash(CAT_MOD_HASH) class CATWallet: if TYPE_CHECKING: - from chia.wallet.wallet_protocol import WalletProtocol - _protocol_check: ClassVar[WalletProtocol] = cast("CATWallet", None) wallet_state_manager: WalletStateManager @@ -819,10 +819,12 @@ class CATWallet: min_coin_amount: Optional[uint64] = None, max_coin_amount: Optional[uint64] = None, excluded_coin_amounts: Optional[List[uint64]] = None, - excluded_cat_coins: Optional[Set[Coin]] = None, - cat_discrepancy: Optional[Tuple[int, Program, Program]] = None, # (extra_delta, tail_reveal, tail_solution) reuse_puzhash: Optional[bool] = None, + **kwargs: Unpack[GSTOptionalArgs], ) -> List[TransactionRecord]: + excluded_cat_coins: Optional[Set[Coin]] = kwargs.get("excluded_cat_coins", None) + # (extra_delta, tail_reveal, tail_solution) + cat_discrepancy: Optional[Tuple[int, Program, Program]] = kwargs.get("cat_discrepancy", None) if memos is None: memos = [[] for _ in range(len(puzzle_hashes))] diff --git a/chia/wallet/did_wallet/did_wallet.py b/chia/wallet/did_wallet/did_wallet.py index eb7f87ca72..ab854ceec0 100644 --- a/chia/wallet/did_wallet/did_wallet.py +++ b/chia/wallet/did_wallet/did_wallet.py @@ -1236,7 +1236,14 @@ class DIDWallet: announcement_set.add(Announcement(launcher_coin.name(), announcement_message)) tx_record: Optional[TransactionRecord] = await self.standard_wallet.generate_signed_transaction( - amount, genesis_launcher_puz.get_tree_hash(), fee, origin.name(), coins, None, False, announcement_set + amount, + genesis_launcher_puz.get_tree_hash(), + fee, + coins, + None, + False, + announcement_set, + origin_id=origin.name(), ) genesis_launcher_solution = Program.to([did_puzzle_hash, amount, bytes(0x80)]) diff --git a/chia/wallet/nft_wallet/nft_wallet.py b/chia/wallet/nft_wallet/nft_wallet.py index d882b49887..38dbf87ad7 100644 --- a/chia/wallet/nft_wallet/nft_wallet.py +++ b/chia/wallet/nft_wallet/nft_wallet.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Set, Tupl from blspy import AugSchemeMPL, G1Element, G2Element from clvm.casts import int_from_bytes, int_to_bytes +from typing_extensions import Unpack import chia.wallet.singleton from chia.protocols.wallet_protocol import CoinState @@ -56,14 +57,13 @@ from chia.wallet.wallet import CHIP_0002_SIGN_MESSAGE_PREFIX, Wallet from chia.wallet.wallet_coin_record import WalletCoinRecord from chia.wallet.wallet_info import WalletInfo from chia.wallet.wallet_nft_store import WalletNftStore +from chia.wallet.wallet_protocol import GSTOptionalArgs, WalletProtocol _T_NFTWallet = TypeVar("_T_NFTWallet", bound="NFTWallet") class NFTWallet: if TYPE_CHECKING: - from chia.wallet.wallet_protocol import WalletProtocol - _protocol_check: ClassVar[WalletProtocol] = cast("NFTWallet", None) wallet_state_manager: Any @@ -401,11 +401,11 @@ class NFTWallet: uint64(amount), nft_puzzles.LAUNCHER_PUZZLE_HASH, fee, - origin.name(), coins, None, False, announcement_set, + origin_id=origin.name(), ) genesis_launcher_solution = Program.to([eve_fullpuz_hash, amount, []]) @@ -620,18 +620,19 @@ class NFTWallet: puzzle_hashes: List[bytes32], fee: uint64 = uint64(0), coins: Optional[Set[Coin]] = None, - nft_coin: Optional[NFTCoinInfo] = None, memos: Optional[List[List[bytes]]] = None, coin_announcements_to_consume: Optional[Set[Announcement]] = None, puzzle_announcements_to_consume: Optional[Set[Announcement]] = None, ignore_max_send_amount: bool = False, - new_owner: Optional[bytes] = None, - new_did_inner_hash: Optional[bytes] = None, - trade_prices_list: Optional[Program] = None, - additional_bundles: List[SpendBundle] = [], - metadata_update: Optional[Tuple[str, str]] = None, reuse_puzhash: Optional[bool] = None, + **kwargs: Unpack[GSTOptionalArgs], ) -> List[TransactionRecord]: + nft_coin: Optional[NFTCoinInfo] = kwargs.get("nft_coin", None) + new_owner: Optional[bytes] = kwargs.get("new_owner", None) + new_did_inner_hash: Optional[bytes] = kwargs.get("new_did_inner_hash", None) + trade_prices_list: Optional[Program] = kwargs.get("trade_prices_list", None) + additional_bundles: List[SpendBundle] = kwargs.get("additional_bundles", []) + metadata_update: Optional[Tuple[str, str]] = kwargs.get("metadata_update", None) if memos is None: memos = [[] for _ in range(len(puzzle_hashes))] diff --git a/chia/wallet/puzzles/tails.py b/chia/wallet/puzzles/tails.py index 83c3ab8a41..603c55b27c 100644 --- a/chia/wallet/puzzles/tails.py +++ b/chia/wallet/puzzles/tails.py @@ -86,7 +86,7 @@ class GenesisById(LimitationsProgram): minted_cat_puzzle_hash: bytes32 = construct_cat_puzzle(CAT_MOD, tail.get_tree_hash(), cat_inner).get_tree_hash() tx_record: TransactionRecord = await wallet.standard_wallet.generate_signed_transaction( - amount, minted_cat_puzzle_hash, uint64(0), origin_id, coins + amount, minted_cat_puzzle_hash, uint64(0), coins, origin_id=origin_id ) assert tx_record.spend_bundle is not None diff --git a/chia/wallet/vc_wallet/vc_wallet.py b/chia/wallet/vc_wallet/vc_wallet.py index 6b5cb127ac..abf1060bef 100644 --- a/chia/wallet/vc_wallet/vc_wallet.py +++ b/chia/wallet/vc_wallet/vc_wallet.py @@ -6,6 +6,7 @@ import time from typing import TYPE_CHECKING, List, Optional, Set, Tuple, Type, TypeVar, Union from blspy import G1Element, G2Element +from typing_extensions import Unpack from chia.protocols.wallet_protocol import CoinState from chia.server.ws_connection import WSChiaConnection @@ -30,6 +31,7 @@ from chia.wallet.vc_wallet.vc_store import VCRecord, VCStore from chia.wallet.wallet import Wallet from chia.wallet.wallet_coin_record import WalletCoinRecord from chia.wallet.wallet_info import WalletInfo +from chia.wallet.wallet_protocol import GSTOptionalArgs, WalletProtocol if TYPE_CHECKING: from chia.wallet.wallet_state_manager import WalletStateManager # pragma: no cover @@ -211,10 +213,13 @@ class VCWallet: puzzle_announcements: Optional[Set[bytes]] = None, coin_announcements_to_consume: Optional[Set[Announcement]] = None, puzzle_announcements_to_consume: Optional[Set[Announcement]] = None, - new_proof_hash: Optional[bytes32] = None, # Requires that this key posesses the DID to update the specified VC - provider_inner_puzhash: Optional[bytes32] = None, reuse_puzhash: Optional[bool] = None, + **kwargs: Unpack[GSTOptionalArgs], ) -> List[TransactionRecord]: + new_proof_hash: Optional[bytes32] = kwargs.get( + "new_proof_hash", None + ) # Requires that this key posesses the DID to update the specified VC + provider_inner_puzhash: Optional[bytes32] = kwargs.get("provider_inner_puzhash", None) """ Entry point for two standard actions: - Cycle the singleton and make an announcement authorizing something @@ -453,6 +458,4 @@ class VCWallet: if TYPE_CHECKING: - from chia.wallet.wallet_protocol import WalletProtocol # pragma: no cover - _dummy: WalletProtocol = VCWallet() # pragma: no cover diff --git a/chia/wallet/wallet.py b/chia/wallet/wallet.py index fa992c8d85..d4d6faa104 100644 --- a/chia/wallet/wallet.py +++ b/chia/wallet/wallet.py @@ -5,6 +5,7 @@ import time from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Set, Tuple, cast from blspy import AugSchemeMPL, G1Element, G2Element +from typing_extensions import Unpack from chia.consensus.cost_calculator import NPCResult from chia.full_node.bundle_tools import simple_solution_generator @@ -46,6 +47,7 @@ from chia.wallet.util.transaction_type import TransactionType from chia.wallet.util.wallet_types import WalletType from chia.wallet.wallet_coin_record import WalletCoinRecord from chia.wallet.wallet_info import WalletInfo +from chia.wallet.wallet_protocol import GSTOptionalArgs, WalletProtocol if TYPE_CHECKING: from chia.server.ws_connection import WSChiaConnection @@ -57,8 +59,6 @@ CHIP_0002_SIGN_MESSAGE_PREFIX = "Chia Signed Message" class Wallet: if TYPE_CHECKING: - from chia.wallet.wallet_protocol import WalletProtocol - _protocol_check: ClassVar[WalletProtocol] = cast("Wallet", None) wallet_info: WalletInfo @@ -485,21 +485,22 @@ class Wallet: amount: uint64, puzzle_hash: bytes32, fee: uint64 = uint64(0), - origin_id: Optional[bytes32] = None, coins: Optional[Set[Coin]] = None, primaries: Optional[List[Payment]] = None, ignore_max_send_amount: bool = False, coin_announcements_to_consume: Optional[Set[Announcement]] = None, puzzle_announcements_to_consume: Optional[Set[Announcement]] = None, memos: Optional[List[bytes]] = None, - negative_change_allowed: bool = False, min_coin_amount: Optional[uint64] = None, max_coin_amount: Optional[uint64] = None, excluded_coin_amounts: Optional[List[uint64]] = None, excluded_coins: Optional[Set[Coin]] = None, puzzle_decorator_override: Optional[List[Dict[str, Any]]] = None, reuse_puzhash: Optional[bool] = None, + **kwargs: Unpack[GSTOptionalArgs], ) -> TransactionRecord: + origin_id: Optional[bytes32] = kwargs.get("origin_id", None) + negative_change_allowed: bool = kwargs.get("negative_change_allowed", False) """ Use this to generate transaction. Note: this must be called under a wallet state manager lock diff --git a/chia/wallet/wallet_protocol.py b/chia/wallet/wallet_protocol.py index ce2a86aa04..6a2be5cdb1 100644 --- a/chia/wallet/wallet_protocol.py +++ b/chia/wallet/wallet_protocol.py @@ -1,14 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Set +from typing import TYPE_CHECKING, List, Optional, Set, Tuple from blspy import G1Element -from typing_extensions import Protocol +from typing_extensions import NotRequired, Protocol, TypedDict from chia.server.ws_connection import WSChiaConnection from chia.types.blockchain_format.coin import Coin +from chia.types.blockchain_format.program import Program from chia.types.blockchain_format.sized_bytes import bytes32 +from chia.types.spend_bundle import SpendBundle from chia.util.ints import uint32, uint64, uint128 +from chia.wallet.nft_wallet.nft_info import NFTCoinInfo from chia.wallet.util.wallet_types import WalletType from chia.wallet.wallet_coin_record import WalletCoinRecord from chia.wallet.wallet_info import WalletInfo @@ -68,3 +71,28 @@ class WalletProtocol(Protocol): # WalletStateManager is only imported for type hinting thus leaving pylint # unable to process this wallet_state_manager: WalletStateManager # pylint: disable=used-before-assignment + + +class GSTOptionalArgs(TypedDict): + # DataLayerWallet + launcher_id: NotRequired[Optional[bytes32]] + new_root_hash: NotRequired[Optional[bytes32]] + sign: NotRequired[bool] + add_pending_singleton: NotRequired[bool] + announce_new_state: NotRequired[bool] + # CATWallet + excluded_cat_coins: NotRequired[Optional[Set[Coin]]] + cat_discrepancy: NotRequired[Optional[Tuple[int, Program, Program]]] + # NFTWallet + nft_coin: NotRequired[Optional[NFTCoinInfo]] + new_owner: NotRequired[Optional[bytes]] + new_did_inner_hash: NotRequired[Optional[bytes]] + trade_prices_list: NotRequired[Optional[Program]] + additional_bundles: NotRequired[List[SpendBundle]] + metadata_update: NotRequired[Optional[Tuple[str, str]]] + # VCWallet + new_proof_hash: NotRequired[Optional[bytes32]] + provider_inner_puzhash: NotRequired[Optional[bytes32]] + # Wallet + origin_id: NotRequired[Optional[bytes32]] + negative_change_allowed: NotRequired[bool] diff --git a/mypy.ini.template b/mypy.ini.template index 69f04397cc..a903d5c12f 100644 --- a/mypy.ini.template +++ b/mypy.ini.template @@ -16,6 +16,7 @@ warn_return_any = True no_implicit_reexport = True strict_equality = True warn_redundant_casts = True +enable_incomplete_feature = Unpack [mypy-chia-exclusions] disable_error_code = annotation-unchecked