mirror of
https://github.com/aljazceru/breez-sdk-liquid.git
synced 2025-12-17 22:14:24 +01:00
SDK events framework (#193)
* Add events framework * Adapt RN codegen and add synced event * Only use get_connection internally
This commit is contained in:
6
cli/.gitignore
vendored
Normal file
6
cli/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
target
|
||||||
|
liquid*/
|
||||||
|
history.txt
|
||||||
|
phrase
|
||||||
|
*.sql
|
||||||
|
*.log
|
||||||
19
cli/Cargo.lock
generated
19
cli/Cargo.lock
generated
@@ -401,6 +401,7 @@ dependencies = [
|
|||||||
"rustyline",
|
"rustyline",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -416,6 +417,7 @@ dependencies = [
|
|||||||
"lwk_common",
|
"lwk_common",
|
||||||
"lwk_signer",
|
"lwk_signer",
|
||||||
"lwk_wollet",
|
"lwk_wollet",
|
||||||
|
"once_cell",
|
||||||
"openssl",
|
"openssl",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"rusqlite_migration",
|
"rusqlite_migration",
|
||||||
@@ -424,6 +426,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
"tungstenite",
|
"tungstenite",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -441,9 +444,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.15.0"
|
version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
|
checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
@@ -2399,9 +2402,21 @@ dependencies = [
|
|||||||
"num_cpus",
|
"num_cpus",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ qrcode-rs = { version = "0.1", default-features = false }
|
|||||||
rustyline = { version = "13.0.0", features = ["derive"] }
|
rustyline = { version = "13.0.0", features = ["derive"] }
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
serde_json = "1.0.115"
|
serde_json = "1.0.115"
|
||||||
|
tokio = { version = "1", features = ["macros"] }
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
# https://github.com/BlockstreamResearch/rust-secp256k1-zkp/pull/48/commits
|
# https://github.com/BlockstreamResearch/rust-secp256k1-zkp/pull/48/commits
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ pub(crate) enum Command {
|
|||||||
ListPayments,
|
ListPayments,
|
||||||
/// Get the balance and general info of the current instance
|
/// Get the balance and general info of the current instance
|
||||||
GetInfo,
|
GetInfo,
|
||||||
|
/// Sync local data with mempool and onchain data
|
||||||
|
Sync,
|
||||||
/// Empties the encrypted transaction cache
|
/// Empties the encrypted transaction cache
|
||||||
EmptyCache,
|
EmptyCache,
|
||||||
/// Backs up the current pending swaps
|
/// Backs up the current pending swaps
|
||||||
@@ -89,7 +91,7 @@ macro_rules! wait_confirmation {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn handle_command(
|
pub(crate) async fn handle_command(
|
||||||
_rl: &mut Editor<CliHelper, DefaultHistory>,
|
_rl: &mut Editor<CliHelper, DefaultHistory>,
|
||||||
sdk: &Arc<LiquidSdk>,
|
sdk: &Arc<LiquidSdk>,
|
||||||
command: Command,
|
command: Command,
|
||||||
@@ -116,8 +118,9 @@ pub(crate) fn handle_command(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
Command::SendPayment { bolt11, delay } => {
|
Command::SendPayment { bolt11, delay } => {
|
||||||
let prepare_response =
|
let prepare_response = sdk
|
||||||
sdk.prepare_send_payment(&PrepareSendRequest { invoice: bolt11 })?;
|
.prepare_send_payment(&PrepareSendRequest { invoice: bolt11 })
|
||||||
|
.await?;
|
||||||
|
|
||||||
wait_confirmation!(
|
wait_confirmation!(
|
||||||
format!(
|
format!(
|
||||||
@@ -131,23 +134,27 @@ pub(crate) fn handle_command(
|
|||||||
let sdk_cloned = sdk.clone();
|
let sdk_cloned = sdk.clone();
|
||||||
let prepare_cloned = prepare_response.clone();
|
let prepare_cloned = prepare_response.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
tokio::spawn(async move {
|
||||||
thread::sleep(Duration::from_secs(delay));
|
thread::sleep(Duration::from_secs(delay));
|
||||||
sdk_cloned.send_payment(&prepare_cloned).unwrap();
|
sdk_cloned.send_payment(&prepare_cloned).await.unwrap();
|
||||||
});
|
});
|
||||||
command_result!(prepare_response)
|
command_result!(prepare_response)
|
||||||
} else {
|
} else {
|
||||||
let response = sdk.send_payment(&prepare_response)?;
|
let response = sdk.send_payment(&prepare_response).await?;
|
||||||
command_result!(response)
|
command_result!(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Command::GetInfo => {
|
Command::GetInfo => {
|
||||||
command_result!(sdk.get_info(GetInfoRequest { with_scan: true })?)
|
command_result!(sdk.get_info(GetInfoRequest { with_scan: true }).await?)
|
||||||
}
|
}
|
||||||
Command::ListPayments => {
|
Command::ListPayments => {
|
||||||
let payments = sdk.list_payments()?;
|
let payments = sdk.list_payments()?;
|
||||||
command_result!(payments)
|
command_result!(payments)
|
||||||
}
|
}
|
||||||
|
Command::Sync => {
|
||||||
|
sdk.sync().await?;
|
||||||
|
command_result!("Synced successfully")
|
||||||
|
}
|
||||||
Command::EmptyCache => {
|
Command::EmptyCache => {
|
||||||
sdk.empty_wallet_cache()?;
|
sdk.empty_wallet_cache()?;
|
||||||
command_result!("Cache emptied successfully")
|
command_result!("Cache emptied successfully")
|
||||||
|
|||||||
@@ -45,7 +45,16 @@ fn show_results(result: Result<String>) -> Result<()> {
|
|||||||
Ok(println!("{result_str}"))
|
Ok(println!("{result_str}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
struct CliEventListener {}
|
||||||
|
|
||||||
|
impl EventListener for CliEventListener {
|
||||||
|
fn on_event(&self, e: LiquidSdkEvent) {
|
||||||
|
info!("Received event: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let data_dir_str = args.data_dir.unwrap_or(DEFAULT_DATA_DIR.to_string());
|
let data_dir_str = args.data_dir.unwrap_or(DEFAULT_DATA_DIR.to_string());
|
||||||
@@ -66,6 +75,8 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
env_logger::builder()
|
env_logger::builder()
|
||||||
.target(env_logger::Target::Pipe(Box::new(log_file)))
|
.target(env_logger::Target::Pipe(Box::new(log_file)))
|
||||||
|
.filter(None, log::LevelFilter::Debug)
|
||||||
|
.filter(Some("rustyline"), log::LevelFilter::Warn)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let persistence = CliPersistence { data_dir };
|
let persistence = CliPersistence { data_dir };
|
||||||
@@ -86,7 +97,11 @@ fn main() -> Result<()> {
|
|||||||
mnemonic: mnemonic.to_string(),
|
mnemonic: mnemonic.to_string(),
|
||||||
data_dir: Some(data_dir_str),
|
data_dir: Some(data_dir_str),
|
||||||
network,
|
network,
|
||||||
})?;
|
})
|
||||||
|
.await?;
|
||||||
|
let listener_id = sdk
|
||||||
|
.add_event_listener(Box::new(CliEventListener {}))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let cli_prompt = match network {
|
let cli_prompt = match network {
|
||||||
Network::Liquid => "breez-liquid-cli [mainnet]> ",
|
Network::Liquid => "breez-liquid-cli [mainnet]> ",
|
||||||
@@ -105,7 +120,7 @@ fn main() -> Result<()> {
|
|||||||
println!("{}", cli_res.unwrap_err());
|
println!("{}", cli_res.unwrap_err());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let res = handle_command(rl, &sdk, cli_res.unwrap());
|
let res = handle_command(rl, &sdk, cli_res.unwrap()).await;
|
||||||
show_results(res)?;
|
show_results(res)?;
|
||||||
}
|
}
|
||||||
Err(ReadlineError::Interrupted) => {
|
Err(ReadlineError::Interrupted) => {
|
||||||
@@ -123,5 +138,6 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sdk.remove_event_listener(listener_id).await?;
|
||||||
rl.save_history(history_file).map_err(|e| anyhow!(e))
|
rl.save_history(history_file).map_err(|e| anyhow!(e))
|
||||||
}
|
}
|
||||||
|
|||||||
4
lib/Cargo.lock
generated
4
lib/Cargo.lock
generated
@@ -520,6 +520,7 @@ dependencies = [
|
|||||||
"lwk_common",
|
"lwk_common",
|
||||||
"lwk_signer",
|
"lwk_signer",
|
||||||
"lwk_wollet",
|
"lwk_wollet",
|
||||||
|
"once_cell",
|
||||||
"openssl",
|
"openssl",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"rusqlite_migration",
|
"rusqlite_migration",
|
||||||
@@ -529,6 +530,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"tempdir",
|
"tempdir",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
"tungstenite",
|
"tungstenite",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
@@ -541,7 +543,9 @@ dependencies = [
|
|||||||
"breez-liquid-sdk",
|
"breez-liquid-sdk",
|
||||||
"camino",
|
"camino",
|
||||||
"glob",
|
"glob",
|
||||||
|
"once_cell",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
"uniffi 0.27.1",
|
"uniffi 0.27.1",
|
||||||
"uniffi-kotlin-multiplatform",
|
"uniffi-kotlin-multiplatform",
|
||||||
"uniffi_bindgen 0.25.3",
|
"uniffi_bindgen 0.25.3",
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ path = "uniffi-bindgen.rs"
|
|||||||
name = "breez_liquid_sdk_bindings"
|
name = "breez_liquid_sdk_bindings"
|
||||||
crate-type = ["staticlib", "cdylib", "lib"]
|
crate-type = ["staticlib", "cdylib", "lib"]
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
breez-liquid-sdk = { path = "../core" }
|
breez-liquid-sdk = { path = "../core" }
|
||||||
@@ -21,6 +20,8 @@ uniffi_bindgen = "0.25.2"
|
|||||||
uniffi-kotlin-multiplatform = { git = "https://gitlab.com/trixnity/uniffi-kotlin-multiplatform-bindings", rev = "55d51f3abf9819b32bd81756053dcfc10f8d5522" }
|
uniffi-kotlin-multiplatform = { git = "https://gitlab.com/trixnity/uniffi-kotlin-multiplatform-bindings", rev = "55d51f3abf9819b32bd81756053dcfc10f8d5522" }
|
||||||
camino = "1.1.1"
|
camino = "1.1.1"
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
tokio = { version = "1", features = ["rt"] }
|
||||||
|
once_cell = "*"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
uniffi = { workspace = true, features = [ "build" ] }
|
uniffi = { workspace = true, features = [ "build" ] }
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ typedef struct _Dart_Handle* Dart_Handle;
|
|||||||
*/
|
*/
|
||||||
#define LIQUID_CLAIM_TX_FEERATE_MSAT 100.0
|
#define LIQUID_CLAIM_TX_FEERATE_MSAT 100.0
|
||||||
|
|
||||||
|
typedef struct wire_cst_list_prim_u_8_strict {
|
||||||
|
uint8_t *ptr;
|
||||||
|
int32_t len;
|
||||||
|
} wire_cst_list_prim_u_8_strict;
|
||||||
|
|
||||||
typedef struct wire_cst_get_info_request {
|
typedef struct wire_cst_get_info_request {
|
||||||
bool with_scan;
|
bool with_scan;
|
||||||
} wire_cst_get_info_request;
|
} wire_cst_get_info_request;
|
||||||
@@ -28,11 +33,6 @@ typedef struct wire_cst_prepare_receive_request {
|
|||||||
uint64_t payer_amount_sat;
|
uint64_t payer_amount_sat;
|
||||||
} wire_cst_prepare_receive_request;
|
} wire_cst_prepare_receive_request;
|
||||||
|
|
||||||
typedef struct wire_cst_list_prim_u_8_strict {
|
|
||||||
uint8_t *ptr;
|
|
||||||
int32_t len;
|
|
||||||
} wire_cst_list_prim_u_8_strict;
|
|
||||||
|
|
||||||
typedef struct wire_cst_prepare_send_request {
|
typedef struct wire_cst_prepare_send_request {
|
||||||
struct wire_cst_list_prim_u_8_strict *invoice;
|
struct wire_cst_list_prim_u_8_strict *invoice;
|
||||||
} wire_cst_prepare_send_request;
|
} wire_cst_prepare_send_request;
|
||||||
@@ -93,6 +93,44 @@ typedef struct wire_cst_liquid_sdk_error {
|
|||||||
union LiquidSdkErrorKind kind;
|
union LiquidSdkErrorKind kind;
|
||||||
} wire_cst_liquid_sdk_error;
|
} wire_cst_liquid_sdk_error;
|
||||||
|
|
||||||
|
typedef struct wire_cst_LiquidSdkEvent_PaymentFailed {
|
||||||
|
struct wire_cst_payment *details;
|
||||||
|
} wire_cst_LiquidSdkEvent_PaymentFailed;
|
||||||
|
|
||||||
|
typedef struct wire_cst_LiquidSdkEvent_PaymentPending {
|
||||||
|
struct wire_cst_payment *details;
|
||||||
|
} wire_cst_LiquidSdkEvent_PaymentPending;
|
||||||
|
|
||||||
|
typedef struct wire_cst_LiquidSdkEvent_PaymentRefunded {
|
||||||
|
struct wire_cst_payment *details;
|
||||||
|
} wire_cst_LiquidSdkEvent_PaymentRefunded;
|
||||||
|
|
||||||
|
typedef struct wire_cst_LiquidSdkEvent_PaymentRefundPending {
|
||||||
|
struct wire_cst_payment *details;
|
||||||
|
} wire_cst_LiquidSdkEvent_PaymentRefundPending;
|
||||||
|
|
||||||
|
typedef struct wire_cst_LiquidSdkEvent_PaymentSucceed {
|
||||||
|
struct wire_cst_payment *details;
|
||||||
|
} wire_cst_LiquidSdkEvent_PaymentSucceed;
|
||||||
|
|
||||||
|
typedef struct wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation {
|
||||||
|
struct wire_cst_payment *details;
|
||||||
|
} wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation;
|
||||||
|
|
||||||
|
typedef union LiquidSdkEventKind {
|
||||||
|
struct wire_cst_LiquidSdkEvent_PaymentFailed PaymentFailed;
|
||||||
|
struct wire_cst_LiquidSdkEvent_PaymentPending PaymentPending;
|
||||||
|
struct wire_cst_LiquidSdkEvent_PaymentRefunded PaymentRefunded;
|
||||||
|
struct wire_cst_LiquidSdkEvent_PaymentRefundPending PaymentRefundPending;
|
||||||
|
struct wire_cst_LiquidSdkEvent_PaymentSucceed PaymentSucceed;
|
||||||
|
struct wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation PaymentWaitingConfirmation;
|
||||||
|
} LiquidSdkEventKind;
|
||||||
|
|
||||||
|
typedef struct wire_cst_liquid_sdk_event {
|
||||||
|
int32_t tag;
|
||||||
|
union LiquidSdkEventKind kind;
|
||||||
|
} wire_cst_liquid_sdk_event;
|
||||||
|
|
||||||
typedef struct wire_cst_PaymentError_Generic {
|
typedef struct wire_cst_PaymentError_Generic {
|
||||||
struct wire_cst_list_prim_u_8_strict *err;
|
struct wire_cst_list_prim_u_8_strict *err;
|
||||||
} wire_cst_PaymentError_Generic;
|
} wire_cst_PaymentError_Generic;
|
||||||
@@ -136,6 +174,10 @@ typedef struct wire_cst_send_payment_response {
|
|||||||
struct wire_cst_list_prim_u_8_strict *txid;
|
struct wire_cst_list_prim_u_8_strict *txid;
|
||||||
} wire_cst_send_payment_response;
|
} wire_cst_send_payment_response;
|
||||||
|
|
||||||
|
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener(int64_t port_,
|
||||||
|
uintptr_t that,
|
||||||
|
struct wire_cst_list_prim_u_8_strict *listener);
|
||||||
|
|
||||||
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(int64_t port_,
|
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(int64_t port_,
|
||||||
uintptr_t that);
|
uintptr_t that);
|
||||||
|
|
||||||
@@ -183,6 +225,8 @@ struct wire_cst_connect_request *frbgen_breez_liquid_cst_new_box_autoadd_connect
|
|||||||
|
|
||||||
struct wire_cst_get_info_request *frbgen_breez_liquid_cst_new_box_autoadd_get_info_request(void);
|
struct wire_cst_get_info_request *frbgen_breez_liquid_cst_new_box_autoadd_get_info_request(void);
|
||||||
|
|
||||||
|
struct wire_cst_payment *frbgen_breez_liquid_cst_new_box_autoadd_payment(void);
|
||||||
|
|
||||||
struct wire_cst_prepare_receive_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request(void);
|
struct wire_cst_prepare_receive_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request(void);
|
||||||
|
|
||||||
struct wire_cst_prepare_receive_response *frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_response(void);
|
struct wire_cst_prepare_receive_response *frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_response(void);
|
||||||
@@ -202,6 +246,7 @@ static int64_t dummy_method_to_enforce_bundling(void) {
|
|||||||
int64_t dummy_var = 0;
|
int64_t dummy_var = 0;
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_connect_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_connect_request);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_get_info_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_get_info_request);
|
||||||
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_payment);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_response);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_response);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request);
|
||||||
@@ -212,6 +257,7 @@ static int64_t dummy_method_to_enforce_bundling(void) {
|
|||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_prim_u_8_strict);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_prim_u_8_strict);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk);
|
||||||
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_empty_wallet_cache);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_empty_wallet_cache);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_get_info);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_get_info);
|
||||||
|
|||||||
@@ -101,10 +101,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
|
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.0"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -309,10 +309,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.4.2"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -330,4 +330,4 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.0 <4.0.0"
|
dart: ">=3.2.0 <4.0.0"
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ Future<void> mainImpl(List<String> args) async {
|
|||||||
final triple = target.triple;
|
final triple = target.triple;
|
||||||
final flutterIdentifier = target.flutterIdentifier;
|
final flutterIdentifier = target.flutterIdentifier;
|
||||||
await run('rustup target add $triple');
|
await run('rustup target add $triple');
|
||||||
await run('${target.compiler} --target $triple $profileArg', args: compilerOpts);
|
await run('${target.compiler} --package breez-liquid-sdk --target $triple $profileArg',
|
||||||
|
args: compilerOpts);
|
||||||
await run('mkdir -p $flutterIdentifier');
|
await run('mkdir -p $flutterIdentifier');
|
||||||
await run('cp ../../../../target/$triple/$profile/${target.libName} $flutterIdentifier/');
|
await run('cp ../../../../target/$triple/$profile/${target.libName} $flutterIdentifier/');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pub use uniffi_bindgen::bindings::kotlin::gen_kotlin::*;
|
|||||||
use crate::generator::RNConfig;
|
use crate::generator::RNConfig;
|
||||||
|
|
||||||
static IGNORED_FUNCTIONS: Lazy<HashSet<String>> = Lazy::new(|| {
|
static IGNORED_FUNCTIONS: Lazy<HashSet<String>> = Lazy::new(|| {
|
||||||
let list: Vec<&str> = vec!["connect"];
|
let list: Vec<&str> = vec!["connect", "add_event_listener"];
|
||||||
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
{% let obj = ci.get_object_definition(name).unwrap() %}
|
{% let obj = ci.get_object_definition(name).unwrap() %}
|
||||||
{% let obj_interface = "getBindingLiquidSdk()." %}
|
{% let obj_interface = "getBindingLiquidSdk()." %}
|
||||||
{%- for func in obj.methods() -%}
|
{%- for func in obj.methods() -%}
|
||||||
|
{%- if func.name()|ignored_function == false -%}
|
||||||
{%- include "TopLevelFunctionTemplate.kt" %}
|
{%- include "TopLevelFunctionTemplate.kt" %}
|
||||||
|
{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{%- endmatch -%}
|
{%- endmatch -%}
|
||||||
|
|||||||
@@ -67,6 +67,22 @@ class BreezLiquidSDKModule(reactContext: ReactApplicationContext) : ReactContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun addEventListener(promise: Promise) {
|
||||||
|
executor.execute {
|
||||||
|
try {
|
||||||
|
val emitter = reactApplicationContext.getJSModule(RCTDeviceEventEmitter::class.java)
|
||||||
|
var eventListener = BreezLiquidSDKEventListener(emitter)
|
||||||
|
val res = getBindingLiquidSdk().addEventListener(eventListener)
|
||||||
|
|
||||||
|
eventListener.setId(res)
|
||||||
|
promise.resolve(res)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
{%- include "Objects.kt" %}
|
{%- include "Objects.kt" %}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::generator::RNConfig;
|
|||||||
pub use uniffi_bindgen::bindings::swift::gen_swift::*;
|
pub use uniffi_bindgen::bindings::swift::gen_swift::*;
|
||||||
|
|
||||||
static IGNORED_FUNCTIONS: Lazy<HashSet<String>> = Lazy::new(|| {
|
static IGNORED_FUNCTIONS: Lazy<HashSet<String>> = Lazy::new(|| {
|
||||||
let list: Vec<&str> = vec!["connect"];
|
let list: Vec<&str> = vec!["connect", "add_event_listener"];
|
||||||
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
{% let obj = ci.get_object_definition(name).unwrap() %}
|
{% let obj = ci.get_object_definition(name).unwrap() %}
|
||||||
{% let obj_interface = "getBindingLiquidSdk()." %}
|
{% let obj_interface = "getBindingLiquidSdk()." %}
|
||||||
{%- for func in obj.methods() -%}
|
{%- for func in obj.methods() -%}
|
||||||
|
{%- if func.name()|ignored_function == false -%}
|
||||||
{%- include "TopLevelFunctionTemplate.swift" %}
|
{%- include "TopLevelFunctionTemplate.swift" %}
|
||||||
|
{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{%- endmatch -%}
|
{%- endmatch -%}
|
||||||
|
|||||||
@@ -12,13 +12,20 @@ RCT_EXTERN_METHOD(
|
|||||||
resolve: (RCTPromiseResolveBlock)resolve
|
resolve: (RCTPromiseResolveBlock)resolve
|
||||||
reject: (RCTPromiseRejectBlock)reject
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
)
|
)
|
||||||
|
|
||||||
|
RCT_EXTERN_METHOD(
|
||||||
|
addEventListener: (RCTPromiseResolveBlock)resolve
|
||||||
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
|
)
|
||||||
{%- for type_ in ci.iter_types() %}
|
{%- for type_ in ci.iter_types() %}
|
||||||
{%- let type_name = type_|type_name %}
|
{%- let type_name = type_|type_name %}
|
||||||
{%- match type_ %}
|
{%- match type_ %}
|
||||||
{%- when Type::Object ( name ) %}
|
{%- when Type::Object ( name ) %}
|
||||||
{% let obj = ci.get_object_definition(name).unwrap() %}
|
{% let obj = ci.get_object_definition(name).unwrap() %}
|
||||||
{%- for func in obj.methods() -%}
|
{%- for func in obj.methods() -%}
|
||||||
|
{%- if func.name()|ignored_function == false -%}
|
||||||
{%- include "ExternFunctionTemplate.m" %}
|
{%- include "ExternFunctionTemplate.m" %}
|
||||||
|
{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{%- endmatch -%}
|
{%- endmatch -%}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
|
|
||||||
public static var emitter: RCTEventEmitter!
|
public static var emitter: RCTEventEmitter!
|
||||||
public static var hasListeners: Bool = false
|
public static var hasListeners: Bool = false
|
||||||
|
public static var supportedEvents: [String] = []
|
||||||
|
|
||||||
private var bindingLiquidSdk: BindingLiquidSdk!
|
private var bindingLiquidSdk: BindingLiquidSdk!
|
||||||
|
|
||||||
@@ -25,9 +26,13 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
override static func moduleName() -> String! {
|
override static func moduleName() -> String! {
|
||||||
TAG
|
TAG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func addSupportedEvent(name: String) {
|
||||||
|
RNBreezLiquidSDK.supportedEvents.append(name)
|
||||||
|
}
|
||||||
|
|
||||||
override func supportedEvents() -> [String]! {
|
override func supportedEvents() -> [String]! {
|
||||||
return []
|
return RNBreezLiquidSDK.supportedEvents
|
||||||
}
|
}
|
||||||
|
|
||||||
override func startObserving() {
|
override func startObserving() {
|
||||||
@@ -73,6 +78,19 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
rejectErr(err: err, reject: reject)
|
rejectErr(err: err, reject: reject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc(addEventListener:reject:)
|
||||||
|
func addEventListener(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
|
do {
|
||||||
|
var eventListener = BreezLiquidSDKEventListener()
|
||||||
|
var res = try getBindingLiquidSdk().addEventListener(listener: eventListener)
|
||||||
|
|
||||||
|
eventListener.setId(id: res)
|
||||||
|
resolve(res)
|
||||||
|
} catch let err {
|
||||||
|
rejectErr(err: err, reject: reject)
|
||||||
|
}
|
||||||
|
}
|
||||||
{%- include "Objects.swift" %}
|
{%- include "Objects.swift" %}
|
||||||
|
|
||||||
func rejectErr(err: Error, reject: @escaping RCTPromiseRejectBlock) {
|
func rejectErr(err: Error, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ static KEYWORDS: Lazy<HashSet<String>> = Lazy::new(|| {
|
|||||||
});
|
});
|
||||||
|
|
||||||
static IGNORED_FUNCTIONS: Lazy<HashSet<String>> = Lazy::new(|| {
|
static IGNORED_FUNCTIONS: Lazy<HashSet<String>> = Lazy::new(|| {
|
||||||
let list: Vec<&str> = vec!["connect"];
|
let list: Vec<&str> = vec!["connect", "add_event_listener"];
|
||||||
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
|
|
||||||
|
export type EventListener = (e: LiquidSdkEvent) => void
|
||||||
|
|
||||||
export const connect = async (req: ConnectRequest): Promise<void> => {
|
export const connect = async (req: ConnectRequest): Promise<void> => {
|
||||||
const response = await BreezLiquidSDK.connect(req)
|
const response = await BreezLiquidSDK.connect(req)
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addEventListener = async (listener: EventListener): Promise<string> => {
|
||||||
|
const response = await BreezLiquidSDK.addEventListener()
|
||||||
|
BreezLiquidSDKEmitter.addListener(`event-${response}`, listener)
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
{%- when Type::Object ( name ) %}
|
{%- when Type::Object ( name ) %}
|
||||||
{% let obj = ci.get_object_definition(name).unwrap() %}
|
{% let obj = ci.get_object_definition(name).unwrap() %}
|
||||||
{%- for func in obj.methods() -%}
|
{%- for func in obj.methods() -%}
|
||||||
|
{%- if func.name()|ignored_function == false -%}
|
||||||
{%- include "TopLevelFunctionTemplate.ts" %}
|
{%- include "TopLevelFunctionTemplate.ts" %}
|
||||||
|
{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{%- endmatch -%}
|
{%- endmatch -%}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { NativeModules, Platform } from "react-native"
|
import { NativeModules, Platform, NativeEventEmitter } from "react-native"
|
||||||
|
|
||||||
const LINKING_ERROR =
|
const LINKING_ERROR =
|
||||||
`The package 'react-native-breez-liquid-sdk' doesn't seem to be linked. Make sure: \n\n` +
|
`The package 'react-native-breez-liquid-sdk' doesn't seem to be linked. Make sure: \n\n` +
|
||||||
@@ -17,6 +17,7 @@ const BreezLiquidSDK = NativeModules.RNBreezLiquidSDK
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const BreezLiquidSDKEmitter = new NativeEventEmitter(BreezLiquidSDK)
|
||||||
{%- import "macros.ts" as ts %}
|
{%- import "macros.ts" as ts %}
|
||||||
{%- include "Types.ts" %}
|
{%- include "Types.ts" %}
|
||||||
{% include "Helpers.ts" -%}
|
{% include "Helpers.ts" -%}
|
||||||
|
|||||||
@@ -96,12 +96,33 @@ enum PaymentState {
|
|||||||
"Failed",
|
"Failed",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[Enum]
|
||||||
|
interface LiquidSdkEvent {
|
||||||
|
PaymentFailed(Payment details);
|
||||||
|
PaymentPending(Payment details);
|
||||||
|
PaymentRefunded(Payment details);
|
||||||
|
PaymentRefundPending(Payment details);
|
||||||
|
PaymentSucceed(Payment details);
|
||||||
|
PaymentWaitingConfirmation(Payment details);
|
||||||
|
Synced();
|
||||||
|
};
|
||||||
|
|
||||||
|
callback interface EventListener {
|
||||||
|
void on_event(LiquidSdkEvent e);
|
||||||
|
};
|
||||||
|
|
||||||
namespace breez_liquid_sdk {
|
namespace breez_liquid_sdk {
|
||||||
[Throws=LiquidSdkError]
|
[Throws=LiquidSdkError]
|
||||||
BindingLiquidSdk connect(ConnectRequest req);
|
BindingLiquidSdk connect(ConnectRequest req);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface BindingLiquidSdk {
|
interface BindingLiquidSdk {
|
||||||
|
[Throws=LiquidSdkError]
|
||||||
|
string add_event_listener(EventListener listener);
|
||||||
|
|
||||||
|
[Throws=LiquidSdkError]
|
||||||
|
void remove_event_listener(string id);
|
||||||
|
|
||||||
[Throws=LiquidSdkError]
|
[Throws=LiquidSdkError]
|
||||||
GetInfoResponse get_info(GetInfoRequest req);
|
GetInfoResponse get_info(GetInfoRequest req);
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,20 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use breez_liquid_sdk::{error::*, model::*, sdk::LiquidSdk};
|
use breez_liquid_sdk::{error::*, model::*, sdk::LiquidSdk};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
|
static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().unwrap());
|
||||||
|
|
||||||
|
fn rt() -> &'static Runtime {
|
||||||
|
&RT
|
||||||
|
}
|
||||||
|
|
||||||
pub fn connect(req: ConnectRequest) -> Result<Arc<BindingLiquidSdk>, LiquidSdkError> {
|
pub fn connect(req: ConnectRequest) -> Result<Arc<BindingLiquidSdk>, LiquidSdkError> {
|
||||||
let ln_sdk = LiquidSdk::connect(req)?;
|
rt().block_on(async {
|
||||||
Ok(Arc::from(BindingLiquidSdk { sdk: ln_sdk }))
|
let sdk = LiquidSdk::connect(req).await?;
|
||||||
|
Ok(Arc::from(BindingLiquidSdk { sdk }))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BindingLiquidSdk {
|
pub struct BindingLiquidSdk {
|
||||||
@@ -13,22 +23,30 @@ pub struct BindingLiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BindingLiquidSdk {
|
impl BindingLiquidSdk {
|
||||||
|
pub fn add_event_listener(&self, listener: Box<dyn EventListener>) -> LiquidSdkResult<String> {
|
||||||
|
rt().block_on(self.sdk.add_event_listener(listener))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_event_listener(&self, id: String) -> LiquidSdkResult<()> {
|
||||||
|
rt().block_on(self.sdk.remove_event_listener(id))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_info(&self, req: GetInfoRequest) -> Result<GetInfoResponse, LiquidSdkError> {
|
pub fn get_info(&self, req: GetInfoRequest) -> Result<GetInfoResponse, LiquidSdkError> {
|
||||||
self.sdk.get_info(req).map_err(Into::into)
|
rt().block_on(self.sdk.get_info(req)).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_send_payment(
|
pub fn prepare_send_payment(
|
||||||
&self,
|
&self,
|
||||||
req: PrepareSendRequest,
|
req: PrepareSendRequest,
|
||||||
) -> Result<PrepareSendResponse, PaymentError> {
|
) -> Result<PrepareSendResponse, PaymentError> {
|
||||||
self.sdk.prepare_send_payment(&req)
|
rt().block_on(self.sdk.prepare_send_payment(&req))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_payment(
|
pub fn send_payment(
|
||||||
&self,
|
&self,
|
||||||
req: PrepareSendResponse,
|
req: PrepareSendResponse,
|
||||||
) -> Result<SendPaymentResponse, PaymentError> {
|
) -> Result<SendPaymentResponse, PaymentError> {
|
||||||
self.sdk.send_payment(&req)
|
rt().block_on(self.sdk.send_payment(&req))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_receive_payment(
|
pub fn prepare_receive_payment(
|
||||||
@@ -49,15 +67,19 @@ impl BindingLiquidSdk {
|
|||||||
self.sdk.list_payments()
|
self.sdk.list_payments()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync(&self) -> Result<(), LiquidSdkError> {
|
pub fn sync(&self) -> LiquidSdkResult<()> {
|
||||||
self.sdk.sync().map_err(Into::into)
|
rt().block_on(self.sdk.sync()).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn backup(&self) -> Result<(), LiquidSdkError> {
|
pub fn empty_wallet_cache(&self) -> LiquidSdkResult<()> {
|
||||||
|
self.sdk.empty_wallet_cache().map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn backup(&self) -> LiquidSdkResult<()> {
|
||||||
self.sdk.backup().map_err(Into::into)
|
self.sdk.backup().map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restore(&self, req: RestoreRequest) -> Result<(), LiquidSdkError> {
|
pub fn restore(&self, req: RestoreRequest) -> LiquidSdkResult<()> {
|
||||||
self.sdk.restore(req).map_err(Into::into)
|
self.sdk.restore(req).map_err(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
|
|
||||||
|
class SDKListener: breez_liquid_sdk.EventListener {
|
||||||
|
override fun onEvent(e: breez_liquid_sdk.LiquidSdkEvent) {
|
||||||
|
println(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
var mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
||||||
|
|
||||||
var connectReq = breez_liquid_sdk.ConnectRequest(mnemonic, breez_liquid_sdk.Network.LIQUID_TESTNET)
|
var connectReq = breez_liquid_sdk.ConnectRequest(mnemonic, breez_liquid_sdk.Network.LIQUID_TESTNET)
|
||||||
var sdk = breez_liquid_sdk.connect(connectReq)
|
var sdk = breez_liquid_sdk.connect(connectReq)
|
||||||
|
|
||||||
|
var listenerId = sdk.addEventListener(SDKListener())
|
||||||
|
|
||||||
var getInfoReq = breez_liquid_sdk.GetInfoRequest(false)
|
var getInfoReq = breez_liquid_sdk.GetInfoRequest(false)
|
||||||
var nodeInfo = sdk.getInfo(getInfoReq)
|
var nodeInfo = sdk.getInfo(getInfoReq)
|
||||||
|
|
||||||
|
sdk.removeEventListener(listenerId)
|
||||||
|
|
||||||
println("$nodeInfo")
|
println("$nodeInfo")
|
||||||
assert(nodeInfo.pubkey.equals("03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494"))
|
assert(nodeInfo.pubkey.equals("03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494"))
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
|
|||||||
@@ -1,14 +1,24 @@
|
|||||||
import breez_liquid_sdk
|
import breez_liquid_sdk
|
||||||
|
|
||||||
|
|
||||||
|
class SDKListener(breez_liquid_sdk.EventListener):
|
||||||
|
def on_event(self, event):
|
||||||
|
print(event)
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
||||||
|
|
||||||
connect_req = breez_liquid_sdk.ConnectRequest(mnemonic=mnemonic, network=breez_liquid_sdk.Network.LIQUID_TESTNET)
|
connect_req = breez_liquid_sdk.ConnectRequest(mnemonic=mnemonic, network=breez_liquid_sdk.Network.LIQUID_TESTNET)
|
||||||
sdk = breez_liquid_sdk.connect(connect_req)
|
sdk = breez_liquid_sdk.connect(connect_req)
|
||||||
|
|
||||||
|
listener_id = sdk.add_event_listener(SDKListener())
|
||||||
|
|
||||||
get_info_req = breez_liquid_sdk.GetInfoRequest(with_scan=False)
|
get_info_req = breez_liquid_sdk.GetInfoRequest(with_scan=False)
|
||||||
node_info = sdk.get_info(get_info_req)
|
node_info = sdk.get_info(get_info_req)
|
||||||
|
|
||||||
|
sdk.remove_event_listener(listener_id)
|
||||||
|
|
||||||
print(node_info)
|
print(node_info)
|
||||||
assert node_info.pubkey == "03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494"
|
assert node_info.pubkey == "03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494"
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
import breez_liquid_sdk
|
import breez_liquid_sdk
|
||||||
|
|
||||||
|
class SDKListener: EventListener {
|
||||||
|
func onEvent(e: LiquidSdkEvent) {
|
||||||
|
print("Received event ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
|
||||||
let connectReq = breez_liquid_sdk.ConnectRequest(mnemonic: mnemonic, network: .liquidTestnet);
|
let connectReq = breez_liquid_sdk.ConnectRequest(mnemonic: mnemonic, network: .liquidTestnet);
|
||||||
let sdk = try breez_liquid_sdk.connect(req: connectReq);
|
let sdk = try breez_liquid_sdk.connect(req: connectReq);
|
||||||
|
|
||||||
|
let listenerId = try sdk.addEventListener(listener: SDKListener());
|
||||||
|
|
||||||
let getInfoReq = breez_liquid_sdk.GetInfoRequest(withScan: false);
|
let getInfoReq = breez_liquid_sdk.GetInfoRequest(withScan: false);
|
||||||
let nodeInfo = try sdk.getInfo(req: getInfoReq);
|
let nodeInfo = try sdk.getInfo(req: getInfoReq);
|
||||||
|
|
||||||
|
try sdk.removeEventListener(id: listenerId);
|
||||||
|
|
||||||
print(nodeInfo);
|
print(nodeInfo);
|
||||||
assert(nodeInfo.pubkey == "03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494", "nodeInfo.pubkey");
|
assert(nodeInfo.pubkey == "03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494", "nodeInfo.pubkey");
|
||||||
@@ -29,7 +29,9 @@ serde = { version = "1.0.197", features = ["derive"] }
|
|||||||
serde_json = "1.0.116"
|
serde_json = "1.0.116"
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tungstenite = { version = "0.21.0", features = ["native-tls-vendored"] }
|
tungstenite = { version = "0.21.0", features = ["native-tls-vendored"] }
|
||||||
|
once_cell = "1"
|
||||||
openssl = { version = "0.10", features = ["vendored"] }
|
openssl = { version = "0.10", features = ["vendored"] }
|
||||||
|
tokio = { version = "1", features = ["rt"] }
|
||||||
|
|
||||||
# Pin these versions to fix iOS build issues
|
# Pin these versions to fix iOS build issues
|
||||||
security-framework = "=2.10.0"
|
security-framework = "=2.10.0"
|
||||||
|
|||||||
@@ -1,10 +1,30 @@
|
|||||||
use crate::{error::*, model::*, sdk::LiquidSdk};
|
use crate::{error::*, frb::bridge::StreamSink, model::*, sdk::LiquidSdk};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
|
static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().unwrap());
|
||||||
|
|
||||||
|
pub(crate) fn rt() -> &'static Runtime {
|
||||||
|
&RT
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BindingEventListener {
|
||||||
|
stream: StreamSink<LiquidSdkEvent>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventListener for BindingEventListener {
|
||||||
|
fn on_event(&self, e: LiquidSdkEvent) {
|
||||||
|
let _ = self.stream.add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn connect(req: ConnectRequest) -> Result<BindingLiquidSdk, LiquidSdkError> {
|
pub fn connect(req: ConnectRequest) -> Result<BindingLiquidSdk, LiquidSdkError> {
|
||||||
let ln_sdk = LiquidSdk::connect(req)?;
|
rt().block_on(async {
|
||||||
Ok(BindingLiquidSdk { sdk: ln_sdk })
|
let ln_sdk = LiquidSdk::connect(req).await?;
|
||||||
|
Ok(BindingLiquidSdk { sdk: ln_sdk })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BindingLiquidSdk {
|
pub struct BindingLiquidSdk {
|
||||||
@@ -13,21 +33,31 @@ pub struct BindingLiquidSdk {
|
|||||||
|
|
||||||
impl BindingLiquidSdk {
|
impl BindingLiquidSdk {
|
||||||
pub fn get_info(&self, req: GetInfoRequest) -> Result<GetInfoResponse, LiquidSdkError> {
|
pub fn get_info(&self, req: GetInfoRequest) -> Result<GetInfoResponse, LiquidSdkError> {
|
||||||
self.sdk.get_info(req).map_err(Into::into)
|
rt().block_on(self.sdk.get_info(req)).map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_event_listener(
|
||||||
|
&self,
|
||||||
|
listener: StreamSink<LiquidSdkEvent>,
|
||||||
|
) -> Result<String, LiquidSdkError> {
|
||||||
|
rt().block_on(
|
||||||
|
self.sdk
|
||||||
|
.add_event_listener(Box::new(BindingEventListener { stream: listener })),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_send_payment(
|
pub fn prepare_send_payment(
|
||||||
&self,
|
&self,
|
||||||
req: PrepareSendRequest,
|
req: PrepareSendRequest,
|
||||||
) -> Result<PrepareSendResponse, PaymentError> {
|
) -> Result<PrepareSendResponse, PaymentError> {
|
||||||
self.sdk.prepare_send_payment(&req)
|
rt().block_on(self.sdk.prepare_send_payment(&req))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_payment(
|
pub fn send_payment(
|
||||||
&self,
|
&self,
|
||||||
req: PrepareSendResponse,
|
req: PrepareSendResponse,
|
||||||
) -> Result<SendPaymentResponse, PaymentError> {
|
) -> Result<SendPaymentResponse, PaymentError> {
|
||||||
self.sdk.send_payment(&req)
|
rt().block_on(self.sdk.send_payment(&req))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_receive_payment(
|
pub fn prepare_receive_payment(
|
||||||
@@ -49,17 +79,17 @@ impl BindingLiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync(&self) -> Result<(), LiquidSdkError> {
|
pub fn sync(&self) -> Result<(), LiquidSdkError> {
|
||||||
self.sdk.sync().map_err(Into::into)
|
rt().block_on(self.sdk.sync()).map_err(Into::into)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn backup(&self) -> Result<(), LiquidSdkError> {
|
|
||||||
self.sdk.backup().map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty_wallet_cache(&self) -> Result<(), LiquidSdkError> {
|
pub fn empty_wallet_cache(&self) -> Result<(), LiquidSdkError> {
|
||||||
self.sdk.empty_wallet_cache().map_err(Into::into)
|
self.sdk.empty_wallet_cache().map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn backup(&self) -> Result<(), LiquidSdkError> {
|
||||||
|
self.sdk.backup().map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn restore(&self, req: RestoreRequest) -> Result<(), LiquidSdkError> {
|
pub fn restore(&self, req: RestoreRequest) -> Result<(), LiquidSdkError> {
|
||||||
self.sdk.restore(req).map_err(Into::into)
|
self.sdk.restore(req).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ impl BoltzStatusStream {
|
|||||||
Ok(socket)
|
Ok(socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn track_pending_swaps(sdk: Arc<LiquidSdk>) -> Result<()> {
|
pub(super) async fn track_pending_swaps(sdk: Arc<LiquidSdk>) -> Result<()> {
|
||||||
let mut socket = Self::connect(sdk.clone())?;
|
let mut socket = Self::connect(sdk.clone())?;
|
||||||
|
|
||||||
let reconnect_delay = Duration::from_secs(15);
|
let reconnect_delay = Duration::from_secs(15);
|
||||||
@@ -77,138 +77,141 @@ impl BoltzStatusStream {
|
|||||||
let mut keep_alive_last_ping_ts = Instant::now();
|
let mut keep_alive_last_ping_ts = Instant::now();
|
||||||
|
|
||||||
// Outer loop: reconnects in case the connection is lost
|
// Outer loop: reconnects in case the connection is lost
|
||||||
thread::spawn(move || loop {
|
tokio::spawn(async move {
|
||||||
// Initially subscribe to all ongoing swaps
|
|
||||||
match sdk.list_ongoing_swaps() {
|
|
||||||
Ok(initial_ongoing_swaps) => {
|
|
||||||
info!("Got {} initial ongoing swaps", initial_ongoing_swaps.len());
|
|
||||||
for ongoing_swap in &initial_ongoing_swaps {
|
|
||||||
Self::maybe_subscribe_fn(ongoing_swap, &mut socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => error!("Failed to list initial ongoing swaps: {e:?}"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inner loop: iterates over incoming messages and handles them
|
|
||||||
loop {
|
loop {
|
||||||
// Decide if we send a keep-alive ping or not
|
// Initially subscribe to all ongoing swaps
|
||||||
if Instant::now()
|
match sdk.list_ongoing_swaps() {
|
||||||
.duration_since(keep_alive_last_ping_ts)
|
Ok(initial_ongoing_swaps) => {
|
||||||
.gt(&keep_alive_ping_interval)
|
info!("Got {} initial ongoing swaps", initial_ongoing_swaps.len());
|
||||||
{
|
for ongoing_swap in &initial_ongoing_swaps {
|
||||||
match socket.send(Message::Ping(vec![])) {
|
Self::maybe_subscribe_fn(ongoing_swap, &mut socket);
|
||||||
Ok(_) => debug!("Sent keep-alive ping"),
|
}
|
||||||
Err(e) => warn!("Failed to send keep-alive ping: {e:?}"),
|
|
||||||
}
|
}
|
||||||
keep_alive_last_ping_ts = Instant::now();
|
Err(e) => error!("Failed to list initial ongoing swaps: {e:?}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
match &socket.read() {
|
// Inner loop: iterates over incoming messages and handles them
|
||||||
Ok(Message::Close(_)) => {
|
loop {
|
||||||
warn!("Received close msg, exiting socket loop");
|
// Decide if we send a keep-alive ping or not
|
||||||
break;
|
if Instant::now()
|
||||||
}
|
.duration_since(keep_alive_last_ping_ts)
|
||||||
Ok(msg) => {
|
.gt(&keep_alive_ping_interval)
|
||||||
info!("Received msg : {msg:?}");
|
{
|
||||||
|
match socket.send(Message::Ping(vec![])) {
|
||||||
// Each time socket.read() returns, we have the opportunity to socket.send().
|
Ok(_) => debug!("Sent keep-alive ping"),
|
||||||
// We use this window to subscribe to any new ongoing swaps.
|
Err(e) => warn!("Failed to send keep-alive ping: {e:?}"),
|
||||||
// This happens on any non-close socket messages, in particular:
|
|
||||||
// Ping (periodic keep-alive), Text (status update)
|
|
||||||
match sdk.list_ongoing_swaps() {
|
|
||||||
Ok(ongoing_swaps) => {
|
|
||||||
for ongoing_swap in &ongoing_swaps {
|
|
||||||
Self::maybe_subscribe_fn(ongoing_swap, &mut socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => error!("Failed to list new ongoing swaps: {e:?}"),
|
|
||||||
}
|
}
|
||||||
|
keep_alive_last_ping_ts = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
// We parse and handle any Text websocket messages, which are likely status updates
|
match &socket.read() {
|
||||||
if msg.is_text() {
|
Ok(Message::Close(_)) => {
|
||||||
info!("Received text msg (status update) : {msg:?}");
|
warn!("Received close msg, exiting socket loop");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(msg) => {
|
||||||
|
info!("Received msg : {msg:?}");
|
||||||
|
|
||||||
match serde_json::from_str::<SwapUpdate>(&msg.to_string()) {
|
// Each time socket.read() returns, we have the opportunity to socket.send().
|
||||||
// Subscription confirmation
|
// We use this window to subscribe to any new ongoing swaps.
|
||||||
Ok(SwapUpdate::Subscription { .. }) => {}
|
// This happens on any non-close socket messages, in particular:
|
||||||
|
// Ping (periodic keep-alive), Text (status update)
|
||||||
// Status update(s)
|
match sdk.list_ongoing_swaps() {
|
||||||
Ok(SwapUpdate::Update {
|
Ok(ongoing_swaps) => {
|
||||||
event: _,
|
for ongoing_swap in &ongoing_swaps {
|
||||||
channel: _,
|
Self::maybe_subscribe_fn(ongoing_swap, &mut socket);
|
||||||
args,
|
|
||||||
}) => {
|
|
||||||
for boltz_client::swaps::boltzv2::Update { id, status } in args
|
|
||||||
{
|
|
||||||
if Self::is_tracked_send_swap(&id) {
|
|
||||||
match SubSwapStates::from_str(&status) {
|
|
||||||
Ok(new_state) => {
|
|
||||||
let res = sdk.try_handle_send_swap_boltz_status(
|
|
||||||
new_state,
|
|
||||||
&id,
|
|
||||||
);
|
|
||||||
info!("Handled new Send Swap status from Boltz, result: {res:?}");
|
|
||||||
}
|
|
||||||
Err(_) => error!("Received invalid SubSwapState for Send Swap {id}: {status}")
|
|
||||||
}
|
|
||||||
} else if Self::is_tracked_receive_swap(&id) {
|
|
||||||
match RevSwapStates::from_str(&status) {
|
|
||||||
Ok(new_state) => {
|
|
||||||
let res = sdk.try_handle_receive_swap_boltz_status(
|
|
||||||
new_state, &id,
|
|
||||||
);
|
|
||||||
info!("Handled new Receive Swap status from Boltz, result: {res:?}");
|
|
||||||
}
|
|
||||||
Err(_) => error!("Received invalid RevSwapState for Receive Swap {id}: {status}"),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("Received a status update for swap {id}, which is not tracked as ongoing")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(e) => error!("Failed to list new ongoing swaps: {e:?}"),
|
||||||
|
}
|
||||||
|
|
||||||
// Error related to subscription, like "Unknown swap ID"
|
// We parse and handle any Text websocket messages, which are likely status updates
|
||||||
Ok(SwapUpdate::Error {
|
if msg.is_text() {
|
||||||
event: _,
|
info!("Received text msg (status update) : {msg:?}");
|
||||||
channel: _,
|
|
||||||
args,
|
|
||||||
}) => error!("Received a status update error: {args:?}"),
|
|
||||||
|
|
||||||
Err(e) => warn!("WS response is invalid SwapUpdate: {e:?}"),
|
match serde_json::from_str::<SwapUpdate>(&msg.to_string()) {
|
||||||
|
// Subscription confirmation
|
||||||
|
Ok(SwapUpdate::Subscription { .. }) => {}
|
||||||
|
|
||||||
|
// Status update(s)
|
||||||
|
Ok(SwapUpdate::Update {
|
||||||
|
event: _,
|
||||||
|
channel: _,
|
||||||
|
args,
|
||||||
|
}) => {
|
||||||
|
for boltz_client::swaps::boltzv2::Update { id, status } in
|
||||||
|
args
|
||||||
|
{
|
||||||
|
if Self::is_tracked_send_swap(&id) {
|
||||||
|
match SubSwapStates::from_str(&status) {
|
||||||
|
Ok(new_state) => {
|
||||||
|
let res = sdk.try_handle_send_swap_boltz_status(
|
||||||
|
new_state,
|
||||||
|
&id,
|
||||||
|
).await;
|
||||||
|
info!("Handled new Send Swap status from Boltz, result: {res:?}");
|
||||||
|
}
|
||||||
|
Err(_) => error!("Received invalid SubSwapState for Send Swap {id}: {status}")
|
||||||
|
}
|
||||||
|
} else if Self::is_tracked_receive_swap(&id) {
|
||||||
|
match RevSwapStates::from_str(&status) {
|
||||||
|
Ok(new_state) => {
|
||||||
|
let res = sdk.try_handle_receive_swap_boltz_status(
|
||||||
|
new_state, &id,
|
||||||
|
).await;
|
||||||
|
info!("Handled new Receive Swap status from Boltz, result: {res:?}");
|
||||||
|
}
|
||||||
|
Err(_) => error!("Received invalid RevSwapState for Receive Swap {id}: {status}"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!("Received a status update for swap {id}, which is not tracked as ongoing")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error related to subscription, like "Unknown swap ID"
|
||||||
|
Ok(SwapUpdate::Error {
|
||||||
|
event: _,
|
||||||
|
channel: _,
|
||||||
|
args,
|
||||||
|
}) => error!("Received a status update error: {args:?}"),
|
||||||
|
|
||||||
|
Err(e) => warn!("WS response is invalid SwapUpdate: {e:?}"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Err(tungstenite::Error::Io(io_err)) => {
|
||||||
Err(tungstenite::Error::Io(io_err)) => {
|
match io_err.kind() {
|
||||||
match io_err.kind() {
|
// Calling socket.read() on a non-blocking stream when there is nothing
|
||||||
// Calling socket.read() on a non-blocking stream when there is nothing
|
// to read results in an WouldBlock error. In this case, we do nothing
|
||||||
// to read results in an WouldBlock error. In this case, we do nothing
|
// and continue the loop.
|
||||||
// and continue the loop.
|
ErrorKind::WouldBlock => {}
|
||||||
ErrorKind::WouldBlock => {}
|
_ => {
|
||||||
_ => {
|
error!("Received stream IO error : {io_err:?}");
|
||||||
error!("Received stream IO error : {io_err:?}");
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Err(tungstenite::Error::AlreadyClosed) => {
|
||||||
Err(tungstenite::Error::AlreadyClosed) => {
|
thread::sleep(reconnect_delay);
|
||||||
thread::sleep(reconnect_delay);
|
info!("Re-connecting...");
|
||||||
info!("Re-connecting...");
|
match Self::connect(sdk.clone()) {
|
||||||
match Self::connect(sdk.clone()) {
|
Ok(new_socket) => {
|
||||||
Ok(new_socket) => {
|
socket = new_socket;
|
||||||
socket = new_socket;
|
info!("Re-connected to WS stream");
|
||||||
info!("Re-connected to WS stream");
|
|
||||||
|
|
||||||
// Clear monitored swaps, so on re-connect we re-subscribe to them
|
// Clear monitored swaps, so on re-connect we re-subscribe to them
|
||||||
send_swap_ids().lock().unwrap().clear();
|
send_swap_ids().lock().unwrap().clear();
|
||||||
receive_swap_ids().lock().unwrap().clear();
|
receive_swap_ids().lock().unwrap().clear();
|
||||||
}
|
}
|
||||||
Err(e) => warn!("Failed to re-connected to WS stream: {e:}"),
|
Err(e) => warn!("Failed to re-connected to WS stream: {e:}"),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Received stream error : {e:?}");
|
error!("Received stream error : {e:?}");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
|
||||||
|
pub type LiquidSdkResult<T, E = LiquidSdkError> = Result<T, E>;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! ensure_sdk {
|
macro_rules! ensure_sdk {
|
||||||
($cond:expr, $err:expr) => {
|
($cond:expr, $err:expr) => {
|
||||||
|
|||||||
38
lib/core/src/event.rs
Normal file
38
lib/core/src/event.rs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use crate::model::{EventListener, LiquidSdkEvent};
|
||||||
|
|
||||||
|
pub(crate) struct EventManager {
|
||||||
|
listeners: RwLock<HashMap<String, Box<dyn EventListener>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventManager {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
listeners: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add(&self, listener: Box<dyn EventListener>) -> Result<String> {
|
||||||
|
let id = format!(
|
||||||
|
"{:X}",
|
||||||
|
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
|
||||||
|
);
|
||||||
|
(*self.listeners.write().await).insert(id.clone(), listener);
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn remove(&self, id: String) {
|
||||||
|
(*self.listeners.write().await).remove(&id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn notify(&self, e: LiquidSdkEvent) {
|
||||||
|
for listener in (*self.listeners.read().await).values() {
|
||||||
|
listener.on_event(e.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,20 @@ impl
|
|||||||
unsafe { decode_rust_opaque_nom(self as _) }
|
unsafe { decode_rust_opaque_nom(self as _) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl
|
||||||
|
CstDecode<
|
||||||
|
StreamSink<crate::model::LiquidSdkEvent, flutter_rust_bridge::for_generated::DcoCodec>,
|
||||||
|
> for *mut wire_cst_list_prim_u_8_strict
|
||||||
|
{
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
fn cst_decode(
|
||||||
|
self,
|
||||||
|
) -> StreamSink<crate::model::LiquidSdkEvent, flutter_rust_bridge::for_generated::DcoCodec>
|
||||||
|
{
|
||||||
|
let raw: String = self.cst_decode();
|
||||||
|
StreamSink::deserialize(raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CstDecode<String> for *mut wire_cst_list_prim_u_8_strict {
|
impl CstDecode<String> for *mut wire_cst_list_prim_u_8_strict {
|
||||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
fn cst_decode(self) -> String {
|
fn cst_decode(self) -> String {
|
||||||
@@ -60,6 +74,13 @@ impl CstDecode<crate::model::GetInfoRequest> for *mut wire_cst_get_info_request
|
|||||||
CstDecode::<crate::model::GetInfoRequest>::cst_decode(*wrap).into()
|
CstDecode::<crate::model::GetInfoRequest>::cst_decode(*wrap).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CstDecode<crate::model::Payment> for *mut wire_cst_payment {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
fn cst_decode(self) -> crate::model::Payment {
|
||||||
|
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
|
||||||
|
CstDecode::<crate::model::Payment>::cst_decode(*wrap).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CstDecode<crate::model::PrepareReceiveRequest> for *mut wire_cst_prepare_receive_request {
|
impl CstDecode<crate::model::PrepareReceiveRequest> for *mut wire_cst_prepare_receive_request {
|
||||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
fn cst_decode(self) -> crate::model::PrepareReceiveRequest {
|
fn cst_decode(self) -> crate::model::PrepareReceiveRequest {
|
||||||
@@ -144,6 +165,51 @@ impl CstDecode<crate::error::LiquidSdkError> for wire_cst_liquid_sdk_error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CstDecode<crate::model::LiquidSdkEvent> for wire_cst_liquid_sdk_event {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
fn cst_decode(self) -> crate::model::LiquidSdkEvent {
|
||||||
|
match self.tag {
|
||||||
|
0 => {
|
||||||
|
let ans = unsafe { self.kind.PaymentFailed };
|
||||||
|
crate::model::LiquidSdkEvent::PaymentFailed {
|
||||||
|
details: ans.details.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
let ans = unsafe { self.kind.PaymentPending };
|
||||||
|
crate::model::LiquidSdkEvent::PaymentPending {
|
||||||
|
details: ans.details.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
let ans = unsafe { self.kind.PaymentRefunded };
|
||||||
|
crate::model::LiquidSdkEvent::PaymentRefunded {
|
||||||
|
details: ans.details.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
let ans = unsafe { self.kind.PaymentRefundPending };
|
||||||
|
crate::model::LiquidSdkEvent::PaymentRefundPending {
|
||||||
|
details: ans.details.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
let ans = unsafe { self.kind.PaymentSucceed };
|
||||||
|
crate::model::LiquidSdkEvent::PaymentSucceed {
|
||||||
|
details: ans.details.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
let ans = unsafe { self.kind.PaymentWaitingConfirmation };
|
||||||
|
crate::model::LiquidSdkEvent::PaymentWaitingConfirmation {
|
||||||
|
details: ans.details.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6 => crate::model::LiquidSdkEvent::Synced,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CstDecode<Vec<crate::model::Payment>> for *mut wire_cst_list_payment {
|
impl CstDecode<Vec<crate::model::Payment>> for *mut wire_cst_list_payment {
|
||||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
fn cst_decode(self) -> Vec<crate::model::Payment> {
|
fn cst_decode(self) -> Vec<crate::model::Payment> {
|
||||||
@@ -338,6 +404,19 @@ impl Default for wire_cst_liquid_sdk_error {
|
|||||||
Self::new_with_null_ptr()
|
Self::new_with_null_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl NewWithNullPtr for wire_cst_liquid_sdk_event {
|
||||||
|
fn new_with_null_ptr() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: -1,
|
||||||
|
kind: LiquidSdkEventKind { nil__: () },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Default for wire_cst_liquid_sdk_event {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new_with_null_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
impl NewWithNullPtr for wire_cst_payment {
|
impl NewWithNullPtr for wire_cst_payment {
|
||||||
fn new_with_null_ptr() -> Self {
|
fn new_with_null_ptr() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -458,6 +537,15 @@ impl Default for wire_cst_send_payment_response {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener(
|
||||||
|
port_: i64,
|
||||||
|
that: usize,
|
||||||
|
listener: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
) {
|
||||||
|
wire__crate__bindings__BindingLiquidSdk_add_event_listener_impl(port_, that, listener)
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(
|
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(
|
||||||
port_: i64,
|
port_: i64,
|
||||||
@@ -586,6 +674,11 @@ pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_get_info_request(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_payment() -> *mut wire_cst_payment {
|
||||||
|
flutter_rust_bridge::for_generated::new_leak_box_ptr(wire_cst_payment::new_with_null_ptr())
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request(
|
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request(
|
||||||
) -> *mut wire_cst_prepare_receive_request {
|
) -> *mut wire_cst_prepare_receive_request {
|
||||||
@@ -693,6 +786,53 @@ pub struct wire_cst_LiquidSdkError_Generic {
|
|||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_liquid_sdk_event {
|
||||||
|
tag: i32,
|
||||||
|
kind: LiquidSdkEventKind,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub union LiquidSdkEventKind {
|
||||||
|
PaymentFailed: wire_cst_LiquidSdkEvent_PaymentFailed,
|
||||||
|
PaymentPending: wire_cst_LiquidSdkEvent_PaymentPending,
|
||||||
|
PaymentRefunded: wire_cst_LiquidSdkEvent_PaymentRefunded,
|
||||||
|
PaymentRefundPending: wire_cst_LiquidSdkEvent_PaymentRefundPending,
|
||||||
|
PaymentSucceed: wire_cst_LiquidSdkEvent_PaymentSucceed,
|
||||||
|
PaymentWaitingConfirmation: wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation,
|
||||||
|
nil__: (),
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_LiquidSdkEvent_PaymentFailed {
|
||||||
|
details: *mut wire_cst_payment,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_LiquidSdkEvent_PaymentPending {
|
||||||
|
details: *mut wire_cst_payment,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_LiquidSdkEvent_PaymentRefunded {
|
||||||
|
details: *mut wire_cst_payment,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_LiquidSdkEvent_PaymentRefundPending {
|
||||||
|
details: *mut wire_cst_payment,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_LiquidSdkEvent_PaymentSucceed {
|
||||||
|
details: *mut wire_cst_payment,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation {
|
||||||
|
details: *mut wire_cst_payment,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct wire_cst_list_payment {
|
pub struct wire_cst_list_payment {
|
||||||
ptr: *mut wire_cst_payment,
|
ptr: *mut wire_cst_payment,
|
||||||
len: i32,
|
len: i32,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
|||||||
default_rust_auto_opaque = RustAutoOpaqueNom,
|
default_rust_auto_opaque = RustAutoOpaqueNom,
|
||||||
);
|
);
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0-dev.35";
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0-dev.35";
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1284301568;
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 692273053;
|
||||||
|
|
||||||
// Section: executor
|
// Section: executor
|
||||||
|
|
||||||
@@ -41,6 +41,46 @@ flutter_rust_bridge::frb_generated_default_handler!();
|
|||||||
|
|
||||||
// Section: wire_funcs
|
// Section: wire_funcs
|
||||||
|
|
||||||
|
fn wire__crate__bindings__BindingLiquidSdk_add_event_listener_impl(
|
||||||
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
|
that: impl CstDecode<
|
||||||
|
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
|
||||||
|
>,
|
||||||
|
listener: impl CstDecode<
|
||||||
|
StreamSink<crate::model::LiquidSdkEvent, flutter_rust_bridge::for_generated::DcoCodec>,
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
|
||||||
|
flutter_rust_bridge::for_generated::TaskInfo {
|
||||||
|
debug_name: "BindingLiquidSdk_add_event_listener",
|
||||||
|
port: Some(port_),
|
||||||
|
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
||||||
|
},
|
||||||
|
move || {
|
||||||
|
let api_that = that.cst_decode();
|
||||||
|
let api_listener = listener.cst_decode();
|
||||||
|
move |context| {
|
||||||
|
transform_result_dco((move || {
|
||||||
|
let mut api_that_decoded = None;
|
||||||
|
let decode_indices_ =
|
||||||
|
flutter_rust_bridge::for_generated::rust_auto_opaque_decode_compute_order(
|
||||||
|
vec![api_that.rust_auto_opaque_lock_order_info(0, false)],
|
||||||
|
);
|
||||||
|
for i in decode_indices_ {
|
||||||
|
match i {
|
||||||
|
0 => {
|
||||||
|
api_that_decoded = Some(api_that.rust_auto_opaque_decode_sync_ref())
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let api_that = api_that_decoded.unwrap();
|
||||||
|
crate::bindings::BindingLiquidSdk::add_event_listener(&api_that, api_listener)
|
||||||
|
})())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
fn wire__crate__bindings__BindingLiquidSdk_backup_impl(
|
fn wire__crate__bindings__BindingLiquidSdk_backup_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
that: impl CstDecode<
|
that: impl CstDecode<
|
||||||
@@ -520,6 +560,16 @@ impl SseDecode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseDecode
|
||||||
|
for StreamSink<crate::model::LiquidSdkEvent, flutter_rust_bridge::for_generated::DcoCodec>
|
||||||
|
{
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
|
let mut inner = <String>::sse_decode(deserializer);
|
||||||
|
return StreamSink::deserialize(inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseDecode for String {
|
impl SseDecode for String {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
@@ -598,6 +648,57 @@ impl SseDecode for crate::error::LiquidSdkError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseDecode for crate::model::LiquidSdkEvent {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
|
let mut tag_ = <i32>::sse_decode(deserializer);
|
||||||
|
match tag_ {
|
||||||
|
0 => {
|
||||||
|
let mut var_details = <crate::model::Payment>::sse_decode(deserializer);
|
||||||
|
return crate::model::LiquidSdkEvent::PaymentFailed {
|
||||||
|
details: var_details,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
let mut var_details = <crate::model::Payment>::sse_decode(deserializer);
|
||||||
|
return crate::model::LiquidSdkEvent::PaymentPending {
|
||||||
|
details: var_details,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
let mut var_details = <crate::model::Payment>::sse_decode(deserializer);
|
||||||
|
return crate::model::LiquidSdkEvent::PaymentRefunded {
|
||||||
|
details: var_details,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
let mut var_details = <crate::model::Payment>::sse_decode(deserializer);
|
||||||
|
return crate::model::LiquidSdkEvent::PaymentRefundPending {
|
||||||
|
details: var_details,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
let mut var_details = <crate::model::Payment>::sse_decode(deserializer);
|
||||||
|
return crate::model::LiquidSdkEvent::PaymentSucceed {
|
||||||
|
details: var_details,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
let mut var_details = <crate::model::Payment>::sse_decode(deserializer);
|
||||||
|
return crate::model::LiquidSdkEvent::PaymentWaitingConfirmation {
|
||||||
|
details: var_details,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
6 => {
|
||||||
|
return crate::model::LiquidSdkEvent::Synced;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unimplemented!("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseDecode for Vec<crate::model::Payment> {
|
impl SseDecode for Vec<crate::model::Payment> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
@@ -987,6 +1088,40 @@ impl flutter_rust_bridge::IntoIntoDart<crate::error::LiquidSdkError>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
impl flutter_rust_bridge::IntoDart for crate::model::LiquidSdkEvent {
|
||||||
|
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||||
|
match self {
|
||||||
|
crate::model::LiquidSdkEvent::PaymentFailed { details } => {
|
||||||
|
[0.into_dart(), details.into_into_dart().into_dart()].into_dart()
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentPending { details } => {
|
||||||
|
[1.into_dart(), details.into_into_dart().into_dart()].into_dart()
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentRefunded { details } => {
|
||||||
|
[2.into_dart(), details.into_into_dart().into_dart()].into_dart()
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentRefundPending { details } => {
|
||||||
|
[3.into_dart(), details.into_into_dart().into_dart()].into_dart()
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentSucceed { details } => {
|
||||||
|
[4.into_dart(), details.into_into_dart().into_dart()].into_dart()
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentWaitingConfirmation { details } => {
|
||||||
|
[5.into_dart(), details.into_into_dart().into_dart()].into_dart()
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::Synced => [6.into_dart()].into_dart(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::LiquidSdkEvent {}
|
||||||
|
impl flutter_rust_bridge::IntoIntoDart<crate::model::LiquidSdkEvent>
|
||||||
|
for crate::model::LiquidSdkEvent
|
||||||
|
{
|
||||||
|
fn into_into_dart(self) -> crate::model::LiquidSdkEvent {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
impl flutter_rust_bridge::IntoDart for crate::model::Network {
|
impl flutter_rust_bridge::IntoDart for crate::model::Network {
|
||||||
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||||
match self {
|
match self {
|
||||||
@@ -1241,6 +1376,15 @@ impl SseEncode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseEncode
|
||||||
|
for StreamSink<crate::model::LiquidSdkEvent, flutter_rust_bridge::for_generated::DcoCodec>
|
||||||
|
{
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
unimplemented!("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseEncode for String {
|
impl SseEncode for String {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
@@ -1300,6 +1444,41 @@ impl SseEncode for crate::error::LiquidSdkError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseEncode for crate::model::LiquidSdkEvent {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
match self {
|
||||||
|
crate::model::LiquidSdkEvent::PaymentFailed { details } => {
|
||||||
|
<i32>::sse_encode(0, serializer);
|
||||||
|
<crate::model::Payment>::sse_encode(details, serializer);
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentPending { details } => {
|
||||||
|
<i32>::sse_encode(1, serializer);
|
||||||
|
<crate::model::Payment>::sse_encode(details, serializer);
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentRefunded { details } => {
|
||||||
|
<i32>::sse_encode(2, serializer);
|
||||||
|
<crate::model::Payment>::sse_encode(details, serializer);
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentRefundPending { details } => {
|
||||||
|
<i32>::sse_encode(3, serializer);
|
||||||
|
<crate::model::Payment>::sse_encode(details, serializer);
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentSucceed { details } => {
|
||||||
|
<i32>::sse_encode(4, serializer);
|
||||||
|
<crate::model::Payment>::sse_encode(details, serializer);
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::PaymentWaitingConfirmation { details } => {
|
||||||
|
<i32>::sse_encode(5, serializer);
|
||||||
|
<crate::model::Payment>::sse_encode(details, serializer);
|
||||||
|
}
|
||||||
|
crate::model::LiquidSdkEvent::Synced => {
|
||||||
|
<i32>::sse_encode(6, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseEncode for Vec<crate::model::Payment> {
|
impl SseEncode for Vec<crate::model::Payment> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
mod bridge;
|
pub(crate) mod bridge;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
pub mod bindings;
|
pub mod bindings;
|
||||||
pub(crate) mod boltz_status_stream;
|
pub(crate) mod boltz_status_stream;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
pub(crate) mod event;
|
||||||
#[cfg(feature = "frb")]
|
#[cfg(feature = "frb")]
|
||||||
pub mod frb;
|
pub mod frb;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
|
|||||||
@@ -49,7 +49,24 @@ impl TryFrom<&str> for Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
/// Trait that can be used to react to various [LiquidSdkEvent]s emitted by the SDK.
|
||||||
|
pub trait EventListener: Send + Sync {
|
||||||
|
fn on_event(&self, e: LiquidSdkEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Event emitted by the SDK. To listen for and react to these events, use an [EventListener] when
|
||||||
|
/// initializing the [LiquidSdk].
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum LiquidSdkEvent {
|
||||||
|
PaymentFailed { details: Payment },
|
||||||
|
PaymentPending { details: Payment },
|
||||||
|
PaymentRefunded { details: Payment },
|
||||||
|
PaymentRefundPending { details: Payment },
|
||||||
|
PaymentSucceed { details: Payment },
|
||||||
|
PaymentWaitingConfirmation { details: Payment },
|
||||||
|
Synced,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct LiquidSdkOptions {
|
pub struct LiquidSdkOptions {
|
||||||
pub signer: SwSigner,
|
pub signer: SwSigner,
|
||||||
pub network: Network,
|
pub network: Network,
|
||||||
@@ -66,6 +83,7 @@ pub struct LiquidSdkOptions {
|
|||||||
/// If not set, it defaults to a Blockstream instance.
|
/// If not set, it defaults to a Blockstream instance.
|
||||||
pub electrum_url: Option<ElectrumUrl>,
|
pub electrum_url: Option<ElectrumUrl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LiquidSdkOptions {
|
impl LiquidSdkOptions {
|
||||||
pub(crate) fn get_electrum_url(&self) -> ElectrumUrl {
|
pub(crate) fn get_electrum_url(&self) -> ElectrumUrl {
|
||||||
self.electrum_url.clone().unwrap_or({
|
self.electrum_url.clone().unwrap_or({
|
||||||
@@ -440,7 +458,7 @@ pub struct PaymentSwapData {
|
|||||||
/// Represents an SDK payment.
|
/// Represents an SDK payment.
|
||||||
///
|
///
|
||||||
/// By default, this is an onchain tx. It may represent a swap, if swap metadata is available.
|
/// By default, this is an onchain tx. It may represent a swap, if swap metadata is available.
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||||
pub struct Payment {
|
pub struct Payment {
|
||||||
/// The tx ID of the onchain transaction
|
/// The tx ID of the onchain transaction
|
||||||
pub tx_id: String,
|
pub tx_id: String,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{collections::HashMap, fs::create_dir_all, path::PathBuf, str::FromStr}
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use migrations::current_migrations;
|
use migrations::current_migrations;
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection, OptionalExtension, Row};
|
||||||
use rusqlite_migration::{Migrations, M};
|
use rusqlite_migration::{Migrations, M};
|
||||||
|
|
||||||
use crate::model::{Network::*, *};
|
use crate::model::{Network::*, *};
|
||||||
@@ -92,12 +92,8 @@ impl Persister {
|
|||||||
Ok([ongoing_send_swaps, ongoing_receive_swaps].concat())
|
Ok([ongoing_send_swaps, ongoing_receive_swaps].concat())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_payments(&self) -> Result<HashMap<String, Payment>> {
|
fn select_payment_query(&self, where_clause: Option<&str>) -> String {
|
||||||
let con = self.get_connection()?;
|
format!(
|
||||||
|
|
||||||
// TODO For refund txs, do not create a new Payment
|
|
||||||
// Assumes there is no swap chaining (send swap lockup tx = receive swap claim tx)
|
|
||||||
let mut stmt = con.prepare(
|
|
||||||
"
|
"
|
||||||
SELECT
|
SELECT
|
||||||
ptx.tx_id,
|
ptx.tx_id,
|
||||||
@@ -121,51 +117,76 @@ impl Persister {
|
|||||||
ON ptx.tx_id = rs.claim_tx_id
|
ON ptx.tx_id = rs.claim_tx_id
|
||||||
LEFT JOIN send_swaps AS ss
|
LEFT JOIN send_swaps AS ss
|
||||||
ON ptx.tx_id = ss.lockup_tx_id
|
ON ptx.tx_id = ss.lockup_tx_id
|
||||||
",
|
WHERE {}
|
||||||
)?;
|
",
|
||||||
|
where_clause.unwrap_or("true")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sql_row_to_payment(&self, row: &Row) -> Result<Payment, rusqlite::Error> {
|
||||||
|
let tx = PaymentTxData {
|
||||||
|
tx_id: row.get(0)?,
|
||||||
|
timestamp: row.get(1)?,
|
||||||
|
amount_sat: row.get(2)?,
|
||||||
|
payment_type: row.get(3)?,
|
||||||
|
is_confirmed: row.get(4)?,
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_receive_swap_id: Option<String> = row.get(5)?;
|
||||||
|
let maybe_receive_swap_created_at: Option<u32> = row.get(6)?;
|
||||||
|
let maybe_receive_swap_payer_amount_sat: Option<u64> = row.get(7)?;
|
||||||
|
let maybe_receive_swap_receiver_amount_sat: Option<u64> = row.get(8)?;
|
||||||
|
let maybe_receive_swap_receiver_state: Option<PaymentState> = row.get(9)?;
|
||||||
|
let maybe_send_swap_id: Option<String> = row.get(10)?;
|
||||||
|
let maybe_send_swap_created_at: Option<u32> = row.get(11)?;
|
||||||
|
let maybe_send_swap_preimage: Option<String> = row.get(12)?;
|
||||||
|
let maybe_send_swap_payer_amount_sat: Option<u64> = row.get(13)?;
|
||||||
|
let maybe_send_swap_receiver_amount_sat: Option<u64> = row.get(14)?;
|
||||||
|
let maybe_send_swap_state: Option<PaymentState> = row.get(15)?;
|
||||||
|
|
||||||
|
let swap = match maybe_receive_swap_id {
|
||||||
|
Some(receive_swap_id) => Some(PaymentSwapData {
|
||||||
|
swap_id: receive_swap_id,
|
||||||
|
created_at: maybe_receive_swap_created_at.unwrap_or(utils::now()),
|
||||||
|
preimage: None,
|
||||||
|
payer_amount_sat: maybe_receive_swap_payer_amount_sat.unwrap_or(0),
|
||||||
|
receiver_amount_sat: maybe_receive_swap_receiver_amount_sat.unwrap_or(0),
|
||||||
|
status: maybe_receive_swap_receiver_state.unwrap_or(PaymentState::Created),
|
||||||
|
}),
|
||||||
|
None => maybe_send_swap_id.map(|send_swap_id| PaymentSwapData {
|
||||||
|
swap_id: send_swap_id,
|
||||||
|
created_at: maybe_send_swap_created_at.unwrap_or(utils::now()),
|
||||||
|
preimage: maybe_send_swap_preimage,
|
||||||
|
payer_amount_sat: maybe_send_swap_payer_amount_sat.unwrap_or(0),
|
||||||
|
receiver_amount_sat: maybe_send_swap_receiver_amount_sat.unwrap_or(0),
|
||||||
|
status: maybe_send_swap_state.unwrap_or(PaymentState::Created),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Payment::from(tx, swap))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_payment(&self, id: String) -> Result<Option<Payment>> {
|
||||||
|
Ok(self
|
||||||
|
.get_connection()?
|
||||||
|
.query_row(
|
||||||
|
&self.select_payment_query(Some(&format!("ptx.tx_id = ?1"))),
|
||||||
|
params![id],
|
||||||
|
|row| self.sql_row_to_payment(row),
|
||||||
|
)
|
||||||
|
.optional()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_payments(&self) -> Result<HashMap<String, Payment>> {
|
||||||
|
let con = self.get_connection()?;
|
||||||
|
|
||||||
|
// TODO For refund txs, do not create a new Payment
|
||||||
|
// Assumes there is no swap chaining (send swap lockup tx = receive swap claim tx)
|
||||||
|
let mut stmt = con.prepare(&self.select_payment_query(None))?;
|
||||||
|
|
||||||
let data = stmt
|
let data = stmt
|
||||||
.query_map(params![], |row| {
|
.query_map(params![], |row| {
|
||||||
let tx = PaymentTxData {
|
self.sql_row_to_payment(row).map(|p| (p.tx_id.clone(), p))
|
||||||
tx_id: row.get(0)?,
|
|
||||||
timestamp: row.get(1)?,
|
|
||||||
amount_sat: row.get(2)?,
|
|
||||||
payment_type: row.get(3)?,
|
|
||||||
is_confirmed: row.get(4)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
let maybe_receive_swap_id: Option<String> = row.get(5)?;
|
|
||||||
let maybe_receive_swap_created_at: Option<u32> = row.get(6)?;
|
|
||||||
let maybe_receive_swap_payer_amount_sat: Option<u64> = row.get(7)?;
|
|
||||||
let maybe_receive_swap_receiver_amount_sat: Option<u64> = row.get(8)?;
|
|
||||||
let maybe_receive_swap_receiver_state: Option<PaymentState> = row.get(9)?;
|
|
||||||
let maybe_send_swap_id: Option<String> = row.get(10)?;
|
|
||||||
let maybe_send_swap_created_at: Option<u32> = row.get(11)?;
|
|
||||||
let maybe_send_swap_preimage: Option<String> = row.get(12)?;
|
|
||||||
let maybe_send_swap_payer_amount_sat: Option<u64> = row.get(13)?;
|
|
||||||
let maybe_send_swap_receiver_amount_sat: Option<u64> = row.get(14)?;
|
|
||||||
let maybe_send_swap_state: Option<PaymentState> = row.get(15)?;
|
|
||||||
|
|
||||||
let swap = match maybe_receive_swap_id {
|
|
||||||
Some(receive_swap_id) => Some(PaymentSwapData {
|
|
||||||
swap_id: receive_swap_id,
|
|
||||||
created_at: maybe_receive_swap_created_at.unwrap_or(utils::now()),
|
|
||||||
preimage: None,
|
|
||||||
payer_amount_sat: maybe_receive_swap_payer_amount_sat.unwrap_or(0),
|
|
||||||
receiver_amount_sat: maybe_receive_swap_receiver_amount_sat.unwrap_or(0),
|
|
||||||
status: maybe_receive_swap_receiver_state.unwrap_or(PaymentState::Created),
|
|
||||||
}),
|
|
||||||
None => maybe_send_swap_id.map(|send_swap_id| PaymentSwapData {
|
|
||||||
swap_id: send_swap_id,
|
|
||||||
created_at: maybe_send_swap_created_at.unwrap_or(utils::now()),
|
|
||||||
preimage: maybe_send_swap_preimage,
|
|
||||||
payer_amount_sat: maybe_send_swap_payer_amount_sat.unwrap_or(0),
|
|
||||||
receiver_amount_sat: maybe_send_swap_receiver_amount_sat.unwrap_or(0),
|
|
||||||
status: maybe_send_swap_state.unwrap_or(PaymentState::Created),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((tx.tx_id.clone(), Payment::from(tx, swap)))
|
|
||||||
})?
|
})?
|
||||||
.map(|i| i.unwrap())
|
.map(|i| i.unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::persist::Persister;
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use boltz_client::swaps::boltzv2::CreateReverseResponse;
|
use boltz_client::swaps::boltzv2::CreateReverseResponse;
|
||||||
use rusqlite::{named_params, params, Connection, OptionalExtension, Row};
|
use rusqlite::{named_params, params, Connection, Row};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
impl Persister {
|
impl Persister {
|
||||||
@@ -73,13 +73,12 @@ impl Persister {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fetch_receive_swap(
|
pub(crate) fn fetch_receive_swap(&self, id: &str) -> Result<Option<ReceiveSwap>> {
|
||||||
con: &Connection,
|
let con: Connection = self.get_connection()?;
|
||||||
id: &str,
|
|
||||||
) -> rusqlite::Result<Option<ReceiveSwap>> {
|
|
||||||
let query = Self::list_receive_swaps_query(vec!["id = ?1".to_string()]);
|
let query = Self::list_receive_swaps_query(vec!["id = ?1".to_string()]);
|
||||||
con.query_row(&query, [id], Self::sql_row_to_receive_swap)
|
let res = con.query_row(&query, [id], Self::sql_row_to_receive_swap);
|
||||||
.optional()
|
|
||||||
|
Ok(res.ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sql_row_to_receive_swap(row: &Row) -> rusqlite::Result<ReceiveSwap> {
|
fn sql_row_to_receive_swap(row: &Row) -> rusqlite::Result<ReceiveSwap> {
|
||||||
@@ -128,10 +127,8 @@ impl Persister {
|
|||||||
self.list_receive_swaps(con, where_clause)
|
self.list_receive_swaps(con, where_clause)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_pending_receive_swaps(
|
pub(crate) fn list_pending_receive_swaps(&self) -> Result<Vec<ReceiveSwap>> {
|
||||||
&self,
|
let con: Connection = self.get_connection()?;
|
||||||
con: &Connection,
|
|
||||||
) -> rusqlite::Result<Vec<ReceiveSwap>> {
|
|
||||||
let query = Self::list_receive_swaps_query(vec!["state = ?1".to_string()]);
|
let query = Self::list_receive_swaps_query(vec!["state = ?1".to_string()]);
|
||||||
let res = con
|
let res = con
|
||||||
.prepare(&query)?
|
.prepare(&query)?
|
||||||
@@ -147,10 +144,9 @@ impl Persister {
|
|||||||
/// Pending Receive Swaps, indexed by claim_tx_id
|
/// Pending Receive Swaps, indexed by claim_tx_id
|
||||||
pub(crate) fn list_pending_receive_swaps_by_claim_tx_id(
|
pub(crate) fn list_pending_receive_swaps_by_claim_tx_id(
|
||||||
&self,
|
&self,
|
||||||
con: &Connection,
|
) -> Result<HashMap<String, ReceiveSwap>> {
|
||||||
) -> rusqlite::Result<HashMap<String, ReceiveSwap>> {
|
|
||||||
let res = self
|
let res = self
|
||||||
.list_pending_receive_swaps(con)?
|
.list_pending_receive_swaps()?
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|pending_receive_swap| {
|
.filter_map(|pending_receive_swap| {
|
||||||
pending_receive_swap
|
pending_receive_swap
|
||||||
@@ -164,12 +160,12 @@ impl Persister {
|
|||||||
|
|
||||||
pub(crate) fn try_handle_receive_swap_update(
|
pub(crate) fn try_handle_receive_swap_update(
|
||||||
&self,
|
&self,
|
||||||
con: &Connection,
|
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
to_state: PaymentState,
|
to_state: PaymentState,
|
||||||
claim_tx_id: Option<&str>,
|
claim_tx_id: Option<&str>,
|
||||||
) -> Result<(), PaymentError> {
|
) -> Result<(), PaymentError> {
|
||||||
// Do not overwrite claim_tx_id
|
// Do not overwrite claim_tx_id
|
||||||
|
let con: Connection = self.get_connection()?;
|
||||||
con.execute(
|
con.execute(
|
||||||
"UPDATE receive_swaps
|
"UPDATE receive_swaps
|
||||||
SET
|
SET
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use boltz_client::swaps::boltzv2::CreateSubmarineResponse;
|
use boltz_client::swaps::boltzv2::CreateSubmarineResponse;
|
||||||
use rusqlite::{named_params, params, Connection, OptionalExtension, Row};
|
use rusqlite::{named_params, params, Connection, Row};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::ensure_sdk;
|
use crate::ensure_sdk;
|
||||||
@@ -70,13 +70,12 @@ impl Persister {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fetch_send_swap(
|
pub(crate) fn fetch_send_swap(&self, id: &str) -> Result<Option<SendSwap>> {
|
||||||
con: &Connection,
|
let con: Connection = self.get_connection()?;
|
||||||
id: &str,
|
|
||||||
) -> rusqlite::Result<Option<SendSwap>> {
|
|
||||||
let query = Self::list_send_swaps_query(vec!["id = ?1".to_string()]);
|
let query = Self::list_send_swaps_query(vec!["id = ?1".to_string()]);
|
||||||
con.query_row(&query, [id], Self::sql_row_to_send_swap)
|
let res = con.query_row(&query, [id], Self::sql_row_to_send_swap);
|
||||||
.optional()
|
|
||||||
|
Ok(res.ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sql_row_to_send_swap(row: &Row) -> rusqlite::Result<SendSwap> {
|
fn sql_row_to_send_swap(row: &Row) -> rusqlite::Result<SendSwap> {
|
||||||
@@ -124,10 +123,8 @@ impl Persister {
|
|||||||
self.list_send_swaps(con, where_clause)
|
self.list_send_swaps(con, where_clause)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_pending_send_swaps(
|
pub(crate) fn list_pending_send_swaps(&self) -> Result<Vec<SendSwap>> {
|
||||||
&self,
|
let con: Connection = self.get_connection()?;
|
||||||
con: &Connection,
|
|
||||||
) -> rusqlite::Result<Vec<SendSwap>> {
|
|
||||||
let query = Self::list_send_swaps_query(vec!["state = ?1".to_string()]);
|
let query = Self::list_send_swaps_query(vec!["state = ?1".to_string()]);
|
||||||
let res = con
|
let res = con
|
||||||
.prepare(&query)?
|
.prepare(&query)?
|
||||||
@@ -140,10 +137,9 @@ impl Persister {
|
|||||||
/// Pending Send swaps, indexed by refund tx id
|
/// Pending Send swaps, indexed by refund tx id
|
||||||
pub(crate) fn list_pending_send_swaps_by_refund_tx_id(
|
pub(crate) fn list_pending_send_swaps_by_refund_tx_id(
|
||||||
&self,
|
&self,
|
||||||
con: &Connection,
|
) -> Result<HashMap<String, SendSwap>> {
|
||||||
) -> rusqlite::Result<HashMap<String, SendSwap>> {
|
|
||||||
let res: HashMap<String, SendSwap> = self
|
let res: HashMap<String, SendSwap> = self
|
||||||
.list_pending_send_swaps(con)?
|
.list_pending_send_swaps()?
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|pending_send_swap| {
|
.filter_map(|pending_send_swap| {
|
||||||
pending_send_swap
|
pending_send_swap
|
||||||
@@ -157,7 +153,6 @@ impl Persister {
|
|||||||
|
|
||||||
pub(crate) fn try_handle_send_swap_update(
|
pub(crate) fn try_handle_send_swap_update(
|
||||||
&self,
|
&self,
|
||||||
con: &Connection,
|
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
to_state: PaymentState,
|
to_state: PaymentState,
|
||||||
preimage: Option<&str>,
|
preimage: Option<&str>,
|
||||||
@@ -165,6 +160,7 @@ impl Persister {
|
|||||||
refund_tx_id: Option<&str>,
|
refund_tx_id: Option<&str>,
|
||||||
) -> Result<(), PaymentError> {
|
) -> Result<(), PaymentError> {
|
||||||
// Do not overwrite preimage, lockup_tx_id, refund_tx_id
|
// Do not overwrite preimage, lockup_tx_id, refund_tx_id
|
||||||
|
let con: Connection = self.get_connection()?;
|
||||||
con.execute(
|
con.execute(
|
||||||
"UPDATE send_swaps
|
"UPDATE send_swaps
|
||||||
SET
|
SET
|
||||||
|
|||||||
@@ -1,14 +1,3 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::{
|
|
||||||
fs,
|
|
||||||
path::PathBuf,
|
|
||||||
str::FromStr,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
thread,
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use boltz_client::{
|
use boltz_client::{
|
||||||
network::electrum::ElectrumConfig,
|
network::electrum::ElectrumConfig,
|
||||||
@@ -31,12 +20,21 @@ use lwk_wollet::{
|
|||||||
BlockchainBackend, ElectrumClient, ElectrumUrl, ElementsNetwork, FsPersister,
|
BlockchainBackend, ElectrumClient, ElectrumUrl, ElementsNetwork, FsPersister,
|
||||||
Wollet as LwkWollet, WolletDescriptor,
|
Wollet as LwkWollet, WolletDescriptor,
|
||||||
};
|
};
|
||||||
|
use std::time::Instant;
|
||||||
|
use std::{fs, path::PathBuf, str::FromStr, sync::Arc, time::Duration};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use crate::boltz_status_stream::set_stream_nonblocking;
|
use crate::boltz_status_stream::set_stream_nonblocking;
|
||||||
use crate::model::PaymentState::*;
|
use crate::model::PaymentState::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
boltz_status_stream::BoltzStatusStream, ensure_sdk, error::PaymentError, get_invoice_amount,
|
boltz_status_stream::BoltzStatusStream,
|
||||||
model::*, persist::Persister, utils,
|
ensure_sdk,
|
||||||
|
error::{LiquidSdkResult, PaymentError},
|
||||||
|
event::EventManager,
|
||||||
|
get_invoice_amount,
|
||||||
|
model::*,
|
||||||
|
persist::Persister,
|
||||||
|
utils,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Claim tx feerate, in sats per vbyte.
|
/// Claim tx feerate, in sats per vbyte.
|
||||||
@@ -54,10 +52,11 @@ pub struct LiquidSdk {
|
|||||||
lwk_signer: SwSigner,
|
lwk_signer: SwSigner,
|
||||||
persister: Persister,
|
persister: Persister,
|
||||||
data_dir_path: String,
|
data_dir_path: String,
|
||||||
|
event_manager: EventManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LiquidSdk {
|
impl LiquidSdk {
|
||||||
pub fn connect(req: ConnectRequest) -> Result<Arc<LiquidSdk>> {
|
pub async fn connect(req: ConnectRequest) -> Result<Arc<LiquidSdk>> {
|
||||||
let is_mainnet = req.network == Network::Liquid;
|
let is_mainnet = req.network == Network::Liquid;
|
||||||
let signer = SwSigner::new(&req.mnemonic, is_mainnet)?;
|
let signer = SwSigner::new(&req.mnemonic, is_mainnet)?;
|
||||||
let descriptor = LiquidSdk::get_descriptor(&signer, req.network)?;
|
let descriptor = LiquidSdk::get_descriptor(&signer, req.network)?;
|
||||||
@@ -70,17 +69,19 @@ impl LiquidSdk {
|
|||||||
network: req.network,
|
network: req.network,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
BoltzStatusStream::track_pending_swaps(sdk.clone())?;
|
BoltzStatusStream::track_pending_swaps(sdk.clone()).await?;
|
||||||
|
|
||||||
// Periodically run sync() in the background
|
// Periodically run sync() in the background
|
||||||
let sdk_clone = sdk.clone();
|
let sdk_clone = sdk.clone();
|
||||||
thread::spawn(move || loop {
|
tokio::spawn(async move {
|
||||||
thread::sleep(Duration::from_secs(30));
|
loop {
|
||||||
_ = sdk_clone.sync();
|
tokio::time::sleep(Duration::from_secs(30)).await;
|
||||||
|
_ = sdk_clone.sync().await;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initial sync() before returning the instance
|
// Initial sync() before returning the instance
|
||||||
sdk.sync()?;
|
sdk.sync().await?;
|
||||||
|
|
||||||
Ok(sdk)
|
Ok(sdk)
|
||||||
}
|
}
|
||||||
@@ -103,6 +104,8 @@ impl LiquidSdk {
|
|||||||
let persister = Persister::new(&data_dir_path, network)?;
|
let persister = Persister::new(&data_dir_path, network)?;
|
||||||
persister.init()?;
|
persister.init()?;
|
||||||
|
|
||||||
|
let event_manager = EventManager::new();
|
||||||
|
|
||||||
let sdk = Arc::new(LiquidSdk {
|
let sdk = Arc::new(LiquidSdk {
|
||||||
lwk_wollet,
|
lwk_wollet,
|
||||||
network,
|
network,
|
||||||
@@ -110,11 +113,29 @@ impl LiquidSdk {
|
|||||||
lwk_signer: opts.signer,
|
lwk_signer: opts.signer,
|
||||||
persister,
|
persister,
|
||||||
data_dir_path,
|
data_dir_path,
|
||||||
|
event_manager,
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(sdk)
|
Ok(sdk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn notify_event_listeners(&self, e: LiquidSdkEvent) -> Result<()> {
|
||||||
|
self.event_manager.notify(e).await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add_event_listener(
|
||||||
|
&self,
|
||||||
|
listener: Box<dyn EventListener>,
|
||||||
|
) -> LiquidSdkResult<String> {
|
||||||
|
Ok(self.event_manager.add(listener).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn remove_event_listener(&self, id: String) -> LiquidSdkResult<()> {
|
||||||
|
self.event_manager.remove(id).await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_descriptor(signer: &SwSigner, network: Network) -> Result<WolletDescriptor> {
|
fn get_descriptor(signer: &SwSigner, network: Network) -> Result<WolletDescriptor> {
|
||||||
let is_mainnet = network == Network::Liquid;
|
let is_mainnet = network == Network::Liquid;
|
||||||
let descriptor_str = singlesig_desc(
|
let descriptor_str = singlesig_desc(
|
||||||
@@ -168,7 +189,7 @@ impl LiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Transitions a Receive swap to a new state
|
/// Transitions a Receive swap to a new state
|
||||||
pub(crate) fn try_handle_receive_swap_update(
|
pub(crate) async fn try_handle_receive_swap_update(
|
||||||
&self,
|
&self,
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
to_state: PaymentState,
|
to_state: PaymentState,
|
||||||
@@ -178,20 +199,24 @@ impl LiquidSdk {
|
|||||||
"Transitioning Receive swap {swap_id} to {to_state:?} (claim_tx_id = {claim_tx_id:?})"
|
"Transitioning Receive swap {swap_id} to {to_state:?} (claim_tx_id = {claim_tx_id:?})"
|
||||||
);
|
);
|
||||||
|
|
||||||
let con = self.persister.get_connection()?;
|
let swap = self
|
||||||
let swap = Persister::fetch_receive_swap(&con, swap_id)
|
.persister
|
||||||
|
.fetch_receive_swap(swap_id)
|
||||||
.map_err(|_| PaymentError::PersistError)?
|
.map_err(|_| PaymentError::PersistError)?
|
||||||
.ok_or(PaymentError::Generic {
|
.ok_or(PaymentError::Generic {
|
||||||
err: format!("Receive Swap not found {swap_id}"),
|
err: format!("Receive Swap not found {swap_id}"),
|
||||||
})?;
|
})?;
|
||||||
|
let payment_id = claim_tx_id.map(|c| c.to_string()).or(swap.claim_tx_id);
|
||||||
|
|
||||||
Self::validate_state_transition(swap.state, to_state)?;
|
Self::validate_state_transition(swap.state, to_state)?;
|
||||||
self.persister
|
self.persister
|
||||||
.try_handle_receive_swap_update(&con, swap_id, to_state, claim_tx_id)
|
.try_handle_receive_swap_update(swap_id, to_state, claim_tx_id)?;
|
||||||
|
|
||||||
|
Ok(self.emit_payment_updated(payment_id).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transitions a Send swap to a new state
|
/// Transitions a Send swap to a new state
|
||||||
pub(crate) fn try_handle_send_swap_update(
|
pub(crate) async fn try_handle_send_swap_update(
|
||||||
&self,
|
&self,
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
to_state: PaymentState,
|
to_state: PaymentState,
|
||||||
@@ -201,36 +226,132 @@ impl LiquidSdk {
|
|||||||
) -> Result<(), PaymentError> {
|
) -> Result<(), PaymentError> {
|
||||||
info!("Transitioning Send swap {swap_id} to {to_state:?} (lockup_tx_id = {lockup_tx_id:?}, refund_tx_id = {refund_tx_id:?})");
|
info!("Transitioning Send swap {swap_id} to {to_state:?} (lockup_tx_id = {lockup_tx_id:?}, refund_tx_id = {refund_tx_id:?})");
|
||||||
|
|
||||||
let con = self.persister.get_connection()?;
|
let swap: SendSwap = self
|
||||||
let swap = Persister::fetch_send_swap(&con, swap_id)
|
.persister
|
||||||
|
.fetch_send_swap(swap_id)
|
||||||
.map_err(|_| PaymentError::PersistError)?
|
.map_err(|_| PaymentError::PersistError)?
|
||||||
.ok_or(PaymentError::Generic {
|
.ok_or(PaymentError::Generic {
|
||||||
err: format!("Send Swap not found {swap_id}"),
|
err: format!("Send Swap not found {swap_id}"),
|
||||||
})?;
|
})?;
|
||||||
|
let payment_id = lockup_tx_id.map(|c| c.to_string()).or(swap.lockup_tx_id);
|
||||||
|
|
||||||
Self::validate_state_transition(swap.state, to_state)?;
|
Self::validate_state_transition(swap.state, to_state)?;
|
||||||
self.persister.try_handle_send_swap_update(
|
self.persister.try_handle_send_swap_update(
|
||||||
&con,
|
|
||||||
swap_id,
|
swap_id,
|
||||||
to_state,
|
to_state,
|
||||||
preimage,
|
preimage,
|
||||||
lockup_tx_id,
|
lockup_tx_id,
|
||||||
refund_tx_id,
|
refund_tx_id,
|
||||||
)
|
)?;
|
||||||
|
Ok(self.emit_payment_updated(payment_id).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn emit_payment_updated(&self, payment_id: Option<String>) -> Result<()> {
|
||||||
|
if let Some(id) = payment_id {
|
||||||
|
match self.persister.get_payment(id.clone())? {
|
||||||
|
Some(payment) => {
|
||||||
|
match payment.status {
|
||||||
|
Complete => {
|
||||||
|
self.notify_event_listeners(LiquidSdkEvent::PaymentSucceed {
|
||||||
|
details: payment,
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
Pending => {
|
||||||
|
// The swap state has changed to Pending
|
||||||
|
match payment.swap_id.clone() {
|
||||||
|
Some(swap_id) => match payment.payment_type {
|
||||||
|
PaymentType::Receive => {
|
||||||
|
match self.persister.fetch_receive_swap(&swap_id)? {
|
||||||
|
Some(swap) => match swap.claim_tx_id {
|
||||||
|
Some(_) => {
|
||||||
|
// The claim tx has now been broadcast
|
||||||
|
self.notify_event_listeners(
|
||||||
|
LiquidSdkEvent::PaymentWaitingConfirmation {
|
||||||
|
details: payment,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// The lockup tx is in the mempool/confirmed
|
||||||
|
self.notify_event_listeners(
|
||||||
|
LiquidSdkEvent::PaymentPending {
|
||||||
|
details: payment,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => debug!("Swap not found: {swap_id}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PaymentType::Send => {
|
||||||
|
match self.persister.fetch_send_swap(&swap_id)? {
|
||||||
|
Some(swap) => match swap.refund_tx_id {
|
||||||
|
Some(_) => {
|
||||||
|
// The refund tx has now been broadcast
|
||||||
|
self.notify_event_listeners(
|
||||||
|
LiquidSdkEvent::PaymentRefundPending {
|
||||||
|
details: payment,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// The lockup tx is in the mempool/confirmed
|
||||||
|
self.notify_event_listeners(
|
||||||
|
LiquidSdkEvent::PaymentPending {
|
||||||
|
details: payment,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => debug!("Swap not found: {swap_id}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => debug!("Payment has no swap id"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Failed => match payment.payment_type {
|
||||||
|
PaymentType::Receive => {
|
||||||
|
self.notify_event_listeners(LiquidSdkEvent::PaymentFailed {
|
||||||
|
details: payment,
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
PaymentType::Send => {
|
||||||
|
// The refund tx is confirmed
|
||||||
|
self.notify_event_listeners(LiquidSdkEvent::PaymentRefunded {
|
||||||
|
details: payment,
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
None => debug!("Payment not found: {id}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles status updates from Boltz for Receive swaps
|
/// Handles status updates from Boltz for Receive swaps
|
||||||
pub(crate) fn try_handle_receive_swap_boltz_status(
|
pub(crate) async fn try_handle_receive_swap_boltz_status(
|
||||||
&self,
|
&self,
|
||||||
swap_state: RevSwapStates,
|
swap_state: RevSwapStates,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.sync()?;
|
self.sync().await?;
|
||||||
|
|
||||||
info!("Handling Receive Swap transition to {swap_state:?} for swap {id}");
|
info!("Handling Receive Swap transition to {swap_state:?} for swap {id}");
|
||||||
|
|
||||||
let con = self.persister.get_connection()?;
|
let receive_swap = self
|
||||||
let receive_swap = Persister::fetch_receive_swap(&con, id)?
|
.persister
|
||||||
|
.fetch_receive_swap(id)?
|
||||||
.ok_or(anyhow!("No ongoing Receive Swap found for ID {id}"))?;
|
.ok_or(anyhow!("No ongoing Receive Swap found for ID {id}"))?;
|
||||||
|
|
||||||
match swap_state {
|
match swap_state {
|
||||||
@@ -239,7 +360,7 @@ impl LiquidSdk {
|
|||||||
| RevSwapStates::TransactionFailed
|
| RevSwapStates::TransactionFailed
|
||||||
| RevSwapStates::TransactionRefunded => {
|
| RevSwapStates::TransactionRefunded => {
|
||||||
error!("Swap {id} entered into an unrecoverable state: {swap_state:?}");
|
error!("Swap {id} entered into an unrecoverable state: {swap_state:?}");
|
||||||
self.try_handle_receive_swap_update(id, Failed, None)?;
|
self.try_handle_receive_swap_update(id, Failed, None).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The lockup tx is in the mempool and we accept 0-conf => try to claim
|
// The lockup tx is in the mempool and we accept 0-conf => try to claim
|
||||||
@@ -251,7 +372,7 @@ impl LiquidSdk {
|
|||||||
Some(claim_tx_id) => {
|
Some(claim_tx_id) => {
|
||||||
warn!("Claim tx for Receive Swap {id} was already broadcast: txid {claim_tx_id}")
|
warn!("Claim tx for Receive Swap {id} was already broadcast: txid {claim_tx_id}")
|
||||||
}
|
}
|
||||||
None => match self.try_claim(&receive_swap) {
|
None => match self.try_claim(&receive_swap).await {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
PaymentError::AlreadyClaimed => warn!("Funds already claimed for Receive Swap {id}"),
|
PaymentError::AlreadyClaimed => warn!("Funds already claimed for Receive Swap {id}"),
|
||||||
@@ -272,17 +393,18 @@ impl LiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handles status updates from Boltz for Send swaps
|
/// Handles status updates from Boltz for Send swaps
|
||||||
pub(crate) fn try_handle_send_swap_boltz_status(
|
pub(crate) async fn try_handle_send_swap_boltz_status(
|
||||||
&self,
|
&self,
|
||||||
swap_state: SubSwapStates,
|
swap_state: SubSwapStates,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.sync()?;
|
self.sync().await?;
|
||||||
|
|
||||||
info!("Handling Send Swap transition to {swap_state:?} for swap {id}");
|
info!("Handling Send Swap transition to {swap_state:?} for swap {id}");
|
||||||
|
|
||||||
let con = self.persister.get_connection()?;
|
let ongoing_send_swap = self
|
||||||
let ongoing_send_swap = Persister::fetch_send_swap(&con, id)?
|
.persister
|
||||||
|
.fetch_send_swap(id)?
|
||||||
.ok_or(anyhow!("No ongoing Send Swap found for ID {id}"))?;
|
.ok_or(anyhow!("No ongoing Send Swap found for ID {id}"))?;
|
||||||
let create_response: CreateSubmarineResponse =
|
let create_response: CreateSubmarineResponse =
|
||||||
ongoing_send_swap.get_boltz_create_response()?;
|
ongoing_send_swap.get_boltz_create_response()?;
|
||||||
@@ -308,6 +430,7 @@ impl LiquidSdk {
|
|||||||
&ongoing_send_swap.invoice,
|
&ongoing_send_swap.invoice,
|
||||||
&keypair,
|
&keypair,
|
||||||
)
|
)
|
||||||
|
.await
|
||||||
.map_err(|e| anyhow!("Could not post claim details. Err: {e:?}"))?;
|
.map_err(|e| anyhow!("Could not post claim details. Err: {e:?}"))?;
|
||||||
|
|
||||||
// We insert a pseudo-lockup-tx in case LWK fails to pick up the new mempool tx for a while
|
// We insert a pseudo-lockup-tx in case LWK fails to pick up the new mempool tx for a while
|
||||||
@@ -327,7 +450,8 @@ impl LiquidSdk {
|
|||||||
warn!("Swap-in {id} has already been claimed");
|
warn!("Swap-in {id} has already been claimed");
|
||||||
let preimage =
|
let preimage =
|
||||||
self.get_preimage_from_script_path_claim_spend(&ongoing_send_swap)?;
|
self.get_preimage_from_script_path_claim_spend(&ongoing_send_swap)?;
|
||||||
self.validate_send_swap_preimage(id, &ongoing_send_swap.invoice, &preimage)?;
|
self.validate_send_swap_preimage(id, &ongoing_send_swap.invoice, &preimage)
|
||||||
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,10 +467,12 @@ impl LiquidSdk {
|
|||||||
)
|
)
|
||||||
.map_err(|e| anyhow!("Could not rebuild refund details for swap-in {id}: {e:?}"))?;
|
.map_err(|e| anyhow!("Could not rebuild refund details for swap-in {id}: {e:?}"))?;
|
||||||
|
|
||||||
let refund_tx_id =
|
let refund_tx_id = self
|
||||||
self.try_refund(id, &swap_script, &keypair, receiver_amount_sat)?;
|
.try_refund(id, &swap_script, &keypair, receiver_amount_sat)
|
||||||
|
.await?;
|
||||||
info!("Broadcast refund tx for Swap-in {id}. Tx id: {refund_tx_id}");
|
info!("Broadcast refund tx for Swap-in {id}. Tx id: {refund_tx_id}");
|
||||||
self.try_handle_send_swap_update(id, Pending, None, None, Some(&refund_tx_id))?;
|
self.try_handle_send_swap_update(id, Pending, None, None, Some(&refund_tx_id))
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -359,16 +485,16 @@ impl LiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the next unused onchain Liquid address
|
/// Gets the next unused onchain Liquid address
|
||||||
fn next_unused_address(&self) -> Result<Address, lwk_wollet::Error> {
|
async fn next_unused_address(&self) -> Result<Address, lwk_wollet::Error> {
|
||||||
let lwk_wollet = self.lwk_wollet.lock().unwrap();
|
let lwk_wollet = self.lwk_wollet.lock().await;
|
||||||
Ok(lwk_wollet.address(None)?.address().clone())
|
Ok(lwk_wollet.address(None)?.address().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_info(&self, req: GetInfoRequest) -> Result<GetInfoResponse> {
|
pub async fn get_info(&self, req: GetInfoRequest) -> Result<GetInfoResponse> {
|
||||||
debug!("next_unused_address: {}", self.next_unused_address()?);
|
debug!("next_unused_address: {}", self.next_unused_address().await?);
|
||||||
|
|
||||||
if req.with_scan {
|
if req.with_scan {
|
||||||
self.sync()?;
|
self.sync().await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pending_send_sat = 0;
|
let mut pending_send_sat = 0;
|
||||||
@@ -420,13 +546,13 @@ impl LiquidSdk {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_tx(
|
async fn build_tx(
|
||||||
&self,
|
&self,
|
||||||
fee_rate: Option<f32>,
|
fee_rate: Option<f32>,
|
||||||
recipient_address: &str,
|
recipient_address: &str,
|
||||||
amount_sat: u64,
|
amount_sat: u64,
|
||||||
) -> Result<Transaction, PaymentError> {
|
) -> Result<Transaction, PaymentError> {
|
||||||
let lwk_wollet = self.lwk_wollet.lock().unwrap();
|
let lwk_wollet = self.lwk_wollet.lock().await;
|
||||||
let mut pset = lwk_wollet::TxBuilder::new(self.network.into())
|
let mut pset = lwk_wollet::TxBuilder::new(self.network.into())
|
||||||
.add_lbtc_recipient(
|
.add_lbtc_recipient(
|
||||||
&ElementsAddress::from_str(recipient_address).map_err(|e| {
|
&ElementsAddress::from_str(recipient_address).map_err(|e| {
|
||||||
@@ -483,7 +609,7 @@ impl LiquidSdk {
|
|||||||
Ok(lbtc_pair)
|
Ok(lbtc_pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_broadcast_fee_estimation(&self, amount_sat: u64) -> Result<u64> {
|
async fn get_broadcast_fee_estimation(&self, amount_sat: u64) -> Result<u64> {
|
||||||
// TODO Replace this with own address when LWK supports taproot
|
// TODO Replace this with own address when LWK supports taproot
|
||||||
// https://github.com/Blockstream/lwk/issues/31
|
// https://github.com/Blockstream/lwk/issues/31
|
||||||
let temp_p2tr_addr = match self.network {
|
let temp_p2tr_addr = match self.network {
|
||||||
@@ -493,13 +619,14 @@ impl LiquidSdk {
|
|||||||
|
|
||||||
// Create a throw-away tx similar to the lockup tx, in order to estimate fees
|
// Create a throw-away tx similar to the lockup tx, in order to estimate fees
|
||||||
Ok(self
|
Ok(self
|
||||||
.build_tx(None, temp_p2tr_addr, amount_sat)?
|
.build_tx(None, temp_p2tr_addr, amount_sat)
|
||||||
|
.await?
|
||||||
.all_fees()
|
.all_fees()
|
||||||
.values()
|
.values()
|
||||||
.sum())
|
.sum())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_send_payment(
|
pub async fn prepare_send_payment(
|
||||||
&self,
|
&self,
|
||||||
req: &PrepareSendRequest,
|
req: &PrepareSendRequest,
|
||||||
) -> Result<PrepareSendResponse, PaymentError> {
|
) -> Result<PrepareSendResponse, PaymentError> {
|
||||||
@@ -512,7 +639,9 @@ impl LiquidSdk {
|
|||||||
let client = self.boltz_client_v2();
|
let client = self.boltz_client_v2();
|
||||||
let lbtc_pair = Self::validate_submarine_pairs(&client, receiver_amount_sat)?;
|
let lbtc_pair = Self::validate_submarine_pairs(&client, receiver_amount_sat)?;
|
||||||
|
|
||||||
let broadcast_fees_sat = self.get_broadcast_fee_estimation(receiver_amount_sat)?;
|
let broadcast_fees_sat = self
|
||||||
|
.get_broadcast_fee_estimation(receiver_amount_sat)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(PrepareSendResponse {
|
Ok(PrepareSendResponse {
|
||||||
invoice: req.invoice.clone(),
|
invoice: req.invoice.clone(),
|
||||||
@@ -531,8 +660,11 @@ impl LiquidSdk {
|
|||||||
.ok_or(PaymentError::InvalidPreimage)
|
.ok_or(PaymentError::InvalidPreimage)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_refund_tx(&self, swap_script: &LBtcSwapScriptV2) -> Result<LBtcSwapTxV2, PaymentError> {
|
async fn new_refund_tx(
|
||||||
let wallet = self.lwk_wollet.lock().unwrap();
|
&self,
|
||||||
|
swap_script: &LBtcSwapScriptV2,
|
||||||
|
) -> Result<LBtcSwapTxV2, PaymentError> {
|
||||||
|
let wallet = self.lwk_wollet.lock().await;
|
||||||
let output_address = wallet.address(Some(0))?.address().to_string();
|
let output_address = wallet.address(Some(0))?.address().to_string();
|
||||||
let network_config = self.network_config();
|
let network_config = self.network_config();
|
||||||
Ok(LBtcSwapTxV2::new_refund(
|
Ok(LBtcSwapTxV2::new_refund(
|
||||||
@@ -542,16 +674,17 @@ impl LiquidSdk {
|
|||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_refund(
|
async fn try_refund(
|
||||||
&self,
|
&self,
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
swap_script: &LBtcSwapScriptV2,
|
swap_script: &LBtcSwapScriptV2,
|
||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
amount_sat: u64,
|
amount_sat: u64,
|
||||||
) -> Result<String, PaymentError> {
|
) -> Result<String, PaymentError> {
|
||||||
let refund_tx = self.new_refund_tx(swap_script)?;
|
let refund_tx = self.new_refund_tx(swap_script).await?;
|
||||||
|
|
||||||
let broadcast_fees_sat = Amount::from_sat(self.get_broadcast_fee_estimation(amount_sat)?);
|
let broadcast_fees_sat =
|
||||||
|
Amount::from_sat(self.get_broadcast_fee_estimation(amount_sat).await?);
|
||||||
let client = self.boltz_client_v2();
|
let client = self.boltz_client_v2();
|
||||||
let is_lowball = Some((&client, boltz_client::network::Chain::from(self.network)));
|
let is_lowball = Some((&client, boltz_client::network::Chain::from(self.network)));
|
||||||
|
|
||||||
@@ -578,7 +711,7 @@ impl LiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the provided preimage matches our invoice. If so, mark the Send payment as [Complete].
|
/// Check if the provided preimage matches our invoice. If so, mark the Send payment as [Complete].
|
||||||
fn validate_send_swap_preimage(
|
async fn validate_send_swap_preimage(
|
||||||
&self,
|
&self,
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
invoice: &str,
|
invoice: &str,
|
||||||
@@ -587,10 +720,11 @@ impl LiquidSdk {
|
|||||||
Self::verify_payment_hash(preimage, invoice)?;
|
Self::verify_payment_hash(preimage, invoice)?;
|
||||||
info!("Preimage is valid for Send Swap {swap_id}");
|
info!("Preimage is valid for Send Swap {swap_id}");
|
||||||
self.try_handle_send_swap_update(swap_id, Complete, Some(preimage), None, None)
|
self.try_handle_send_swap_update(swap_id, Complete, Some(preimage), None, None)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Interact with Boltz to assist in them doing a cooperative claim
|
/// Interact with Boltz to assist in them doing a cooperative claim
|
||||||
fn cooperate_send_swap_claim(
|
async fn cooperate_send_swap_claim(
|
||||||
&self,
|
&self,
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
swap_script: &LBtcSwapScriptV2,
|
swap_script: &LBtcSwapScriptV2,
|
||||||
@@ -599,12 +733,13 @@ impl LiquidSdk {
|
|||||||
) -> Result<(), PaymentError> {
|
) -> Result<(), PaymentError> {
|
||||||
debug!("Claim is pending for swap-in {swap_id}. Initiating cooperative claim");
|
debug!("Claim is pending for swap-in {swap_id}. Initiating cooperative claim");
|
||||||
let client = self.boltz_client_v2();
|
let client = self.boltz_client_v2();
|
||||||
let refund_tx = self.new_refund_tx(swap_script)?;
|
let refund_tx = self.new_refund_tx(swap_script).await?;
|
||||||
|
|
||||||
let claim_tx_response = client.get_claim_tx_details(&swap_id.to_string())?;
|
let claim_tx_response = client.get_claim_tx_details(&swap_id.to_string())?;
|
||||||
debug!("Received claim tx details: {:?}", &claim_tx_response);
|
debug!("Received claim tx details: {:?}", &claim_tx_response);
|
||||||
|
|
||||||
self.validate_send_swap_preimage(swap_id, invoice, &claim_tx_response.preimage)?;
|
self.validate_send_swap_preimage(swap_id, invoice, &claim_tx_response.preimage)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let (partial_sig, pub_nonce) =
|
let (partial_sig, pub_nonce) =
|
||||||
refund_tx.submarine_partial_sig(keypair, &claim_tx_response)?;
|
refund_tx.submarine_partial_sig(keypair, &claim_tx_response)?;
|
||||||
@@ -614,7 +749,7 @@ impl LiquidSdk {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lockup_funds(
|
async fn lockup_funds(
|
||||||
&self,
|
&self,
|
||||||
swap_id: &str,
|
swap_id: &str,
|
||||||
create_response: &CreateSubmarineResponse,
|
create_response: &CreateSubmarineResponse,
|
||||||
@@ -624,11 +759,13 @@ impl LiquidSdk {
|
|||||||
create_response.expected_amount, create_response.address
|
create_response.expected_amount, create_response.address
|
||||||
);
|
);
|
||||||
|
|
||||||
let lockup_tx = self.build_tx(
|
let lockup_tx = self
|
||||||
None,
|
.build_tx(
|
||||||
&create_response.address,
|
None,
|
||||||
create_response.expected_amount,
|
&create_response.address,
|
||||||
)?;
|
create_response.expected_amount,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let electrum_client = ElectrumClient::new(&self.electrum_url)?;
|
let electrum_client = ElectrumClient::new(&self.electrum_url)?;
|
||||||
let lockup_tx_id = electrum_client.broadcast(&lockup_tx)?.to_string();
|
let lockup_tx_id = electrum_client.broadcast(&lockup_tx)?.to_string();
|
||||||
@@ -639,7 +776,7 @@ impl LiquidSdk {
|
|||||||
Ok(lockup_tx_id)
|
Ok(lockup_tx_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_payment(
|
pub async fn send_payment(
|
||||||
&self,
|
&self,
|
||||||
req: &PrepareSendResponse,
|
req: &PrepareSendResponse,
|
||||||
) -> Result<SendPaymentResponse, PaymentError> {
|
) -> Result<SendPaymentResponse, PaymentError> {
|
||||||
@@ -648,7 +785,9 @@ impl LiquidSdk {
|
|||||||
|
|
||||||
let client = self.boltz_client_v2();
|
let client = self.boltz_client_v2();
|
||||||
let lbtc_pair = Self::validate_submarine_pairs(&client, receiver_amount_sat)?;
|
let lbtc_pair = Self::validate_submarine_pairs(&client, receiver_amount_sat)?;
|
||||||
let broadcast_fees_sat = self.get_broadcast_fee_estimation(receiver_amount_sat)?;
|
let broadcast_fees_sat = self
|
||||||
|
.get_broadcast_fee_estimation(receiver_amount_sat)
|
||||||
|
.await?;
|
||||||
ensure_sdk!(
|
ensure_sdk!(
|
||||||
req.fees_sat == lbtc_pair.fees.total(receiver_amount_sat) + broadcast_fees_sat,
|
req.fees_sat == lbtc_pair.fees.total(receiver_amount_sat) + broadcast_fees_sat,
|
||||||
PaymentError::InvalidOrExpiredFees
|
PaymentError::InvalidOrExpiredFees
|
||||||
@@ -719,16 +858,16 @@ impl LiquidSdk {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Sync before handling new state
|
// Sync before handling new state
|
||||||
self.sync()?;
|
self.sync().await?;
|
||||||
|
|
||||||
// See https://docs.boltz.exchange/v/api/lifecycle#normal-submarine-swaps
|
// See https://docs.boltz.exchange/v/api/lifecycle#normal-submarine-swaps
|
||||||
match state {
|
match state {
|
||||||
// Boltz has locked the HTLC, we proceed with locking up the funds
|
// Boltz has locked the HTLC, we proceed with locking up the funds
|
||||||
SubSwapStates::InvoiceSet => {
|
SubSwapStates::InvoiceSet => {
|
||||||
// Check that we have not persisted the swap already
|
// Check that we have not persisted the swap already
|
||||||
let con = self.persister.get_connection()?;
|
if let Some(ongoing_swap) = self
|
||||||
|
.persister
|
||||||
if let Some(ongoing_swap) = Persister::fetch_send_swap(&con, swap_id)
|
.fetch_send_swap(swap_id)
|
||||||
.map_err(|_| PaymentError::PersistError)?
|
.map_err(|_| PaymentError::PersistError)?
|
||||||
{
|
{
|
||||||
if ongoing_swap.lockup_tx_id.is_some() {
|
if ongoing_swap.lockup_tx_id.is_some() {
|
||||||
@@ -736,14 +875,15 @@ impl LiquidSdk {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
lockup_tx_id = self.lockup_funds(swap_id, &create_response)?;
|
lockup_tx_id = self.lockup_funds(swap_id, &create_response).await?;
|
||||||
self.try_handle_send_swap_update(
|
self.try_handle_send_swap_update(
|
||||||
swap_id,
|
swap_id,
|
||||||
Pending,
|
Pending,
|
||||||
None,
|
None,
|
||||||
Some(&lockup_tx_id),
|
Some(&lockup_tx_id),
|
||||||
None,
|
None,
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Boltz has detected the lockup in the mempool, we can speed up
|
// Boltz has detected the lockup in the mempool, we can speed up
|
||||||
@@ -751,7 +891,8 @@ impl LiquidSdk {
|
|||||||
SubSwapStates::TransactionClaimPending => {
|
SubSwapStates::TransactionClaimPending => {
|
||||||
// TODO Consolidate status handling: merge with and reuse try_handle_send_swap_boltz_status
|
// TODO Consolidate status handling: merge with and reuse try_handle_send_swap_boltz_status
|
||||||
|
|
||||||
self.cooperate_send_swap_claim(swap_id, &swap_script, &req.invoice, &keypair)?;
|
self.cooperate_send_swap_claim(swap_id, &swap_script, &req.invoice, &keypair)
|
||||||
|
.await?;
|
||||||
debug!("Boltz successfully claimed the funds");
|
debug!("Boltz successfully claimed the funds");
|
||||||
|
|
||||||
BoltzStatusStream::unmark_swap_as_tracked(swap_id, SwapType::Submarine);
|
BoltzStatusStream::unmark_swap_as_tracked(swap_id, SwapType::Submarine);
|
||||||
@@ -770,8 +911,9 @@ impl LiquidSdk {
|
|||||||
SubSwapStates::InvoiceFailedToPay
|
SubSwapStates::InvoiceFailedToPay
|
||||||
| SubSwapStates::SwapExpired
|
| SubSwapStates::SwapExpired
|
||||||
| SubSwapStates::TransactionLockupFailed => {
|
| SubSwapStates::TransactionLockupFailed => {
|
||||||
let refund_tx_id =
|
let refund_tx_id = self
|
||||||
self.try_refund(swap_id, &swap_script, &keypair, receiver_amount_sat)?;
|
.try_refund(swap_id, &swap_script, &keypair, receiver_amount_sat)
|
||||||
|
.await?;
|
||||||
|
|
||||||
result = Err(PaymentError::Refunded {
|
result = Err(PaymentError::Refunded {
|
||||||
err: format!(
|
err: format!(
|
||||||
@@ -790,7 +932,7 @@ impl LiquidSdk {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_claim(&self, ongoing_receive_swap: &ReceiveSwap) -> Result<(), PaymentError> {
|
async fn try_claim(&self, ongoing_receive_swap: &ReceiveSwap) -> Result<(), PaymentError> {
|
||||||
ensure_sdk!(
|
ensure_sdk!(
|
||||||
ongoing_receive_swap.claim_tx_id.is_none(),
|
ongoing_receive_swap.claim_tx_id.is_none(),
|
||||||
PaymentError::AlreadyClaimed
|
PaymentError::AlreadyClaimed
|
||||||
@@ -799,6 +941,9 @@ impl LiquidSdk {
|
|||||||
let swap_id = &ongoing_receive_swap.id;
|
let swap_id = &ongoing_receive_swap.id;
|
||||||
debug!("Trying to claim Receive Swap {swap_id}",);
|
debug!("Trying to claim Receive Swap {swap_id}",);
|
||||||
|
|
||||||
|
self.try_handle_receive_swap_update(swap_id, Pending, None)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let lsk = self.get_liquid_swap_key()?;
|
let lsk = self.get_liquid_swap_key()?;
|
||||||
let our_keys = lsk.keypair;
|
let our_keys = lsk.keypair;
|
||||||
|
|
||||||
@@ -808,7 +953,7 @@ impl LiquidSdk {
|
|||||||
our_keys.public_key().into(),
|
our_keys.public_key().into(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let claim_address = self.next_unused_address()?.to_string();
|
let claim_address = self.next_unused_address().await?.to_string();
|
||||||
let claim_tx_wrapper = LBtcSwapTxV2::new_claim(
|
let claim_tx_wrapper = LBtcSwapTxV2::new_claim(
|
||||||
swap_script,
|
swap_script,
|
||||||
claim_address,
|
claim_address,
|
||||||
@@ -834,18 +979,19 @@ impl LiquidSdk {
|
|||||||
info!("Successfully broadcast claim tx {claim_tx_id} for Receive Swap {swap_id}");
|
info!("Successfully broadcast claim tx {claim_tx_id} for Receive Swap {swap_id}");
|
||||||
debug!("Claim Tx {:?}", claim_tx);
|
debug!("Claim Tx {:?}", claim_tx);
|
||||||
|
|
||||||
self.try_handle_receive_swap_update(swap_id, Pending, Some(&claim_tx_id))?;
|
|
||||||
|
|
||||||
// We insert a pseudo-claim-tx in case LWK fails to pick up the new mempool tx for a while
|
// We insert a pseudo-claim-tx in case LWK fails to pick up the new mempool tx for a while
|
||||||
// This makes the tx known to the SDK (get_info, list_payments) instantly
|
// This makes the tx known to the SDK (get_info, list_payments) instantly
|
||||||
self.persister.insert_or_update_payment(PaymentTxData {
|
self.persister.insert_or_update_payment(PaymentTxData {
|
||||||
tx_id: claim_tx_id,
|
tx_id: claim_tx_id.clone(),
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
amount_sat: ongoing_receive_swap.receiver_amount_sat,
|
amount_sat: ongoing_receive_swap.receiver_amount_sat,
|
||||||
payment_type: PaymentType::Receive,
|
payment_type: PaymentType::Receive,
|
||||||
is_confirmed: false,
|
is_confirmed: false,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
self.try_handle_receive_swap_update(swap_id, Pending, Some(&claim_tx_id))
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -954,22 +1100,19 @@ impl LiquidSdk {
|
|||||||
|
|
||||||
/// This method fetches the chain tx data (onchain and mempool) using LWK. For every wallet tx,
|
/// This method fetches the chain tx data (onchain and mempool) using LWK. For every wallet tx,
|
||||||
/// it inserts or updates a corresponding entry in our Payments table.
|
/// it inserts or updates a corresponding entry in our Payments table.
|
||||||
fn sync_payments_with_chain_data(&self, with_scan: bool) -> Result<()> {
|
async fn sync_payments_with_chain_data(&self, with_scan: bool) -> Result<()> {
|
||||||
if with_scan {
|
if with_scan {
|
||||||
let mut electrum_client = ElectrumClient::new(&self.electrum_url)?;
|
let mut electrum_client = ElectrumClient::new(&self.electrum_url)?;
|
||||||
let mut lwk_wollet = self.lwk_wollet.lock().unwrap();
|
let mut lwk_wollet = self.lwk_wollet.lock().await;
|
||||||
lwk_wollet::full_scan_with_electrum_client(&mut lwk_wollet, &mut electrum_client)?;
|
lwk_wollet::full_scan_with_electrum_client(&mut lwk_wollet, &mut electrum_client)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let con = self.persister.get_connection()?;
|
let pending_receive_swaps_by_claim_tx_id =
|
||||||
let pending_receive_swaps_by_claim_tx_id: HashMap<String, ReceiveSwap> = self
|
self.persister.list_pending_receive_swaps_by_claim_tx_id()?;
|
||||||
.persister
|
let pending_send_swaps_by_refund_tx_id =
|
||||||
.list_pending_receive_swaps_by_claim_tx_id(&con)?;
|
self.persister.list_pending_send_swaps_by_refund_tx_id()?;
|
||||||
let pending_send_swaps_by_refund_tx_id: HashMap<String, SendSwap> = self
|
|
||||||
.persister
|
|
||||||
.list_pending_send_swaps_by_refund_tx_id(&con)?;
|
|
||||||
|
|
||||||
for tx in self.lwk_wollet.lock().unwrap().transactions()? {
|
for tx in self.lwk_wollet.lock().await.transactions()? {
|
||||||
let tx_id = tx.txid.to_string();
|
let tx_id = tx.txid.to_string();
|
||||||
let is_tx_confirmed = tx.height.is_some();
|
let is_tx_confirmed = tx.height.is_some();
|
||||||
let amount_sat = tx.balance.values().sum::<i64>();
|
let amount_sat = tx.balance.values().sum::<i64>();
|
||||||
@@ -977,10 +1120,12 @@ impl LiquidSdk {
|
|||||||
// Transition the swaps whose state depends on this tx being confirmed
|
// Transition the swaps whose state depends on this tx being confirmed
|
||||||
if is_tx_confirmed {
|
if is_tx_confirmed {
|
||||||
if let Some(swap) = pending_receive_swaps_by_claim_tx_id.get(&tx_id) {
|
if let Some(swap) = pending_receive_swaps_by_claim_tx_id.get(&tx_id) {
|
||||||
self.try_handle_receive_swap_update(&swap.id, Complete, None)?;
|
self.try_handle_receive_swap_update(&swap.id, Complete, None)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
if let Some(swap) = pending_send_swaps_by_refund_tx_id.get(&tx_id) {
|
if let Some(swap) = pending_send_swaps_by_refund_tx_id.get(&tx_id) {
|
||||||
self.try_handle_send_swap_update(&swap.id, Failed, None, None, None)?;
|
self.try_handle_send_swap_update(&swap.id, Failed, None, None, None)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1096,12 +1241,13 @@ impl LiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Synchronize the DB with mempool and onchain data
|
/// Synchronize the DB with mempool and onchain data
|
||||||
pub fn sync(&self) -> Result<()> {
|
pub async fn sync(&self) -> Result<()> {
|
||||||
let t0 = Instant::now();
|
let t0 = Instant::now();
|
||||||
self.sync_payments_with_chain_data(true)?;
|
self.sync_payments_with_chain_data(true).await?;
|
||||||
let duration_ms = Instant::now().duration_since(t0).as_millis();
|
let duration_ms = Instant::now().duration_since(t0).as_millis();
|
||||||
info!("Synchronized with mempool and onchain data (t = {duration_ms} ms)");
|
info!("Synchronized with mempool and onchain data (t = {duration_ms} ms)");
|
||||||
|
|
||||||
|
self.notify_event_listeners(LiquidSdkEvent::Synced).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1155,30 +1301,33 @@ mod tests {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn normal_submarine_swap() -> Result<()> {
|
async fn normal_submarine_swap() -> Result<()> {
|
||||||
let (_data_dir, data_dir_str) = create_temp_dir()?;
|
let (_data_dir, data_dir_str) = create_temp_dir()?;
|
||||||
let sdk = LiquidSdk::connect(ConnectRequest {
|
let sdk = LiquidSdk::connect(ConnectRequest {
|
||||||
mnemonic: TEST_MNEMONIC.to_string(),
|
mnemonic: TEST_MNEMONIC.to_string(),
|
||||||
data_dir: Some(data_dir_str),
|
data_dir: Some(data_dir_str),
|
||||||
network: Network::LiquidTestnet,
|
network: Network::LiquidTestnet,
|
||||||
})?;
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
let invoice = "lntb10u1pnqwkjrpp5j8ucv9mgww0ajk95yfpvuq0gg5825s207clrzl5thvtuzfn68h0sdqqcqzzsxqr23srzjqv8clnrfs9keq3zlg589jvzpw87cqh6rjks0f9g2t9tvuvcqgcl45f6pqqqqqfcqqyqqqqlgqqqqqqgq2qsp5jnuprlxrargr6hgnnahl28nvutj3gkmxmmssu8ztfhmmey3gq2ss9qyyssq9ejvcp6frwklf73xvskzdcuhnnw8dmxag6v44pffwqrxznsly4nqedem3p3zhn6u4ln7k79vk6zv55jjljhnac4gnvr677fyhfgn07qp4x6wrq".to_string();
|
let invoice = "lntb10u1pnqwkjrpp5j8ucv9mgww0ajk95yfpvuq0gg5825s207clrzl5thvtuzfn68h0sdqqcqzzsxqr23srzjqv8clnrfs9keq3zlg589jvzpw87cqh6rjks0f9g2t9tvuvcqgcl45f6pqqqqqfcqqyqqqqlgqqqqqqgq2qsp5jnuprlxrargr6hgnnahl28nvutj3gkmxmmssu8ztfhmmey3gq2ss9qyyssq9ejvcp6frwklf73xvskzdcuhnnw8dmxag6v44pffwqrxznsly4nqedem3p3zhn6u4ln7k79vk6zv55jjljhnac4gnvr677fyhfgn07qp4x6wrq".to_string();
|
||||||
sdk.prepare_send_payment(&PrepareSendRequest { invoice })?;
|
sdk.prepare_send_payment(&PrepareSendRequest { invoice })
|
||||||
|
.await?;
|
||||||
assert!(!list_pending(&sdk)?.is_empty());
|
assert!(!list_pending(&sdk)?.is_empty());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn reverse_submarine_swap() -> Result<()> {
|
async fn reverse_submarine_swap() -> Result<()> {
|
||||||
let (_data_dir, data_dir_str) = create_temp_dir()?;
|
let (_data_dir, data_dir_str) = create_temp_dir()?;
|
||||||
let sdk = LiquidSdk::connect(ConnectRequest {
|
let sdk = LiquidSdk::connect(ConnectRequest {
|
||||||
mnemonic: TEST_MNEMONIC.to_string(),
|
mnemonic: TEST_MNEMONIC.to_string(),
|
||||||
data_dir: Some(data_dir_str),
|
data_dir: Some(data_dir_str),
|
||||||
network: Network::LiquidTestnet,
|
network: Network::LiquidTestnet,
|
||||||
})?;
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
let prepare_response = sdk.prepare_receive_payment(&PrepareReceiveRequest {
|
let prepare_response = sdk.prepare_receive_payment(&PrepareReceiveRequest {
|
||||||
payer_amount_sat: 1_000,
|
payer_amount_sat: 1_000,
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import 'frb_generated.dart';
|
|||||||
import 'model.dart';
|
import 'model.dart';
|
||||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// The type `BindingEventListener` is not used by any `pub` functions, thus it is ignored.
|
||||||
|
|
||||||
Future<BindingLiquidSdk> connect({required ConnectRequest req, dynamic hint}) =>
|
Future<BindingLiquidSdk> connect({required ConnectRequest req, dynamic hint}) =>
|
||||||
RustLib.instance.api.crateBindingsConnect(req: req, hint: hint);
|
RustLib.instance.api.crateBindingsConnect(req: req, hint: hint);
|
||||||
|
|
||||||
@@ -25,6 +27,9 @@ class BindingLiquidSdk extends RustOpaque {
|
|||||||
rustArcDecrementStrongCountPtr: RustLib.instance.api.rust_arc_decrement_strong_count_BindingLiquidSdkPtr,
|
rustArcDecrementStrongCountPtr: RustLib.instance.api.rust_arc_decrement_strong_count_BindingLiquidSdkPtr,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Stream<LiquidSdkEvent> addEventListener({dynamic hint}) =>
|
||||||
|
RustLib.instance.api.crateBindingsBindingLiquidSdkAddEventListener(that: this, hint: hint);
|
||||||
|
|
||||||
Future<void> backup({dynamic hint}) =>
|
Future<void> backup({dynamic hint}) =>
|
||||||
RustLib.instance.api.crateBindingsBindingLiquidSdkBackup(that: this, hint: hint);
|
RustLib.instance.api.crateBindingsBindingLiquidSdkBackup(that: this, hint: hint);
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||||||
String get codegenVersion => '2.0.0-dev.35';
|
String get codegenVersion => '2.0.0-dev.35';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get rustContentHash => 1284301568;
|
int get rustContentHash => 692273053;
|
||||||
|
|
||||||
static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig(
|
static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig(
|
||||||
stem: 'breez_liquid_sdk',
|
stem: 'breez_liquid_sdk',
|
||||||
@@ -63,6 +63,9 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class RustLibApi extends BaseApi {
|
abstract class RustLibApi extends BaseApi {
|
||||||
|
Stream<LiquidSdkEvent> crateBindingsBindingLiquidSdkAddEventListener(
|
||||||
|
{required BindingLiquidSdk that, dynamic hint});
|
||||||
|
|
||||||
Future<void> crateBindingsBindingLiquidSdkBackup({required BindingLiquidSdk that, dynamic hint});
|
Future<void> crateBindingsBindingLiquidSdkBackup({required BindingLiquidSdk that, dynamic hint});
|
||||||
|
|
||||||
Future<void> crateBindingsBindingLiquidSdkEmptyWalletCache({required BindingLiquidSdk that, dynamic hint});
|
Future<void> crateBindingsBindingLiquidSdkEmptyWalletCache({required BindingLiquidSdk that, dynamic hint});
|
||||||
@@ -107,6 +110,35 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
required super.portManager,
|
required super.portManager,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<LiquidSdkEvent> crateBindingsBindingLiquidSdkAddEventListener(
|
||||||
|
{required BindingLiquidSdk that, dynamic hint}) {
|
||||||
|
final listener = RustStreamSink<LiquidSdkEvent>();
|
||||||
|
unawaited(handler.executeNormal(NormalTask(
|
||||||
|
callFfi: (port_) {
|
||||||
|
var arg0 =
|
||||||
|
cst_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
|
that);
|
||||||
|
var arg1 = cst_encode_StreamSink_liquid_sdk_event_Dco(listener);
|
||||||
|
return wire.wire__crate__bindings__BindingLiquidSdk_add_event_listener(port_, arg0, arg1);
|
||||||
|
},
|
||||||
|
codec: DcoCodec(
|
||||||
|
decodeSuccessData: dco_decode_String,
|
||||||
|
decodeErrorData: dco_decode_liquid_sdk_error,
|
||||||
|
),
|
||||||
|
constMeta: kCrateBindingsBindingLiquidSdkAddEventListenerConstMeta,
|
||||||
|
argValues: [that, listener],
|
||||||
|
apiImpl: this,
|
||||||
|
hint: hint,
|
||||||
|
)));
|
||||||
|
return listener.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskConstMeta get kCrateBindingsBindingLiquidSdkAddEventListenerConstMeta => const TaskConstMeta(
|
||||||
|
debugName: "BindingLiquidSdk_add_event_listener",
|
||||||
|
argNames: ["that", "listener"],
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> crateBindingsBindingLiquidSdkBackup({required BindingLiquidSdk that, dynamic hint}) {
|
Future<void> crateBindingsBindingLiquidSdkBackup({required BindingLiquidSdk that, dynamic hint}) {
|
||||||
return handler.executeNormal(NormalTask(
|
return handler.executeNormal(NormalTask(
|
||||||
@@ -423,6 +455,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return BindingLiquidSdk.dcoDecode(raw as List<dynamic>);
|
return BindingLiquidSdk.dcoDecode(raw as List<dynamic>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LiquidSdkEvent> dco_decode_StreamSink_liquid_sdk_event_Dco(dynamic raw) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
String dco_decode_String(dynamic raw) {
|
String dco_decode_String(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@@ -447,6 +485,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return dco_decode_get_info_request(raw);
|
return dco_decode_get_info_request(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Payment dco_decode_box_autoadd_payment(dynamic raw) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
return dco_decode_payment(raw);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PrepareReceiveRequest dco_decode_box_autoadd_prepare_receive_request(dynamic raw) {
|
PrepareReceiveRequest dco_decode_box_autoadd_prepare_receive_request(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@@ -537,6 +581,41 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LiquidSdkEvent dco_decode_liquid_sdk_event(dynamic raw) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
switch (raw[0]) {
|
||||||
|
case 0:
|
||||||
|
return LiquidSdkEvent_PaymentFailed(
|
||||||
|
details: dco_decode_box_autoadd_payment(raw[1]),
|
||||||
|
);
|
||||||
|
case 1:
|
||||||
|
return LiquidSdkEvent_PaymentPending(
|
||||||
|
details: dco_decode_box_autoadd_payment(raw[1]),
|
||||||
|
);
|
||||||
|
case 2:
|
||||||
|
return LiquidSdkEvent_PaymentRefunded(
|
||||||
|
details: dco_decode_box_autoadd_payment(raw[1]),
|
||||||
|
);
|
||||||
|
case 3:
|
||||||
|
return LiquidSdkEvent_PaymentRefundPending(
|
||||||
|
details: dco_decode_box_autoadd_payment(raw[1]),
|
||||||
|
);
|
||||||
|
case 4:
|
||||||
|
return LiquidSdkEvent_PaymentSucceed(
|
||||||
|
details: dco_decode_box_autoadd_payment(raw[1]),
|
||||||
|
);
|
||||||
|
case 5:
|
||||||
|
return LiquidSdkEvent_PaymentWaitingConfirmation(
|
||||||
|
details: dco_decode_box_autoadd_payment(raw[1]),
|
||||||
|
);
|
||||||
|
case 6:
|
||||||
|
return LiquidSdkEvent_Synced();
|
||||||
|
default:
|
||||||
|
throw Exception("unreachable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<Payment> dco_decode_list_payment(dynamic raw) {
|
List<Payment> dco_decode_list_payment(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@@ -768,6 +847,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return BindingLiquidSdk.sseDecode(sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
|
return BindingLiquidSdk.sseDecode(sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LiquidSdkEvent> sse_decode_StreamSink_liquid_sdk_event_Dco(SseDeserializer deserializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
throw UnimplementedError('Unreachable ()');
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
String sse_decode_String(SseDeserializer deserializer) {
|
String sse_decode_String(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -793,6 +878,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return (sse_decode_get_info_request(deserializer));
|
return (sse_decode_get_info_request(deserializer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Payment sse_decode_box_autoadd_payment(SseDeserializer deserializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
return (sse_decode_payment(deserializer));
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PrepareReceiveRequest sse_decode_box_autoadd_prepare_receive_request(SseDeserializer deserializer) {
|
PrepareReceiveRequest sse_decode_box_autoadd_prepare_receive_request(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -879,6 +970,37 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LiquidSdkEvent sse_decode_liquid_sdk_event(SseDeserializer deserializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|
||||||
|
var tag_ = sse_decode_i_32(deserializer);
|
||||||
|
switch (tag_) {
|
||||||
|
case 0:
|
||||||
|
var var_details = sse_decode_box_autoadd_payment(deserializer);
|
||||||
|
return LiquidSdkEvent_PaymentFailed(details: var_details);
|
||||||
|
case 1:
|
||||||
|
var var_details = sse_decode_box_autoadd_payment(deserializer);
|
||||||
|
return LiquidSdkEvent_PaymentPending(details: var_details);
|
||||||
|
case 2:
|
||||||
|
var var_details = sse_decode_box_autoadd_payment(deserializer);
|
||||||
|
return LiquidSdkEvent_PaymentRefunded(details: var_details);
|
||||||
|
case 3:
|
||||||
|
var var_details = sse_decode_box_autoadd_payment(deserializer);
|
||||||
|
return LiquidSdkEvent_PaymentRefundPending(details: var_details);
|
||||||
|
case 4:
|
||||||
|
var var_details = sse_decode_box_autoadd_payment(deserializer);
|
||||||
|
return LiquidSdkEvent_PaymentSucceed(details: var_details);
|
||||||
|
case 5:
|
||||||
|
var var_details = sse_decode_box_autoadd_payment(deserializer);
|
||||||
|
return LiquidSdkEvent_PaymentWaitingConfirmation(details: var_details);
|
||||||
|
case 6:
|
||||||
|
return LiquidSdkEvent_Synced();
|
||||||
|
default:
|
||||||
|
throw UnimplementedError('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<Payment> sse_decode_list_payment(SseDeserializer deserializer) {
|
List<Payment> sse_decode_list_payment(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -1186,6 +1308,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_usize(self.sseEncode(move: null), serializer);
|
sse_encode_usize(self.sseEncode(move: null), serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_StreamSink_liquid_sdk_event_Dco(
|
||||||
|
RustStreamSink<LiquidSdkEvent> self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
sse_encode_String(
|
||||||
|
self.setupAndSerialize(
|
||||||
|
codec: DcoCodec(decodeSuccessData: dco_decode_liquid_sdk_event, decodeErrorData: null)),
|
||||||
|
serializer);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_String(String self, SseSerializer serializer) {
|
void sse_encode_String(String self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -1210,6 +1342,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_get_info_request(self, serializer);
|
sse_encode_get_info_request(self, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_box_autoadd_payment(Payment self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
sse_encode_payment(self, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_box_autoadd_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer) {
|
void sse_encode_box_autoadd_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -1286,6 +1424,33 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_liquid_sdk_event(LiquidSdkEvent self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
switch (self) {
|
||||||
|
case LiquidSdkEvent_PaymentFailed(details: final details):
|
||||||
|
sse_encode_i_32(0, serializer);
|
||||||
|
sse_encode_box_autoadd_payment(details, serializer);
|
||||||
|
case LiquidSdkEvent_PaymentPending(details: final details):
|
||||||
|
sse_encode_i_32(1, serializer);
|
||||||
|
sse_encode_box_autoadd_payment(details, serializer);
|
||||||
|
case LiquidSdkEvent_PaymentRefunded(details: final details):
|
||||||
|
sse_encode_i_32(2, serializer);
|
||||||
|
sse_encode_box_autoadd_payment(details, serializer);
|
||||||
|
case LiquidSdkEvent_PaymentRefundPending(details: final details):
|
||||||
|
sse_encode_i_32(3, serializer);
|
||||||
|
sse_encode_box_autoadd_payment(details, serializer);
|
||||||
|
case LiquidSdkEvent_PaymentSucceed(details: final details):
|
||||||
|
sse_encode_i_32(4, serializer);
|
||||||
|
sse_encode_box_autoadd_payment(details, serializer);
|
||||||
|
case LiquidSdkEvent_PaymentWaitingConfirmation(details: final details):
|
||||||
|
sse_encode_i_32(5, serializer);
|
||||||
|
sse_encode_box_autoadd_payment(details, serializer);
|
||||||
|
case LiquidSdkEvent_Synced():
|
||||||
|
sse_encode_i_32(6, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_list_payment(List<Payment> self, SseSerializer serializer) {
|
void sse_encode_list_payment(List<Payment> self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
BindingLiquidSdk dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
BindingLiquidSdk dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
dynamic raw);
|
dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LiquidSdkEvent> dco_decode_StreamSink_liquid_sdk_event_Dco(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
String dco_decode_String(dynamic raw);
|
String dco_decode_String(dynamic raw);
|
||||||
|
|
||||||
@@ -49,6 +52,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
GetInfoRequest dco_decode_box_autoadd_get_info_request(dynamic raw);
|
GetInfoRequest dco_decode_box_autoadd_get_info_request(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Payment dco_decode_box_autoadd_payment(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PrepareReceiveRequest dco_decode_box_autoadd_prepare_receive_request(dynamic raw);
|
PrepareReceiveRequest dco_decode_box_autoadd_prepare_receive_request(dynamic raw);
|
||||||
|
|
||||||
@@ -82,6 +88,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
LiquidSdkError dco_decode_liquid_sdk_error(dynamic raw);
|
LiquidSdkError dco_decode_liquid_sdk_error(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LiquidSdkEvent dco_decode_liquid_sdk_event(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<Payment> dco_decode_list_payment(dynamic raw);
|
List<Payment> dco_decode_list_payment(dynamic raw);
|
||||||
|
|
||||||
@@ -159,6 +168,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
BindingLiquidSdk sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
BindingLiquidSdk sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
SseDeserializer deserializer);
|
SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LiquidSdkEvent> sse_decode_StreamSink_liquid_sdk_event_Dco(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
String sse_decode_String(SseDeserializer deserializer);
|
String sse_decode_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -171,6 +183,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
GetInfoRequest sse_decode_box_autoadd_get_info_request(SseDeserializer deserializer);
|
GetInfoRequest sse_decode_box_autoadd_get_info_request(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Payment sse_decode_box_autoadd_payment(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PrepareReceiveRequest sse_decode_box_autoadd_prepare_receive_request(SseDeserializer deserializer);
|
PrepareReceiveRequest sse_decode_box_autoadd_prepare_receive_request(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -204,6 +219,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
LiquidSdkError sse_decode_liquid_sdk_error(SseDeserializer deserializer);
|
LiquidSdkError sse_decode_liquid_sdk_error(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LiquidSdkEvent sse_decode_liquid_sdk_event(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<Payment> sse_decode_list_payment(SseDeserializer deserializer);
|
List<Payment> sse_decode_list_payment(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -267,6 +285,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
int sse_decode_usize(SseDeserializer deserializer);
|
int sse_decode_usize(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_StreamSink_liquid_sdk_event_Dco(
|
||||||
|
RustStreamSink<LiquidSdkEvent> raw) {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
return cst_encode_String(raw.setupAndSerialize(
|
||||||
|
codec: DcoCodec(decodeSuccessData: dco_decode_liquid_sdk_event, decodeErrorData: null)));
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_String(String raw) {
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_String(String raw) {
|
||||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
@@ -289,6 +315,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ffi.Pointer<wire_cst_payment> cst_encode_box_autoadd_payment(Payment raw) {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
final ptr = wire.cst_new_box_autoadd_payment();
|
||||||
|
cst_api_fill_to_wire_payment(raw, ptr.ref);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
ffi.Pointer<wire_cst_prepare_receive_request> cst_encode_box_autoadd_prepare_receive_request(
|
ffi.Pointer<wire_cst_prepare_receive_request> cst_encode_box_autoadd_prepare_receive_request(
|
||||||
PrepareReceiveRequest raw) {
|
PrepareReceiveRequest raw) {
|
||||||
@@ -387,6 +421,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
cst_api_fill_to_wire_get_info_request(apiObj, wireObj.ref);
|
cst_api_fill_to_wire_get_info_request(apiObj, wireObj.ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void cst_api_fill_to_wire_box_autoadd_payment(Payment apiObj, ffi.Pointer<wire_cst_payment> wireObj) {
|
||||||
|
cst_api_fill_to_wire_payment(apiObj, wireObj.ref);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void cst_api_fill_to_wire_box_autoadd_prepare_receive_request(
|
void cst_api_fill_to_wire_box_autoadd_prepare_receive_request(
|
||||||
PrepareReceiveRequest apiObj, ffi.Pointer<wire_cst_prepare_receive_request> wireObj) {
|
PrepareReceiveRequest apiObj, ffi.Pointer<wire_cst_prepare_receive_request> wireObj) {
|
||||||
@@ -447,6 +486,50 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void cst_api_fill_to_wire_liquid_sdk_event(LiquidSdkEvent apiObj, wire_cst_liquid_sdk_event wireObj) {
|
||||||
|
if (apiObj is LiquidSdkEvent_PaymentFailed) {
|
||||||
|
var pre_details = cst_encode_box_autoadd_payment(apiObj.details);
|
||||||
|
wireObj.tag = 0;
|
||||||
|
wireObj.kind.PaymentFailed.details = pre_details;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (apiObj is LiquidSdkEvent_PaymentPending) {
|
||||||
|
var pre_details = cst_encode_box_autoadd_payment(apiObj.details);
|
||||||
|
wireObj.tag = 1;
|
||||||
|
wireObj.kind.PaymentPending.details = pre_details;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (apiObj is LiquidSdkEvent_PaymentRefunded) {
|
||||||
|
var pre_details = cst_encode_box_autoadd_payment(apiObj.details);
|
||||||
|
wireObj.tag = 2;
|
||||||
|
wireObj.kind.PaymentRefunded.details = pre_details;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (apiObj is LiquidSdkEvent_PaymentRefundPending) {
|
||||||
|
var pre_details = cst_encode_box_autoadd_payment(apiObj.details);
|
||||||
|
wireObj.tag = 3;
|
||||||
|
wireObj.kind.PaymentRefundPending.details = pre_details;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (apiObj is LiquidSdkEvent_PaymentSucceed) {
|
||||||
|
var pre_details = cst_encode_box_autoadd_payment(apiObj.details);
|
||||||
|
wireObj.tag = 4;
|
||||||
|
wireObj.kind.PaymentSucceed.details = pre_details;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (apiObj is LiquidSdkEvent_PaymentWaitingConfirmation) {
|
||||||
|
var pre_details = cst_encode_box_autoadd_payment(apiObj.details);
|
||||||
|
wireObj.tag = 5;
|
||||||
|
wireObj.kind.PaymentWaitingConfirmation.details = pre_details;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (apiObj is LiquidSdkEvent_Synced) {
|
||||||
|
wireObj.tag = 6;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void cst_api_fill_to_wire_payment(Payment apiObj, wire_cst_payment wireObj) {
|
void cst_api_fill_to_wire_payment(Payment apiObj, wire_cst_payment wireObj) {
|
||||||
wireObj.tx_id = cst_encode_String(apiObj.txId);
|
wireObj.tx_id = cst_encode_String(apiObj.txId);
|
||||||
@@ -622,6 +705,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
BindingLiquidSdk self, SseSerializer serializer);
|
BindingLiquidSdk self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_StreamSink_liquid_sdk_event_Dco(
|
||||||
|
RustStreamSink<LiquidSdkEvent> self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_String(String self, SseSerializer serializer);
|
void sse_encode_String(String self, SseSerializer serializer);
|
||||||
|
|
||||||
@@ -634,6 +721,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_box_autoadd_get_info_request(GetInfoRequest self, SseSerializer serializer);
|
void sse_encode_box_autoadd_get_info_request(GetInfoRequest self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_box_autoadd_payment(Payment self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_box_autoadd_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer);
|
void sse_encode_box_autoadd_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer);
|
||||||
|
|
||||||
@@ -667,6 +757,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_liquid_sdk_error(LiquidSdkError self, SseSerializer serializer);
|
void sse_encode_liquid_sdk_error(LiquidSdkError self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_liquid_sdk_event(LiquidSdkEvent self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_list_payment(List<Payment> self, SseSerializer serializer);
|
void sse_encode_list_payment(List<Payment> self, SseSerializer serializer);
|
||||||
|
|
||||||
@@ -766,6 +859,26 @@ class RustLibWire implements BaseWire {
|
|||||||
late final _store_dart_post_cobject =
|
late final _store_dart_post_cobject =
|
||||||
_store_dart_post_cobjectPtr.asFunction<void Function(DartPostCObjectFnType)>();
|
_store_dart_post_cobjectPtr.asFunction<void Function(DartPostCObjectFnType)>();
|
||||||
|
|
||||||
|
void wire__crate__bindings__BindingLiquidSdk_add_event_listener(
|
||||||
|
int port_,
|
||||||
|
int that,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> listener,
|
||||||
|
) {
|
||||||
|
return _wire__crate__bindings__BindingLiquidSdk_add_event_listener(
|
||||||
|
port_,
|
||||||
|
that,
|
||||||
|
listener,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _wire__crate__bindings__BindingLiquidSdk_add_event_listenerPtr = _lookup<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||||
|
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener');
|
||||||
|
late final _wire__crate__bindings__BindingLiquidSdk_add_event_listener =
|
||||||
|
_wire__crate__bindings__BindingLiquidSdk_add_event_listenerPtr
|
||||||
|
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||||
|
|
||||||
void wire__crate__bindings__BindingLiquidSdk_backup(
|
void wire__crate__bindings__BindingLiquidSdk_backup(
|
||||||
int port_,
|
int port_,
|
||||||
int that,
|
int that,
|
||||||
@@ -1018,6 +1131,16 @@ class RustLibWire implements BaseWire {
|
|||||||
late final _cst_new_box_autoadd_get_info_request = _cst_new_box_autoadd_get_info_requestPtr
|
late final _cst_new_box_autoadd_get_info_request = _cst_new_box_autoadd_get_info_requestPtr
|
||||||
.asFunction<ffi.Pointer<wire_cst_get_info_request> Function()>();
|
.asFunction<ffi.Pointer<wire_cst_get_info_request> Function()>();
|
||||||
|
|
||||||
|
ffi.Pointer<wire_cst_payment> cst_new_box_autoadd_payment() {
|
||||||
|
return _cst_new_box_autoadd_payment();
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _cst_new_box_autoadd_paymentPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_payment> Function()>>(
|
||||||
|
'frbgen_breez_liquid_cst_new_box_autoadd_payment');
|
||||||
|
late final _cst_new_box_autoadd_payment =
|
||||||
|
_cst_new_box_autoadd_paymentPtr.asFunction<ffi.Pointer<wire_cst_payment> Function()>();
|
||||||
|
|
||||||
ffi.Pointer<wire_cst_prepare_receive_request> cst_new_box_autoadd_prepare_receive_request() {
|
ffi.Pointer<wire_cst_prepare_receive_request> cst_new_box_autoadd_prepare_receive_request() {
|
||||||
return _cst_new_box_autoadd_prepare_receive_request();
|
return _cst_new_box_autoadd_prepare_receive_request();
|
||||||
}
|
}
|
||||||
@@ -1127,6 +1250,13 @@ typedef DartDartPostCObjectFnTypeFunction = bool Function(
|
|||||||
typedef DartPort = ffi.Int64;
|
typedef DartPort = ffi.Int64;
|
||||||
typedef DartDartPort = int;
|
typedef DartDartPort = int;
|
||||||
|
|
||||||
|
final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
|
||||||
|
external ffi.Pointer<ffi.Uint8> ptr;
|
||||||
|
|
||||||
|
@ffi.Int32()
|
||||||
|
external int len;
|
||||||
|
}
|
||||||
|
|
||||||
final class wire_cst_get_info_request extends ffi.Struct {
|
final class wire_cst_get_info_request extends ffi.Struct {
|
||||||
@ffi.Bool()
|
@ffi.Bool()
|
||||||
external bool with_scan;
|
external bool with_scan;
|
||||||
@@ -1137,13 +1267,6 @@ final class wire_cst_prepare_receive_request extends ffi.Struct {
|
|||||||
external int payer_amount_sat;
|
external int payer_amount_sat;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
|
|
||||||
external ffi.Pointer<ffi.Uint8> ptr;
|
|
||||||
|
|
||||||
@ffi.Int32()
|
|
||||||
external int len;
|
|
||||||
}
|
|
||||||
|
|
||||||
final class wire_cst_prepare_send_request extends ffi.Struct {
|
final class wire_cst_prepare_send_request extends ffi.Struct {
|
||||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
|
||||||
}
|
}
|
||||||
@@ -1233,6 +1356,51 @@ final class wire_cst_liquid_sdk_error extends ffi.Struct {
|
|||||||
external LiquidSdkErrorKind kind;
|
external LiquidSdkErrorKind kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentFailed extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentPending extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentRefunded extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentRefundPending extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentSucceed extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class LiquidSdkEventKind extends ffi.Union {
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentFailed PaymentFailed;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentPending PaymentPending;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentRefunded PaymentRefunded;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentRefundPending PaymentRefundPending;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentSucceed PaymentSucceed;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation PaymentWaitingConfirmation;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_liquid_sdk_event extends ffi.Struct {
|
||||||
|
@ffi.Int32()
|
||||||
|
external int tag;
|
||||||
|
|
||||||
|
external LiquidSdkEventKind kind;
|
||||||
|
}
|
||||||
|
|
||||||
final class wire_cst_PaymentError_Generic extends ffi.Struct {
|
final class wire_cst_PaymentError_Generic extends ffi.Struct {
|
||||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
import 'frb_generated.dart';
|
import 'frb_generated.dart';
|
||||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart' hide protected;
|
||||||
|
part 'model.freezed.dart';
|
||||||
|
|
||||||
class ConnectRequest {
|
class ConnectRequest {
|
||||||
final String mnemonic;
|
final String mnemonic;
|
||||||
@@ -79,6 +81,31 @@ class GetInfoResponse {
|
|||||||
pubkey == other.pubkey;
|
pubkey == other.pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class LiquidSdkEvent with _$LiquidSdkEvent {
|
||||||
|
const LiquidSdkEvent._();
|
||||||
|
|
||||||
|
const factory LiquidSdkEvent.paymentFailed({
|
||||||
|
required Payment details,
|
||||||
|
}) = LiquidSdkEvent_PaymentFailed;
|
||||||
|
const factory LiquidSdkEvent.paymentPending({
|
||||||
|
required Payment details,
|
||||||
|
}) = LiquidSdkEvent_PaymentPending;
|
||||||
|
const factory LiquidSdkEvent.paymentRefunded({
|
||||||
|
required Payment details,
|
||||||
|
}) = LiquidSdkEvent_PaymentRefunded;
|
||||||
|
const factory LiquidSdkEvent.paymentRefundPending({
|
||||||
|
required Payment details,
|
||||||
|
}) = LiquidSdkEvent_PaymentRefundPending;
|
||||||
|
const factory LiquidSdkEvent.paymentSucceed({
|
||||||
|
required Payment details,
|
||||||
|
}) = LiquidSdkEvent_PaymentSucceed;
|
||||||
|
const factory LiquidSdkEvent.paymentWaitingConfirmation({
|
||||||
|
required Payment details,
|
||||||
|
}) = LiquidSdkEvent_PaymentWaitingConfirmation;
|
||||||
|
const factory LiquidSdkEvent.synced() = LiquidSdkEvent_Synced;
|
||||||
|
}
|
||||||
|
|
||||||
enum Network {
|
enum Network {
|
||||||
liquid,
|
liquid,
|
||||||
liquidTestnet,
|
liquidTestnet,
|
||||||
|
|||||||
522
packages/dart/lib/src/model.freezed.dart
Normal file
522
packages/dart/lib/src/model.freezed.dart
Normal file
@@ -0,0 +1,522 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'model.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$LiquidSdkEvent {}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $LiquidSdkEventCopyWith<$Res> {
|
||||||
|
factory $LiquidSdkEventCopyWith(LiquidSdkEvent value, $Res Function(LiquidSdkEvent) then) =
|
||||||
|
_$LiquidSdkEventCopyWithImpl<$Res, LiquidSdkEvent>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$LiquidSdkEventCopyWithImpl<$Res, $Val extends LiquidSdkEvent>
|
||||||
|
implements $LiquidSdkEventCopyWith<$Res> {
|
||||||
|
_$LiquidSdkEventCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LiquidSdkEvent_PaymentFailedImplCopyWith<$Res> {
|
||||||
|
factory _$$LiquidSdkEvent_PaymentFailedImplCopyWith(
|
||||||
|
_$LiquidSdkEvent_PaymentFailedImpl value, $Res Function(_$LiquidSdkEvent_PaymentFailedImpl) then) =
|
||||||
|
__$$LiquidSdkEvent_PaymentFailedImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Payment details});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LiquidSdkEvent_PaymentFailedImplCopyWithImpl<$Res>
|
||||||
|
extends _$LiquidSdkEventCopyWithImpl<$Res, _$LiquidSdkEvent_PaymentFailedImpl>
|
||||||
|
implements _$$LiquidSdkEvent_PaymentFailedImplCopyWith<$Res> {
|
||||||
|
__$$LiquidSdkEvent_PaymentFailedImplCopyWithImpl(
|
||||||
|
_$LiquidSdkEvent_PaymentFailedImpl _value, $Res Function(_$LiquidSdkEvent_PaymentFailedImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? details = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LiquidSdkEvent_PaymentFailedImpl(
|
||||||
|
details: null == details
|
||||||
|
? _value.details
|
||||||
|
: details // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Payment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LiquidSdkEvent_PaymentFailedImpl extends LiquidSdkEvent_PaymentFailed {
|
||||||
|
const _$LiquidSdkEvent_PaymentFailedImpl({required this.details}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
final Payment details;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LiquidSdkEvent.paymentFailed(details: $details)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LiquidSdkEvent_PaymentFailedImpl &&
|
||||||
|
(identical(other.details, details) || other.details == details));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, details);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LiquidSdkEvent_PaymentFailedImplCopyWith<_$LiquidSdkEvent_PaymentFailedImpl> get copyWith =>
|
||||||
|
__$$LiquidSdkEvent_PaymentFailedImplCopyWithImpl<_$LiquidSdkEvent_PaymentFailedImpl>(this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LiquidSdkEvent_PaymentFailed extends LiquidSdkEvent {
|
||||||
|
const factory LiquidSdkEvent_PaymentFailed({required final Payment details}) =
|
||||||
|
_$LiquidSdkEvent_PaymentFailedImpl;
|
||||||
|
const LiquidSdkEvent_PaymentFailed._() : super._();
|
||||||
|
|
||||||
|
Payment get details;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$LiquidSdkEvent_PaymentFailedImplCopyWith<_$LiquidSdkEvent_PaymentFailedImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LiquidSdkEvent_PaymentPendingImplCopyWith<$Res> {
|
||||||
|
factory _$$LiquidSdkEvent_PaymentPendingImplCopyWith(_$LiquidSdkEvent_PaymentPendingImpl value,
|
||||||
|
$Res Function(_$LiquidSdkEvent_PaymentPendingImpl) then) =
|
||||||
|
__$$LiquidSdkEvent_PaymentPendingImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Payment details});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LiquidSdkEvent_PaymentPendingImplCopyWithImpl<$Res>
|
||||||
|
extends _$LiquidSdkEventCopyWithImpl<$Res, _$LiquidSdkEvent_PaymentPendingImpl>
|
||||||
|
implements _$$LiquidSdkEvent_PaymentPendingImplCopyWith<$Res> {
|
||||||
|
__$$LiquidSdkEvent_PaymentPendingImplCopyWithImpl(
|
||||||
|
_$LiquidSdkEvent_PaymentPendingImpl _value, $Res Function(_$LiquidSdkEvent_PaymentPendingImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? details = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LiquidSdkEvent_PaymentPendingImpl(
|
||||||
|
details: null == details
|
||||||
|
? _value.details
|
||||||
|
: details // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Payment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LiquidSdkEvent_PaymentPendingImpl extends LiquidSdkEvent_PaymentPending {
|
||||||
|
const _$LiquidSdkEvent_PaymentPendingImpl({required this.details}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
final Payment details;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LiquidSdkEvent.paymentPending(details: $details)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LiquidSdkEvent_PaymentPendingImpl &&
|
||||||
|
(identical(other.details, details) || other.details == details));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, details);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LiquidSdkEvent_PaymentPendingImplCopyWith<_$LiquidSdkEvent_PaymentPendingImpl> get copyWith =>
|
||||||
|
__$$LiquidSdkEvent_PaymentPendingImplCopyWithImpl<_$LiquidSdkEvent_PaymentPendingImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LiquidSdkEvent_PaymentPending extends LiquidSdkEvent {
|
||||||
|
const factory LiquidSdkEvent_PaymentPending({required final Payment details}) =
|
||||||
|
_$LiquidSdkEvent_PaymentPendingImpl;
|
||||||
|
const LiquidSdkEvent_PaymentPending._() : super._();
|
||||||
|
|
||||||
|
Payment get details;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$LiquidSdkEvent_PaymentPendingImplCopyWith<_$LiquidSdkEvent_PaymentPendingImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LiquidSdkEvent_PaymentRefundedImplCopyWith<$Res> {
|
||||||
|
factory _$$LiquidSdkEvent_PaymentRefundedImplCopyWith(_$LiquidSdkEvent_PaymentRefundedImpl value,
|
||||||
|
$Res Function(_$LiquidSdkEvent_PaymentRefundedImpl) then) =
|
||||||
|
__$$LiquidSdkEvent_PaymentRefundedImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Payment details});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LiquidSdkEvent_PaymentRefundedImplCopyWithImpl<$Res>
|
||||||
|
extends _$LiquidSdkEventCopyWithImpl<$Res, _$LiquidSdkEvent_PaymentRefundedImpl>
|
||||||
|
implements _$$LiquidSdkEvent_PaymentRefundedImplCopyWith<$Res> {
|
||||||
|
__$$LiquidSdkEvent_PaymentRefundedImplCopyWithImpl(
|
||||||
|
_$LiquidSdkEvent_PaymentRefundedImpl _value, $Res Function(_$LiquidSdkEvent_PaymentRefundedImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? details = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LiquidSdkEvent_PaymentRefundedImpl(
|
||||||
|
details: null == details
|
||||||
|
? _value.details
|
||||||
|
: details // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Payment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LiquidSdkEvent_PaymentRefundedImpl extends LiquidSdkEvent_PaymentRefunded {
|
||||||
|
const _$LiquidSdkEvent_PaymentRefundedImpl({required this.details}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
final Payment details;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LiquidSdkEvent.paymentRefunded(details: $details)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LiquidSdkEvent_PaymentRefundedImpl &&
|
||||||
|
(identical(other.details, details) || other.details == details));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, details);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LiquidSdkEvent_PaymentRefundedImplCopyWith<_$LiquidSdkEvent_PaymentRefundedImpl> get copyWith =>
|
||||||
|
__$$LiquidSdkEvent_PaymentRefundedImplCopyWithImpl<_$LiquidSdkEvent_PaymentRefundedImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LiquidSdkEvent_PaymentRefunded extends LiquidSdkEvent {
|
||||||
|
const factory LiquidSdkEvent_PaymentRefunded({required final Payment details}) =
|
||||||
|
_$LiquidSdkEvent_PaymentRefundedImpl;
|
||||||
|
const LiquidSdkEvent_PaymentRefunded._() : super._();
|
||||||
|
|
||||||
|
Payment get details;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$LiquidSdkEvent_PaymentRefundedImplCopyWith<_$LiquidSdkEvent_PaymentRefundedImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LiquidSdkEvent_PaymentRefundPendingImplCopyWith<$Res> {
|
||||||
|
factory _$$LiquidSdkEvent_PaymentRefundPendingImplCopyWith(_$LiquidSdkEvent_PaymentRefundPendingImpl value,
|
||||||
|
$Res Function(_$LiquidSdkEvent_PaymentRefundPendingImpl) then) =
|
||||||
|
__$$LiquidSdkEvent_PaymentRefundPendingImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Payment details});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LiquidSdkEvent_PaymentRefundPendingImplCopyWithImpl<$Res>
|
||||||
|
extends _$LiquidSdkEventCopyWithImpl<$Res, _$LiquidSdkEvent_PaymentRefundPendingImpl>
|
||||||
|
implements _$$LiquidSdkEvent_PaymentRefundPendingImplCopyWith<$Res> {
|
||||||
|
__$$LiquidSdkEvent_PaymentRefundPendingImplCopyWithImpl(_$LiquidSdkEvent_PaymentRefundPendingImpl _value,
|
||||||
|
$Res Function(_$LiquidSdkEvent_PaymentRefundPendingImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? details = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LiquidSdkEvent_PaymentRefundPendingImpl(
|
||||||
|
details: null == details
|
||||||
|
? _value.details
|
||||||
|
: details // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Payment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LiquidSdkEvent_PaymentRefundPendingImpl extends LiquidSdkEvent_PaymentRefundPending {
|
||||||
|
const _$LiquidSdkEvent_PaymentRefundPendingImpl({required this.details}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
final Payment details;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LiquidSdkEvent.paymentRefundPending(details: $details)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LiquidSdkEvent_PaymentRefundPendingImpl &&
|
||||||
|
(identical(other.details, details) || other.details == details));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, details);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LiquidSdkEvent_PaymentRefundPendingImplCopyWith<_$LiquidSdkEvent_PaymentRefundPendingImpl>
|
||||||
|
get copyWith =>
|
||||||
|
__$$LiquidSdkEvent_PaymentRefundPendingImplCopyWithImpl<_$LiquidSdkEvent_PaymentRefundPendingImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LiquidSdkEvent_PaymentRefundPending extends LiquidSdkEvent {
|
||||||
|
const factory LiquidSdkEvent_PaymentRefundPending({required final Payment details}) =
|
||||||
|
_$LiquidSdkEvent_PaymentRefundPendingImpl;
|
||||||
|
const LiquidSdkEvent_PaymentRefundPending._() : super._();
|
||||||
|
|
||||||
|
Payment get details;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$LiquidSdkEvent_PaymentRefundPendingImplCopyWith<_$LiquidSdkEvent_PaymentRefundPendingImpl>
|
||||||
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LiquidSdkEvent_PaymentSucceedImplCopyWith<$Res> {
|
||||||
|
factory _$$LiquidSdkEvent_PaymentSucceedImplCopyWith(_$LiquidSdkEvent_PaymentSucceedImpl value,
|
||||||
|
$Res Function(_$LiquidSdkEvent_PaymentSucceedImpl) then) =
|
||||||
|
__$$LiquidSdkEvent_PaymentSucceedImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Payment details});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LiquidSdkEvent_PaymentSucceedImplCopyWithImpl<$Res>
|
||||||
|
extends _$LiquidSdkEventCopyWithImpl<$Res, _$LiquidSdkEvent_PaymentSucceedImpl>
|
||||||
|
implements _$$LiquidSdkEvent_PaymentSucceedImplCopyWith<$Res> {
|
||||||
|
__$$LiquidSdkEvent_PaymentSucceedImplCopyWithImpl(
|
||||||
|
_$LiquidSdkEvent_PaymentSucceedImpl _value, $Res Function(_$LiquidSdkEvent_PaymentSucceedImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? details = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LiquidSdkEvent_PaymentSucceedImpl(
|
||||||
|
details: null == details
|
||||||
|
? _value.details
|
||||||
|
: details // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Payment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LiquidSdkEvent_PaymentSucceedImpl extends LiquidSdkEvent_PaymentSucceed {
|
||||||
|
const _$LiquidSdkEvent_PaymentSucceedImpl({required this.details}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
final Payment details;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LiquidSdkEvent.paymentSucceed(details: $details)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LiquidSdkEvent_PaymentSucceedImpl &&
|
||||||
|
(identical(other.details, details) || other.details == details));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, details);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LiquidSdkEvent_PaymentSucceedImplCopyWith<_$LiquidSdkEvent_PaymentSucceedImpl> get copyWith =>
|
||||||
|
__$$LiquidSdkEvent_PaymentSucceedImplCopyWithImpl<_$LiquidSdkEvent_PaymentSucceedImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LiquidSdkEvent_PaymentSucceed extends LiquidSdkEvent {
|
||||||
|
const factory LiquidSdkEvent_PaymentSucceed({required final Payment details}) =
|
||||||
|
_$LiquidSdkEvent_PaymentSucceedImpl;
|
||||||
|
const LiquidSdkEvent_PaymentSucceed._() : super._();
|
||||||
|
|
||||||
|
Payment get details;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$LiquidSdkEvent_PaymentSucceedImplCopyWith<_$LiquidSdkEvent_PaymentSucceedImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWith<$Res> {
|
||||||
|
factory _$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWith(
|
||||||
|
_$LiquidSdkEvent_PaymentWaitingConfirmationImpl value,
|
||||||
|
$Res Function(_$LiquidSdkEvent_PaymentWaitingConfirmationImpl) then) =
|
||||||
|
__$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Payment details});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWithImpl<$Res>
|
||||||
|
extends _$LiquidSdkEventCopyWithImpl<$Res, _$LiquidSdkEvent_PaymentWaitingConfirmationImpl>
|
||||||
|
implements _$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWith<$Res> {
|
||||||
|
__$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWithImpl(
|
||||||
|
_$LiquidSdkEvent_PaymentWaitingConfirmationImpl _value,
|
||||||
|
$Res Function(_$LiquidSdkEvent_PaymentWaitingConfirmationImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? details = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LiquidSdkEvent_PaymentWaitingConfirmationImpl(
|
||||||
|
details: null == details
|
||||||
|
? _value.details
|
||||||
|
: details // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Payment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LiquidSdkEvent_PaymentWaitingConfirmationImpl extends LiquidSdkEvent_PaymentWaitingConfirmation {
|
||||||
|
const _$LiquidSdkEvent_PaymentWaitingConfirmationImpl({required this.details}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
final Payment details;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LiquidSdkEvent.paymentWaitingConfirmation(details: $details)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LiquidSdkEvent_PaymentWaitingConfirmationImpl &&
|
||||||
|
(identical(other.details, details) || other.details == details));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, details);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWith<_$LiquidSdkEvent_PaymentWaitingConfirmationImpl>
|
||||||
|
get copyWith => __$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWithImpl<
|
||||||
|
_$LiquidSdkEvent_PaymentWaitingConfirmationImpl>(this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LiquidSdkEvent_PaymentWaitingConfirmation extends LiquidSdkEvent {
|
||||||
|
const factory LiquidSdkEvent_PaymentWaitingConfirmation({required final Payment details}) =
|
||||||
|
_$LiquidSdkEvent_PaymentWaitingConfirmationImpl;
|
||||||
|
const LiquidSdkEvent_PaymentWaitingConfirmation._() : super._();
|
||||||
|
|
||||||
|
Payment get details;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$LiquidSdkEvent_PaymentWaitingConfirmationImplCopyWith<_$LiquidSdkEvent_PaymentWaitingConfirmationImpl>
|
||||||
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LiquidSdkEvent_SyncedImplCopyWith<$Res> {
|
||||||
|
factory _$$LiquidSdkEvent_SyncedImplCopyWith(
|
||||||
|
_$LiquidSdkEvent_SyncedImpl value, $Res Function(_$LiquidSdkEvent_SyncedImpl) then) =
|
||||||
|
__$$LiquidSdkEvent_SyncedImplCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LiquidSdkEvent_SyncedImplCopyWithImpl<$Res>
|
||||||
|
extends _$LiquidSdkEventCopyWithImpl<$Res, _$LiquidSdkEvent_SyncedImpl>
|
||||||
|
implements _$$LiquidSdkEvent_SyncedImplCopyWith<$Res> {
|
||||||
|
__$$LiquidSdkEvent_SyncedImplCopyWithImpl(
|
||||||
|
_$LiquidSdkEvent_SyncedImpl _value, $Res Function(_$LiquidSdkEvent_SyncedImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LiquidSdkEvent_SyncedImpl extends LiquidSdkEvent_Synced {
|
||||||
|
const _$LiquidSdkEvent_SyncedImpl() : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LiquidSdkEvent.synced()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType && other is _$LiquidSdkEvent_SyncedImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LiquidSdkEvent_Synced extends LiquidSdkEvent {
|
||||||
|
const factory LiquidSdkEvent_Synced() = _$LiquidSdkEvent_SyncedImpl;
|
||||||
|
const LiquidSdkEvent_Synced._() : super._();
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ EXTERNAL SOURCES:
|
|||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
flutter_breez_liquid: 90494dd8df26d6258f0d2a90663204ee6257ede2
|
flutter_breez_liquid: 90494dd8df26d6258f0d2a90663204ee6257ede2
|
||||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||||
|
|
||||||
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
|
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,26 @@ class FlutterBreezLiquidBindings {
|
|||||||
late final _store_dart_post_cobject =
|
late final _store_dart_post_cobject =
|
||||||
_store_dart_post_cobjectPtr.asFunction<void Function(DartPostCObjectFnType)>();
|
_store_dart_post_cobjectPtr.asFunction<void Function(DartPostCObjectFnType)>();
|
||||||
|
|
||||||
|
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener(
|
||||||
|
int port_,
|
||||||
|
int that,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> listener,
|
||||||
|
) {
|
||||||
|
return _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener(
|
||||||
|
port_,
|
||||||
|
that,
|
||||||
|
listener,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listenerPtr = _lookup<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||||
|
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener');
|
||||||
|
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listener =
|
||||||
|
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_listenerPtr
|
||||||
|
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||||
|
|
||||||
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(
|
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(
|
||||||
int port_,
|
int port_,
|
||||||
int that,
|
int that,
|
||||||
@@ -297,6 +317,17 @@ class FlutterBreezLiquidBindings {
|
|||||||
_frbgen_breez_liquid_cst_new_box_autoadd_get_info_requestPtr
|
_frbgen_breez_liquid_cst_new_box_autoadd_get_info_requestPtr
|
||||||
.asFunction<ffi.Pointer<wire_cst_get_info_request> Function()>();
|
.asFunction<ffi.Pointer<wire_cst_get_info_request> Function()>();
|
||||||
|
|
||||||
|
ffi.Pointer<wire_cst_payment> frbgen_breez_liquid_cst_new_box_autoadd_payment() {
|
||||||
|
return _frbgen_breez_liquid_cst_new_box_autoadd_payment();
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _frbgen_breez_liquid_cst_new_box_autoadd_paymentPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_payment> Function()>>(
|
||||||
|
'frbgen_breez_liquid_cst_new_box_autoadd_payment');
|
||||||
|
late final _frbgen_breez_liquid_cst_new_box_autoadd_payment =
|
||||||
|
_frbgen_breez_liquid_cst_new_box_autoadd_paymentPtr
|
||||||
|
.asFunction<ffi.Pointer<wire_cst_payment> Function()>();
|
||||||
|
|
||||||
ffi.Pointer<wire_cst_prepare_receive_request>
|
ffi.Pointer<wire_cst_prepare_receive_request>
|
||||||
frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request() {
|
frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request() {
|
||||||
return _frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request();
|
return _frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request();
|
||||||
@@ -426,6 +457,13 @@ typedef DartDartPort = int;
|
|||||||
|
|
||||||
final class _Dart_Handle extends ffi.Opaque {}
|
final class _Dart_Handle extends ffi.Opaque {}
|
||||||
|
|
||||||
|
final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
|
||||||
|
external ffi.Pointer<ffi.Uint8> ptr;
|
||||||
|
|
||||||
|
@ffi.Int32()
|
||||||
|
external int len;
|
||||||
|
}
|
||||||
|
|
||||||
final class wire_cst_get_info_request extends ffi.Struct {
|
final class wire_cst_get_info_request extends ffi.Struct {
|
||||||
@ffi.Bool()
|
@ffi.Bool()
|
||||||
external bool with_scan;
|
external bool with_scan;
|
||||||
@@ -436,13 +474,6 @@ final class wire_cst_prepare_receive_request extends ffi.Struct {
|
|||||||
external int payer_amount_sat;
|
external int payer_amount_sat;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
|
|
||||||
external ffi.Pointer<ffi.Uint8> ptr;
|
|
||||||
|
|
||||||
@ffi.Int32()
|
|
||||||
external int len;
|
|
||||||
}
|
|
||||||
|
|
||||||
final class wire_cst_prepare_send_request extends ffi.Struct {
|
final class wire_cst_prepare_send_request extends ffi.Struct {
|
||||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
|
||||||
}
|
}
|
||||||
@@ -532,6 +563,51 @@ final class wire_cst_liquid_sdk_error extends ffi.Struct {
|
|||||||
external LiquidSdkErrorKind kind;
|
external LiquidSdkErrorKind kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentFailed extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentPending extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentRefunded extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentRefundPending extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentSucceed extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_payment> details;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class LiquidSdkEventKind extends ffi.Union {
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentFailed PaymentFailed;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentPending PaymentPending;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentRefunded PaymentRefunded;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentRefundPending PaymentRefundPending;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentSucceed PaymentSucceed;
|
||||||
|
|
||||||
|
external wire_cst_LiquidSdkEvent_PaymentWaitingConfirmation PaymentWaitingConfirmation;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class wire_cst_liquid_sdk_event extends ffi.Struct {
|
||||||
|
@ffi.Int32()
|
||||||
|
external int tag;
|
||||||
|
|
||||||
|
external LiquidSdkEventKind kind;
|
||||||
|
}
|
||||||
|
|
||||||
final class wire_cst_PaymentError_Generic extends ffi.Struct {
|
final class wire_cst_PaymentError_Generic extends ffi.Struct {
|
||||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.breezliquidsdk
|
||||||
|
|
||||||
|
import breez_liquid_sdk.LiquidSdkEvent
|
||||||
|
import breez_liquid_sdk.EventListener
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
||||||
|
|
||||||
|
class BreezLiquidSDKEventListener(private val emitter: RCTDeviceEventEmitter) : EventListener {
|
||||||
|
private var id: String? = null
|
||||||
|
|
||||||
|
fun setId(id: String) {
|
||||||
|
this.id = id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEvent(e: LiquidSdkEvent) {
|
||||||
|
this.id?.let {
|
||||||
|
emitter.emit("event-$it", readableMapOf(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -420,6 +420,78 @@ fun asSendPaymentResponseList(arr: ReadableArray): List<SendPaymentResponse> {
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun asLiquidSdkEvent(liquidSdkEvent: ReadableMap): LiquidSdkEvent? {
|
||||||
|
val type = liquidSdkEvent.getString("type")
|
||||||
|
|
||||||
|
if (type == "paymentFailed") {
|
||||||
|
return LiquidSdkEvent.PaymentFailed(liquidSdkEvent.getMap("details")?.let { asPayment(it) }!!)
|
||||||
|
}
|
||||||
|
if (type == "paymentPending") {
|
||||||
|
return LiquidSdkEvent.PaymentPending(liquidSdkEvent.getMap("details")?.let { asPayment(it) }!!)
|
||||||
|
}
|
||||||
|
if (type == "paymentRefunded") {
|
||||||
|
return LiquidSdkEvent.PaymentRefunded(liquidSdkEvent.getMap("details")?.let { asPayment(it) }!!)
|
||||||
|
}
|
||||||
|
if (type == "paymentRefundPending") {
|
||||||
|
return LiquidSdkEvent.PaymentRefundPending(liquidSdkEvent.getMap("details")?.let { asPayment(it) }!!)
|
||||||
|
}
|
||||||
|
if (type == "paymentSucceed") {
|
||||||
|
return LiquidSdkEvent.PaymentSucceed(liquidSdkEvent.getMap("details")?.let { asPayment(it) }!!)
|
||||||
|
}
|
||||||
|
if (type == "paymentWaitingConfirmation") {
|
||||||
|
return LiquidSdkEvent.PaymentWaitingConfirmation(liquidSdkEvent.getMap("details")?.let { asPayment(it) }!!)
|
||||||
|
}
|
||||||
|
if (type == "synced") {
|
||||||
|
return LiquidSdkEvent.Synced
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readableMapOf(liquidSdkEvent: LiquidSdkEvent): ReadableMap? {
|
||||||
|
val map = Arguments.createMap()
|
||||||
|
when (liquidSdkEvent) {
|
||||||
|
is LiquidSdkEvent.PaymentFailed -> {
|
||||||
|
pushToMap(map, "type", "paymentFailed")
|
||||||
|
pushToMap(map, "details", readableMapOf(liquidSdkEvent.details))
|
||||||
|
}
|
||||||
|
is LiquidSdkEvent.PaymentPending -> {
|
||||||
|
pushToMap(map, "type", "paymentPending")
|
||||||
|
pushToMap(map, "details", readableMapOf(liquidSdkEvent.details))
|
||||||
|
}
|
||||||
|
is LiquidSdkEvent.PaymentRefunded -> {
|
||||||
|
pushToMap(map, "type", "paymentRefunded")
|
||||||
|
pushToMap(map, "details", readableMapOf(liquidSdkEvent.details))
|
||||||
|
}
|
||||||
|
is LiquidSdkEvent.PaymentRefundPending -> {
|
||||||
|
pushToMap(map, "type", "paymentRefundPending")
|
||||||
|
pushToMap(map, "details", readableMapOf(liquidSdkEvent.details))
|
||||||
|
}
|
||||||
|
is LiquidSdkEvent.PaymentSucceed -> {
|
||||||
|
pushToMap(map, "type", "paymentSucceed")
|
||||||
|
pushToMap(map, "details", readableMapOf(liquidSdkEvent.details))
|
||||||
|
}
|
||||||
|
is LiquidSdkEvent.PaymentWaitingConfirmation -> {
|
||||||
|
pushToMap(map, "type", "paymentWaitingConfirmation")
|
||||||
|
pushToMap(map, "details", readableMapOf(liquidSdkEvent.details))
|
||||||
|
}
|
||||||
|
is LiquidSdkEvent.Synced -> {
|
||||||
|
pushToMap(map, "type", "synced")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
fun asLiquidSdkEventList(arr: ReadableArray): List<LiquidSdkEvent> {
|
||||||
|
val list = ArrayList<LiquidSdkEvent>()
|
||||||
|
for (value in arr.toArrayList()) {
|
||||||
|
when (value) {
|
||||||
|
is ReadableMap -> list.add(asLiquidSdkEvent(value)!!)
|
||||||
|
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
fun asNetwork(type: String): Network {
|
fun asNetwork(type: String): Network {
|
||||||
return Network.valueOf(camelToUpperSnakeCase(type))
|
return Network.valueOf(camelToUpperSnakeCase(type))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.breezliquidsdk
|
|||||||
|
|
||||||
import breez_liquid_sdk.*
|
import breez_liquid_sdk.*
|
||||||
import com.facebook.react.bridge.*
|
import com.facebook.react.bridge.*
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
@@ -66,6 +67,37 @@ class BreezLiquidSDKModule(reactContext: ReactApplicationContext) : ReactContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun addEventListener(promise: Promise) {
|
||||||
|
executor.execute {
|
||||||
|
try {
|
||||||
|
val emitter = reactApplicationContext.getJSModule(RCTDeviceEventEmitter::class.java)
|
||||||
|
var eventListener = BreezLiquidSDKEventListener(emitter)
|
||||||
|
val res = getBindingLiquidSdk().addEventListener(eventListener)
|
||||||
|
|
||||||
|
eventListener.setId(res)
|
||||||
|
promise.resolve(res)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun removeEventListener(
|
||||||
|
id: String,
|
||||||
|
promise: Promise,
|
||||||
|
) {
|
||||||
|
executor.execute {
|
||||||
|
try {
|
||||||
|
getBindingLiquidSdk().removeEventListener(id)
|
||||||
|
promise.resolve(readableMapOf("status" to "ok"))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
fun getInfo(
|
fun getInfo(
|
||||||
req: ReadableMap,
|
req: ReadableMap,
|
||||||
|
|||||||
21
packages/react-native/example/App.js
vendored
21
packages/react-native/example/App.js
vendored
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import React, { useState } from "react"
|
import React, { useState } from "react"
|
||||||
import { SafeAreaView, ScrollView, StatusBar, Text, TouchableOpacity, View } from "react-native"
|
import { SafeAreaView, ScrollView, StatusBar, Text, TouchableOpacity, View } from "react-native"
|
||||||
import { Network, getInfo, connect } from "@breeztech/react-native-breez-liquid-sdk"
|
import { addEventListener, Network, getInfo, connect, removeEventListener } from "@breeztech/react-native-breez-liquid-sdk"
|
||||||
import { generateMnemonic } from "@dreson4/react-native-quick-bip39"
|
import { generateMnemonic } from "@dreson4/react-native-quick-bip39"
|
||||||
import { getSecureItem, setSecureItem } from "./utils/storage"
|
import { getSecureItem, setSecureItem } from "./utils/storage"
|
||||||
|
|
||||||
@@ -33,7 +33,13 @@ const App = () => {
|
|||||||
console.log(`${title}${text && text.length > 0 ? ": " + text : ""}`)
|
console.log(`${title}${text && text.length > 0 ? ": " + text : ""}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const eventHandler = (e) => {
|
||||||
|
addLine("event", JSON.stringify(e))
|
||||||
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
let listenerId = null
|
||||||
|
|
||||||
const asyncFn = async () => {
|
const asyncFn = async () => {
|
||||||
try {
|
try {
|
||||||
let mnemonic = await getSecureItem(MNEMONIC_STORE)
|
let mnemonic = await getSecureItem(MNEMONIC_STORE)
|
||||||
@@ -43,10 +49,13 @@ const App = () => {
|
|||||||
setSecureItem(MNEMONIC_STORE, mnemonic)
|
setSecureItem(MNEMONIC_STORE, mnemonic)
|
||||||
}
|
}
|
||||||
|
|
||||||
await connect({mnemonic, network: Network.LIQUID_TESTNET})
|
await connect({ mnemonic, network: Network.LIQUID_TESTNET })
|
||||||
addLine("connect", null)
|
addLine("connect", null)
|
||||||
|
|
||||||
let walletInfo = await getInfo({withScan: false})
|
listenerId = await addEventListener(eventHandler)
|
||||||
|
addLine("addEventListener", listenerId)
|
||||||
|
|
||||||
|
let walletInfo = await getInfo({ withScan: false })
|
||||||
addLine("getInfo", JSON.stringify(walletInfo))
|
addLine("getInfo", JSON.stringify(walletInfo))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
addLine("error", e.toString())
|
addLine("error", e.toString())
|
||||||
@@ -55,6 +64,12 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
asyncFn()
|
asyncFn()
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (listenerId) {
|
||||||
|
removeEventListener(listenerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -383,8 +383,13 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.breezliquidsdk;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.breezliquidsdk;
|
||||||
PRODUCT_NAME = BreezLiquidSDKExample;
|
PRODUCT_NAME = BreezLiquidSDKExample;
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -485,7 +490,12 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.breezliquidsdk;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.breezliquidsdk;
|
||||||
PRODUCT_NAME = BreezLiquidSDKExample;
|
PRODUCT_NAME = BreezLiquidSDKExample;
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|||||||
@@ -552,7 +552,7 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
boost: 9fa78656d705f55b1220151d997e57e2a3f2cde0
|
boost: 9fa78656d705f55b1220151d997e57e2a3f2cde0
|
||||||
BreezLiquidSDK: 4bca3771d7dfe9c834dbe26836ffadfe8f283c76
|
BreezLiquidSDK: 287a36ed15beff2b9ba61a869e1868f790b4fa20
|
||||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||||
FBLazyVector: 9cf707e46f9bd90816b7c91b2c1c8b8a2f549527
|
FBLazyVector: 9cf707e46f9bd90816b7c91b2c1c8b8a2f549527
|
||||||
|
|||||||
20
packages/react-native/ios/BreezLiquidSDKEventListener.swift
Normal file
20
packages/react-native/ios/BreezLiquidSDKEventListener.swift
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import Foundation
|
||||||
|
import BreezLiquidSDK
|
||||||
|
|
||||||
|
class BreezLiquidSDKEventListener: EventListener {
|
||||||
|
private var id: String?
|
||||||
|
|
||||||
|
func setId(id: String) {
|
||||||
|
self.id = id
|
||||||
|
RNBreezLiquidSDK.addSupportedEvent(name: "event-\(id)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func onEvent(e: LiquidSdkEvent) {
|
||||||
|
if let id = self.id {
|
||||||
|
if RNBreezLiquidSDK.hasListeners {
|
||||||
|
RNBreezLiquidSDK.emitter.sendEvent(withName: "event-\(id)",
|
||||||
|
body: BreezLiquidSDKMapper.dictionaryOf(liquidSdkEvent: e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -460,6 +460,137 @@ enum BreezLiquidSDKMapper {
|
|||||||
return sendPaymentResponseList.map { v -> [String: Any?] in dictionaryOf(sendPaymentResponse: v) }
|
return sendPaymentResponseList.map { v -> [String: Any?] in dictionaryOf(sendPaymentResponse: v) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func asLiquidSdkEvent(liquidSdkEvent: [String: Any?]) throws -> LiquidSdkEvent {
|
||||||
|
let type = liquidSdkEvent["type"] as! String
|
||||||
|
if type == "paymentFailed" {
|
||||||
|
guard let detailsTmp = liquidSdkEvent["details"] as? [String: Any?] else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "details", typeName: "LiquidSdkEvent"))
|
||||||
|
}
|
||||||
|
let _details = try asPayment(payment: detailsTmp)
|
||||||
|
|
||||||
|
return LiquidSdkEvent.paymentFailed(details: _details)
|
||||||
|
}
|
||||||
|
if type == "paymentPending" {
|
||||||
|
guard let detailsTmp = liquidSdkEvent["details"] as? [String: Any?] else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "details", typeName: "LiquidSdkEvent"))
|
||||||
|
}
|
||||||
|
let _details = try asPayment(payment: detailsTmp)
|
||||||
|
|
||||||
|
return LiquidSdkEvent.paymentPending(details: _details)
|
||||||
|
}
|
||||||
|
if type == "paymentRefunded" {
|
||||||
|
guard let detailsTmp = liquidSdkEvent["details"] as? [String: Any?] else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "details", typeName: "LiquidSdkEvent"))
|
||||||
|
}
|
||||||
|
let _details = try asPayment(payment: detailsTmp)
|
||||||
|
|
||||||
|
return LiquidSdkEvent.paymentRefunded(details: _details)
|
||||||
|
}
|
||||||
|
if type == "paymentRefundPending" {
|
||||||
|
guard let detailsTmp = liquidSdkEvent["details"] as? [String: Any?] else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "details", typeName: "LiquidSdkEvent"))
|
||||||
|
}
|
||||||
|
let _details = try asPayment(payment: detailsTmp)
|
||||||
|
|
||||||
|
return LiquidSdkEvent.paymentRefundPending(details: _details)
|
||||||
|
}
|
||||||
|
if type == "paymentSucceed" {
|
||||||
|
guard let detailsTmp = liquidSdkEvent["details"] as? [String: Any?] else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "details", typeName: "LiquidSdkEvent"))
|
||||||
|
}
|
||||||
|
let _details = try asPayment(payment: detailsTmp)
|
||||||
|
|
||||||
|
return LiquidSdkEvent.paymentSucceed(details: _details)
|
||||||
|
}
|
||||||
|
if type == "paymentWaitingConfirmation" {
|
||||||
|
guard let detailsTmp = liquidSdkEvent["details"] as? [String: Any?] else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "details", typeName: "LiquidSdkEvent"))
|
||||||
|
}
|
||||||
|
let _details = try asPayment(payment: detailsTmp)
|
||||||
|
|
||||||
|
return LiquidSdkEvent.paymentWaitingConfirmation(details: _details)
|
||||||
|
}
|
||||||
|
if type == "synced" {
|
||||||
|
return LiquidSdkEvent.synced
|
||||||
|
}
|
||||||
|
|
||||||
|
throw LiquidSdkError.Generic(message: "Unexpected type \(type) for enum LiquidSdkEvent")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func dictionaryOf(liquidSdkEvent: LiquidSdkEvent) -> [String: Any?] {
|
||||||
|
switch liquidSdkEvent {
|
||||||
|
case let .paymentFailed(
|
||||||
|
details
|
||||||
|
):
|
||||||
|
return [
|
||||||
|
"type": "paymentFailed",
|
||||||
|
"details": dictionaryOf(payment: details),
|
||||||
|
]
|
||||||
|
|
||||||
|
case let .paymentPending(
|
||||||
|
details
|
||||||
|
):
|
||||||
|
return [
|
||||||
|
"type": "paymentPending",
|
||||||
|
"details": dictionaryOf(payment: details),
|
||||||
|
]
|
||||||
|
|
||||||
|
case let .paymentRefunded(
|
||||||
|
details
|
||||||
|
):
|
||||||
|
return [
|
||||||
|
"type": "paymentRefunded",
|
||||||
|
"details": dictionaryOf(payment: details),
|
||||||
|
]
|
||||||
|
|
||||||
|
case let .paymentRefundPending(
|
||||||
|
details
|
||||||
|
):
|
||||||
|
return [
|
||||||
|
"type": "paymentRefundPending",
|
||||||
|
"details": dictionaryOf(payment: details),
|
||||||
|
]
|
||||||
|
|
||||||
|
case let .paymentSucceed(
|
||||||
|
details
|
||||||
|
):
|
||||||
|
return [
|
||||||
|
"type": "paymentSucceed",
|
||||||
|
"details": dictionaryOf(payment: details),
|
||||||
|
]
|
||||||
|
|
||||||
|
case let .paymentWaitingConfirmation(
|
||||||
|
details
|
||||||
|
):
|
||||||
|
return [
|
||||||
|
"type": "paymentWaitingConfirmation",
|
||||||
|
"details": dictionaryOf(payment: details),
|
||||||
|
]
|
||||||
|
|
||||||
|
case .synced:
|
||||||
|
return [
|
||||||
|
"type": "synced",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func arrayOf(liquidSdkEventList: [LiquidSdkEvent]) -> [Any] {
|
||||||
|
return liquidSdkEventList.map { v -> [String: Any?] in dictionaryOf(liquidSdkEvent: v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static func asLiquidSdkEventList(arr: [Any]) throws -> [LiquidSdkEvent] {
|
||||||
|
var list = [LiquidSdkEvent]()
|
||||||
|
for value in arr {
|
||||||
|
if let val = value as? [String: Any?] {
|
||||||
|
var liquidSdkEvent = try asLiquidSdkEvent(liquidSdkEvent: val)
|
||||||
|
list.append(liquidSdkEvent)
|
||||||
|
} else {
|
||||||
|
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "LiquidSdkEvent"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
static func asNetwork(network: String) throws -> Network {
|
static func asNetwork(network: String) throws -> Network {
|
||||||
switch network {
|
switch network {
|
||||||
case "liquid":
|
case "liquid":
|
||||||
|
|||||||
@@ -9,6 +9,17 @@ RCT_EXTERN_METHOD(
|
|||||||
reject: (RCTPromiseRejectBlock)reject
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
)
|
)
|
||||||
|
|
||||||
|
RCT_EXTERN_METHOD(
|
||||||
|
addEventListener: (RCTPromiseResolveBlock)resolve
|
||||||
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
|
)
|
||||||
|
|
||||||
|
RCT_EXTERN_METHOD(
|
||||||
|
removeEventListener: (NSString*)id
|
||||||
|
resolve: (RCTPromiseResolveBlock)resolve
|
||||||
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
|
)
|
||||||
|
|
||||||
RCT_EXTERN_METHOD(
|
RCT_EXTERN_METHOD(
|
||||||
getInfo: (NSDictionary*)req
|
getInfo: (NSDictionary*)req
|
||||||
resolve: (RCTPromiseResolveBlock)resolve
|
resolve: (RCTPromiseResolveBlock)resolve
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
|
|
||||||
public static var emitter: RCTEventEmitter!
|
public static var emitter: RCTEventEmitter!
|
||||||
public static var hasListeners: Bool = false
|
public static var hasListeners: Bool = false
|
||||||
|
public static var supportedEvents: [String] = []
|
||||||
|
|
||||||
private var bindingLiquidSdk: BindingLiquidSdk!
|
private var bindingLiquidSdk: BindingLiquidSdk!
|
||||||
|
|
||||||
@@ -26,8 +27,12 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
TAG
|
TAG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func addSupportedEvent(name: String) {
|
||||||
|
RNBreezLiquidSDK.supportedEvents.append(name)
|
||||||
|
}
|
||||||
|
|
||||||
override func supportedEvents() -> [String]! {
|
override func supportedEvents() -> [String]! {
|
||||||
return []
|
return RNBreezLiquidSDK.supportedEvents
|
||||||
}
|
}
|
||||||
|
|
||||||
override func startObserving() {
|
override func startObserving() {
|
||||||
@@ -68,6 +73,29 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc(addEventListener:reject:)
|
||||||
|
func addEventListener(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
|
do {
|
||||||
|
var eventListener = BreezLiquidSDKEventListener()
|
||||||
|
var res = try getBindingLiquidSdk().addEventListener(listener: eventListener)
|
||||||
|
|
||||||
|
eventListener.setId(id: res)
|
||||||
|
resolve(res)
|
||||||
|
} catch let err {
|
||||||
|
rejectErr(err: err, reject: reject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc(removeEventListener:resolve:reject:)
|
||||||
|
func removeEventListener(_ id: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
|
do {
|
||||||
|
try getBindingLiquidSdk().removeEventListener(id: id)
|
||||||
|
resolve(["status": "ok"])
|
||||||
|
} catch let err {
|
||||||
|
rejectErr(err: err, reject: reject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc(getInfo:resolve:reject:)
|
@objc(getInfo:resolve:reject:)
|
||||||
func getInfo(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
func getInfo(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { NativeModules, Platform } from "react-native"
|
import { NativeModules, Platform, NativeEventEmitter } from "react-native"
|
||||||
|
|
||||||
const LINKING_ERROR =
|
const LINKING_ERROR =
|
||||||
`The package 'react-native-breez-liquid-sdk' doesn't seem to be linked. Make sure: \n\n` +
|
`The package 'react-native-breez-liquid-sdk' doesn't seem to be linked. Make sure: \n\n` +
|
||||||
@@ -17,6 +17,8 @@ const BreezLiquidSDK = NativeModules.RNBreezLiquidSDK
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const BreezLiquidSDKEmitter = new NativeEventEmitter(BreezLiquidSDK)
|
||||||
|
|
||||||
export interface ConnectRequest {
|
export interface ConnectRequest {
|
||||||
mnemonic: string
|
mnemonic: string
|
||||||
network: Network
|
network: Network
|
||||||
@@ -76,6 +78,38 @@ export interface SendPaymentResponse {
|
|||||||
txid: string
|
txid: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum LiquidSdkEventVariant {
|
||||||
|
PAYMENT_FAILED = "paymentFailed",
|
||||||
|
PAYMENT_PENDING = "paymentPending",
|
||||||
|
PAYMENT_REFUNDED = "paymentRefunded",
|
||||||
|
PAYMENT_REFUND_PENDING = "paymentRefundPending",
|
||||||
|
PAYMENT_SUCCEED = "paymentSucceed",
|
||||||
|
PAYMENT_WAITING_CONFIRMATION = "paymentWaitingConfirmation",
|
||||||
|
SYNCED = "synced"
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LiquidSdkEvent = {
|
||||||
|
type: LiquidSdkEventVariant.PAYMENT_FAILED,
|
||||||
|
details: Payment
|
||||||
|
} | {
|
||||||
|
type: LiquidSdkEventVariant.PAYMENT_PENDING,
|
||||||
|
details: Payment
|
||||||
|
} | {
|
||||||
|
type: LiquidSdkEventVariant.PAYMENT_REFUNDED,
|
||||||
|
details: Payment
|
||||||
|
} | {
|
||||||
|
type: LiquidSdkEventVariant.PAYMENT_REFUND_PENDING,
|
||||||
|
details: Payment
|
||||||
|
} | {
|
||||||
|
type: LiquidSdkEventVariant.PAYMENT_SUCCEED,
|
||||||
|
details: Payment
|
||||||
|
} | {
|
||||||
|
type: LiquidSdkEventVariant.PAYMENT_WAITING_CONFIRMATION,
|
||||||
|
details: Payment
|
||||||
|
} | {
|
||||||
|
type: LiquidSdkEventVariant.SYNCED
|
||||||
|
}
|
||||||
|
|
||||||
export enum Network {
|
export enum Network {
|
||||||
LIQUID = "liquid",
|
LIQUID = "liquid",
|
||||||
LIQUID_TESTNET = "liquidTestnet"
|
LIQUID_TESTNET = "liquidTestnet"
|
||||||
@@ -93,11 +127,24 @@ export enum PaymentType {
|
|||||||
SEND = "send"
|
SEND = "send"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type EventListener = (e: LiquidSdkEvent) => void
|
||||||
|
|
||||||
export const connect = async (req: ConnectRequest): Promise<void> => {
|
export const connect = async (req: ConnectRequest): Promise<void> => {
|
||||||
const response = await BreezLiquidSDK.connect(req)
|
const response = await BreezLiquidSDK.connect(req)
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addEventListener = async (listener: EventListener): Promise<string> => {
|
||||||
|
const response = await BreezLiquidSDK.addEventListener()
|
||||||
|
BreezLiquidSDKEmitter.addListener(`event-${response}`, listener)
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
export const removeEventListener = async (id: string): Promise<void> => {
|
||||||
|
await BreezLiquidSDK.removeEventListener(id)
|
||||||
|
}
|
||||||
|
|
||||||
export const getInfo = async (req: GetInfoRequest): Promise<GetInfoResponse> => {
|
export const getInfo = async (req: GetInfoRequest): Promise<GetInfoResponse> => {
|
||||||
const response = await BreezLiquidSDK.getInfo(req)
|
const response = await BreezLiquidSDK.getInfo(req)
|
||||||
return response
|
return response
|
||||||
|
|||||||
Reference in New Issue
Block a user