mirror of
https://github.com/aljazceru/breez-sdk-liquid.git
synced 2025-12-24 01:14:22 +01:00
Add global SDK logger (#242)
* Add SDK global logger * Add bindings * Fix path to internal uniffi log * Exclude "set_log_stream" from generated RN methods * Move logger-specific structs to a separate module * Delegate init_logging to method in logger.rs * Rename uniffi BindingLogger to UniffiBindingLogger * Add set_log_stream for dart bindings * Add SDK logger to Dart bindings * Rename dart binding logger to DartBindingLogger * Add rustdocs * RN bindings: Add manual handling for setLogStream() * Re-generate dart bindings * Re-generate RN bindings * Remove LOG_INIT cell * Set global maximum log level once on initialization Return a LiquidSdkError::Generic instead of Anyhow error when initializing log stream on Dart bindings * Do not panic when initializing binding loggers * Rename LogStream to Logger --------- Co-authored-by: Erdem Yerebasmaz <erdem@yerebasmaz.com>
This commit is contained in:
4
cli/Cargo.lock
generated
4
cli/Cargo.lock
generated
@@ -395,7 +395,6 @@ dependencies = [
|
|||||||
"bip39",
|
"bip39",
|
||||||
"breez-liquid-sdk",
|
"breez-liquid-sdk",
|
||||||
"clap",
|
"clap",
|
||||||
"env_logger 0.11.3",
|
|
||||||
"log",
|
"log",
|
||||||
"qrcode-rs",
|
"qrcode-rs",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
@@ -411,6 +410,8 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"bip39",
|
"bip39",
|
||||||
"boltz-client",
|
"boltz-client",
|
||||||
|
"chrono",
|
||||||
|
"env_logger 0.11.3",
|
||||||
"flutter_rust_bridge",
|
"flutter_rust_bridge",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"glob",
|
"glob",
|
||||||
@@ -418,7 +419,6 @@ dependencies = [
|
|||||||
"lwk_common",
|
"lwk_common",
|
||||||
"lwk_signer",
|
"lwk_signer",
|
||||||
"lwk_wollet",
|
"lwk_wollet",
|
||||||
"once_cell",
|
|
||||||
"openssl",
|
"openssl",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"rusqlite_migration",
|
"rusqlite_migration",
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ anyhow = "1.0.80"
|
|||||||
bip39 = "2.0.0"
|
bip39 = "2.0.0"
|
||||||
breez-liquid-sdk = { path = "../lib/core" }
|
breez-liquid-sdk = { path = "../lib/core" }
|
||||||
clap = { version = "4.5.1", features = ["derive"] }
|
clap = { version = "4.5.1", features = ["derive"] }
|
||||||
env_logger = "0.11"
|
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
qrcode-rs = { version = "0.1", default-features = false }
|
qrcode-rs = { version = "0.1", default-features = false }
|
||||||
rustyline = { version = "13.0.0", features = ["derive"] }
|
rustyline = { version = "13.0.0", features = ["derive"] }
|
||||||
|
|||||||
@@ -24,14 +24,3 @@ To specify a custom data directory, use
|
|||||||
```bash
|
```bash
|
||||||
cargo run -- --data-dir temp-dir
|
cargo run -- --data-dir temp-dir
|
||||||
```
|
```
|
||||||
|
|
||||||
To set a custom log level, use
|
|
||||||
|
|
||||||
```bash
|
|
||||||
RUST_LOG=info|debug|warn cargo run
|
|
||||||
```
|
|
||||||
|
|
||||||
To specify a file to pipe logs to, use
|
|
||||||
```bash
|
|
||||||
RUST_LOG=info|debug|warn cargo run -- --log-file /tmp/log
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
mod commands;
|
mod commands;
|
||||||
mod persist;
|
mod persist;
|
||||||
|
|
||||||
use std::{
|
use std::{fs, path::PathBuf};
|
||||||
fs::{self, OpenOptions},
|
|
||||||
path::PathBuf,
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use breez_liquid_sdk::{
|
use breez_liquid_sdk::{
|
||||||
@@ -61,23 +58,7 @@ async fn main() -> Result<()> {
|
|||||||
let data_dir = PathBuf::from(&data_dir_str);
|
let data_dir = PathBuf::from(&data_dir_str);
|
||||||
fs::create_dir_all(&data_dir)?;
|
fs::create_dir_all(&data_dir)?;
|
||||||
|
|
||||||
let log_path = args.log_file.unwrap_or(
|
LiquidSdk::init_logging(&data_dir_str, None)?;
|
||||||
data_dir
|
|
||||||
.join("cli.log")
|
|
||||||
.to_str()
|
|
||||||
.ok_or(anyhow!("Could not create log file"))?
|
|
||||||
.to_string(),
|
|
||||||
);
|
|
||||||
let log_file = OpenOptions::new()
|
|
||||||
.create(true)
|
|
||||||
.append(true)
|
|
||||||
.open(log_path)?;
|
|
||||||
|
|
||||||
env_logger::builder()
|
|
||||||
.target(env_logger::Target::Pipe(Box::new(log_file)))
|
|
||||||
.filter(None, log::LevelFilter::Debug)
|
|
||||||
.filter(Some("rustyline"), log::LevelFilter::Warn)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
let persistence = CliPersistence { data_dir };
|
let persistence = CliPersistence { data_dir };
|
||||||
let history_file = &persistence.history_file();
|
let history_file = &persistence.history_file();
|
||||||
|
|||||||
35
lib/Cargo.lock
generated
35
lib/Cargo.lock
generated
@@ -514,6 +514,8 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"bip39",
|
"bip39",
|
||||||
"boltz-client",
|
"boltz-client",
|
||||||
|
"chrono",
|
||||||
|
"env_logger 0.11.3",
|
||||||
"flutter_rust_bridge",
|
"flutter_rust_bridge",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"glob",
|
"glob",
|
||||||
@@ -521,7 +523,6 @@ dependencies = [
|
|||||||
"lwk_common",
|
"lwk_common",
|
||||||
"lwk_signer",
|
"lwk_signer",
|
||||||
"lwk_wollet",
|
"lwk_wollet",
|
||||||
"once_cell",
|
|
||||||
"openssl",
|
"openssl",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"rusqlite_migration",
|
"rusqlite_migration",
|
||||||
@@ -545,6 +546,7 @@ dependencies = [
|
|||||||
"breez-liquid-sdk",
|
"breez-liquid-sdk",
|
||||||
"camino",
|
"camino",
|
||||||
"glob",
|
"glob",
|
||||||
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -894,6 +896,16 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_filter"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -901,7 +913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"humantime",
|
"humantime 1.3.0",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
@@ -917,6 +929,19 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"env_filter",
|
||||||
|
"humantime 2.1.0",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@@ -1344,6 +1369,12 @@ dependencies = [
|
|||||||
"quick-error",
|
"quick-error",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ version = "0.0.1"
|
|||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
log = "0.4.20"
|
||||||
|
once_cell = "1.19"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
uniffi = "0.27.1"
|
uniffi = "0.27.1"
|
||||||
uniffi_macros = "0.27.1"
|
uniffi_macros = "0.27.1"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ crate-type = ["staticlib", "cdylib", "lib"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
breez-liquid-sdk = { path = "../core" }
|
breez-liquid-sdk = { path = "../core" }
|
||||||
|
log = { workspace = true }
|
||||||
uniffi = { workspace = true, features = [ "bindgen-tests", "cli" ] }
|
uniffi = { workspace = true, features = [ "bindgen-tests", "cli" ] }
|
||||||
# Bindgen used by KMP, version has to match the one supported by KMP
|
# Bindgen used by KMP, version has to match the one supported by KMP
|
||||||
uniffi_bindgen = "0.25.2"
|
uniffi_bindgen = "0.25.2"
|
||||||
@@ -21,7 +22,7 @@ uniffi-kotlin-multiplatform = { git = "https://gitlab.com/trixnity/uniffi-kotlin
|
|||||||
camino = "1.1.1"
|
camino = "1.1.1"
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tokio = { version = "1", features = ["rt"] }
|
tokio = { version = "1", features = ["rt"] }
|
||||||
once_cell = "*"
|
once_cell = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
uniffi = { workspace = true, features = [ "build" ] }
|
uniffi = { workspace = true, features = [ "build" ] }
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ typedef struct wire_cst_ln_invoice {
|
|||||||
uint64_t min_final_cltv_expiry_delta;
|
uint64_t min_final_cltv_expiry_delta;
|
||||||
} wire_cst_ln_invoice;
|
} wire_cst_ln_invoice;
|
||||||
|
|
||||||
|
typedef struct wire_cst_log_entry {
|
||||||
|
struct wire_cst_list_prim_u_8_strict *line;
|
||||||
|
struct wire_cst_list_prim_u_8_strict *level;
|
||||||
|
} wire_cst_log_entry;
|
||||||
|
|
||||||
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;
|
||||||
@@ -260,6 +265,9 @@ void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_send_payment(in
|
|||||||
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_sync(int64_t port_,
|
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_sync(int64_t port_,
|
||||||
uintptr_t that);
|
uintptr_t that);
|
||||||
|
|
||||||
|
void frbgen_breez_liquid_wire__crate__bindings__breez_log_stream(int64_t port_,
|
||||||
|
struct wire_cst_list_prim_u_8_strict *s);
|
||||||
|
|
||||||
void frbgen_breez_liquid_wire__crate__bindings__connect(int64_t port_,
|
void frbgen_breez_liquid_wire__crate__bindings__connect(int64_t port_,
|
||||||
struct wire_cst_connect_request *req);
|
struct wire_cst_connect_request *req);
|
||||||
|
|
||||||
@@ -327,6 +335,7 @@ static int64_t dummy_method_to_enforce_bundling(void) {
|
|||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_restore);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_restore);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_send_payment);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_send_payment);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_sync);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_sync);
|
||||||
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__breez_log_stream);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__connect);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__connect);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__parse_invoice);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__parse_invoice);
|
||||||
dummy_var ^= ((int64_t) (void*) store_dart_post_cobject);
|
dummy_var ^= ((int64_t) (void*) store_dart_post_cobject);
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ uniffi = { version = "0.23.0", features = ["bindgen-tests", "cli"] }
|
|||||||
uniffi_bindgen = "0.23.0"
|
uniffi_bindgen = "0.23.0"
|
||||||
uniffi_macros = "0.23.0"
|
uniffi_macros = "0.23.0"
|
||||||
camino = "1.1.1"
|
camino = "1.1.1"
|
||||||
log = "*"
|
log = { workspace = true }
|
||||||
serde = "*"
|
serde = "*"
|
||||||
askama = { version = "0.11.1", default-features = false, features = ["config"] }
|
askama = { version = "0.11.1", default-features = false, features = ["config"] }
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
clap = { version = "3.2.22", features = ["derive"] }
|
clap = { version = "3.2.22", features = ["derive"] }
|
||||||
heck = "0.4"
|
heck = "0.4"
|
||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
once_cell = "1.12"
|
once_cell = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
uniffi_build = { version = "0.23.0" }
|
uniffi_build = { version = "0.23.0" }
|
||||||
|
|||||||
@@ -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", "add_event_listener"];
|
let list: Vec<&str> = vec!["connect", "add_event_listener", "set_logger"];
|
||||||
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,21 @@ class BreezLiquidSDKModule(reactContext: ReactApplicationContext) : ReactContext
|
|||||||
{%- if func.name()|ignored_function == false -%}
|
{%- if func.name()|ignored_function == false -%}
|
||||||
{% include "TopLevelFunctionTemplate.kt" %}
|
{% include "TopLevelFunctionTemplate.kt" %}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
@ReactMethod
|
||||||
|
fun setLogger(promise: Promise) {
|
||||||
|
executor.execute {
|
||||||
|
try {
|
||||||
|
val emitter = reactApplicationContext.getJSModule(RCTDeviceEventEmitter::class.java)
|
||||||
|
|
||||||
|
setLogger(BreezLiquidSDKLogger(emitter))
|
||||||
|
promise.resolve(readableMapOf("status" to "ok"))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
fun connect(req: ReadableMap, promise: Promise) {
|
fun connect(req: ReadableMap, promise: Promise) {
|
||||||
|
|||||||
@@ -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", "add_event_listener"];
|
let list: Vec<&str> = vec!["connect", "add_event_listener", "set_logger"];
|
||||||
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,11 @@
|
|||||||
{% include "ExternFunctionTemplate.m" %}
|
{% include "ExternFunctionTemplate.m" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
RCT_EXTERN_METHOD(
|
||||||
|
setLogger: (RCTPromiseResolveBlock)resolve
|
||||||
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
|
)
|
||||||
|
|
||||||
RCT_EXTERN_METHOD(
|
RCT_EXTERN_METHOD(
|
||||||
connect: (NSDictionary*)req
|
connect: (NSDictionary*)req
|
||||||
resolve: (RCTPromiseResolveBlock)resolve
|
resolve: (RCTPromiseResolveBlock)resolve
|
||||||
|
|||||||
@@ -7,7 +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] = []
|
public static var supportedEvents: [String] = ["breezLiquidSdkLog"]
|
||||||
|
|
||||||
private var bindingLiquidSdk: BindingLiquidSdk!
|
private var bindingLiquidSdk: BindingLiquidSdk!
|
||||||
|
|
||||||
@@ -62,6 +62,16 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
{% include "TopLevelFunctionTemplate.swift" %}
|
{% include "TopLevelFunctionTemplate.swift" %}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
@objc(setLogger:reject:)
|
||||||
|
func setLogger(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
||||||
|
do {
|
||||||
|
try BreezLiquidSDK.setLogger(Logger: BreezLiquidSDKLogger())
|
||||||
|
resolve(["status": "ok"])
|
||||||
|
} catch let err {
|
||||||
|
rejectErr(err: err, reject: reject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc(connect:resolve:reject:)
|
@objc(connect:resolve:reject:)
|
||||||
func connect(_ req:[String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
func connect(_ req:[String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
||||||
if bindingLiquidSdk != nil {
|
if bindingLiquidSdk != nil {
|
||||||
|
|||||||
@@ -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", "add_event_listener"];
|
let list: Vec<&str> = vec!["connect", "add_event_listener", "set_logger"];
|
||||||
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
HashSet::from_iter(list.into_iter().map(|s| s.to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
export type EventListener = (e: LiquidSdkEvent) => void
|
export type EventListener = (e: LiquidSdkEvent) => void
|
||||||
|
|
||||||
|
export type Logger = (logEntry: LogEntry) => 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
|
||||||
@@ -12,3 +14,13 @@ export const addEventListener = async (listener: EventListener): Promise<string>
|
|||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const setLogger = async (logger: Logger): Promise<EmitterSubscription> => {
|
||||||
|
const subscription = BreezLiquidSDKEmitter.addListener("breezLiquidSdkLog", logger)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await BreezLiquidSDK.setLogger()
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
return subscription
|
||||||
|
}
|
||||||
@@ -150,10 +150,22 @@ callback interface EventListener {
|
|||||||
void on_event(LiquidSdkEvent e);
|
void on_event(LiquidSdkEvent e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
callback interface Logger {
|
||||||
|
void log(LogEntry l);
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary LogEntry {
|
||||||
|
string line;
|
||||||
|
string level;
|
||||||
|
};
|
||||||
|
|
||||||
namespace breez_liquid_sdk {
|
namespace breez_liquid_sdk {
|
||||||
[Throws=LiquidSdkError]
|
[Throws=LiquidSdkError]
|
||||||
BindingLiquidSdk connect(ConnectRequest req);
|
BindingLiquidSdk connect(ConnectRequest req);
|
||||||
|
|
||||||
|
[Throws=LiquidSdkError]
|
||||||
|
void set_logger(Logger logger);
|
||||||
|
|
||||||
[Throws=PaymentError]
|
[Throws=PaymentError]
|
||||||
LNInvoice parse_invoice(string invoice);
|
LNInvoice parse_invoice(string invoice);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
|
//! Uniffi bindings
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use breez_liquid_sdk::logger::Logger;
|
||||||
use breez_liquid_sdk::{error::*, model::*, sdk::LiquidSdk};
|
use breez_liquid_sdk::{error::*, model::*, sdk::LiquidSdk};
|
||||||
|
use log::{Metadata, Record, SetLoggerError};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
use uniffi::deps::log::{Level, LevelFilter};
|
||||||
|
|
||||||
static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().unwrap());
|
static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().unwrap());
|
||||||
|
|
||||||
@@ -11,6 +16,41 @@ fn rt() -> &'static Runtime {
|
|||||||
&RT
|
&RT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct UniffiBindingLogger {
|
||||||
|
logger: Box<dyn Logger>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UniffiBindingLogger {
|
||||||
|
fn init(logger: Box<dyn Logger>) -> Result<(), SetLoggerError> {
|
||||||
|
let binding_logger: UniffiBindingLogger = UniffiBindingLogger { logger };
|
||||||
|
log::set_boxed_logger(Box::new(binding_logger))
|
||||||
|
.map(|_| log::set_max_level(LevelFilter::Trace))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl log::Log for UniffiBindingLogger {
|
||||||
|
fn enabled(&self, m: &Metadata) -> bool {
|
||||||
|
// ignore the internal uniffi log to prevent infinite loop.
|
||||||
|
return m.level() <= Level::Trace && *m.target() != *"breez_liquid_sdk_bindings";
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&self, record: &Record) {
|
||||||
|
self.logger.log(LogEntry {
|
||||||
|
line: record.args().to_string(),
|
||||||
|
level: record.level().as_str().to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fn flush(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If used, this must be called before `connect`
|
||||||
|
pub fn set_logger(logger: Box<dyn Logger>) -> Result<(), LiquidSdkError> {
|
||||||
|
UniffiBindingLogger::init(logger).map_err(|_| LiquidSdkError::Generic {
|
||||||
|
err: "Logger already created".into(),
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn connect(req: ConnectRequest) -> Result<Arc<BindingLiquidSdk>, LiquidSdkError> {
|
pub fn connect(req: ConnectRequest) -> Result<Arc<BindingLiquidSdk>, LiquidSdkError> {
|
||||||
rt().block_on(async {
|
rt().block_on(async {
|
||||||
let sdk = LiquidSdk::connect(req).await?;
|
let sdk = LiquidSdk::connect(req).await?;
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ anyhow = { workspace = true }
|
|||||||
bip39 = { version = "2.0.0", features = ["serde"] }
|
bip39 = { version = "2.0.0", features = ["serde"] }
|
||||||
#boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "a05731cc33030ada9ae14afcafe0cded22842ba6" }
|
#boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "a05731cc33030ada9ae14afcafe0cded22842ba6" }
|
||||||
boltz-client = { git = "https://github.com/ok300/boltz-rust", branch = "ok300-breez-latest-05-28" }
|
boltz-client = { git = "https://github.com/ok300/boltz-rust", branch = "ok300-breez-latest-05-28" }
|
||||||
|
chrono = "0.4"
|
||||||
|
env_logger = "0.11"
|
||||||
flutter_rust_bridge = { version = "=2.0.0-dev.36", features = ["chrono"], optional = true }
|
flutter_rust_bridge = { version = "=2.0.0-dev.36", features = ["chrono"], optional = true }
|
||||||
log = "0.4.20"
|
log = { workspace = true }
|
||||||
lwk_common = "0.5.1"
|
lwk_common = "0.5.1"
|
||||||
lwk_signer = "0.5.1"
|
lwk_signer = "0.5.1"
|
||||||
# Switch back to published version once this PR is merged: https://github.com/Blockstream/lwk/pull/34
|
# Switch back to published version once this PR is merged: https://github.com/Blockstream/lwk/pull/34
|
||||||
@@ -29,7 +31,6 @@ serde = { version = "1.0.197", features = ["derive"] }
|
|||||||
serde_json = "1.0.116"
|
serde_json = "1.0.116"
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tokio-tungstenite = { version = "0.21.0", features = ["native-tls-vendored"] }
|
tokio-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", "macros"] }
|
tokio = { version = "1", features = ["rt", "macros"] }
|
||||||
url = "2.5.0"
|
url = "2.5.0"
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
use crate::{error::*, frb::bridge::StreamSink, model::*, sdk::LiquidSdk};
|
//! Dart / flutter bindings
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use flutter_rust_bridge::frb;
|
use flutter_rust_bridge::frb;
|
||||||
use std::sync::Arc;
|
use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};
|
||||||
|
|
||||||
|
use crate::{error::*, frb::bridge::StreamSink, model::*, sdk::LiquidSdk};
|
||||||
|
|
||||||
struct BindingEventListener {
|
struct BindingEventListener {
|
||||||
stream: StreamSink<LiquidSdkEvent>,
|
stream: StreamSink<LiquidSdkEvent>,
|
||||||
@@ -13,11 +18,47 @@ impl EventListener for BindingEventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DartBindingLogger {
|
||||||
|
log_stream: StreamSink<LogEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DartBindingLogger {
|
||||||
|
fn init(log_stream: StreamSink<LogEntry>) -> Result<(), SetLoggerError> {
|
||||||
|
let binding_logger: DartBindingLogger = DartBindingLogger { log_stream };
|
||||||
|
log::set_boxed_logger(Box::new(binding_logger))
|
||||||
|
.map(|_| log::set_max_level(LevelFilter::Trace))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl log::Log for DartBindingLogger {
|
||||||
|
fn enabled(&self, m: &Metadata) -> bool {
|
||||||
|
m.level() <= Level::Trace
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&self, record: &Record) {
|
||||||
|
if self.enabled(record.metadata()) {
|
||||||
|
let _ = self.log_stream.add(LogEntry {
|
||||||
|
line: record.args().to_string(),
|
||||||
|
level: record.level().as_str().to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn flush(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn connect(req: ConnectRequest) -> Result<BindingLiquidSdk, LiquidSdkError> {
|
pub async fn connect(req: ConnectRequest) -> Result<BindingLiquidSdk, LiquidSdkError> {
|
||||||
let ln_sdk = LiquidSdk::connect(req).await?;
|
let ln_sdk = LiquidSdk::connect(req).await?;
|
||||||
Ok(BindingLiquidSdk { sdk: ln_sdk })
|
Ok(BindingLiquidSdk { sdk: ln_sdk })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If used, this must be called before `connect`. It can only be called once.
|
||||||
|
pub fn breez_log_stream(s: StreamSink<LogEntry>) -> Result<()> {
|
||||||
|
DartBindingLogger::init(s).map_err(|_| LiquidSdkError::Generic {
|
||||||
|
err: "Log stream already created".into(),
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_invoice(input: String) -> Result<LNInvoice, PaymentError> {
|
pub fn parse_invoice(input: String) -> Result<LNInvoice, PaymentError> {
|
||||||
LiquidSdk::parse_invoice(&input)
|
LiquidSdk::parse_invoice(&input)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,14 @@ flutter_rust_bridge::frb_generated_boilerplate_io!();
|
|||||||
|
|
||||||
// Section: dart2rust
|
// Section: dart2rust
|
||||||
|
|
||||||
|
impl CstDecode<flutter_rust_bridge::for_generated::anyhow::Error>
|
||||||
|
for *mut wire_cst_list_prim_u_8_strict
|
||||||
|
{
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
fn cst_decode(self) -> flutter_rust_bridge::for_generated::anyhow::Error {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CstDecode<BindingLiquidSdk> for usize {
|
impl CstDecode<BindingLiquidSdk> for usize {
|
||||||
// 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) -> BindingLiquidSdk {
|
fn cst_decode(self) -> BindingLiquidSdk {
|
||||||
@@ -54,6 +62,17 @@ impl
|
|||||||
StreamSink::deserialize(raw)
|
StreamSink::deserialize(raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CstDecode<StreamSink<crate::model::LogEntry, 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::LogEntry, 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 {
|
||||||
@@ -286,6 +305,15 @@ impl CstDecode<crate::model::LNInvoice> for wire_cst_ln_invoice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CstDecode<crate::model::LogEntry> for wire_cst_log_entry {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
fn cst_decode(self) -> crate::model::LogEntry {
|
||||||
|
crate::model::LogEntry {
|
||||||
|
line: self.line.cst_decode(),
|
||||||
|
level: self.level.cst_decode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CstDecode<crate::model::Payment> for wire_cst_payment {
|
impl CstDecode<crate::model::Payment> for wire_cst_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) -> crate::model::Payment {
|
fn cst_decode(self) -> crate::model::Payment {
|
||||||
@@ -534,6 +562,19 @@ impl Default for wire_cst_ln_invoice {
|
|||||||
Self::new_with_null_ptr()
|
Self::new_with_null_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl NewWithNullPtr for wire_cst_log_entry {
|
||||||
|
fn new_with_null_ptr() -> Self {
|
||||||
|
Self {
|
||||||
|
line: core::ptr::null_mut(),
|
||||||
|
level: core::ptr::null_mut(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Default for wire_cst_log_entry {
|
||||||
|
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 {
|
||||||
@@ -787,6 +828,14 @@ pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_sy
|
|||||||
wire__crate__bindings__BindingLiquidSdk_sync_impl(port_, that)
|
wire__crate__bindings__BindingLiquidSdk_sync_impl(port_, that)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__breez_log_stream(
|
||||||
|
port_: i64,
|
||||||
|
s: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
) {
|
||||||
|
wire__crate__bindings__breez_log_stream_impl(port_, s)
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__connect(
|
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__connect(
|
||||||
port_: i64,
|
port_: i64,
|
||||||
@@ -1077,6 +1126,12 @@ pub struct wire_cst_ln_invoice {
|
|||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct wire_cst_log_entry {
|
||||||
|
line: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
level: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct wire_cst_payment {
|
pub struct wire_cst_payment {
|
||||||
tx_id: *mut wire_cst_list_prim_u_8_strict,
|
tx_id: *mut wire_cst_list_prim_u_8_strict,
|
||||||
swap_id: *mut wire_cst_list_prim_u_8_strict,
|
swap_id: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
|||||||
@@ -34,7 +34,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.36";
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0-dev.36";
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 84136112;
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -532134055;
|
||||||
|
|
||||||
// Section: executor
|
// Section: executor
|
||||||
|
|
||||||
@@ -360,6 +360,16 @@ let decode_indices_ = flutter_rust_bridge::for_generated::rust_auto_opaque_decod
|
|||||||
})().await)
|
})().await)
|
||||||
} })
|
} })
|
||||||
}
|
}
|
||||||
|
fn wire__crate__bindings__breez_log_stream_impl(
|
||||||
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
|
s: impl CstDecode<StreamSink<crate::model::LogEntry, 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: "breez_log_stream", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { let api_s = s.cst_decode(); move |context| {
|
||||||
|
transform_result_dco((move || {
|
||||||
|
crate::bindings::breez_log_stream(api_s)
|
||||||
|
})())
|
||||||
|
} })
|
||||||
|
}
|
||||||
fn wire__crate__bindings__connect_impl(
|
fn wire__crate__bindings__connect_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
req: impl CstDecode<crate::model::ConnectRequest>,
|
req: impl CstDecode<crate::model::ConnectRequest>,
|
||||||
@@ -470,6 +480,14 @@ impl CstDecode<usize> for usize {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl SseDecode for flutter_rust_bridge::for_generated::anyhow::Error {
|
||||||
|
// 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 flutter_rust_bridge::for_generated::anyhow::anyhow!("{}", inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseDecode for BindingLiquidSdk {
|
impl SseDecode for BindingLiquidSdk {
|
||||||
// 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 {
|
||||||
@@ -500,6 +518,16 @@ impl SseDecode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseDecode
|
||||||
|
for StreamSink<crate::model::LogEntry, 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 {
|
||||||
@@ -725,6 +753,18 @@ impl SseDecode for crate::model::LNInvoice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseDecode for crate::model::LogEntry {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
|
let mut var_line = <String>::sse_decode(deserializer);
|
||||||
|
let mut var_level = <String>::sse_decode(deserializer);
|
||||||
|
return crate::model::LogEntry {
|
||||||
|
line: var_line,
|
||||||
|
level: var_level,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseDecode for crate::model::Network {
|
impl SseDecode for crate::model::Network {
|
||||||
// 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 {
|
||||||
@@ -1208,6 +1248,22 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::LNInvoice> for crate::model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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::LogEntry {
|
||||||
|
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||||
|
[
|
||||||
|
self.line.into_into_dart().into_dart(),
|
||||||
|
self.level.into_into_dart().into_dart(),
|
||||||
|
]
|
||||||
|
.into_dart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::LogEntry {}
|
||||||
|
impl flutter_rust_bridge::IntoIntoDart<crate::model::LogEntry> for crate::model::LogEntry {
|
||||||
|
fn into_into_dart(self) -> crate::model::LogEntry {
|
||||||
|
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 {
|
||||||
@@ -1483,6 +1539,13 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::SendPaymentResponse>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseEncode for flutter_rust_bridge::for_generated::anyhow::Error {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
<String>::sse_encode(format!("{:?}", self), serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseEncode for BindingLiquidSdk {
|
impl SseEncode for BindingLiquidSdk {
|
||||||
// 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) {
|
||||||
@@ -1510,6 +1573,15 @@ impl SseEncode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseEncode
|
||||||
|
for StreamSink<crate::model::LogEntry, 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) {
|
||||||
@@ -1675,6 +1747,14 @@ impl SseEncode for crate::model::LNInvoice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseEncode for crate::model::LogEntry {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
<String>::sse_encode(self.line, serializer);
|
||||||
|
<String>::sse_encode(self.level, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseEncode for crate::model::Network {
|
impl SseEncode for crate::model::Network {
|
||||||
// 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) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ pub mod error;
|
|||||||
pub(crate) mod event;
|
pub(crate) mod event;
|
||||||
#[cfg(feature = "frb")]
|
#[cfg(feature = "frb")]
|
||||||
pub mod frb;
|
pub mod frb;
|
||||||
|
pub mod logger;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub mod persist;
|
pub mod persist;
|
||||||
pub mod sdk;
|
pub mod sdk;
|
||||||
|
|||||||
84
lib/core/src/logger.rs
Normal file
84
lib/core/src/logger.rs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
use std::fs::OpenOptions;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use chrono::Local;
|
||||||
|
use log::{LevelFilter, Metadata, Record};
|
||||||
|
|
||||||
|
use crate::model::LogEntry;
|
||||||
|
|
||||||
|
pub(crate) struct GlobalSdkLogger {
|
||||||
|
/// SDK internal logger, which logs to file
|
||||||
|
pub(crate) logger: env_logger::Logger,
|
||||||
|
/// Optional external log listener, that can receive a stream of log statements
|
||||||
|
pub(crate) log_listener: Option<Box<dyn log::Log>>,
|
||||||
|
}
|
||||||
|
impl log::Log for GlobalSdkLogger {
|
||||||
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||||
|
metadata.level() <= log::Level::Trace
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&self, record: &Record) {
|
||||||
|
if self.enabled(record.metadata()) {
|
||||||
|
self.logger.log(record);
|
||||||
|
|
||||||
|
if let Some(s) = &self.log_listener.as_ref() {
|
||||||
|
if s.enabled(record.metadata()) {
|
||||||
|
s.log(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn init_logging(log_dir: &str, app_logger: Option<Box<dyn log::Log>>) -> Result<()> {
|
||||||
|
let target_log_file = Box::new(
|
||||||
|
OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.append(true)
|
||||||
|
.open(format!("{log_dir}/sdk.log"))
|
||||||
|
.map_err(|e| anyhow!("Can't create log file: {e}"))?,
|
||||||
|
);
|
||||||
|
let logger = env_logger::Builder::new()
|
||||||
|
.target(env_logger::Target::Pipe(target_log_file))
|
||||||
|
.parse_filters(
|
||||||
|
r#"
|
||||||
|
debug,
|
||||||
|
breez_liquid_sdk=debug,
|
||||||
|
electrum_client::raw_client=warn,
|
||||||
|
lwk_wollet=info,
|
||||||
|
rustls=warn,
|
||||||
|
rustyline=warn,
|
||||||
|
tungstenite=warn
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.format(|buf, record| {
|
||||||
|
writeln!(
|
||||||
|
buf,
|
||||||
|
"[{} {} {}:{}] {}",
|
||||||
|
Local::now().format("%Y-%m-%d %H:%M:%S%.3f"),
|
||||||
|
record.level(),
|
||||||
|
record.module_path().unwrap_or("unknown"),
|
||||||
|
record.line().unwrap_or(0),
|
||||||
|
record.args()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let global_logger = GlobalSdkLogger {
|
||||||
|
logger,
|
||||||
|
log_listener: app_logger,
|
||||||
|
};
|
||||||
|
|
||||||
|
log::set_boxed_logger(Box::new(global_logger))
|
||||||
|
.map_err(|e| anyhow!("Failed to set global logger: {e}"))?;
|
||||||
|
log::set_max_level(LevelFilter::Trace);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Logger: Send + Sync {
|
||||||
|
fn log(&self, l: LogEntry);
|
||||||
|
}
|
||||||
@@ -567,6 +567,13 @@ impl Payment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Internal SDK log entry used in the Uniffi and Dart bindings
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct LogEntry {
|
||||||
|
pub line: String,
|
||||||
|
pub level: String,
|
||||||
|
}
|
||||||
|
|
||||||
/// Wrapper for a BOLT11 LN invoice
|
/// Wrapper for a BOLT11 LN invoice
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct LNInvoice {
|
pub struct LNInvoice {
|
||||||
|
|||||||
@@ -1501,6 +1501,33 @@ impl LiquidSdk {
|
|||||||
};
|
};
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configures a global SDK logger that will log to file and will forward log events to
|
||||||
|
/// an optional application-specific logger.
|
||||||
|
///
|
||||||
|
/// If called, it should be called before any SDK methods (for example, before `connect`).
|
||||||
|
///
|
||||||
|
/// It must be called only once in the application lifecycle. Alternatively, If the application
|
||||||
|
/// already uses a globally-registered logger, this method shouldn't be called at all.
|
||||||
|
///
|
||||||
|
/// ### Arguments
|
||||||
|
///
|
||||||
|
/// - `log_dir`: Location where the the SDK log file will be created. The directory must already exist.
|
||||||
|
///
|
||||||
|
/// - `app_logger`: Optional application logger.
|
||||||
|
///
|
||||||
|
/// If the application is to use it's own logger, but would also like the SDK to log SDK-specific
|
||||||
|
/// log output to a file in the configured `log_dir`, then do not register the
|
||||||
|
/// app-specific logger as a global logger and instead call this method with the app logger as an arg.
|
||||||
|
///
|
||||||
|
/// ### Errors
|
||||||
|
///
|
||||||
|
/// An error is thrown if the log file cannot be created in the working directory.
|
||||||
|
///
|
||||||
|
/// An error is thrown if a global logger is already configured.
|
||||||
|
pub fn init_logging(log_dir: &str, app_logger: Option<Box<dyn log::Log>>) -> Result<()> {
|
||||||
|
crate::logger::init_logging(log_dir, app_logger)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -9,10 +9,15 @@ 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.
|
// The type `BindingEventListener` is not used by any `pub` functions, thus it is ignored.
|
||||||
|
// The type `DartBindingLogger` 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);
|
||||||
|
|
||||||
|
/// If used, this must be called before `connect`. It can only be called once.
|
||||||
|
Stream<LogEntry> breezLogStream({dynamic hint}) =>
|
||||||
|
RustLib.instance.api.crateBindingsBreezLogStream(hint: hint);
|
||||||
|
|
||||||
Future<LNInvoice> parseInvoice({required String input, dynamic hint}) =>
|
Future<LNInvoice> parseInvoice({required String input, dynamic hint}) =>
|
||||||
RustLib.instance.api.crateBindingsParseInvoice(input: input, hint: hint);
|
RustLib.instance.api.crateBindingsParseInvoice(input: input, hint: hint);
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||||||
String get codegenVersion => '2.0.0-dev.36';
|
String get codegenVersion => '2.0.0-dev.36';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get rustContentHash => 84136112;
|
int get rustContentHash => -532134055;
|
||||||
|
|
||||||
static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig(
|
static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig(
|
||||||
stem: 'breez_liquid_sdk',
|
stem: 'breez_liquid_sdk',
|
||||||
@@ -96,6 +96,8 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
|
|
||||||
Future<void> crateBindingsBindingLiquidSdkSync({required BindingLiquidSdk that, dynamic hint});
|
Future<void> crateBindingsBindingLiquidSdkSync({required BindingLiquidSdk that, dynamic hint});
|
||||||
|
|
||||||
|
Stream<LogEntry> crateBindingsBreezLogStream({dynamic hint});
|
||||||
|
|
||||||
Future<BindingLiquidSdk> crateBindingsConnect({required ConnectRequest req, dynamic hint});
|
Future<BindingLiquidSdk> crateBindingsConnect({required ConnectRequest req, dynamic hint});
|
||||||
|
|
||||||
Future<LNInvoice> crateBindingsParseInvoice({required String input, dynamic hint});
|
Future<LNInvoice> crateBindingsParseInvoice({required String input, dynamic hint});
|
||||||
@@ -434,6 +436,31 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
argNames: ["that"],
|
argNames: ["that"],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<LogEntry> crateBindingsBreezLogStream({dynamic hint}) {
|
||||||
|
final s = RustStreamSink<LogEntry>();
|
||||||
|
unawaited(handler.executeNormal(NormalTask(
|
||||||
|
callFfi: (port_) {
|
||||||
|
var arg0 = cst_encode_StreamSink_log_entry_Dco(s);
|
||||||
|
return wire.wire__crate__bindings__breez_log_stream(port_, arg0);
|
||||||
|
},
|
||||||
|
codec: DcoCodec(
|
||||||
|
decodeSuccessData: dco_decode_unit,
|
||||||
|
decodeErrorData: dco_decode_AnyhowException,
|
||||||
|
),
|
||||||
|
constMeta: kCrateBindingsBreezLogStreamConstMeta,
|
||||||
|
argValues: [s],
|
||||||
|
apiImpl: this,
|
||||||
|
hint: hint,
|
||||||
|
)));
|
||||||
|
return s.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskConstMeta get kCrateBindingsBreezLogStreamConstMeta => const TaskConstMeta(
|
||||||
|
debugName: "breez_log_stream",
|
||||||
|
argNames: ["s"],
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<BindingLiquidSdk> crateBindingsConnect({required ConnectRequest req, dynamic hint}) {
|
Future<BindingLiquidSdk> crateBindingsConnect({required ConnectRequest req, dynamic hint}) {
|
||||||
return handler.executeNormal(NormalTask(
|
return handler.executeNormal(NormalTask(
|
||||||
@@ -487,6 +514,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
RustArcDecrementStrongCountFnType get rust_arc_decrement_strong_count_BindingLiquidSdk => wire
|
RustArcDecrementStrongCountFnType get rust_arc_decrement_strong_count_BindingLiquidSdk => wire
|
||||||
.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk;
|
.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk;
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AnyhowException dco_decode_AnyhowException(dynamic raw) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
return AnyhowException(raw as String);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
BindingLiquidSdk
|
BindingLiquidSdk
|
||||||
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
@@ -516,6 +549,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LogEntry> dco_decode_StreamSink_log_entry_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
|
||||||
@@ -736,6 +775,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LogEntry dco_decode_log_entry(dynamic raw) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
final arr = raw as List<dynamic>;
|
||||||
|
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
|
||||||
|
return LogEntry(
|
||||||
|
line: dco_decode_String(arr[0]),
|
||||||
|
level: dco_decode_String(arr[1]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
Network dco_decode_network(dynamic raw) {
|
Network dco_decode_network(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@@ -962,6 +1012,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return dcoDecodeU64(raw);
|
return dcoDecodeU64(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
var inner = sse_decode_String(deserializer);
|
||||||
|
return AnyhowException(inner);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
BindingLiquidSdk
|
BindingLiquidSdk
|
||||||
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
@@ -991,6 +1048,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
throw UnimplementedError('Unreachable ()');
|
throw UnimplementedError('Unreachable ()');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LogEntry> sse_decode_StreamSink_log_entry_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
|
||||||
@@ -1229,6 +1292,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
minFinalCltvExpiryDelta: var_minFinalCltvExpiryDelta);
|
minFinalCltvExpiryDelta: var_minFinalCltvExpiryDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LogEntry sse_decode_log_entry(SseDeserializer deserializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
var var_line = sse_decode_String(deserializer);
|
||||||
|
var var_level = sse_decode_String(deserializer);
|
||||||
|
return LogEntry(line: var_line, level: var_level);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
Network sse_decode_network(SseDeserializer deserializer) {
|
Network sse_decode_network(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -1523,6 +1594,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_AnyhowException(AnyhowException self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
sse_encode_String(self.message, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
BindingLiquidSdk self, SseSerializer serializer) {
|
BindingLiquidSdk self, SseSerializer serializer) {
|
||||||
@@ -1554,6 +1631,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
serializer);
|
serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_StreamSink_log_entry_Dco(RustStreamSink<LogEntry> self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
sse_encode_String(
|
||||||
|
self.setupAndSerialize(
|
||||||
|
codec: DcoCodec(decodeSuccessData: dco_decode_log_entry, 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
|
||||||
@@ -1754,6 +1840,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_u_64(self.minFinalCltvExpiryDelta, serializer);
|
sse_encode_u_64(self.minFinalCltvExpiryDelta, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_log_entry(LogEntry self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
sse_encode_String(self.line, serializer);
|
||||||
|
sse_encode_String(self.level, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_network(Network self, SseSerializer serializer) {
|
void sse_encode_network(Network self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_BindingLiquidSdkPtr => wire
|
CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_BindingLiquidSdkPtr => wire
|
||||||
._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdkPtr;
|
._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdkPtr;
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AnyhowException dco_decode_AnyhowException(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
BindingLiquidSdk
|
BindingLiquidSdk
|
||||||
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
@@ -40,6 +43,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
RustStreamSink<LiquidSdkEvent> dco_decode_StreamSink_liquid_sdk_event_Dco(dynamic raw);
|
RustStreamSink<LiquidSdkEvent> dco_decode_StreamSink_liquid_sdk_event_Dco(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LogEntry> dco_decode_StreamSink_log_entry_Dco(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
String dco_decode_String(dynamic raw);
|
String dco_decode_String(dynamic raw);
|
||||||
|
|
||||||
@@ -112,6 +118,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
LNInvoice dco_decode_ln_invoice(dynamic raw);
|
LNInvoice dco_decode_ln_invoice(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LogEntry dco_decode_log_entry(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
Network dco_decode_network(dynamic raw);
|
Network dco_decode_network(dynamic raw);
|
||||||
|
|
||||||
@@ -175,6 +184,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
BigInt dco_decode_usize(dynamic raw);
|
BigInt dco_decode_usize(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
BindingLiquidSdk
|
BindingLiquidSdk
|
||||||
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
@@ -192,6 +204,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
RustStreamSink<LiquidSdkEvent> sse_decode_StreamSink_liquid_sdk_event_Dco(SseDeserializer deserializer);
|
RustStreamSink<LiquidSdkEvent> sse_decode_StreamSink_liquid_sdk_event_Dco(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
RustStreamSink<LogEntry> sse_decode_StreamSink_log_entry_Dco(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
String sse_decode_String(SseDeserializer deserializer);
|
String sse_decode_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -264,6 +279,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
LNInvoice sse_decode_ln_invoice(SseDeserializer deserializer);
|
LNInvoice sse_decode_ln_invoice(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
LogEntry sse_decode_log_entry(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
Network sse_decode_network(SseDeserializer deserializer);
|
Network sse_decode_network(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -327,6 +345,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
BigInt sse_decode_usize(SseDeserializer deserializer);
|
BigInt sse_decode_usize(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_AnyhowException(AnyhowException raw) {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_StreamSink_liquid_sdk_event_Dco(
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_StreamSink_liquid_sdk_event_Dco(
|
||||||
RustStreamSink<LiquidSdkEvent> raw) {
|
RustStreamSink<LiquidSdkEvent> raw) {
|
||||||
@@ -335,6 +359,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
codec: DcoCodec(decodeSuccessData: dco_decode_liquid_sdk_event, decodeErrorData: null)));
|
codec: DcoCodec(decodeSuccessData: dco_decode_liquid_sdk_event, decodeErrorData: null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_StreamSink_log_entry_Dco(
|
||||||
|
RustStreamSink<LogEntry> raw) {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
return cst_encode_String(raw.setupAndSerialize(
|
||||||
|
codec: DcoCodec(decodeSuccessData: dco_decode_log_entry, 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
|
||||||
@@ -641,6 +673,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
wireObj.min_final_cltv_expiry_delta = cst_encode_u_64(apiObj.minFinalCltvExpiryDelta);
|
wireObj.min_final_cltv_expiry_delta = cst_encode_u_64(apiObj.minFinalCltvExpiryDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void cst_api_fill_to_wire_log_entry(LogEntry apiObj, wire_cst_log_entry wireObj) {
|
||||||
|
wireObj.line = cst_encode_String(apiObj.line);
|
||||||
|
wireObj.level = cst_encode_String(apiObj.level);
|
||||||
|
}
|
||||||
|
|
||||||
@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);
|
||||||
@@ -823,6 +861,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void cst_encode_unit(void raw);
|
void cst_encode_unit(void raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_AnyhowException(AnyhowException self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
|
||||||
BindingLiquidSdk self, SseSerializer serializer);
|
BindingLiquidSdk self, SseSerializer serializer);
|
||||||
@@ -839,6 +880,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
void sse_encode_StreamSink_liquid_sdk_event_Dco(
|
void sse_encode_StreamSink_liquid_sdk_event_Dco(
|
||||||
RustStreamSink<LiquidSdkEvent> self, SseSerializer serializer);
|
RustStreamSink<LiquidSdkEvent> self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_StreamSink_log_entry_Dco(RustStreamSink<LogEntry> self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_String(String self, SseSerializer serializer);
|
void sse_encode_String(String self, SseSerializer serializer);
|
||||||
|
|
||||||
@@ -911,6 +955,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_ln_invoice(LNInvoice self, SseSerializer serializer);
|
void sse_encode_ln_invoice(LNInvoice self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_log_entry(LogEntry self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_network(Network self, SseSerializer serializer);
|
void sse_encode_network(Network self, SseSerializer serializer);
|
||||||
|
|
||||||
@@ -1229,6 +1276,22 @@ class RustLibWire implements BaseWire {
|
|||||||
late final _wire__crate__bindings__BindingLiquidSdk_sync =
|
late final _wire__crate__bindings__BindingLiquidSdk_sync =
|
||||||
_wire__crate__bindings__BindingLiquidSdk_syncPtr.asFunction<void Function(int, int)>();
|
_wire__crate__bindings__BindingLiquidSdk_syncPtr.asFunction<void Function(int, int)>();
|
||||||
|
|
||||||
|
void wire__crate__bindings__breez_log_stream(
|
||||||
|
int port_,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> s,
|
||||||
|
) {
|
||||||
|
return _wire__crate__bindings__breez_log_stream(
|
||||||
|
port_,
|
||||||
|
s,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _wire__crate__bindings__breez_log_streamPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||||
|
'frbgen_breez_liquid_wire__crate__bindings__breez_log_stream');
|
||||||
|
late final _wire__crate__bindings__breez_log_stream = _wire__crate__bindings__breez_log_streamPtr
|
||||||
|
.asFunction<void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||||
|
|
||||||
void wire__crate__bindings__connect(
|
void wire__crate__bindings__connect(
|
||||||
int port_,
|
int port_,
|
||||||
ffi.Pointer<wire_cst_connect_request> req,
|
ffi.Pointer<wire_cst_connect_request> req,
|
||||||
@@ -1697,6 +1760,12 @@ final class wire_cst_ln_invoice extends ffi.Struct {
|
|||||||
external int min_final_cltv_expiry_delta;
|
external int min_final_cltv_expiry_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class wire_cst_log_entry extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> line;
|
||||||
|
|
||||||
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> level;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,6 +190,25 @@ class LNInvoice {
|
|||||||
minFinalCltvExpiryDelta == other.minFinalCltvExpiryDelta;
|
minFinalCltvExpiryDelta == other.minFinalCltvExpiryDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Internal SDK log entry used in the Uniffi and Dart bindings
|
||||||
|
class LogEntry {
|
||||||
|
final String line;
|
||||||
|
final String level;
|
||||||
|
|
||||||
|
const LogEntry({
|
||||||
|
required this.line,
|
||||||
|
required this.level,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => line.hashCode ^ level.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is LogEntry && runtimeType == other.runtimeType && line == other.line && level == other.level;
|
||||||
|
}
|
||||||
|
|
||||||
enum Network {
|
enum Network {
|
||||||
/// Mainnet Bitcoin and Liquid chains
|
/// Mainnet Bitcoin and Liquid chains
|
||||||
mainnet,
|
mainnet,
|
||||||
|
|||||||
@@ -260,6 +260,23 @@ class FlutterBreezLiquidBindings {
|
|||||||
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_syncPtr
|
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_syncPtr
|
||||||
.asFunction<void Function(int, int)>();
|
.asFunction<void Function(int, int)>();
|
||||||
|
|
||||||
|
void frbgen_breez_liquid_wire__crate__bindings__breez_log_stream(
|
||||||
|
int port_,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> s,
|
||||||
|
) {
|
||||||
|
return _frbgen_breez_liquid_wire__crate__bindings__breez_log_stream(
|
||||||
|
port_,
|
||||||
|
s,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _frbgen_breez_liquid_wire__crate__bindings__breez_log_streamPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||||
|
'frbgen_breez_liquid_wire__crate__bindings__breez_log_stream');
|
||||||
|
late final _frbgen_breez_liquid_wire__crate__bindings__breez_log_stream =
|
||||||
|
_frbgen_breez_liquid_wire__crate__bindings__breez_log_streamPtr
|
||||||
|
.asFunction<void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||||
|
|
||||||
void frbgen_breez_liquid_wire__crate__bindings__connect(
|
void frbgen_breez_liquid_wire__crate__bindings__connect(
|
||||||
int port_,
|
int port_,
|
||||||
ffi.Pointer<wire_cst_connect_request> req,
|
ffi.Pointer<wire_cst_connect_request> req,
|
||||||
@@ -755,6 +772,12 @@ final class wire_cst_ln_invoice extends ffi.Struct {
|
|||||||
external int min_final_cltv_expiry_delta;
|
external int min_final_cltv_expiry_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class wire_cst_log_entry extends ffi.Struct {
|
||||||
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> line;
|
||||||
|
|
||||||
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> level;
|
||||||
|
}
|
||||||
|
|
||||||
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,15 @@
|
|||||||
|
package com.breezliquidsdk
|
||||||
|
|
||||||
|
import breez_liquid_sdk.LogEntry
|
||||||
|
import breez_liquid_sdk.Logger
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
||||||
|
|
||||||
|
class BreezLiquidSDKLogger(private val emitter: RCTDeviceEventEmitter) : Logger {
|
||||||
|
companion object {
|
||||||
|
var emitterName = "breezLiquidSdkLog"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun log(l: LogEntry) {
|
||||||
|
emitter.emit(emitterName, readableMapOf(l))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -226,6 +226,43 @@ fun asLnInvoiceList(arr: ReadableArray): List<LnInvoice> {
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun asLogEntry(logEntry: ReadableMap): LogEntry? {
|
||||||
|
if (!validateMandatoryFields(
|
||||||
|
logEntry,
|
||||||
|
arrayOf(
|
||||||
|
"line",
|
||||||
|
"level",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val line = logEntry.getString("line")!!
|
||||||
|
val level = logEntry.getString("level")!!
|
||||||
|
return LogEntry(
|
||||||
|
line,
|
||||||
|
level,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readableMapOf(logEntry: LogEntry): ReadableMap {
|
||||||
|
return readableMapOf(
|
||||||
|
"line" to logEntry.line,
|
||||||
|
"level" to logEntry.level,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun asLogEntryList(arr: ReadableArray): List<LogEntry> {
|
||||||
|
val list = ArrayList<LogEntry>()
|
||||||
|
for (value in arr.toArrayList()) {
|
||||||
|
when (value) {
|
||||||
|
is ReadableMap -> list.add(asLogEntry(value)!!)
|
||||||
|
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
fun asPayment(payment: ReadableMap): Payment? {
|
fun asPayment(payment: ReadableMap): Payment? {
|
||||||
if (!validateMandatoryFields(
|
if (!validateMandatoryFields(
|
||||||
payment,
|
payment,
|
||||||
|
|||||||
@@ -55,6 +55,21 @@ class BreezLiquidSDKModule(reactContext: ReactApplicationContext) : ReactContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun setLogger(promise: Promise) {
|
||||||
|
executor.execute {
|
||||||
|
try {
|
||||||
|
val emitter = reactApplicationContext.getJSModule(RCTDeviceEventEmitter::class.java)
|
||||||
|
|
||||||
|
setLogger(BreezLiquidSDKLogger(emitter))
|
||||||
|
promise.resolve(readableMapOf("status" to "ok"))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
fun connect(
|
fun connect(
|
||||||
req: ReadableMap,
|
req: ReadableMap,
|
||||||
|
|||||||
13
packages/react-native/ios/BreezLiquidSDKLogStream.swift
Normal file
13
packages/react-native/ios/BreezLiquidSDKLogStream.swift
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import Foundation
|
||||||
|
import BreezLiquidSDK
|
||||||
|
|
||||||
|
class BreezLiquidSDKLogger: Logger {
|
||||||
|
static let emitterName: String = "breezLiquidSdkLog"
|
||||||
|
|
||||||
|
func log(l: LogEntry) {
|
||||||
|
if RNBreezLiquidSDK.hasListeners {
|
||||||
|
RNBreezLiquidSDK.emitter.sendEvent(withName: BreezLiquidSDKLogger.emitterName,
|
||||||
|
body: BreezLiquidSDKMapper.dictionaryOf(logEntry: l))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -271,6 +271,44 @@ enum BreezLiquidSDKMapper {
|
|||||||
return lnInvoiceList.map { v -> [String: Any?] in dictionaryOf(lnInvoice: v) }
|
return lnInvoiceList.map { v -> [String: Any?] in dictionaryOf(lnInvoice: v) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func asLogEntry(logEntry: [String: Any?]) throws -> LogEntry {
|
||||||
|
guard let line = logEntry["line"] as? String else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "line", typeName: "LogEntry"))
|
||||||
|
}
|
||||||
|
guard let level = logEntry["level"] as? String else {
|
||||||
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "level", typeName: "LogEntry"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return LogEntry(
|
||||||
|
line: line,
|
||||||
|
level: level
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func dictionaryOf(logEntry: LogEntry) -> [String: Any?] {
|
||||||
|
return [
|
||||||
|
"line": logEntry.line,
|
||||||
|
"level": logEntry.level,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
static func asLogEntryList(arr: [Any]) throws -> [LogEntry] {
|
||||||
|
var list = [LogEntry]()
|
||||||
|
for value in arr {
|
||||||
|
if let val = value as? [String: Any?] {
|
||||||
|
var logEntry = try asLogEntry(logEntry: val)
|
||||||
|
list.append(logEntry)
|
||||||
|
} else {
|
||||||
|
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "LogEntry"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
static func arrayOf(logEntryList: [LogEntry]) -> [Any] {
|
||||||
|
return logEntryList.map { v -> [String: Any?] in dictionaryOf(logEntry: v) }
|
||||||
|
}
|
||||||
|
|
||||||
static func asPayment(payment: [String: Any?]) throws -> Payment {
|
static func asPayment(payment: [String: Any?]) throws -> Payment {
|
||||||
guard let txId = payment["txId"] as? String else {
|
guard let txId = payment["txId"] as? String else {
|
||||||
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "txId", typeName: "Payment"))
|
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "txId", typeName: "Payment"))
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ RCT_EXTERN_METHOD(
|
|||||||
reject: (RCTPromiseRejectBlock)reject
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
)
|
)
|
||||||
|
|
||||||
|
RCT_EXTERN_METHOD(
|
||||||
|
setLogger: (RCTPromiseResolveBlock)resolve
|
||||||
|
reject: (RCTPromiseRejectBlock)reject
|
||||||
|
)
|
||||||
|
|
||||||
RCT_EXTERN_METHOD(
|
RCT_EXTERN_METHOD(
|
||||||
connect: (NSDictionary*)req
|
connect: (NSDictionary*)req
|
||||||
resolve: (RCTPromiseResolveBlock)resolve
|
resolve: (RCTPromiseResolveBlock)resolve
|
||||||
|
|||||||
@@ -7,7 +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] = []
|
public static var supportedEvents: [String] = ["breezLiquidSdkLog"]
|
||||||
|
|
||||||
private var bindingLiquidSdk: BindingLiquidSdk!
|
private var bindingLiquidSdk: BindingLiquidSdk!
|
||||||
|
|
||||||
@@ -66,6 +66,16 @@ class RNBreezLiquidSDK: RCTEventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc(setLogger:reject:)
|
||||||
|
func setLogger(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
|
do {
|
||||||
|
try BreezLiquidSDK.setLogger(Logger: BreezLiquidSDKLogger())
|
||||||
|
resolve(["status": "ok"])
|
||||||
|
} catch let err {
|
||||||
|
rejectErr(err: err, reject: reject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc(connect:resolve:reject:)
|
@objc(connect:resolve:reject:)
|
||||||
func connect(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
func connect(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
if bindingLiquidSdk != nil {
|
if bindingLiquidSdk != nil {
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ export interface LnInvoice {
|
|||||||
minFinalCltvExpiryDelta: number
|
minFinalCltvExpiryDelta: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LogEntry {
|
||||||
|
line: string
|
||||||
|
level: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface Payment {
|
export interface Payment {
|
||||||
txId: string
|
txId: string
|
||||||
swapId?: string
|
swapId?: string
|
||||||
@@ -165,6 +170,8 @@ export enum PaymentType {
|
|||||||
|
|
||||||
export type EventListener = (e: LiquidSdkEvent) => void
|
export type EventListener = (e: LiquidSdkEvent) => void
|
||||||
|
|
||||||
|
export type Logger = (logEntry: LogEntry) => 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
|
||||||
@@ -176,6 +183,16 @@ export const addEventListener = async (listener: EventListener): Promise<string>
|
|||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const setLogger = async (logger: Logger): Promise<EmitterSubscription> => {
|
||||||
|
const subscription = BreezLiquidSDKEmitter.addListener("breezLiquidSdkLog", logger)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await BreezLiquidSDK.setLogger()
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
return subscription
|
||||||
|
}
|
||||||
export const parseInvoice = async (invoice: string): Promise<LnInvoice> => {
|
export const parseInvoice = async (invoice: string): Promise<LnInvoice> => {
|
||||||
const response = await BreezLiquidSDK.parseInvoice(invoice)
|
const response = await BreezLiquidSDK.parseInvoice(invoice)
|
||||||
return response
|
return response
|
||||||
|
|||||||
Reference in New Issue
Block a user