From cff827ea93b1a14d12b4fe96e1da68e291996c0f Mon Sep 17 00:00:00 2001 From: delcin-raj Date: Tue, 17 Dec 2024 22:05:51 +0530 Subject: [PATCH 1/2] Ability to detect and spend unblinded addresses * Added `blinded: bool` field, false means unblinded. * created `build_unblinded_tx` function, to spend unblinded utxos --- rust/src/api/types.rs | 25 +++++++--------- rust/src/api/wallet.rs | 66 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 17 deletions(-) diff --git a/rust/src/api/types.rs b/rust/src/api/types.rs index 8e3f8d2..5eed0a7 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 as u64, + 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 as u64, + blinded: true, }) .collect() } } -use std::convert::TryFrom; - use super::error::LwkError; impl From for Balances { @@ -83,17 +83,13 @@ impl From for Balances { asset_id_map .0 .into_iter() - .filter_map(|(key, value)| match i64::try_from(value) { - Ok(converted_value) => Some(Balance { + .map(|(key, value)| { + Balance { asset_id: key.to_string(), - value: converted_value, - }), - Err(_) => { - eprintln!("Warning: Overflow encountered converting {} to i64", value); - None + value, + blinded: true, } - }) - .collect() + }).collect() } } @@ -120,7 +116,8 @@ impl From for TxOut { #[frb(dart_metadata=("freezed"))] pub struct Balance { pub asset_id: String, - pub value: i64, + pub value: u64, + pub blinded: bool, } #[derive(Clone, Debug, PartialEq)] diff --git a/rust/src/api/wallet.rs b/rust/src/api/wallet.rs index 33a3dec..e82a52a 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,29 @@ 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().map( + |utxo| { + Balance { + asset_id: utxo.unblinded.asset.to_string(), + value: utxo.unblinded.value, + blinded: false, + } + } + ).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 +164,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)?; From 95cf9ea264daa7190441f2adcb600b8d1cb61a99 Mon Sep 17 00:00:00 2001 From: delcin-raj Date: Wed, 18 Dec 2024 11:34:35 +0530 Subject: [PATCH 2/2] Reverted back Balance.value to i64 --- rust/src/api/types.rs | 19 ++++++++++++------- rust/src/api/wallet.rs | 18 +++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/rust/src/api/types.rs b/rust/src/api/types.rs index 5eed0a7..54917fd 100644 --- a/rust/src/api/types.rs +++ b/rust/src/api/types.rs @@ -56,7 +56,7 @@ impl From for Balances { .into_iter() .map(|(key, value)| Balance { asset_id: key.to_string(), - value: value as u64, + value: value, blinded: true, }) .collect() @@ -69,7 +69,7 @@ impl From for Balances { .into_iter() .map(|(key, value)| Balance { asset_id: key.to_string(), - value: value as u64, + value: value, blinded: true, }) .collect() @@ -83,13 +83,18 @@ impl From for Balances { asset_id_map .0 .into_iter() - .map(|(key, value)| { - Balance { + .filter_map(|(key, value)| match i64::try_from(value) { + Ok(converted_value) => Some(Balance { asset_id: key.to_string(), - value, + value: converted_value, blinded: true, + }), + Err(_) => { + eprintln!("Warning: Overflow encountered converting {} to i64", value); + None } - }).collect() + }) + .collect() } } @@ -116,7 +121,7 @@ impl From for TxOut { #[frb(dart_metadata=("freezed"))] pub struct Balance { pub asset_id: String, - pub value: u64, + pub value: i64, pub blinded: bool, } diff --git a/rust/src/api/wallet.rs b/rust/src/api/wallet.rs index e82a52a..07120a8 100644 --- a/rust/src/api/wallet.rs +++ b/rust/src/api/wallet.rs @@ -86,15 +86,19 @@ impl Wallet { let mut balance_map = wallet.balance()?; let explicit_utxos = wallet.explicit_utxos()?; - let ublinded_balances: Balances = explicit_utxos.iter().map( - |utxo| { - Balance { + 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: utxo.unblinded.value, - blinded: false, + value: converted_value, + blinded: true, + }), + Err(_) => { + eprintln!("Warning: Overflow encountered converting {} to i64", utxo.unblinded.value); + None } - } - ).collect(); + }) + .collect(); for utxo in explicit_utxos { balance_map.insert(utxo.unblinded.asset, utxo.unblinded.value);