mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-08-17 06:41:17 +03:00
Merge pull request #12619 from Chia-Network/post_1.5.0-expand_select_coins_rpc
post 1.5.0 - expand select coins rpc
This commit is contained in:
commit
916ccee549
@ -18,7 +18,7 @@ from chia.types.blockchain_format.sized_bytes import bytes32
|
|||||||
from chia.util.bech32m import bech32_decode, decode_puzzle_hash, encode_puzzle_hash
|
from chia.util.bech32m import bech32_decode, decode_puzzle_hash, encode_puzzle_hash
|
||||||
from chia.util.config import load_config
|
from chia.util.config import load_config
|
||||||
from chia.util.default_root import DEFAULT_ROOT_PATH
|
from chia.util.default_root import DEFAULT_ROOT_PATH
|
||||||
from chia.util.ints import uint16, uint32, uint64, uint128
|
from chia.util.ints import uint16, uint32, uint64
|
||||||
from chia.wallet.did_wallet.did_info import DID_HRP
|
from chia.wallet.did_wallet.did_info import DID_HRP
|
||||||
from chia.wallet.nft_wallet.nft_info import NFT_HRP, NFTInfo
|
from chia.wallet.nft_wallet.nft_info import NFT_HRP, NFTInfo
|
||||||
from chia.wallet.trade_record import TradeRecord
|
from chia.wallet.trade_record import TradeRecord
|
||||||
@ -213,17 +213,17 @@ async def send(args: dict, wallet_client: WalletRpcClient, fingerprint: int) ->
|
|||||||
|
|
||||||
final_fee = uint64(int(fee * units["chia"]))
|
final_fee = uint64(int(fee * units["chia"]))
|
||||||
final_amount: uint64
|
final_amount: uint64
|
||||||
final_min_coin_amount: uint128
|
final_min_coin_amount: uint64
|
||||||
if typ == WalletType.STANDARD_WALLET:
|
if typ == WalletType.STANDARD_WALLET:
|
||||||
final_amount = uint64(int(amount * units["chia"]))
|
final_amount = uint64(int(amount * units["chia"]))
|
||||||
final_min_coin_amount = uint128(int(min_coin_amount * units["chia"]))
|
final_min_coin_amount = uint64(int(min_coin_amount * units["chia"]))
|
||||||
print("Submitting transaction...")
|
print("Submitting transaction...")
|
||||||
res = await wallet_client.send_transaction(
|
res = await wallet_client.send_transaction(
|
||||||
str(wallet_id), final_amount, address, final_fee, memos, final_min_coin_amount
|
str(wallet_id), final_amount, address, final_fee, memos, final_min_coin_amount
|
||||||
)
|
)
|
||||||
elif typ == WalletType.CAT:
|
elif typ == WalletType.CAT:
|
||||||
final_amount = uint64(int(amount * units["cat"]))
|
final_amount = uint64(int(amount * units["cat"]))
|
||||||
final_min_coin_amount = uint128(int(min_coin_amount * units["cat"]))
|
final_min_coin_amount = uint64(int(min_coin_amount * units["cat"]))
|
||||||
print("Submitting transaction...")
|
print("Submitting transaction...")
|
||||||
res = await wallet_client.cat_spend(
|
res = await wallet_client.cat_spend(
|
||||||
str(wallet_id), final_amount, address, final_fee, memos, final_min_coin_amount
|
str(wallet_id), final_amount, address, final_fee, memos, final_min_coin_amount
|
||||||
|
@ -23,7 +23,7 @@ from chia.types.spend_bundle import SpendBundle
|
|||||||
from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
|
from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
|
||||||
from chia.util.byte_types import hexstr_to_bytes
|
from chia.util.byte_types import hexstr_to_bytes
|
||||||
from chia.util.config import load_config
|
from chia.util.config import load_config
|
||||||
from chia.util.ints import uint8, uint32, uint64, uint16, uint128
|
from chia.util.ints import uint8, uint32, uint64, uint16
|
||||||
from chia.util.keychain import KeyringIsLocked, bytes_to_mnemonic, generate_mnemonic
|
from chia.util.keychain import KeyringIsLocked, bytes_to_mnemonic, generate_mnemonic
|
||||||
from chia.util.path import path_from_root
|
from chia.util.path import path_from_root
|
||||||
from chia.util.ws_message import WsRpcMessage, create_payload_dict
|
from chia.util.ws_message import WsRpcMessage, create_payload_dict
|
||||||
@ -840,7 +840,7 @@ class WalletRpcApi:
|
|||||||
memos = [mem.encode("utf-8") for mem in request["memos"]]
|
memos = [mem.encode("utf-8") for mem in request["memos"]]
|
||||||
|
|
||||||
fee: uint64 = uint64(request.get("fee", 0))
|
fee: uint64 = uint64(request.get("fee", 0))
|
||||||
min_coin_amount: uint128 = uint128(request.get("min_coin_amount", 0))
|
min_coin_amount: uint64 = uint64(request.get("min_coin_amount", 0))
|
||||||
async with self.service.wallet_state_manager.lock:
|
async with self.service.wallet_state_manager.lock:
|
||||||
tx: TransactionRecord = await wallet.generate_signed_transaction(
|
tx: TransactionRecord = await wallet.generate_signed_transaction(
|
||||||
amount, puzzle_hash, fee, memos=memos, min_coin_amount=min_coin_amount
|
amount, puzzle_hash, fee, memos=memos, min_coin_amount=min_coin_amount
|
||||||
@ -896,10 +896,16 @@ class WalletRpcApi:
|
|||||||
|
|
||||||
amount = uint64(request["amount"])
|
amount = uint64(request["amount"])
|
||||||
wallet_id = uint32(request["wallet_id"])
|
wallet_id = uint32(request["wallet_id"])
|
||||||
|
min_coin_amount = uint64(request.get("min_coin_amount", 0))
|
||||||
|
excluded_coins: Optional[List] = request.get("excluded_coins")
|
||||||
|
if excluded_coins is not None:
|
||||||
|
excluded_coins = [Coin.from_json_dict(json_coin) for json_coin in excluded_coins]
|
||||||
|
|
||||||
wallet = self.service.wallet_state_manager.wallets[wallet_id]
|
wallet = self.service.wallet_state_manager.wallets[wallet_id]
|
||||||
async with self.service.wallet_state_manager.lock:
|
async with self.service.wallet_state_manager.lock:
|
||||||
selected_coins = await wallet.select_coins(amount=amount)
|
selected_coins = await wallet.select_coins(
|
||||||
|
amount=amount, min_coin_amount=min_coin_amount, exclude=excluded_coins
|
||||||
|
)
|
||||||
|
|
||||||
return {"coins": [coin.to_json_dict() for coin in selected_coins]}
|
return {"coins": [coin.to_json_dict() for coin in selected_coins]}
|
||||||
|
|
||||||
@ -999,7 +1005,7 @@ class WalletRpcApi:
|
|||||||
raise ValueError("An integer amount or fee is required (too many decimals)")
|
raise ValueError("An integer amount or fee is required (too many decimals)")
|
||||||
amount: uint64 = uint64(request["amount"])
|
amount: uint64 = uint64(request["amount"])
|
||||||
fee: uint64 = uint64(request.get("fee", 0))
|
fee: uint64 = uint64(request.get("fee", 0))
|
||||||
min_coin_amount: uint128 = uint128(request.get("min_coin_amount", 0))
|
min_coin_amount: uint64 = uint64(request.get("min_coin_amount", 0))
|
||||||
async with self.service.wallet_state_manager.lock:
|
async with self.service.wallet_state_manager.lock:
|
||||||
txs: List[TransactionRecord] = await wallet.generate_signed_transaction(
|
txs: List[TransactionRecord] = await wallet.generate_signed_transaction(
|
||||||
[amount], [puzzle_hash], fee, memos=[memos], min_coin_amount=min_coin_amount
|
[amount], [puzzle_hash], fee, memos=[memos], min_coin_amount=min_coin_amount
|
||||||
@ -1037,7 +1043,7 @@ class WalletRpcApi:
|
|||||||
fee: uint64 = uint64(request.get("fee", 0))
|
fee: uint64 = uint64(request.get("fee", 0))
|
||||||
validate_only: bool = request.get("validate_only", False)
|
validate_only: bool = request.get("validate_only", False)
|
||||||
driver_dict_str: Optional[Dict[str, Any]] = request.get("driver_dict", None)
|
driver_dict_str: Optional[Dict[str, Any]] = request.get("driver_dict", None)
|
||||||
min_coin_amount: uint128 = uint128(request.get("min_coin_amount", 0))
|
min_coin_amount: uint64 = uint64(request.get("min_coin_amount", 0))
|
||||||
|
|
||||||
# This driver_dict construction is to maintain backward compatibility where everything is assumed to be a CAT
|
# This driver_dict construction is to maintain backward compatibility where everything is assumed to be a CAT
|
||||||
driver_dict: Dict[bytes32, PuzzleInfo] = {}
|
driver_dict: Dict[bytes32, PuzzleInfo] = {}
|
||||||
@ -1096,7 +1102,7 @@ class WalletRpcApi:
|
|||||||
offer_hex: str = request["offer"]
|
offer_hex: str = request["offer"]
|
||||||
offer = Offer.from_bech32(offer_hex)
|
offer = Offer.from_bech32(offer_hex)
|
||||||
fee: uint64 = uint64(request.get("fee", 0))
|
fee: uint64 = uint64(request.get("fee", 0))
|
||||||
min_coin_amount: uint128 = uint128(request.get("min_coin_amount", 0))
|
min_coin_amount: uint64 = uint64(request.get("min_coin_amount", 0))
|
||||||
|
|
||||||
async with self.service.wallet_state_manager.lock:
|
async with self.service.wallet_state_manager.lock:
|
||||||
(success, trade_record, error,) = await self.service.wallet_state_manager.trade_manager.respond_to_offer(
|
(success, trade_record, error,) = await self.service.wallet_state_manager.trade_manager.respond_to_offer(
|
||||||
@ -1805,7 +1811,7 @@ class WalletRpcApi:
|
|||||||
additional_outputs.append({"puzzlehash": receiver_ph, "amount": amount, "memos": memos})
|
additional_outputs.append({"puzzlehash": receiver_ph, "amount": amount, "memos": memos})
|
||||||
|
|
||||||
fee: uint64 = uint64(request.get("fee", 0))
|
fee: uint64 = uint64(request.get("fee", 0))
|
||||||
min_coin_amount: uint128 = uint128(request.get("min_coin_amount", 0))
|
min_coin_amount: uint64 = uint64(request.get("min_coin_amount", 0))
|
||||||
|
|
||||||
coins = None
|
coins = None
|
||||||
if "coins" in request and len(request["coins"]) > 0:
|
if "coins" in request and len(request["coins"]) > 0:
|
||||||
|
@ -5,7 +5,7 @@ from chia.rpc.rpc_client import RpcClient
|
|||||||
from chia.types.announcement import Announcement
|
from chia.types.announcement import Announcement
|
||||||
from chia.types.blockchain_format.coin import Coin
|
from chia.types.blockchain_format.coin import Coin
|
||||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||||
from chia.util.ints import uint32, uint64, uint128
|
from chia.util.ints import uint32, uint64
|
||||||
from chia.wallet.trade_record import TradeRecord
|
from chia.wallet.trade_record import TradeRecord
|
||||||
from chia.wallet.trading.offer import Offer
|
from chia.wallet.trading.offer import Offer
|
||||||
from chia.wallet.transaction_record import TransactionRecord
|
from chia.wallet.transaction_record import TransactionRecord
|
||||||
@ -146,7 +146,7 @@ class WalletRpcClient(RpcClient):
|
|||||||
address: str,
|
address: str,
|
||||||
fee: uint64 = uint64(0),
|
fee: uint64 = uint64(0),
|
||||||
memos: Optional[List[str]] = None,
|
memos: Optional[List[str]] = None,
|
||||||
min_coin_amount: uint128 = uint128(0),
|
min_coin_amount: uint64 = uint64(0),
|
||||||
) -> TransactionRecord:
|
) -> TransactionRecord:
|
||||||
if memos is None:
|
if memos is None:
|
||||||
send_dict: Dict = {
|
send_dict: Dict = {
|
||||||
@ -213,7 +213,7 @@ class WalletRpcClient(RpcClient):
|
|||||||
fee: uint64 = uint64(0),
|
fee: uint64 = uint64(0),
|
||||||
coin_announcements: Optional[List[Announcement]] = None,
|
coin_announcements: Optional[List[Announcement]] = None,
|
||||||
puzzle_announcements: Optional[List[Announcement]] = None,
|
puzzle_announcements: Optional[List[Announcement]] = None,
|
||||||
min_coin_amount: uint128 = uint128(0),
|
min_coin_amount: uint64 = uint64(0),
|
||||||
) -> TransactionRecord:
|
) -> TransactionRecord:
|
||||||
# Converts bytes to hex for puzzle hashes
|
# Converts bytes to hex for puzzle hashes
|
||||||
additions_hex = []
|
additions_hex = []
|
||||||
@ -255,8 +255,22 @@ class WalletRpcClient(RpcClient):
|
|||||||
response: Dict = await self.fetch("create_signed_transaction", request)
|
response: Dict = await self.fetch("create_signed_transaction", request)
|
||||||
return TransactionRecord.from_json_dict_convenience(response["signed_tx"])
|
return TransactionRecord.from_json_dict_convenience(response["signed_tx"])
|
||||||
|
|
||||||
async def select_coins(self, *, amount: int, wallet_id: int) -> List[Coin]:
|
async def select_coins(
|
||||||
request = {"amount": amount, "wallet_id": wallet_id}
|
self,
|
||||||
|
*,
|
||||||
|
amount: int,
|
||||||
|
wallet_id: int,
|
||||||
|
excluded_coins: Optional[List[Coin]] = None,
|
||||||
|
min_coin_amount: uint64 = uint64(0),
|
||||||
|
) -> List[Coin]:
|
||||||
|
if excluded_coins is None:
|
||||||
|
excluded_coins = []
|
||||||
|
request = {
|
||||||
|
"amount": amount,
|
||||||
|
"wallet_id": wallet_id,
|
||||||
|
"min_coin_amount": min_coin_amount,
|
||||||
|
"excluded_coins": [excluded_coin.to_json_dict() for excluded_coin in excluded_coins],
|
||||||
|
}
|
||||||
response: Dict[str, List[Dict]] = await self.fetch("select_coins", request)
|
response: Dict[str, List[Dict]] = await self.fetch("select_coins", request)
|
||||||
return [Coin.from_json_dict(coin) for coin in response["coins"]]
|
return [Coin.from_json_dict(coin) for coin in response["coins"]]
|
||||||
|
|
||||||
@ -505,7 +519,7 @@ class WalletRpcClient(RpcClient):
|
|||||||
inner_address: str,
|
inner_address: str,
|
||||||
fee: uint64 = uint64(0),
|
fee: uint64 = uint64(0),
|
||||||
memos: Optional[List[str]] = None,
|
memos: Optional[List[str]] = None,
|
||||||
min_coin_amount: uint128 = uint128(0),
|
min_coin_amount: uint64 = uint64(0),
|
||||||
) -> TransactionRecord:
|
) -> TransactionRecord:
|
||||||
send_dict = {
|
send_dict = {
|
||||||
"wallet_id": wallet_id,
|
"wallet_id": wallet_id,
|
||||||
@ -525,7 +539,7 @@ class WalletRpcClient(RpcClient):
|
|||||||
driver_dict: Dict[str, Any] = None,
|
driver_dict: Dict[str, Any] = None,
|
||||||
fee=uint64(0),
|
fee=uint64(0),
|
||||||
validate_only: bool = False,
|
validate_only: bool = False,
|
||||||
min_coin_amount: uint128 = uint128(0),
|
min_coin_amount: uint64 = uint64(0),
|
||||||
) -> Tuple[Optional[Offer], TradeRecord]:
|
) -> Tuple[Optional[Offer], TradeRecord]:
|
||||||
send_dict: Dict[str, int] = {}
|
send_dict: Dict[str, int] = {}
|
||||||
for key in offer_dict:
|
for key in offer_dict:
|
||||||
@ -552,7 +566,7 @@ class WalletRpcClient(RpcClient):
|
|||||||
res = await self.fetch("check_offer_validity", {"offer": offer.to_bech32()})
|
res = await self.fetch("check_offer_validity", {"offer": offer.to_bech32()})
|
||||||
return res["valid"]
|
return res["valid"]
|
||||||
|
|
||||||
async def take_offer(self, offer: Offer, fee=uint64(0), min_coin_amount: uint128 = uint128(0)) -> TradeRecord:
|
async def take_offer(self, offer: Offer, fee=uint64(0), min_coin_amount: uint64 = uint64(0)) -> TradeRecord:
|
||||||
res = await self.fetch(
|
res = await self.fetch(
|
||||||
"take_offer", {"offer": offer.to_bech32(), "fee": fee, "min_coin_amount": min_coin_amount}
|
"take_offer", {"offer": offer.to_bech32(), "fee": fee, "min_coin_amount": min_coin_amount}
|
||||||
)
|
)
|
||||||
|
@ -445,7 +445,7 @@ class CATWallet:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
async def select_coins(
|
async def select_coins(
|
||||||
self, amount: uint64, exclude: Optional[List[Coin]] = None, min_coin_amount: Optional[uint128] = None
|
self, amount: uint64, exclude: Optional[List[Coin]] = None, min_coin_amount: Optional[uint64] = None
|
||||||
) -> Set[Coin]:
|
) -> Set[Coin]:
|
||||||
"""
|
"""
|
||||||
Returns a set of coins that can be used for generating a new transaction.
|
Returns a set of coins that can be used for generating a new transaction.
|
||||||
@ -532,7 +532,7 @@ class CATWallet:
|
|||||||
fee: uint64,
|
fee: uint64,
|
||||||
amount_to_claim: uint64,
|
amount_to_claim: uint64,
|
||||||
announcement_to_assert: Optional[Announcement] = None,
|
announcement_to_assert: Optional[Announcement] = None,
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> Tuple[TransactionRecord, Optional[Announcement]]:
|
) -> Tuple[TransactionRecord, Optional[Announcement]]:
|
||||||
"""
|
"""
|
||||||
This function creates a non-CAT transaction to pay fees, contribute funds for issuance, and absorb melt value.
|
This function creates a non-CAT transaction to pay fees, contribute funds for issuance, and absorb melt value.
|
||||||
@ -586,7 +586,7 @@ class CATWallet:
|
|||||||
coins: Set[Coin] = None,
|
coins: Set[Coin] = None,
|
||||||
coin_announcements_to_consume: Optional[Set[Announcement]] = None,
|
coin_announcements_to_consume: Optional[Set[Announcement]] = None,
|
||||||
puzzle_announcements_to_consume: Optional[Set[Announcement]] = None,
|
puzzle_announcements_to_consume: Optional[Set[Announcement]] = None,
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> Tuple[SpendBundle, Optional[TransactionRecord]]:
|
) -> Tuple[SpendBundle, Optional[TransactionRecord]]:
|
||||||
if coin_announcements_to_consume is not None:
|
if coin_announcements_to_consume is not None:
|
||||||
coin_announcements_bytes: Optional[Set[bytes32]] = {a.name() for a in coin_announcements_to_consume}
|
coin_announcements_bytes: Optional[Set[bytes32]] = {a.name() for a in coin_announcements_to_consume}
|
||||||
@ -722,7 +722,7 @@ class CATWallet:
|
|||||||
memos: Optional[List[List[bytes]]] = None,
|
memos: Optional[List[List[bytes]]] = None,
|
||||||
coin_announcements_to_consume: Optional[Set[Announcement]] = None,
|
coin_announcements_to_consume: Optional[Set[Announcement]] = None,
|
||||||
puzzle_announcements_to_consume: Optional[Set[Announcement]] = None,
|
puzzle_announcements_to_consume: Optional[Set[Announcement]] = None,
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> List[TransactionRecord]:
|
) -> List[TransactionRecord]:
|
||||||
if memos is None:
|
if memos is None:
|
||||||
memos = [[] for _ in range(len(puzzle_hashes))]
|
memos = [[] for _ in range(len(puzzle_hashes))]
|
||||||
@ -828,7 +828,7 @@ class CATWallet:
|
|||||||
return PuzzleInfo({"type": AssetType.CAT.value, "tail": "0x" + self.get_asset_id()})
|
return PuzzleInfo({"type": AssetType.CAT.value, "tail": "0x" + self.get_asset_id()})
|
||||||
|
|
||||||
async def get_coins_to_offer(
|
async def get_coins_to_offer(
|
||||||
self, asset_id: Optional[bytes32], amount: uint64, min_coin_amount: Optional[uint128] = None
|
self, asset_id: Optional[bytes32], amount: uint64, min_coin_amount: Optional[uint64] = None
|
||||||
) -> Set[Coin]:
|
) -> Set[Coin]:
|
||||||
balance = await self.get_confirmed_balance()
|
balance = await self.get_confirmed_balance()
|
||||||
if balance < amount:
|
if balance < amount:
|
||||||
|
@ -16,7 +16,7 @@ async def select_coins(
|
|||||||
log: logging.Logger,
|
log: logging.Logger,
|
||||||
amount: uint128,
|
amount: uint128,
|
||||||
exclude: Optional[List[Coin]] = None,
|
exclude: Optional[List[Coin]] = None,
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> Set[Coin]:
|
) -> Set[Coin]:
|
||||||
"""
|
"""
|
||||||
Returns a set of coins that can be used for generating a new transaction.
|
Returns a set of coins that can be used for generating a new transaction.
|
||||||
@ -24,7 +24,7 @@ async def select_coins(
|
|||||||
if exclude is None:
|
if exclude is None:
|
||||||
exclude = []
|
exclude = []
|
||||||
if min_coin_amount is None:
|
if min_coin_amount is None:
|
||||||
min_coin_amount = uint128(0)
|
min_coin_amount = uint64(0)
|
||||||
|
|
||||||
if amount > spendable_amount:
|
if amount > spendable_amount:
|
||||||
error_msg = (
|
error_msg = (
|
||||||
|
@ -299,7 +299,7 @@ class DIDWallet:
|
|||||||
return await self.wallet_state_manager.get_unconfirmed_balance(self.id(), record_list)
|
return await self.wallet_state_manager.get_unconfirmed_balance(self.id(), record_list)
|
||||||
|
|
||||||
async def select_coins(
|
async def select_coins(
|
||||||
self, amount: uint64, exclude: Optional[List[Coin]] = None, min_coin_amount: Optional[uint128] = None
|
self, amount: uint64, exclude: Optional[List[Coin]] = None, min_coin_amount: Optional[uint64] = None
|
||||||
) -> Optional[Set[Coin]]:
|
) -> Optional[Set[Coin]]:
|
||||||
"""
|
"""
|
||||||
Returns a set of coins that can be used for generating a new transaction.
|
Returns a set of coins that can be used for generating a new transaction.
|
||||||
|
@ -547,7 +547,7 @@ class NFTWallet:
|
|||||||
return puzzle_info
|
return puzzle_info
|
||||||
|
|
||||||
async def get_coins_to_offer(
|
async def get_coins_to_offer(
|
||||||
self, nft_id: bytes32, amount: uint64, min_coin_amount: Optional[uint128] = None
|
self, nft_id: bytes32, amount: uint64, min_coin_amount: Optional[uint64] = None
|
||||||
) -> Set[Coin]:
|
) -> Set[Coin]:
|
||||||
nft_coin: Optional[NFTCoinInfo] = self.get_nft(nft_id)
|
nft_coin: Optional[NFTCoinInfo] = self.get_nft(nft_id)
|
||||||
if nft_coin is None:
|
if nft_coin is None:
|
||||||
|
@ -11,7 +11,7 @@ from chia.types.blockchain_format.sized_bytes import bytes32
|
|||||||
from chia.types.spend_bundle import SpendBundle
|
from chia.types.spend_bundle import SpendBundle
|
||||||
from chia.util.db_wrapper import DBWrapper
|
from chia.util.db_wrapper import DBWrapper
|
||||||
from chia.util.hash import std_hash
|
from chia.util.hash import std_hash
|
||||||
from chia.util.ints import uint32, uint64, uint128
|
from chia.util.ints import uint32, uint64
|
||||||
from chia.wallet.nft_wallet.nft_wallet import NFTWallet
|
from chia.wallet.nft_wallet.nft_wallet import NFTWallet
|
||||||
from chia.wallet.outer_puzzles import AssetType
|
from chia.wallet.outer_puzzles import AssetType
|
||||||
from chia.wallet.payment import Payment
|
from chia.wallet.payment import Payment
|
||||||
@ -297,7 +297,7 @@ class TradeManager:
|
|||||||
driver_dict: Optional[Dict[bytes32, PuzzleInfo]] = None,
|
driver_dict: Optional[Dict[bytes32, PuzzleInfo]] = None,
|
||||||
fee: uint64 = uint64(0),
|
fee: uint64 = uint64(0),
|
||||||
validate_only: bool = False,
|
validate_only: bool = False,
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> Tuple[bool, Optional[TradeRecord], Optional[str]]:
|
) -> Tuple[bool, Optional[TradeRecord], Optional[str]]:
|
||||||
if driver_dict is None:
|
if driver_dict is None:
|
||||||
driver_dict = {}
|
driver_dict = {}
|
||||||
@ -331,7 +331,7 @@ class TradeManager:
|
|||||||
offer_dict: Dict[Union[int, bytes32], int],
|
offer_dict: Dict[Union[int, bytes32], int],
|
||||||
driver_dict: Optional[Dict[bytes32, PuzzleInfo]] = None,
|
driver_dict: Optional[Dict[bytes32, PuzzleInfo]] = None,
|
||||||
fee: uint64 = uint64(0),
|
fee: uint64 = uint64(0),
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> Tuple[bool, Optional[Offer], Optional[str]]:
|
) -> Tuple[bool, Optional[Offer], Optional[str]]:
|
||||||
"""
|
"""
|
||||||
Offer is dictionary of wallet ids and amount
|
Offer is dictionary of wallet ids and amount
|
||||||
@ -586,7 +586,7 @@ class TradeManager:
|
|||||||
return txs
|
return txs
|
||||||
|
|
||||||
async def respond_to_offer(
|
async def respond_to_offer(
|
||||||
self, offer: Offer, fee=uint64(0), min_coin_amount: Optional[uint128] = None
|
self, offer: Offer, fee=uint64(0), min_coin_amount: Optional[uint64] = None
|
||||||
) -> Tuple[bool, Optional[TradeRecord], Optional[str]]:
|
) -> Tuple[bool, Optional[TradeRecord], Optional[str]]:
|
||||||
take_offer_dict: Dict[Union[bytes32, int], int] = {}
|
take_offer_dict: Dict[Union[bytes32, int], int] = {}
|
||||||
arbitrage: Dict[Optional[bytes32], int] = offer.arbitrage()
|
arbitrage: Dict[Optional[bytes32], int] = offer.arbitrage()
|
||||||
|
@ -247,7 +247,7 @@ class Wallet:
|
|||||||
return Program.to(python_program)
|
return Program.to(python_program)
|
||||||
|
|
||||||
async def select_coins(
|
async def select_coins(
|
||||||
self, amount: uint64, exclude: Optional[List[Coin]] = None, min_coin_amount: Optional[uint128] = None
|
self, amount: uint64, exclude: Optional[List[Coin]] = None, min_coin_amount: Optional[uint64] = None
|
||||||
) -> Set[Coin]:
|
) -> Set[Coin]:
|
||||||
"""
|
"""
|
||||||
Returns a set of coins that can be used for generating a new transaction.
|
Returns a set of coins that can be used for generating a new transaction.
|
||||||
@ -291,7 +291,7 @@ class Wallet:
|
|||||||
puzzle_announcements_to_consume: Set[Announcement] = None,
|
puzzle_announcements_to_consume: Set[Announcement] = None,
|
||||||
memos: Optional[List[bytes]] = None,
|
memos: Optional[List[bytes]] = None,
|
||||||
negative_change_allowed: bool = False,
|
negative_change_allowed: bool = False,
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> List[CoinSpend]:
|
) -> List[CoinSpend]:
|
||||||
"""
|
"""
|
||||||
Generates a unsigned transaction in form of List(Puzzle, Solutions)
|
Generates a unsigned transaction in form of List(Puzzle, Solutions)
|
||||||
@ -418,7 +418,7 @@ class Wallet:
|
|||||||
puzzle_announcements_to_consume: Set[Announcement] = None,
|
puzzle_announcements_to_consume: Set[Announcement] = None,
|
||||||
memos: Optional[List[bytes]] = None,
|
memos: Optional[List[bytes]] = None,
|
||||||
negative_change_allowed: bool = False,
|
negative_change_allowed: bool = False,
|
||||||
min_coin_amount: Optional[uint128] = None,
|
min_coin_amount: Optional[uint64] = None,
|
||||||
) -> TransactionRecord:
|
) -> TransactionRecord:
|
||||||
"""
|
"""
|
||||||
Use this to generate transaction.
|
Use this to generate transaction.
|
||||||
@ -531,7 +531,7 @@ class Wallet:
|
|||||||
return spend_bundle
|
return spend_bundle
|
||||||
|
|
||||||
async def get_coins_to_offer(
|
async def get_coins_to_offer(
|
||||||
self, asset_id: Optional[bytes32], amount: uint64, min_coin_amount: Optional[uint128] = None
|
self, asset_id: Optional[bytes32], amount: uint64, min_coin_amount: Optional[uint64] = None
|
||||||
) -> Set[Coin]:
|
) -> Set[Coin]:
|
||||||
if asset_id is not None:
|
if asset_id is not None:
|
||||||
raise ValueError(f"The standard wallet cannot offer coins with asset id {asset_id}")
|
raise ValueError(f"The standard wallet cannot offer coins with asset id {asset_id}")
|
||||||
|
@ -19,6 +19,7 @@ from chia.server.server import ChiaServer
|
|||||||
from chia.simulator.full_node_simulator import FullNodeSimulator
|
from chia.simulator.full_node_simulator import FullNodeSimulator
|
||||||
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
|
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
|
||||||
from chia.types.announcement import Announcement
|
from chia.types.announcement import Announcement
|
||||||
|
from chia.types.blockchain_format.coin import Coin
|
||||||
from chia.types.blockchain_format.program import Program
|
from chia.types.blockchain_format.program import Program
|
||||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||||
from chia.types.coin_record import CoinRecord
|
from chia.types.coin_record import CoinRecord
|
||||||
@ -1014,3 +1015,45 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
|
|||||||
# Delete all keys
|
# Delete all keys
|
||||||
await client.delete_all_keys()
|
await client.delete_all_keys()
|
||||||
assert len(await client.get_public_keys()) == 0
|
assert len(await client.get_public_keys()) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment):
|
||||||
|
env: WalletRpcTestEnvironment = wallet_rpc_environment
|
||||||
|
|
||||||
|
wallet_2: Wallet = env.wallet_2.wallet
|
||||||
|
wallet_node: WalletNode = env.wallet_1.node
|
||||||
|
full_node_api: FullNodeSimulator = env.full_node.api
|
||||||
|
client: WalletRpcClient = env.wallet_1.rpc_client
|
||||||
|
client_2: WalletRpcClient = env.wallet_2.rpc_client
|
||||||
|
|
||||||
|
funds = await generate_funds(full_node_api, env.wallet_1)
|
||||||
|
|
||||||
|
addr = encode_puzzle_hash(await wallet_2.get_new_puzzlehash(), "txch")
|
||||||
|
coin_300: List[Coin]
|
||||||
|
for tx_amount in [uint64(1000), uint64(300), uint64(1000), uint64(1000), uint64(10000)]:
|
||||||
|
funds -= tx_amount
|
||||||
|
# create coins for tests
|
||||||
|
tx = await client.send_transaction("1", tx_amount, addr)
|
||||||
|
spend_bundle = tx.spend_bundle
|
||||||
|
assert spend_bundle is not None
|
||||||
|
for coin in spend_bundle.additions():
|
||||||
|
if coin.amount == uint64(300):
|
||||||
|
coin_300 = [coin]
|
||||||
|
|
||||||
|
await time_out_assert(5, tx_in_mempool, True, client, tx.name)
|
||||||
|
await farm_transaction(full_node_api, wallet_node, spend_bundle)
|
||||||
|
await time_out_assert(5, get_confirmed_balance, funds, client, 1)
|
||||||
|
|
||||||
|
# test min coin amount
|
||||||
|
min_coins: List[Coin] = await client_2.select_coins(amount=1000, wallet_id=1, min_coin_amount=uint64(1001))
|
||||||
|
assert min_coins is not None
|
||||||
|
assert len(min_coins) == 1 and min_coins[0].amount == uint64(10000)
|
||||||
|
|
||||||
|
# test excluded coins
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
await client_2.select_coins(amount=5000, wallet_id=1, excluded_coins=min_coins)
|
||||||
|
excluded_test = await client_2.select_coins(amount=1300, wallet_id=1, excluded_coins=coin_300)
|
||||||
|
assert len(excluded_test) == 2
|
||||||
|
for coin in excluded_test:
|
||||||
|
assert coin != coin_300[0]
|
||||||
|
@ -449,7 +449,7 @@ class TestCoinSelection:
|
|||||||
{},
|
{},
|
||||||
logging.getLogger("test"),
|
logging.getLogger("test"),
|
||||||
uint128(target_amount),
|
uint128(target_amount),
|
||||||
min_coin_amount=uint128(min_coin_amount),
|
min_coin_amount=uint64(min_coin_amount),
|
||||||
)
|
)
|
||||||
assert result is not None # this should never happen
|
assert result is not None # this should never happen
|
||||||
assert sum(coin.amount for coin in result) >= target_amount
|
assert sum(coin.amount for coin in result) >= target_amount
|
||||||
|
Loading…
Reference in New Issue
Block a user