diff --git a/rust/src/api/types.rs b/rust/src/api/types.rs index 8e3f8d2..54917fd 100644 --- a/rust/src/api/types.rs +++ b/rust/src/api/types.rs @@ -56,7 +56,8 @@ impl From for Balances { .into_iter() .map(|(key, value)| Balance { asset_id: key.to_string(), - value, + value: value, + blinded: true, }) .collect() } @@ -68,14 +69,13 @@ impl From for Balances { .into_iter() .map(|(key, value)| Balance { asset_id: key.to_string(), - value, + value: value, + blinded: true, }) .collect() } } -use std::convert::TryFrom; - use super::error::LwkError; impl From for Balances { @@ -87,6 +87,7 @@ impl From for Balances { Ok(converted_value) => Some(Balance { asset_id: key.to_string(), value: converted_value, + blinded: true, }), Err(_) => { eprintln!("Warning: Overflow encountered converting {} to i64", value); @@ -121,6 +122,7 @@ impl From for TxOut { pub struct Balance { pub asset_id: String, pub value: i64, + pub blinded: bool, } #[derive(Clone, Debug, PartialEq)] diff --git a/rust/src/api/wallet.rs b/rust/src/api/wallet.rs index 33a3dec..07120a8 100644 --- a/rust/src/api/wallet.rs +++ b/rust/src/api/wallet.rs @@ -18,6 +18,7 @@ use super::descriptor::Descriptor; use super::error::LwkError; use super::types::Address; use super::types::AssetIdBTreeMapUInt; +use super::types::Balance; use super::types::Balances; use super::types::Network; use super::types::PsetAmounts; @@ -81,9 +82,33 @@ impl Wallet { } pub fn balances(&self) -> anyhow::Result { - let balance_map: AssetIdBTreeMapUInt = (self.get_wallet()?.balance()?).into(); - let balance = Balances::from(balance_map); - Ok(balance) + let wallet = self.get_wallet()?; + let mut balance_map = wallet.balance()?; + let explicit_utxos = wallet.explicit_utxos()?; + + let ublinded_balances: Balances = explicit_utxos.iter() + .filter_map(|utxo| match i64::try_from(utxo.unblinded.value) { + Ok(converted_value) => Some(Balance { + asset_id: utxo.unblinded.asset.to_string(), + value: converted_value, + blinded: true, + }), + Err(_) => { + eprintln!("Warning: Overflow encountered converting {} to i64", utxo.unblinded.value); + None + } + }) + .collect(); + + for utxo in explicit_utxos { + balance_map.insert(utxo.unblinded.asset, utxo.unblinded.value); + } + + let balance_map: AssetIdBTreeMapUInt = balance_map.into(); + + let mut balances = Balances::from(balance_map); + balances.extend(ublinded_balances); + Ok(balances) } pub fn txs(&self) -> anyhow::Result, LwkError> { @@ -143,6 +168,45 @@ impl Wallet { Ok(pset.to_string()) } + pub fn build_unblinded_tx( + &self, + sats: u64, + out_address: String, + fee_rate: f32, + asset: String, + ) -> anyhow::Result { + let wallet = self.get_wallet()?; + let tx_builder = wallet.tx_builder(); + let address = LwkAddress::from_str(&out_address)?; + let asset = match LwkAssetId::from_str(&asset) { + Ok(result) => result, + Err(_) => { + return Err(LwkError { + msg: "Invalid asset".to_string(), + }) + } + }; + let external_utxos = wallet.explicit_utxos()?; + let matching_utxo = external_utxos + .into_iter() + .filter(|e_utxo| e_utxo.unblinded.asset == asset) + .next(); + + match matching_utxo { + Some(external_utxo) => { + let pset = tx_builder + .add_recipient(&address, sats, asset)? + .fee_rate(Some(fee_rate)) + .add_external_utxos(vec![external_utxo])? + .finish()?; + Ok(pset.to_string()) + } + None => Err(LwkError { + msg: "Asset Id not found".to_owned(), + }), + } + } + pub fn decode_tx(&self, pset: String) -> anyhow::Result { let mut pset = PartiallySignedTransaction::from_str(&pset)?; let pset_details = self.get_wallet()?.get_details(&mut pset)?;