From 5f51079458e703d39047eba7c6f310d3f447c40f Mon Sep 17 00:00:00 2001 From: Rigidity Date: Wed, 4 Sep 2024 12:59:17 -0400 Subject: [PATCH] Allow multiple outputs in send_xch --- index.d.ts | 12 ++++++++---- src/lib.rs | 27 ++++++++++++++++++++------- src/wallet.rs | 17 +++++++++++------ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/index.d.ts b/index.d.ts index 2ad21eb..a34611c 100644 --- a/index.d.ts +++ b/index.d.ts @@ -186,16 +186,20 @@ export interface UnspentCoinsResponse { * @returns {Vec} Array of selected coins. */ export declare function selectCoins(allCoins: Array, totalAmount: bigint): Array +/** An output puzzle hash and amount. */ +export interface Output { + puzzleHash: Buffer + amount: bigint +} /** - * Sends XCH to a given puzzle hash. + * Sends XCH to a given set of puzzle hashes. * * @param {Buffer} syntheticKey - The synthetic key used by the wallet. * @param {Vec} selectedCoins - Coins to be spent, as retured by `select_coins`. - * @param {Buffer} puzzleHash - The puzzle hash to send to. - * @param {BigInt} amount - The amount to use for the created coin. + * @param {Vec} outputs - The output amounts to create. * @param {BigInt} fee - The fee to use for the transaction. */ -export declare function sendXch(syntheticKey: Buffer, selectedCoins: Array, puzzleHash: Buffer, amount: bigint, fee: bigint): Array +export declare function sendXch(syntheticKey: Buffer, selectedCoins: Array, outputs: Array, fee: bigint): Array /** * Adds an offset to a launcher id to make it deterministically unique from the original. * diff --git a/src/lib.rs b/src/lib.rs index c46df9d..83c42f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -726,29 +726,42 @@ pub fn select_coins(all_coins: Vec, total_amount: BigInt) -> napi::Result< .collect::>>() } -/// Sends XCH to a given puzzle hash. +/// An output puzzle hash and amount. +#[napi(object)] +pub struct Output { + pub puzzle_hash: Buffer, + pub amount: BigInt, +} + +/// Sends XCH to a given set of puzzle hashes. /// /// @param {Buffer} syntheticKey - The synthetic key used by the wallet. /// @param {Vec} selectedCoins - Coins to be spent, as retured by `select_coins`. -/// @param {Buffer} puzzleHash - The puzzle hash to send to. -/// @param {BigInt} amount - The amount to use for the created coin. +/// @param {Vec} outputs - The output amounts to create. /// @param {BigInt} fee - The fee to use for the transaction. #[napi] pub fn send_xch( synthetic_key: Buffer, selected_coins: Vec, - puzzle_hash: Buffer, - amount: BigInt, + outputs: Vec, fee: BigInt, ) -> napi::Result> { + let mut items = Vec::new(); + + for output in outputs { + items.push(( + RustBytes32::from_js(output.puzzle_hash)?, + u64::from_js(output.amount)?, + )); + } + let coin_spends = wallet::send_xch( RustPublicKey::from_js(synthetic_key)?, &selected_coins .into_iter() .map(RustCoin::from_js) .collect::>>()?, - RustBytes32::from_js(puzzle_hash)?, - u64::from_js(amount)?, + &items, u64::from_js(fee)?, ) .map_err(js::err)?; diff --git a/src/wallet.rs b/src/wallet.rs index 82a2748..007566c 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -193,20 +193,25 @@ fn spend_coins_together( pub fn send_xch( synthetic_key: PublicKey, coins: &[Coin], - puzzle_hash: Bytes32, - amount: u64, + outputs: &[(Bytes32, u64)], fee: u64, ) -> Result, WalletError> { let mut ctx = SpendContext::new(); + let mut conditions = Conditions::new().reserve_fee(fee); + let mut total_amount = fee; + + for output in outputs { + conditions = conditions.create_coin(output.0, output.1, Vec::new()); + total_amount += output.1; + } + spend_coins_together( &mut ctx, synthetic_key, coins, - Conditions::new() - .create_coin(puzzle_hash, amount, Vec::new()) - .reserve_fee(fee), - (amount + fee).try_into().unwrap(), + conditions, + total_amount.try_into().unwrap(), StandardArgs::curry_tree_hash(synthetic_key).into(), )?;