Skip to content

Commit 6b7155f

Browse files
committed
Integrate token transfers
1 parent 0823ef4 commit 6b7155f

File tree

52 files changed

+3291
-207
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3291
-207
lines changed

Cargo.lock

Lines changed: 60 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ members = [
1515
"crates/breez-sdk/lnurl-models",
1616
"crates/breez-sdk/breez-itest",
1717
"crates/breez-sdk/wasm",
18+
"crates/flashnet",
1819
"crates/macros",
1920
"crates/macro_test",
2021
"crates/spark",
@@ -64,6 +65,7 @@ dotenvy = "0.15.7"
6465
ecies = { version = "0.2.7", default-features = false, features = ["pure"] }
6566
enum_to_enum = "0.1.0"
6667
figment = "0.10.19"
68+
flashnet = { path = "crates/flashnet", default-features = false }
6769
# frost-core = "2.1.0"
6870
frost-core = { package = "frost-core-unofficial", version = "2.2.0" }
6971
# frost-secp256k1-tr = "2.1.0"

crates/breez-sdk/breez-itest/tests/spark_htlcs.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ async fn send_htlc_alice_to_bob(
6161
.list_payments(ListPaymentsRequest {
6262
status_filter: Some(vec![PaymentStatus::Pending]),
6363
type_filter: Some(vec![PaymentType::Receive]),
64-
spark_htlc_status_filter: Some(vec![SparkHtlcStatus::WaitingForPreimage]),
64+
payment_details_filter: Some(PaymentDetailsFilter::Spark {
65+
htlc_status: Some(vec![SparkHtlcStatus::WaitingForPreimage]),
66+
transfer_refund_needed: None,
67+
}),
6568
..Default::default()
6669
})
6770
.await?;
@@ -89,7 +92,10 @@ async fn send_htlc_alice_to_bob(
8992
.list_payments(ListPaymentsRequest {
9093
status_filter: Some(vec![PaymentStatus::Pending]),
9194
type_filter: Some(vec![PaymentType::Send]),
92-
spark_htlc_status_filter: Some(vec![SparkHtlcStatus::WaitingForPreimage]),
95+
payment_details_filter: Some(PaymentDetailsFilter::Spark {
96+
htlc_status: Some(vec![SparkHtlcStatus::WaitingForPreimage]),
97+
transfer_refund_needed: None,
98+
}),
9399
..Default::default()
94100
})
95101
.await?;
@@ -239,7 +245,10 @@ async fn test_02_htlc_refund(
239245
.list_payments(ListPaymentsRequest {
240246
status_filter: Some(vec![PaymentStatus::Failed]),
241247
type_filter: Some(vec![PaymentType::Receive]),
242-
spark_htlc_status_filter: Some(vec![SparkHtlcStatus::Returned]),
248+
payment_details_filter: Some(PaymentDetailsFilter::Spark {
249+
htlc_status: Some(vec![SparkHtlcStatus::Returned]),
250+
transfer_refund_needed: None,
251+
}),
243252
..Default::default()
244253
})
245254
.await?;
@@ -268,7 +277,10 @@ async fn test_02_htlc_refund(
268277
.list_payments(ListPaymentsRequest {
269278
status_filter: Some(vec![PaymentStatus::Failed]),
270279
type_filter: Some(vec![PaymentType::Send]),
271-
spark_htlc_status_filter: Some(vec![SparkHtlcStatus::Returned]),
280+
payment_details_filter: Some(PaymentDetailsFilter::Spark {
281+
htlc_status: Some(vec![SparkHtlcStatus::Returned]),
282+
transfer_refund_needed: None,
283+
}),
272284
..Default::default()
273285
})
274286
.await?;

crates/breez-sdk/cli/src/command/mod.rs

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ use breez_sdk_spark::{
55
AssetFilter, BreezSdk, CheckLightningAddressRequest, ClaimDepositRequest,
66
ClaimHtlcPaymentRequest, Fee, GetInfoRequest, GetPaymentRequest, GetTokensMetadataRequest,
77
InputType, LightningAddressDetails, ListPaymentsRequest, ListUnclaimedDepositsRequest,
8-
LnurlPayRequest, LnurlWithdrawRequest, OnchainConfirmationSpeed, PaymentStatus, PaymentType,
9-
PrepareLnurlPayRequest, PrepareSendPaymentRequest, ReceivePaymentMethod, ReceivePaymentRequest,
10-
RefundDepositRequest, RegisterLightningAddressRequest, SendPaymentMethod, SendPaymentOptions,
11-
SendPaymentRequest, SparkHtlcOptions, SparkHtlcStatus, SyncWalletRequest, TokenIssuer,
12-
UpdateUserSettingsRequest,
8+
LnurlPayRequest, LnurlWithdrawRequest, OnchainConfirmationSpeed, PaymentDetailsFilter,
9+
PaymentStatus, PaymentType, PrepareLnurlPayRequest, PrepareSendPaymentRequest,
10+
PrepareTransferTokenRequest, ReceivePaymentMethod, ReceivePaymentRequest, RefundDepositRequest,
11+
RegisterLightningAddressRequest, SendPaymentMethod, SendPaymentOptions, SendPaymentRequest,
12+
SparkHtlcOptions, SparkHtlcStatus, SyncWalletRequest, TokenIssuer, TransferTokenRequest,
13+
TransferType, UpdateUserSettingsRequest,
1314
};
1415
use clap::Parser;
1516
use rand::RngCore;
@@ -222,6 +223,20 @@ pub enum Command {
222223
/// The token identifiers to get metadata for
223224
token_identifiers: Vec<String>,
224225
},
226+
TokenTransfer {
227+
/// The amount to transfer
228+
amount: u128,
229+
230+
#[clap(short = 'f', long, action = clap::ArgAction::SetTrue)]
231+
from_bitcoin: bool,
232+
233+
/// The token identifier of the token
234+
token_identifier: String,
235+
236+
/// The maximum slippage in basis points (1/100 of a percent)
237+
#[clap(short = 's', long)]
238+
max_slippage_bps: Option<u32>,
239+
},
225240
GetUserSettings,
226241
SetUserSettings {
227242
/// Whether spark private mode is enabled.
@@ -286,7 +301,12 @@ pub(crate) async fn execute_command(
286301
type_filter,
287302
status_filter,
288303
asset_filter,
289-
spark_htlc_status_filter,
304+
payment_details_filter: spark_htlc_status_filter.map(|statuses| {
305+
PaymentDetailsFilter::Spark {
306+
htlc_status: Some(statuses),
307+
transfer_refund_needed: None,
308+
}
309+
}),
290310
from_timestamp,
291311
to_timestamp,
292312
sort_ascending,
@@ -585,6 +605,38 @@ pub(crate) async fn execute_command(
585605
print_value(&res)?;
586606
Ok(true)
587607
}
608+
Command::TokenTransfer {
609+
amount,
610+
from_bitcoin,
611+
token_identifier,
612+
max_slippage_bps,
613+
} => {
614+
let transfer_type = if from_bitcoin {
615+
TransferType::FromBitcoin
616+
} else {
617+
TransferType::ToBitcoin
618+
};
619+
let prepare_response = sdk
620+
.prepare_transfer_token(PrepareTransferTokenRequest {
621+
amount,
622+
token_identifier,
623+
transfer_type,
624+
})
625+
.await?;
626+
println!("Prepared transfer: {prepare_response:#?}\n Do you want to continue? (y/n)");
627+
let line = rl.readline_with_initial("", ("y", ""))?.to_lowercase();
628+
if line != "y" {
629+
return Ok(true);
630+
}
631+
let res = sdk
632+
.transfer_token(TransferTokenRequest {
633+
prepare_response,
634+
max_slippage_bps,
635+
})
636+
.await?;
637+
print_value(&res)?;
638+
Ok(true)
639+
}
588640
Command::GetUserSettings => {
589641
let res = sdk.get_user_settings().await?;
590642
print_value(&res)?;

crates/breez-sdk/core/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ uniffi = [
1313
openssl-vendored = ["openssl"]
1414
test-utils = []
1515
# TLS features
16-
default-tls = ["reqwest/default-tls", "breez-sdk-common/default-tls"]
17-
rustls-tls = ["reqwest/rustls-tls", "breez-sdk-common/rustls-tls"]
18-
native-tls = ["reqwest/native-tls", "breez-sdk-common/native-tls"]
16+
default-tls = ["reqwest/default-tls", "breez-sdk-common/default-tls", "flashnet/default-tls"]
17+
rustls-tls = ["reqwest/rustls-tls", "breez-sdk-common/rustls-tls", "flashnet/rustls-tls"]
18+
native-tls = ["reqwest/native-tls", "breez-sdk-common/native-tls", "flashnet/native-tls"]
1919

2020
[lib]
2121
crate-type = ["staticlib", "cdylib", "lib"]
@@ -36,6 +36,7 @@ clap = { workspace = true, features = ["derive"] }
3636
dotenvy.workspace = true
3737
ecies.workspace = true
3838
figment = { workspace = true, features = ["env", "yaml"] }
39+
flashnet.workspace = true
3940
hex.workspace = true
4041
lnurl-models.workspace = true
4142
macros.workspace = true

crates/breez-sdk/core/src/error.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ pub enum SdkError {
1919
#[error("SparkSdkError: {0}")]
2020
SparkError(String),
2121

22+
#[error("Insufficient funds")]
23+
InsufficientFunds,
24+
2225
#[error("Invalid UUID: {0}")]
2326
InvalidUuid(String),
2427

@@ -81,6 +84,21 @@ impl From<bitcoin::address::ParseError> for SdkError {
8184
}
8285
}
8386

87+
impl From<flashnet::FlashnetError> for SdkError {
88+
fn from(e: flashnet::FlashnetError) -> Self {
89+
match e {
90+
flashnet::FlashnetError::Network { reason, code } => {
91+
let code = match code {
92+
Some(c) => format!(" (code: {c})"),
93+
None => String::new(),
94+
};
95+
SdkError::NetworkError(format!("{reason}{code}"))
96+
}
97+
_ => SdkError::Generic(e.to_string()),
98+
}
99+
}
100+
}
101+
84102
impl From<persist::StorageError> for SdkError {
85103
fn from(e: persist::StorageError) -> Self {
86104
SdkError::StorageError(e.to_string())
@@ -125,7 +143,10 @@ impl From<serde_json::Error> for SdkError {
125143

126144
impl From<SparkWalletError> for SdkError {
127145
fn from(e: SparkWalletError) -> Self {
128-
SdkError::SparkError(e.to_string())
146+
match e {
147+
SparkWalletError::InsufficientFunds => SdkError::InsufficientFunds,
148+
_ => SdkError::SparkError(e.to_string()),
149+
}
129150
}
130151
}
131152

crates/breez-sdk/core/src/models/adaptors.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ impl PaymentDetails {
8888
SspUserRequest::LeavesSwapRequest(_) => PaymentDetails::Spark {
8989
invoice_details: None,
9090
htlc_details: None,
91+
transfer_info: None,
92+
transfer_refund_info: None,
9193
},
9294
SspUserRequest::ClaimStaticDeposit(request) => PaymentDetails::Deposit {
9395
tx_id: request.transaction_id.clone(),
@@ -107,6 +109,8 @@ impl PaymentDetails {
107109
return Ok(Some(PaymentDetails::Spark {
108110
invoice_details: Some(invoice_details.into()),
109111
htlc_details: None,
112+
transfer_info: None,
113+
transfer_refund_info: None,
110114
}));
111115
}
112116

@@ -115,6 +119,17 @@ impl PaymentDetails {
115119
return Ok(Some(PaymentDetails::Spark {
116120
invoice_details: None,
117121
htlc_details: Some(htlc_preimage_request.clone().try_into()?),
122+
transfer_info: None,
123+
transfer_refund_info: None,
124+
}));
125+
}
126+
127+
if transfer.transfer_type == TransferType::Transfer {
128+
return Ok(Some(PaymentDetails::Spark {
129+
invoice_details: None,
130+
htlc_details: None,
131+
transfer_info: None,
132+
transfer_refund_info: None,
118133
}));
119134
}
120135

0 commit comments

Comments
 (0)