1pub(crate) mod adaptors;
2pub mod payment_observer;
3pub use payment_observer::*;
4
5pub use crate::token_conversion::{
7 AmountAdjustmentReason, ConversionEstimate, ConversionInfo, ConversionOptions,
8 ConversionPurpose, ConversionStatus, ConversionType, FetchConversionLimitsRequest,
9 FetchConversionLimitsResponse,
10};
11
12use core::fmt;
13use lnurl_models::RecoverLnurlPayResponse;
14use serde::{Deserialize, Serialize};
15use serde_json::Value;
16use std::{
17 collections::{HashMap, HashSet},
18 fmt::Display,
19 str::FromStr,
20};
21
22use crate::{
23 BitcoinAddressDetails, BitcoinChainService, BitcoinNetwork, Bolt11InvoiceDetails,
24 ExternalInputParser, FiatCurrency, LnurlPayRequestDetails, LnurlWithdrawRequestDetails, Rate,
25 SdkError, SparkInvoiceDetails, SuccessAction, SuccessActionProcessed, error::DepositClaimError,
26};
27
28pub const DEFAULT_EXTERNAL_INPUT_PARSERS: &[(&str, &str, &str)] = &[
31 (
32 "picknpay",
33 "(.*)(za.co.electrum.picknpay)(.*)",
34 "https://cryptoqr.net/.well-known/lnurlp/<input>",
35 ),
36 (
37 "bootleggers",
38 r"(.*)(wigroup\.co|yoyogroup\.co)(.*)",
39 "https://cryptoqr.net/.well-known/lnurlw/<input>",
40 ),
41];
42
43#[derive(Debug, Clone)]
46#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
47pub enum Seed {
48 Mnemonic {
50 mnemonic: String,
52 passphrase: Option<String>,
54 },
55 Entropy(Vec<u8>),
57}
58
59impl Seed {
60 pub fn to_bytes(&self) -> Result<Vec<u8>, SdkError> {
61 match self {
62 Seed::Mnemonic {
63 mnemonic,
64 passphrase,
65 } => {
66 let mnemonic = bip39::Mnemonic::parse(mnemonic)
67 .map_err(|e| SdkError::Generic(e.to_string()))?;
68
69 Ok(mnemonic
70 .to_seed(passphrase.as_deref().unwrap_or(""))
71 .to_vec())
72 }
73 Seed::Entropy(entropy) => Ok(entropy.clone()),
74 }
75 }
76}
77
78#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
79pub struct ConnectRequest {
80 pub config: Config,
81 pub seed: Seed,
82 pub storage_dir: String,
83}
84
85#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
89#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
90pub struct ConnectWithSignerRequest {
91 pub config: Config,
92 pub signer: std::sync::Arc<dyn crate::signer::ExternalSigner>,
93 pub storage_dir: String,
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
98#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
99pub enum PaymentType {
100 Send,
102 Receive,
104}
105
106impl fmt::Display for PaymentType {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match self {
109 PaymentType::Send => write!(f, "send"),
110 PaymentType::Receive => write!(f, "receive"),
111 }
112 }
113}
114
115impl FromStr for PaymentType {
116 type Err = String;
117
118 fn from_str(s: &str) -> Result<Self, Self::Err> {
119 Ok(match s.to_lowercase().as_str() {
120 "receive" => PaymentType::Receive,
121 "send" => PaymentType::Send,
122 _ => return Err(format!("invalid payment type '{s}'")),
123 })
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
129#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
130pub enum PaymentStatus {
131 Completed,
133 Pending,
135 Failed,
137}
138
139impl PaymentStatus {
140 pub fn is_final(&self) -> bool {
142 matches!(self, PaymentStatus::Completed | PaymentStatus::Failed)
143 }
144}
145
146impl fmt::Display for PaymentStatus {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 match self {
149 PaymentStatus::Completed => write!(f, "completed"),
150 PaymentStatus::Pending => write!(f, "pending"),
151 PaymentStatus::Failed => write!(f, "failed"),
152 }
153 }
154}
155
156impl FromStr for PaymentStatus {
157 type Err = String;
158
159 fn from_str(s: &str) -> Result<Self, Self::Err> {
160 Ok(match s.to_lowercase().as_str() {
161 "completed" => PaymentStatus::Completed,
162 "pending" => PaymentStatus::Pending,
163 "failed" => PaymentStatus::Failed,
164 _ => return Err(format!("Invalid payment status '{s}'")),
165 })
166 }
167}
168
169#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
170#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
171pub enum PaymentMethod {
172 Lightning,
173 Spark,
174 Token,
175 Deposit,
176 Withdraw,
177 Unknown,
178}
179
180impl Display for PaymentMethod {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 match self {
183 PaymentMethod::Lightning => write!(f, "lightning"),
184 PaymentMethod::Spark => write!(f, "spark"),
185 PaymentMethod::Token => write!(f, "token"),
186 PaymentMethod::Deposit => write!(f, "deposit"),
187 PaymentMethod::Withdraw => write!(f, "withdraw"),
188 PaymentMethod::Unknown => write!(f, "unknown"),
189 }
190 }
191}
192
193impl FromStr for PaymentMethod {
194 type Err = ();
195
196 fn from_str(s: &str) -> Result<Self, Self::Err> {
197 match s {
198 "lightning" => Ok(PaymentMethod::Lightning),
199 "spark" => Ok(PaymentMethod::Spark),
200 "token" => Ok(PaymentMethod::Token),
201 "deposit" => Ok(PaymentMethod::Deposit),
202 "withdraw" => Ok(PaymentMethod::Withdraw),
203 "unknown" => Ok(PaymentMethod::Unknown),
204 _ => Err(()),
205 }
206 }
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
211#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
212pub struct Payment {
213 pub id: String,
215 pub payment_type: PaymentType,
217 pub status: PaymentStatus,
219 pub amount: u128,
221 pub fees: u128,
223 pub timestamp: u64,
225 pub method: PaymentMethod,
228 pub details: Option<PaymentDetails>,
230 pub conversion_details: Option<ConversionDetails>,
232}
233
234impl Payment {
235 pub fn is_conversion_child(&self) -> bool {
241 matches!(
242 &self.details,
243 Some(
244 PaymentDetails::Spark {
245 conversion_info: Some(_),
246 ..
247 } | PaymentDetails::Token {
248 conversion_info: Some(_),
249 ..
250 }
251 )
252 )
253 }
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
261#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
262pub struct ConversionDetails {
263 pub status: ConversionStatus,
265 pub from: Option<ConversionStep>,
267 pub to: Option<ConversionStep>,
269}
270
271pub fn conversion_steps_from_payments(
280 payments: &[Payment],
281) -> Result<(Option<ConversionStep>, Option<ConversionStep>), SdkError> {
282 let from = payments
283 .iter()
284 .find(|p| p.payment_type == PaymentType::Send)
285 .map(TryInto::try_into)
286 .transpose()?;
287 let to = payments
288 .iter()
289 .find(|p| p.payment_type == PaymentType::Receive)
290 .map(TryInto::try_into)
291 .transpose()?;
292 Ok((from, to))
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize)]
297#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
298pub struct ConversionStep {
299 pub payment_id: String,
301 pub amount: u128,
303 pub fee: u128,
306 pub method: PaymentMethod,
308 pub token_metadata: Option<TokenMetadata>,
310 #[serde(default)]
312 pub amount_adjustment: Option<AmountAdjustmentReason>,
313}
314
315impl TryFrom<&Payment> for ConversionStep {
319 type Error = SdkError;
320 fn try_from(payment: &Payment) -> Result<Self, Self::Error> {
321 let (conversion_info, token_metadata) = match &payment.details {
322 Some(PaymentDetails::Spark {
323 conversion_info: Some(info),
324 ..
325 }) => (info, None),
326 Some(PaymentDetails::Token {
327 conversion_info: Some(info),
328 metadata,
329 ..
330 }) => (info, Some(metadata.clone())),
331 _ => {
332 return Err(SdkError::Generic(format!(
333 "No conversion info available for payment {}",
334 payment.id
335 )));
336 }
337 };
338 Ok(ConversionStep {
339 payment_id: payment.id.clone(),
340 amount: payment.amount,
341 fee: payment
342 .fees
343 .saturating_add(conversion_info.fee.unwrap_or(0)),
344 method: payment.method,
345 token_metadata,
346 amount_adjustment: conversion_info.amount_adjustment.clone(),
347 })
348 }
349}
350
351#[cfg(feature = "uniffi")]
352uniffi::custom_type!(u128, String, {
353 remote,
354 try_lift: |val| val.parse::<u128>().map_err(uniffi::deps::anyhow::Error::msg),
355 lower: |obj| obj.to_string(),
356});
357
358#[allow(clippy::large_enum_variant)]
361#[derive(Debug, Clone, Serialize, Deserialize)]
362#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
363pub enum PaymentDetails {
364 Spark {
365 invoice_details: Option<SparkInvoicePaymentDetails>,
367 htlc_details: Option<SparkHtlcDetails>,
369 conversion_info: Option<ConversionInfo>,
371 },
372 Token {
373 metadata: TokenMetadata,
374 tx_hash: String,
375 tx_type: TokenTransactionType,
376 invoice_details: Option<SparkInvoicePaymentDetails>,
378 conversion_info: Option<ConversionInfo>,
380 },
381 Lightning {
382 description: Option<String>,
384 invoice: String,
388
389 destination_pubkey: String,
391
392 htlc_details: SparkHtlcDetails,
394
395 lnurl_pay_info: Option<LnurlPayInfo>,
397
398 lnurl_withdraw_info: Option<LnurlWithdrawInfo>,
400
401 lnurl_receive_metadata: Option<LnurlReceiveMetadata>,
403 },
404 Withdraw {
405 tx_id: String,
406 },
407 Deposit {
408 tx_id: String,
409 },
410}
411
412#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
413#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
414pub enum TokenTransactionType {
415 Transfer,
416 Mint,
417 Burn,
418}
419
420impl fmt::Display for TokenTransactionType {
421 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422 match self {
423 TokenTransactionType::Transfer => write!(f, "transfer"),
424 TokenTransactionType::Mint => write!(f, "mint"),
425 TokenTransactionType::Burn => write!(f, "burn"),
426 }
427 }
428}
429
430impl FromStr for TokenTransactionType {
431 type Err = String;
432
433 fn from_str(s: &str) -> Result<Self, Self::Err> {
434 match s.to_lowercase().as_str() {
435 "transfer" => Ok(TokenTransactionType::Transfer),
436 "mint" => Ok(TokenTransactionType::Mint),
437 "burn" => Ok(TokenTransactionType::Burn),
438 _ => Err(format!("Invalid token transaction type '{s}'")),
439 }
440 }
441}
442
443#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
444#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
445pub struct SparkInvoicePaymentDetails {
446 pub description: Option<String>,
448 pub invoice: String,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
453#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
454pub struct SparkHtlcDetails {
455 pub payment_hash: String,
457 pub preimage: Option<String>,
459 pub expiry_time: u64,
461 pub status: SparkHtlcStatus,
463}
464
465#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
466#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
467pub enum SparkHtlcStatus {
468 WaitingForPreimage,
470 PreimageShared,
472 Returned,
474}
475
476impl fmt::Display for SparkHtlcStatus {
477 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
478 match self {
479 SparkHtlcStatus::WaitingForPreimage => write!(f, "WaitingForPreimage"),
480 SparkHtlcStatus::PreimageShared => write!(f, "PreimageShared"),
481 SparkHtlcStatus::Returned => write!(f, "Returned"),
482 }
483 }
484}
485
486impl FromStr for SparkHtlcStatus {
487 type Err = String;
488
489 fn from_str(s: &str) -> Result<Self, Self::Err> {
490 match s {
491 "WaitingForPreimage" => Ok(SparkHtlcStatus::WaitingForPreimage),
492 "PreimageShared" => Ok(SparkHtlcStatus::PreimageShared),
493 "Returned" => Ok(SparkHtlcStatus::Returned),
494 _ => Err("Invalid Spark HTLC status".to_string()),
495 }
496 }
497}
498
499#[derive(Debug, Clone, Copy, PartialEq, Eq)]
500#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
501pub enum Network {
502 Mainnet,
503 Regtest,
504}
505
506impl std::fmt::Display for Network {
507 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
508 match self {
509 Network::Mainnet => write!(f, "Mainnet"),
510 Network::Regtest => write!(f, "Regtest"),
511 }
512 }
513}
514
515impl From<Network> for BitcoinNetwork {
516 fn from(network: Network) -> Self {
517 match network {
518 Network::Mainnet => BitcoinNetwork::Bitcoin,
519 Network::Regtest => BitcoinNetwork::Regtest,
520 }
521 }
522}
523
524impl From<Network> for breez_sdk_common::network::BitcoinNetwork {
525 fn from(network: Network) -> Self {
526 match network {
527 Network::Mainnet => breez_sdk_common::network::BitcoinNetwork::Bitcoin,
528 Network::Regtest => breez_sdk_common::network::BitcoinNetwork::Regtest,
529 }
530 }
531}
532
533impl From<Network> for bitcoin::Network {
534 fn from(network: Network) -> Self {
535 match network {
536 Network::Mainnet => bitcoin::Network::Bitcoin,
537 Network::Regtest => bitcoin::Network::Regtest,
538 }
539 }
540}
541
542impl FromStr for Network {
543 type Err = String;
544
545 fn from_str(s: &str) -> Result<Self, Self::Err> {
546 match s {
547 "mainnet" => Ok(Network::Mainnet),
548 "regtest" => Ok(Network::Regtest),
549 _ => Err("Invalid network".to_string()),
550 }
551 }
552}
553
554#[derive(Debug, Clone)]
555#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
556#[allow(clippy::struct_excessive_bools)]
557pub struct Config {
558 pub api_key: Option<String>,
559 pub network: Network,
560 pub sync_interval_secs: u32,
561
562 pub max_deposit_claim_fee: Option<MaxFee>,
565
566 pub lnurl_domain: Option<String>,
568
569 pub prefer_spark_over_lightning: bool,
573
574 pub external_input_parsers: Option<Vec<ExternalInputParser>>,
578 pub use_default_external_input_parsers: bool,
582
583 pub real_time_sync_server_url: Option<String>,
585
586 pub private_enabled_default: bool,
598
599 pub leaf_optimization_config: LeafOptimizationConfig,
605
606 pub token_optimization_config: TokenOptimizationConfig,
613
614 pub stable_balance_config: Option<StableBalanceConfig>,
619
620 pub max_concurrent_claims: u32,
624
625 pub spark_config: Option<SparkConfig>,
631
632 pub background_tasks_enabled: bool,
657}
658
659#[derive(Debug, Clone)]
661#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
662pub struct LeafOptimizationConfig {
663 pub auto_enabled: bool,
670 pub multiplicity: u8,
682}
683
684#[derive(Debug, Clone)]
686#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
687pub struct TokenOptimizationConfig {
688 pub auto_enabled: bool,
696 pub target_output_count: u32,
709 pub min_outputs_threshold: u32,
718}
719
720#[derive(Debug, Clone)]
722#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
723pub struct StableBalanceToken {
724 pub label: String,
730
731 pub token_identifier: String,
733}
734
735#[derive(Debug, Clone)]
749#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
750pub struct StableBalanceConfig {
751 pub tokens: Vec<StableBalanceToken>,
753
754 #[cfg_attr(feature = "uniffi", uniffi(default = None))]
760 pub default_active_label: Option<String>,
761
762 #[cfg_attr(feature = "uniffi", uniffi(default = None))]
767 pub threshold_sats: Option<u64>,
768
769 #[cfg_attr(feature = "uniffi", uniffi(default = None))]
773 pub max_slippage_bps: Option<u32>,
774}
775
776#[derive(Debug, Clone)]
778#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
779pub enum StableBalanceActiveLabel {
780 Set { label: String },
782 Unset,
784}
785
786#[derive(Debug, Clone)]
792#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
793pub struct SparkConfig {
794 pub coordinator_identifier: String,
796 pub threshold: u32,
798 pub signing_operators: Vec<SparkSigningOperator>,
800 pub ssp_config: SparkSspConfig,
802 pub expected_withdraw_bond_sats: u64,
804 pub expected_withdraw_relative_block_locktime: u64,
806}
807
808#[derive(Debug, Clone)]
810#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
811pub struct SparkSigningOperator {
812 pub id: u32,
814 pub identifier: String,
816 pub address: String,
818 pub identity_public_key: String,
820}
821
822#[derive(Debug, Clone)]
824#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
825pub struct SparkSspConfig {
826 pub base_url: String,
828 pub identity_public_key: String,
830 pub schema_endpoint: Option<String>,
833}
834
835impl Config {
836 pub fn validate(&self) -> Result<(), SdkError> {
840 if self.max_concurrent_claims == 0 {
841 return Err(SdkError::InvalidInput(
842 "max_concurrent_claims must be greater than 0".to_string(),
843 ));
844 }
845
846 if let Some(sb) = &self.stable_balance_config {
847 if sb.tokens.is_empty() {
848 return Err(SdkError::InvalidInput(
849 "tokens must not be empty".to_string(),
850 ));
851 }
852
853 let mut seen_labels = HashSet::new();
854 let mut seen_identifiers = HashSet::new();
855 for token in &sb.tokens {
856 if token.label.is_empty() {
857 return Err(SdkError::InvalidInput(
858 "token label must not be empty".to_string(),
859 ));
860 }
861 if token.token_identifier.is_empty() {
862 return Err(SdkError::InvalidInput(
863 "token_identifier must not be empty".to_string(),
864 ));
865 }
866 if !seen_labels.insert(&token.label) {
867 return Err(SdkError::InvalidInput(format!(
868 "tokens contains duplicate label: {}",
869 token.label
870 )));
871 }
872 if !seen_identifiers.insert(&token.token_identifier) {
873 return Err(SdkError::InvalidInput(format!(
874 "tokens contains duplicate token_identifier: {}",
875 token.token_identifier
876 )));
877 }
878 }
879
880 if let Some(bps) = sb.max_slippage_bps
881 && bps > 10000
882 {
883 return Err(SdkError::InvalidInput(
884 "max_slippage_bps must be <= 10000".to_string(),
885 ));
886 }
887
888 if let Some(default_label) = &sb.default_active_label
889 && !seen_labels.contains(default_label)
890 {
891 return Err(SdkError::InvalidInput(format!(
892 "default_active_label '{default_label}' not found in tokens list"
893 )));
894 }
895 }
896
897 let token_opt = &self.token_optimization_config;
898 if token_opt.min_outputs_threshold <= 1 {
899 return Err(SdkError::InvalidInput(
900 "token optimization minimum outputs threshold must be greater than 1".to_string(),
901 ));
902 }
903 if token_opt.target_output_count < 1 {
904 return Err(SdkError::InvalidInput(
905 "token optimization target output count must be at least 1".to_string(),
906 ));
907 }
908 if token_opt.target_output_count >= token_opt.min_outputs_threshold {
909 return Err(SdkError::InvalidInput(
910 "token optimization target output count must be less than the minimum outputs threshold".to_string(),
911 ));
912 }
913
914 Ok(())
915 }
916
917 pub(crate) fn get_all_external_input_parsers(&self) -> Vec<ExternalInputParser> {
918 let mut external_input_parsers = Vec::new();
919 if self.use_default_external_input_parsers {
920 let default_parsers = DEFAULT_EXTERNAL_INPUT_PARSERS
921 .iter()
922 .map(|(id, regex, url)| ExternalInputParser {
923 provider_id: (*id).to_string(),
924 input_regex: (*regex).to_string(),
925 parser_url: (*url).to_string(),
926 })
927 .collect::<Vec<_>>();
928 external_input_parsers.extend(default_parsers);
929 }
930 external_input_parsers.extend(self.external_input_parsers.clone().unwrap_or_default());
931
932 external_input_parsers
933 }
934}
935
936#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
937#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
938pub enum MaxFee {
939 Fixed { amount: u64 },
941 Rate { sat_per_vbyte: u64 },
943 NetworkRecommended { leeway_sat_per_vbyte: u64 },
945}
946
947impl MaxFee {
948 pub(crate) async fn to_fee(&self, client: &dyn BitcoinChainService) -> Result<Fee, SdkError> {
949 match self {
950 MaxFee::Fixed { amount } => Ok(Fee::Fixed { amount: *amount }),
951 MaxFee::Rate { sat_per_vbyte } => Ok(Fee::Rate {
952 sat_per_vbyte: *sat_per_vbyte,
953 }),
954 MaxFee::NetworkRecommended {
955 leeway_sat_per_vbyte,
956 } => {
957 let recommended_fees = client.recommended_fees().await?;
958 let max_fee_rate = recommended_fees
959 .fastest_fee
960 .saturating_add(*leeway_sat_per_vbyte);
961 Ok(Fee::Rate {
962 sat_per_vbyte: max_fee_rate,
963 })
964 }
965 }
966 }
967}
968
969#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
970#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
971pub enum Fee {
972 Fixed { amount: u64 },
974 Rate { sat_per_vbyte: u64 },
976}
977
978impl Fee {
979 pub fn to_sats(&self, vbytes: u64) -> u64 {
980 match self {
981 Fee::Fixed { amount } => *amount,
982 Fee::Rate { sat_per_vbyte } => sat_per_vbyte.saturating_mul(vbytes),
983 }
984 }
985}
986
987#[derive(Debug, Clone, Serialize, Deserialize)]
988#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
989pub struct DepositInfo {
990 pub txid: String,
991 pub vout: u32,
992 pub amount_sats: u64,
993 pub is_mature: bool,
994 pub refund_tx: Option<String>,
995 pub refund_tx_id: Option<String>,
996 pub claim_error: Option<DepositClaimError>,
997}
998
999#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1000pub struct ClaimDepositRequest {
1001 pub txid: String,
1002 pub vout: u32,
1003 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1004 pub max_fee: Option<MaxFee>,
1005}
1006
1007#[derive(Debug, Clone, Serialize)]
1008#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1009pub struct ClaimDepositResponse {
1010 pub payment: Payment,
1011}
1012
1013#[derive(Debug, Clone, Serialize)]
1014#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1015pub struct RefundDepositRequest {
1016 pub txid: String,
1017 pub vout: u32,
1018 pub destination_address: String,
1019 pub fee: Fee,
1020}
1021
1022#[derive(Debug, Clone, Serialize)]
1023#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1024pub struct RefundDepositResponse {
1025 pub tx_id: String,
1026 pub tx_hex: String,
1027}
1028
1029#[derive(Debug, Clone, Serialize)]
1030#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1031pub struct ListUnclaimedDepositsRequest {}
1032
1033#[derive(Debug, Clone, Serialize)]
1034#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1035pub struct ListUnclaimedDepositsResponse {
1036 pub deposits: Vec<DepositInfo>,
1037}
1038
1039#[derive(Debug, Clone)]
1044#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1045pub enum BuyBitcoinRequest {
1046 Moonpay {
1049 locked_amount_sat: Option<u64>,
1051 redirect_url: Option<String>,
1053 },
1054 CashApp {
1063 amount_sats: u64,
1065 },
1066}
1067
1068impl Default for BuyBitcoinRequest {
1069 fn default() -> Self {
1070 Self::Moonpay {
1071 locked_amount_sat: None,
1072 redirect_url: None,
1073 }
1074 }
1075}
1076
1077#[derive(Debug, Clone, Serialize)]
1079#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1080pub struct BuyBitcoinResponse {
1081 pub url: String,
1083}
1084
1085impl std::fmt::Display for MaxFee {
1086 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1087 match self {
1088 MaxFee::Fixed { amount } => write!(f, "Fixed: {amount}"),
1089 MaxFee::Rate { sat_per_vbyte } => write!(f, "Rate: {sat_per_vbyte}"),
1090 MaxFee::NetworkRecommended {
1091 leeway_sat_per_vbyte,
1092 } => write!(f, "NetworkRecommended: {leeway_sat_per_vbyte}"),
1093 }
1094 }
1095}
1096
1097#[derive(Debug, Clone)]
1098#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1099pub struct Credentials {
1100 pub username: String,
1101 pub password: String,
1102}
1103
1104#[derive(Debug, Clone)]
1106#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1107pub struct GetInfoRequest {
1108 pub ensure_synced: Option<bool>,
1115}
1116
1117#[derive(Debug, Clone, Serialize)]
1119#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1120pub struct GetInfoResponse {
1121 pub identity_pubkey: String,
1123 pub balance_sats: u64,
1125 pub token_balances: HashMap<String, TokenBalance>,
1127}
1128
1129#[derive(Debug, Clone, Serialize, Deserialize)]
1130#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1131pub struct TokenBalance {
1132 pub balance: u128,
1133 pub token_metadata: TokenMetadata,
1134}
1135
1136#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1137#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1138pub struct TokenMetadata {
1139 pub identifier: String,
1140 pub issuer_public_key: String,
1142 pub name: String,
1143 pub ticker: String,
1144 pub decimals: u32,
1146 pub max_supply: u128,
1147 pub is_freezable: bool,
1148}
1149
1150#[derive(Debug, Clone)]
1152#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1153pub struct SyncWalletRequest {}
1154
1155#[derive(Debug, Clone, Serialize)]
1157#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1158pub struct SyncWalletResponse {}
1159
1160#[derive(Debug, Clone, Serialize)]
1161#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1162pub enum ReceivePaymentMethod {
1163 SparkAddress,
1164 SparkInvoice {
1165 amount: Option<u128>,
1167 token_identifier: Option<String>,
1170 expiry_time: Option<u64>,
1172 description: Option<String>,
1174 sender_public_key: Option<String>,
1176 },
1177 BitcoinAddress {
1178 new_address: Option<bool>,
1182 },
1183 Bolt11Invoice {
1184 description: String,
1185 amount_sats: Option<u64>,
1186 expiry_secs: Option<u32>,
1188 payment_hash: Option<String>,
1192 },
1193}
1194
1195#[derive(Debug, Clone, Serialize)]
1196#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1197pub enum SendPaymentMethod {
1198 BitcoinAddress {
1199 address: BitcoinAddressDetails,
1200 fee_quote: SendOnchainFeeQuote,
1201 },
1202 Bolt11Invoice {
1203 invoice_details: Bolt11InvoiceDetails,
1204 spark_transfer_fee_sats: Option<u64>,
1205 lightning_fee_sats: u64,
1206 }, SparkAddress {
1208 address: String,
1209 fee: u128,
1212 token_identifier: Option<String>,
1215 },
1216 SparkInvoice {
1217 spark_invoice_details: SparkInvoiceDetails,
1218 fee: u128,
1221 token_identifier: Option<String>,
1224 },
1225}
1226
1227#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1228#[derive(Debug, Clone, Serialize)]
1229pub struct SendOnchainFeeQuote {
1230 pub id: String,
1231 pub expires_at: u64,
1232 pub speed_fast: SendOnchainSpeedFeeQuote,
1233 pub speed_medium: SendOnchainSpeedFeeQuote,
1234 pub speed_slow: SendOnchainSpeedFeeQuote,
1235}
1236
1237#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1238#[derive(Debug, Clone, Serialize)]
1239pub struct SendOnchainSpeedFeeQuote {
1240 pub user_fee_sat: u64,
1241 pub l1_broadcast_fee_sat: u64,
1242}
1243
1244impl SendOnchainSpeedFeeQuote {
1245 pub fn total_fee_sat(&self) -> u64 {
1246 self.user_fee_sat.saturating_add(self.l1_broadcast_fee_sat)
1247 }
1248}
1249
1250#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1251pub struct ReceivePaymentRequest {
1252 pub payment_method: ReceivePaymentMethod,
1253}
1254
1255#[derive(Debug, Clone, Serialize)]
1256#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1257pub struct ReceivePaymentResponse {
1258 pub payment_request: String,
1259 pub fee: u128,
1262}
1263
1264#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1265pub struct PrepareLnurlPayRequest {
1266 pub amount: u128,
1269 pub pay_request: LnurlPayRequestDetails,
1270 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1271 pub comment: Option<String>,
1272 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1273 pub validate_success_action_url: Option<bool>,
1274 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1276 pub token_identifier: Option<String>,
1277 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1279 pub conversion_options: Option<ConversionOptions>,
1280 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1282 pub fee_policy: Option<FeePolicy>,
1283}
1284
1285#[derive(Debug, Clone)]
1286#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1287pub struct PrepareLnurlPayResponse {
1288 pub amount_sats: u64,
1293 pub comment: Option<String>,
1294 pub pay_request: LnurlPayRequestDetails,
1295 pub fee_sats: u64,
1298 pub invoice_details: Bolt11InvoiceDetails,
1299 pub success_action: Option<SuccessAction>,
1300 pub conversion_estimate: Option<ConversionEstimate>,
1302 pub fee_policy: FeePolicy,
1304}
1305
1306#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1307pub struct LnurlPayRequest {
1308 pub prepare_response: PrepareLnurlPayResponse,
1309 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1313 pub idempotency_key: Option<String>,
1314}
1315
1316#[derive(Debug, Serialize)]
1317#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1318pub struct LnurlPayResponse {
1319 pub payment: Payment,
1320 pub success_action: Option<SuccessActionProcessed>,
1321}
1322
1323#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1324pub struct LnurlWithdrawRequest {
1325 pub amount_sats: u64,
1328 pub withdraw_request: LnurlWithdrawRequestDetails,
1329 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1333 pub completion_timeout_secs: Option<u32>,
1334}
1335
1336#[derive(Debug, Serialize)]
1337#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1338pub struct LnurlWithdrawResponse {
1339 pub payment_request: String,
1341 pub payment: Option<Payment>,
1342}
1343
1344#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
1346#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1347pub struct LnurlPayInfo {
1348 pub ln_address: Option<String>,
1349 pub comment: Option<String>,
1350 pub domain: Option<String>,
1351 pub metadata: Option<String>,
1352 pub processed_success_action: Option<SuccessActionProcessed>,
1353 pub raw_success_action: Option<SuccessAction>,
1354}
1355
1356#[derive(Clone, Debug, Deserialize, Serialize)]
1358#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1359pub struct LnurlWithdrawInfo {
1360 pub withdraw_url: String,
1361}
1362
1363impl LnurlPayInfo {
1364 pub fn extract_description(&self) -> Option<String> {
1365 let Some(metadata) = &self.metadata else {
1366 return None;
1367 };
1368
1369 let Ok(metadata) = serde_json::from_str::<Vec<Vec<Value>>>(metadata) else {
1370 return None;
1371 };
1372
1373 for arr in metadata {
1374 if arr.len() != 2 {
1375 continue;
1376 }
1377 if let (Some(key), Some(value)) = (arr[0].as_str(), arr[1].as_str())
1378 && key == "text/plain"
1379 {
1380 return Some(value.to_string());
1381 }
1382 }
1383
1384 None
1385 }
1386}
1387
1388#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
1390#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1391pub enum FeePolicy {
1392 #[default]
1395 FeesExcluded,
1396 FeesIncluded,
1399}
1400
1401#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1402#[derive(Debug, Clone, Serialize)]
1403pub enum OnchainConfirmationSpeed {
1404 Fast,
1405 Medium,
1406 Slow,
1407}
1408
1409#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1410pub struct PrepareSendPaymentRequest {
1411 pub payment_request: String,
1412 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1417 pub amount: Option<u128>,
1418 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1421 pub token_identifier: Option<String>,
1422 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1424 pub conversion_options: Option<ConversionOptions>,
1425 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1427 pub fee_policy: Option<FeePolicy>,
1428}
1429
1430#[derive(Debug, Clone, Serialize)]
1431#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1432pub struct PrepareSendPaymentResponse {
1433 pub payment_method: SendPaymentMethod,
1434 pub amount: u128,
1439 pub token_identifier: Option<String>,
1442 pub conversion_estimate: Option<ConversionEstimate>,
1444 pub fee_policy: FeePolicy,
1446}
1447
1448#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1449pub enum SendPaymentOptions {
1450 BitcoinAddress {
1451 confirmation_speed: OnchainConfirmationSpeed,
1453 },
1454 Bolt11Invoice {
1455 prefer_spark: bool,
1456
1457 completion_timeout_secs: Option<u32>,
1460 },
1461 SparkAddress {
1462 htlc_options: Option<SparkHtlcOptions>,
1465 },
1466}
1467
1468#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1469pub struct SparkHtlcOptions {
1470 pub payment_hash: String,
1472 pub expiry_duration_secs: u64,
1475}
1476
1477#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1478pub struct SendPaymentRequest {
1479 pub prepare_response: PrepareSendPaymentResponse,
1480 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1481 pub options: Option<SendPaymentOptions>,
1482 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1487 pub idempotency_key: Option<String>,
1488}
1489
1490#[derive(Debug, Clone, Serialize)]
1491#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1492pub struct SendPaymentResponse {
1493 pub payment: Payment,
1494}
1495
1496#[derive(Debug, Clone)]
1497#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1498pub enum PaymentDetailsFilter {
1499 Spark {
1500 htlc_status: Option<Vec<SparkHtlcStatus>>,
1502 conversion_refund_needed: Option<bool>,
1504 },
1505 Token {
1506 conversion_refund_needed: Option<bool>,
1508 tx_hash: Option<String>,
1510 tx_type: Option<TokenTransactionType>,
1512 },
1513 Lightning {
1514 htlc_status: Option<Vec<SparkHtlcStatus>>,
1516 },
1517}
1518
1519#[derive(Debug, Clone, Default)]
1521#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1522pub struct ListPaymentsRequest {
1523 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1524 pub type_filter: Option<Vec<PaymentType>>,
1525 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1526 pub status_filter: Option<Vec<PaymentStatus>>,
1527 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1528 pub asset_filter: Option<AssetFilter>,
1529 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1531 pub payment_details_filter: Option<Vec<PaymentDetailsFilter>>,
1532 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1534 pub from_timestamp: Option<u64>,
1535 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1537 pub to_timestamp: Option<u64>,
1538 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1540 pub offset: Option<u32>,
1541 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1543 pub limit: Option<u32>,
1544 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1545 pub sort_ascending: Option<bool>,
1546}
1547
1548#[derive(Debug, Clone)]
1550#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1551pub enum AssetFilter {
1552 Bitcoin,
1553 Token {
1554 token_identifier: Option<String>,
1556 },
1557}
1558
1559impl FromStr for AssetFilter {
1560 type Err = String;
1561
1562 fn from_str(s: &str) -> Result<Self, Self::Err> {
1563 Ok(match s.to_lowercase().as_str() {
1564 "bitcoin" => AssetFilter::Bitcoin,
1565 "token" => AssetFilter::Token {
1566 token_identifier: None,
1567 },
1568 str if str.starts_with("token:") => AssetFilter::Token {
1569 token_identifier: Some(
1570 str.split_once(':')
1571 .ok_or(format!("Invalid asset filter '{s}'"))?
1572 .1
1573 .to_string(),
1574 ),
1575 },
1576 _ => return Err(format!("Invalid asset filter '{s}'")),
1577 })
1578 }
1579}
1580
1581#[derive(Debug, Clone, Serialize)]
1583#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1584pub struct ListPaymentsResponse {
1585 pub payments: Vec<Payment>,
1587}
1588
1589#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1590pub struct GetPaymentRequest {
1591 pub payment_id: String,
1592}
1593
1594#[derive(Debug, Clone, Serialize)]
1595#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1596pub struct GetPaymentResponse {
1597 pub payment: Payment,
1598}
1599
1600#[cfg_attr(feature = "uniffi", uniffi::export(callback_interface))]
1601pub trait Logger: Send + Sync {
1602 fn log(&self, l: LogEntry);
1603}
1604
1605#[derive(Debug, Clone, Serialize)]
1606#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1607pub struct LogEntry {
1608 pub line: String,
1609 pub level: String,
1610}
1611
1612#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1613#[derive(Debug, Clone, Serialize, Deserialize)]
1614pub struct CheckLightningAddressRequest {
1615 pub username: String,
1616}
1617
1618#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1619#[derive(Debug, Clone, Serialize, Deserialize)]
1620pub struct RegisterLightningAddressRequest {
1621 pub username: String,
1622 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1623 pub description: Option<String>,
1624}
1625
1626#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1627#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
1628pub struct LnurlInfo {
1629 pub url: String,
1630 pub bech32: String,
1631}
1632
1633impl LnurlInfo {
1634 pub fn new(url: String) -> Self {
1635 let bech32 =
1636 breez_sdk_common::lnurl::encode_lnurl_to_bech32(&url).unwrap_or_else(|_| url.clone());
1637 Self { url, bech32 }
1638 }
1639}
1640
1641#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1642#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
1643pub struct LightningAddressInfo {
1644 pub description: String,
1645 pub lightning_address: String,
1646 pub lnurl: LnurlInfo,
1647 pub username: String,
1648}
1649
1650impl From<RecoverLnurlPayResponse> for LightningAddressInfo {
1651 fn from(resp: RecoverLnurlPayResponse) -> Self {
1652 Self {
1653 description: resp.description,
1654 lightning_address: resp.lightning_address,
1655 lnurl: LnurlInfo::new(resp.lnurl),
1656 username: resp.username,
1657 }
1658 }
1659}
1660
1661#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1662#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1663pub enum KeySetType {
1664 #[default]
1665 Default,
1666 Taproot,
1667 NativeSegwit,
1668 WrappedSegwit,
1669 Legacy,
1670}
1671
1672impl From<spark_wallet::KeySetType> for KeySetType {
1673 fn from(value: spark_wallet::KeySetType) -> Self {
1674 match value {
1675 spark_wallet::KeySetType::Default => KeySetType::Default,
1676 spark_wallet::KeySetType::Taproot => KeySetType::Taproot,
1677 spark_wallet::KeySetType::NativeSegwit => KeySetType::NativeSegwit,
1678 spark_wallet::KeySetType::WrappedSegwit => KeySetType::WrappedSegwit,
1679 spark_wallet::KeySetType::Legacy => KeySetType::Legacy,
1680 }
1681 }
1682}
1683
1684impl From<KeySetType> for spark_wallet::KeySetType {
1685 fn from(value: KeySetType) -> Self {
1686 match value {
1687 KeySetType::Default => spark_wallet::KeySetType::Default,
1688 KeySetType::Taproot => spark_wallet::KeySetType::Taproot,
1689 KeySetType::NativeSegwit => spark_wallet::KeySetType::NativeSegwit,
1690 KeySetType::WrappedSegwit => spark_wallet::KeySetType::WrappedSegwit,
1691 KeySetType::Legacy => spark_wallet::KeySetType::Legacy,
1692 }
1693 }
1694}
1695
1696#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
1700#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1701pub struct KeySetConfig {
1702 pub key_set_type: KeySetType,
1704 pub use_address_index: bool,
1706 pub account_number: Option<u32>,
1708}
1709
1710impl Default for KeySetConfig {
1711 fn default() -> Self {
1712 Self {
1713 key_set_type: KeySetType::Default,
1714 use_address_index: false,
1715 account_number: None,
1716 }
1717 }
1718}
1719
1720#[derive(Debug, Clone, Serialize)]
1722#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1723pub struct ListFiatCurrenciesResponse {
1724 pub currencies: Vec<FiatCurrency>,
1726}
1727
1728#[derive(Debug, Clone, Serialize)]
1730#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1731pub struct ListFiatRatesResponse {
1732 pub rates: Vec<Rate>,
1734}
1735
1736#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
1738#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1739pub enum ServiceStatus {
1740 Operational,
1742 Degraded,
1744 Partial,
1746 Unknown,
1748 Major,
1750}
1751
1752#[derive(Debug, Clone, Serialize)]
1754#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1755pub struct SparkStatus {
1756 pub status: ServiceStatus,
1758 pub last_updated: u64,
1760}
1761
1762pub(crate) enum WaitForPaymentIdentifier {
1763 PaymentId(String),
1764 PaymentRequest(String),
1765}
1766
1767#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1768pub struct GetTokensMetadataRequest {
1769 pub token_identifiers: Vec<String>,
1770}
1771
1772#[derive(Debug, Clone, Serialize)]
1773#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1774pub struct GetTokensMetadataResponse {
1775 pub tokens_metadata: Vec<TokenMetadata>,
1776}
1777
1778#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1779pub struct SignMessageRequest {
1780 pub message: String,
1781 pub compact: bool,
1783}
1784
1785#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1786pub struct SignMessageResponse {
1787 pub pubkey: String,
1788 pub signature: String,
1790}
1791
1792#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1793pub struct CheckMessageRequest {
1794 pub message: String,
1796 pub pubkey: String,
1798 pub signature: String,
1800}
1801
1802#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1803pub struct CheckMessageResponse {
1804 pub is_valid: bool,
1805}
1806
1807#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1808#[derive(Debug, Clone, Serialize)]
1809pub struct UserSettings {
1810 pub spark_private_mode_enabled: bool,
1811
1812 pub stable_balance_active_label: Option<String>,
1814}
1815
1816#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1817pub struct UpdateUserSettingsRequest {
1818 pub spark_private_mode_enabled: Option<bool>,
1819
1820 #[cfg_attr(feature = "uniffi", uniffi(default = None))]
1822 pub stable_balance_active_label: Option<StableBalanceActiveLabel>,
1823}
1824
1825#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1826pub struct ClaimHtlcPaymentRequest {
1827 pub preimage: String,
1828}
1829
1830#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1831pub struct ClaimHtlcPaymentResponse {
1832 pub payment: Payment,
1833}
1834
1835#[derive(Debug, Clone, Deserialize, Serialize)]
1836#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1837pub struct LnurlReceiveMetadata {
1838 pub nostr_zap_request: Option<String>,
1839 pub nostr_zap_receipt: Option<String>,
1840 pub sender_comment: Option<String>,
1841}
1842
1843#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1844pub struct OptimizationProgress {
1845 pub is_running: bool,
1846 pub current_round: u32,
1847 pub total_rounds: u32,
1848}
1849
1850#[derive(Debug, Clone, Serialize, Deserialize)]
1852#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1853pub struct Contact {
1854 pub id: String,
1855 pub name: String,
1856 pub payment_identifier: String,
1858 pub created_at: u64,
1859 pub updated_at: u64,
1860}
1861
1862#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1864pub struct AddContactRequest {
1865 pub name: String,
1866 pub payment_identifier: String,
1868}
1869
1870#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1872pub struct UpdateContactRequest {
1873 pub id: String,
1874 pub name: String,
1875 pub payment_identifier: String,
1877}
1878
1879#[derive(Debug, Clone, Default)]
1881#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1882pub struct ListContactsRequest {
1883 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1884 pub offset: Option<u32>,
1885 #[cfg_attr(feature = "uniffi", uniffi(default=None))]
1886 pub limit: Option<u32>,
1887}
1888
1889#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1891#[allow(clippy::enum_variant_names)]
1892#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
1893pub enum WebhookEventType {
1894 LightningReceiveFinished,
1896 LightningSendFinished,
1898 CoopExitFinished,
1900 StaticDepositFinished,
1902 Unknown(String),
1904}
1905
1906#[derive(Debug, Clone, Serialize)]
1908#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1909pub struct Webhook {
1910 pub id: String,
1912 pub url: String,
1914 pub event_types: Vec<WebhookEventType>,
1916}
1917
1918#[derive(Debug, Clone)]
1920#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1921pub struct RegisterWebhookRequest {
1922 pub url: String,
1924 pub secret: String,
1926 pub event_types: Vec<WebhookEventType>,
1928}
1929
1930#[derive(Debug, Clone, Serialize)]
1932#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1933pub struct RegisterWebhookResponse {
1934 pub webhook_id: String,
1936}
1937
1938#[derive(Debug, Clone)]
1940#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1941pub struct UnregisterWebhookRequest {
1942 pub webhook_id: String,
1944}