99
1010from chia_rs import AugSchemeMPL , Coin , CoinSpend , CoinState , G1Element , G2Element , PrivateKey
1111from chia_rs .sized_bytes import bytes32
12- from chia_rs .sized_ints import uint8 , uint16 , uint32 , uint64
12+ from chia_rs .sized_ints import uint16 , uint32 , uint64
1313from clvm_tools .binutils import assemble
1414
1515from chia .consensus .block_rewards import calculate_base_farmer_reward
8989from chia .wallet .util .compute_hints import compute_spend_hints_and_additions
9090from chia .wallet .util .compute_memos import compute_memos
9191from chia .wallet .util .curry_and_treehash import NIL_TREEHASH
92- from chia .wallet .util .query_filter import FilterMode , HashFilter
92+ from chia .wallet .util .query_filter import HashFilter
9393from chia .wallet .util .transaction_type import CLAWBACK_INCOMING_TRANSACTION_TYPES , TransactionType
9494from chia .wallet .util .tx_config import DEFAULT_TX_CONFIG , TXConfig , TXConfigLoader
9595from chia .wallet .util .wallet_sync_utils import fetch_coin_spend_for_coin_state
@@ -1376,57 +1376,13 @@ async def get_transaction_memo(self, request: GetTransactionMemo) -> GetTransact
13761376 async def split_coins (
13771377 self , request : SplitCoins , action_scope : WalletActionScope , extra_conditions : tuple [Condition , ...] = tuple ()
13781378 ) -> SplitCoinsResponse :
1379- if request .number_of_coins > 500 :
1380- raise ValueError (f"{ request .number_of_coins } coins is greater then the maximum limit of 500 coins." )
1381-
1382- optional_coin = await self .service .wallet_state_manager .coin_store .get_coin_record (request .target_coin_id )
1383- if optional_coin is None :
1384- raise ValueError (f"Could not find coin with ID { request .target_coin_id } " )
1385- else :
1386- coin = optional_coin .coin
1387-
1388- total_amount = request .amount_per_coin * request .number_of_coins
1389-
1390- if coin .amount < total_amount :
1391- raise ValueError (
1392- f"Coin amount: { coin .amount } is less than the total amount of the split: { total_amount } , exiting."
1393- )
1394-
1395- if request .wallet_id not in self .service .wallet_state_manager .wallets :
1396- raise ValueError (f"Wallet with ID { request .wallet_id } does not exist" )
1397- wallet = self .service .wallet_state_manager .wallets [request .wallet_id ]
1398- if not isinstance (wallet , (Wallet , CATWallet )):
1399- raise ValueError ("Cannot split coins from non-fungible wallet types" )
1400-
1401- outputs = [
1402- CreateCoin (
1403- await action_scope .get_puzzle_hash (
1404- self .service .wallet_state_manager , override_reuse_puzhash_with = False
1405- ),
1406- request .amount_per_coin ,
1407- )
1408- for _ in range (request .number_of_coins )
1409- ]
1410- if len (outputs ) == 0 :
1411- return SplitCoinsResponse ([], [])
1412-
1413- if wallet .type () == WalletType .STANDARD_WALLET and coin .amount < total_amount + request .fee :
1414- async with action_scope .use () as interface :
1415- interface .side_effects .selected_coins .append (coin )
1416- coins = await wallet .select_coins (
1417- uint64 (total_amount + request .fee - coin .amount ),
1418- action_scope ,
1419- )
1420- coins .add (coin )
1421- else :
1422- coins = {coin }
1423-
1424- await wallet .generate_signed_transaction (
1425- [output .amount for output in outputs ],
1426- [output .puzzle_hash for output in outputs ],
1427- action_scope ,
1428- request .fee ,
1429- coins = coins ,
1379+ await self .service .wallet_state_manager .split_coins (
1380+ action_scope = action_scope ,
1381+ wallet_id = request .wallet_id ,
1382+ target_coin_id = request .target_coin_id ,
1383+ amount_per_coin = request .amount_per_coin ,
1384+ number_of_coins = request .number_of_coins ,
1385+ fee = request .fee ,
14301386 extra_conditions = extra_conditions ,
14311387 )
14321388
@@ -1437,93 +1393,17 @@ async def split_coins(
14371393 async def combine_coins (
14381394 self , request : CombineCoins , action_scope : WalletActionScope , extra_conditions : tuple [Condition , ...] = tuple ()
14391395 ) -> CombineCoinsResponse :
1440- # Some "number of coins" validation
1441- if request .number_of_coins > request .coin_num_limit :
1442- raise ValueError (
1443- f"{ request .number_of_coins } coins is greater then the maximum limit of { request .coin_num_limit } coins."
1444- )
1445- if request .number_of_coins < 1 :
1446- raise ValueError ("You need at least two coins to combine" )
1447- if len (request .target_coin_ids ) > request .number_of_coins :
1448- raise ValueError ("More coin IDs specified than desired number of coins to combine" )
1449-
1450- if request .wallet_id not in self .service .wallet_state_manager .wallets :
1451- raise ValueError (f"Wallet with ID { request .wallet_id } does not exist" )
1452- wallet = self .service .wallet_state_manager .wallets [request .wallet_id ]
1453- if not isinstance (wallet , (Wallet , CATWallet )):
1454- raise ValueError ("Cannot combine coins from non-fungible wallet types" )
1455-
1456- coins : list [Coin ] = []
1457-
1458- # First get the coin IDs specified
1459- if request .target_coin_ids != []:
1460- coins .extend (
1461- cr .coin
1462- for cr in (
1463- await self .service .wallet_state_manager .coin_store .get_coin_records (
1464- wallet_id = request .wallet_id ,
1465- coin_id_filter = HashFilter (request .target_coin_ids , mode = uint8 (FilterMode .include .value )),
1466- )
1467- ).records
1468- )
1469-
1470- async with action_scope .use () as interface :
1471- interface .side_effects .selected_coins .extend (coins )
1472-
1473- # Next let's select enough coins to meet the target + fee if there is one
1474- fungible_amount_needed = uint64 (0 ) if request .target_coin_amount is None else request .target_coin_amount
1475- if isinstance (wallet , Wallet ):
1476- fungible_amount_needed = uint64 (fungible_amount_needed + request .fee )
1477- amount_selected = sum (c .amount for c in coins )
1478- if amount_selected < fungible_amount_needed : # implicit fungible_amount_needed > 0 here
1479- coins .extend (
1480- await wallet .select_coins (
1481- amount = uint64 (fungible_amount_needed - amount_selected ), action_scope = action_scope
1482- )
1483- )
1484-
1485- if len (coins ) > request .number_of_coins :
1486- raise ValueError (
1487- f"Options specified cannot be met without selecting more coins than specified: { len (coins )} "
1488- )
1489-
1490- # Now let's select enough coins to get to the target number to combine
1491- if len (coins ) < request .number_of_coins :
1492- async with action_scope .use () as interface :
1493- coins .extend (
1494- cr .coin
1495- for cr in (
1496- await self .service .wallet_state_manager .coin_store .get_coin_records (
1497- wallet_id = request .wallet_id ,
1498- limit = uint32 (request .number_of_coins - len (coins )),
1499- order = CoinRecordOrder .amount ,
1500- coin_id_filter = HashFilter (
1501- [c .name () for c in interface .side_effects .selected_coins ],
1502- mode = uint8 (FilterMode .exclude .value ),
1503- ),
1504- reverse = request .largest_first ,
1505- )
1506- ).records
1507- )
1508-
1509- async with action_scope .use () as interface :
1510- interface .side_effects .selected_coins .extend (coins )
1511-
1512- primary_output_amount = (
1513- uint64 (sum (c .amount for c in coins )) if request .target_coin_amount is None else request .target_coin_amount
1514- )
1515- if isinstance (wallet , Wallet ):
1516- primary_output_amount = uint64 (primary_output_amount - request .fee )
1517-
1518- await wallet .generate_signed_transaction (
1519- [primary_output_amount ],
1520- [await action_scope .get_puzzle_hash (self .service .wallet_state_manager )],
1521- action_scope ,
1522- request .fee ,
1523- coins = set (coins ),
1396+ await self .service .wallet_state_manager .combine_coins (
1397+ action_scope = action_scope ,
1398+ wallet_id = request .wallet_id ,
1399+ number_of_coins = request .number_of_coins ,
1400+ largest_first = request .largest_first ,
1401+ coin_num_limit = request .coin_num_limit ,
1402+ fee = request .fee ,
1403+ target_coin_amount = request .target_coin_amount ,
1404+ target_coin_ids = request .target_coin_ids if request .target_coin_ids != [] else None ,
15241405 extra_conditions = extra_conditions ,
15251406 )
1526-
15271407 return CombineCoinsResponse ([], []) # tx_endpoint will take care to fill this out
15281408
15291409 @marshal
0 commit comments