WASM: Interface (#757)

* Define common types

* Define sdk types

* Add SDK methods

* Add LiquidSdkBuilder

* Add callback interfaces

* Update CI for WASM

* Replace async and test macros

* Update sdk-common/macros dependencies
This commit is contained in:
Ross Savage
2025-03-11 06:21:46 +01:00
committed by GitHub
parent 15968b0ead
commit 6d72fdce57
44 changed files with 2337 additions and 598 deletions

View File

@@ -34,6 +34,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install WASM target
run: rustup target add wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
workspaces: |
@@ -46,12 +49,21 @@ jobs:
version: "27.2"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check Rust Clippy
run: |
cd lib
cargo clippy -- -D warnings
cd ../cli
cargo clippy -- -D warnings
- name: Clippy bindings
working-directory: lib/bindings
run: cargo clippy -- -D warnings
- name: Clippy core
working-directory: lib/core
run: cargo clippy -- -D warnings
- name: Clippy WASM
working-directory: lib/wasm
run: cargo clippy --target=wasm32-unknown-unknown -- -D warnings
- name: Clippy cli
working-directory: cli
run: cargo clippy -- -D warnings
build:
name: Cargo Build
@@ -59,6 +71,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install WASM target
run: rustup target add wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
workspaces: |
@@ -71,8 +86,17 @@ jobs:
version: "27.2"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- run: cargo build
working-directory: lib
- name: Cargo build bindings
working-directory: lib/bindings
run: cargo build
- name: Cargo build core
working-directory: lib/core
run: cargo build
- name: Cargo build WASM
working-directory: lib/wasm
run: cargo build --target=wasm32-unknown-unknown
- name: Check git status
env:
@@ -171,6 +195,34 @@ jobs:
cd lib/bindings
cargo test
build-wasm:
name: Test WASM
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install WASM target
run: rustup target add wasm32-unknown-unknown
- name: Install wasm-pack
run: cargo install wasm-pack
- uses: Swatinem/rust-cache@v2
with:
workspaces: |
lib -> target
cli -> target
- name: Install Protoc
uses: arduino/setup-protoc@v3
with:
version: "27.2"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Test WASM
working-directory: lib/wasm
run: wasm-pack test --headless --firefox
notification-plugin:
name: Check notification plugin
runs-on: macOS-14

View File

@@ -4,13 +4,26 @@ fmt:
cd lib && cargo fmt
cd cli && cargo fmt
clippy:
cd lib && cargo clippy -- -D warnings
cd lib && cargo clippy --tests -- -D warnings
clippy: cargo-clippy wasm-clippy
cargo-clippy:
cd lib/bindings && cargo clippy -- -D warnings
cd lib/bindings && cargo clippy --tests -- -D warnings
cd lib/core && cargo clippy -- -D warnings
cd lib/core && cargo clippy --tests -- -D warnings
cd cli && cargo clippy -- -D warnings
test:
cd lib && cargo test
wasm-clippy:
make -C ./lib/wasm clippy
test: cargo-test wasm-test
cargo-test:
cd lib/bindings && cargo test
cd lib/core && cargo test
wasm-test:
make -C ./lib/wasm test
codegen: flutter-codegen react-native-codegen

325
cli/Cargo.lock generated
View File

@@ -33,7 +33,7 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cipher",
"cpufeatures",
]
@@ -441,7 +441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
"cfg-if",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object",
@@ -721,6 +721,7 @@ dependencies = [
"bip39",
"boltz-client",
"chrono",
"console_log",
"derivative",
"ecies",
"electrum-client",
@@ -734,11 +735,13 @@ dependencies = [
"lwk_common",
"lwk_signer",
"lwk_wollet",
"maybe-sync",
"prost 0.13.5",
"reqwest 0.12.12",
"reqwest 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rusqlite",
"rusqlite_migration",
"sdk-common",
"sdk-macros",
"security-framework",
"security-framework-sys",
"semver",
@@ -807,6 +810,12 @@ dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
@@ -825,7 +834,7 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cipher",
"cpufeatures",
]
@@ -917,6 +926,15 @@ dependencies = [
"error-code",
]
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
@@ -929,10 +947,20 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"wasm-bindgen",
]
[[package]]
name = "console_log"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
dependencies = [
"log",
"web-sys",
]
[[package]]
name = "cookie-factory"
version = "0.3.3"
@@ -973,7 +1001,7 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
]
[[package]]
@@ -1020,7 +1048,7 @@ version = "4.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"curve25519-dalek-derive",
"fiat-crypto",
@@ -1055,7 +1083,7 @@ version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"num_cpus",
]
@@ -1065,12 +1093,12 @@ version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"crossbeam-utils",
"hashbrown 0.14.5",
"lock_api",
"lock_api 0.4.12",
"once_cell",
"parking_lot_core",
"parking_lot_core 0.9.10",
]
[[package]]
@@ -1155,6 +1183,16 @@ dependencies = [
"syn 2.0.99",
]
[[package]]
name = "dns-parser"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea"
dependencies = [
"byteorder",
"quick-error",
]
[[package]]
name = "ecies"
version = "0.2.7"
@@ -1166,7 +1204,7 @@ dependencies = [
"hkdf",
"libsecp256k1",
"once_cell",
"parking_lot",
"parking_lot 0.12.3",
"rand_core",
"sha2",
"typenum",
@@ -1227,7 +1265,7 @@ version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
]
[[package]]
@@ -1340,7 +1378,7 @@ version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"rustix",
"windows-sys 0.52.0",
]
@@ -1625,7 +1663,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
@@ -1638,7 +1676,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets 0.52.6",
@@ -1666,19 +1704,6 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "gloo-utils"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa"
dependencies = [
"js-sys",
"serde",
"serde_json",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "h2"
version = "0.3.26"
@@ -1808,7 +1833,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248"
dependencies = [
"async-trait",
"cfg-if",
"cfg-if 1.0.0",
"data-encoding",
"enum-as-inner",
"futures-channel",
@@ -1832,13 +1857,13 @@ version = "0.24.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"futures-util",
"hickory-proto",
"ipconfig",
"lru-cache",
"once_cell",
"parking_lot",
"parking_lot 0.12.3",
"rand",
"resolv-conf",
"smallvec",
@@ -2056,19 +2081,6 @@ dependencies = [
"tower-service",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper 0.14.32",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
@@ -2131,7 +2143,7 @@ dependencies = [
"i18n-embed-impl",
"intl-memoizer",
"log",
"parking_lot",
"parking_lot 0.12.3",
"rust-embed",
"thiserror 1.0.69",
"unic-langid",
@@ -2600,6 +2612,15 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
[[package]]
name = "lock_api"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
dependencies = [
"scopeguard",
]
[[package]]
name = "lock_api"
version = "0.4.12"
@@ -2674,7 +2695,7 @@ dependencies = [
"once_cell",
"rand",
"regex-lite",
"reqwest 0.12.12",
"reqwest 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde",
"serde_json",
"thiserror 1.0.69",
@@ -2696,13 +2717,22 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "maybe-sync"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7551d6fcc47ecf769e6c8b2e5dd7f56f90361d3d1360e3a280c8d0d7c8e680b7"
dependencies = [
"parking_lot 0.10.2",
]
[[package]]
name = "md-5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"digest 0.10.7",
]
@@ -2810,7 +2840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
dependencies = [
"bitflags 2.9.0",
"cfg-if",
"cfg-if 1.0.0",
"libc",
]
@@ -2909,7 +2939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd"
dependencies = [
"bitflags 2.9.0",
"cfg-if",
"cfg-if 1.0.0",
"foreign-types",
"libc",
"once_cell",
@@ -2967,14 +2997,38 @@ dependencies = [
"log",
]
[[package]]
name = "parking_lot"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
dependencies = [
"lock_api 0.3.4",
"parking_lot_core 0.7.3",
]
[[package]]
name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
"lock_api 0.4.12",
"parking_lot_core 0.9.10",
]
[[package]]
name = "parking_lot_core"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b93f386bb233083c799e6e642a9d73db98c24a5deeb95ffc85bf281255dffc98"
dependencies = [
"cfg-if 0.1.10",
"cloudabi",
"libc",
"redox_syscall 0.1.57",
"smallvec",
"winapi",
]
[[package]]
@@ -2983,9 +3037,9 @@ version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"redox_syscall",
"redox_syscall 0.5.10",
"smallvec",
"windows-targets 0.52.6",
]
@@ -3087,7 +3141,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"opaque-debug",
"universal-hash",
@@ -3399,6 +3453,12 @@ dependencies = [
"getrandom 0.2.14",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_syscall"
version = "0.5.10"
@@ -3443,43 +3503,6 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.11.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
dependencies = [
"base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.32",
"hyper-tls 0.5.0",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
[[package]]
name = "reqwest"
version = "0.12.12"
@@ -3498,7 +3521,7 @@ dependencies = [
"http-body-util",
"hyper 1.6.0",
"hyper-rustls",
"hyper-tls 0.6.0",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
@@ -3530,6 +3553,49 @@ dependencies = [
"windows-registry",
]
[[package]]
name = "reqwest"
version = "0.12.12"
source = "git+https://github.com/seanmonstar/reqwest?rev=1e7e9653e5b7ee3175131052c097a8d9a07ecbcd#1e7e9653e5b7ee3175131052c097a8d9a07ecbcd"
dependencies = [
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.4.8",
"http 1.2.0",
"http-body 1.0.1",
"http-body-util",
"hyper 1.6.0",
"hyper-rustls",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile 2.2.0",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 1.0.2",
"system-configuration",
"tokio",
"tokio-native-tls",
"tower 0.5.2",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-registry",
]
[[package]]
name = "resolv-conf"
version = "0.7.0"
@@ -3562,7 +3628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73"
dependencies = [
"cc",
"cfg-if",
"cfg-if 1.0.0",
"getrandom 0.2.14",
"libc",
"untrusted 0.9.0",
@@ -3765,7 +3831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86"
dependencies = [
"bitflags 2.9.0",
"cfg-if",
"cfg-if 1.0.0",
"clipboard-win",
"fd-lock",
"home",
@@ -3855,7 +3921,7 @@ dependencies = [
[[package]]
name = "sdk-common"
version = "0.6.2"
source = "git+https://github.com/breez/breez-sdk?rev=19ed955c6fa854ad6cd2beb2eca9127d8099c506#19ed955c6fa854ad6cd2beb2eca9127d8099c506"
source = "git+https://github.com/breez/breez-sdk?rev=0017f7d3f76a1f0094ad9ff25422b72c31acc60e#0017f7d3f76a1f0094ad9ff25422b72c31acc60e"
dependencies = [
"aes",
"anyhow",
@@ -3864,6 +3930,7 @@ dependencies = [
"bip21",
"bitcoin 0.29.2",
"cbc",
"dns-parser",
"elements",
"getrandom 0.2.14",
"hex",
@@ -3878,7 +3945,8 @@ dependencies = [
"prost 0.13.5",
"querystring",
"regex",
"reqwest 0.11.20",
"reqwest 0.12.12 (git+https://github.com/seanmonstar/reqwest?rev=1e7e9653e5b7ee3175131052c097a8d9a07ecbcd)",
"sdk-macros",
"serde",
"serde_json",
"strum_macros",
@@ -3889,12 +3957,21 @@ dependencies = [
"tonic-build 0.12.3",
"tonic-build 0.8.4",
"tonic-web-wasm-client",
"tsify-next",
"url",
"urlencoding",
"wasm-bindgen",
]
[[package]]
name = "sdk-macros"
version = "0.6.2"
source = "git+https://github.com/breez/breez-sdk?rev=0017f7d3f76a1f0094ad9ff25422b72c31acc60e#0017f7d3f76a1f0094ad9ff25422b72c31acc60e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.99",
]
[[package]]
name = "secp256k1"
version = "0.24.3"
@@ -4029,17 +4106,6 @@ dependencies = [
"syn 2.0.99",
]
[[package]]
name = "serde_derive_internals"
version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.99",
]
[[package]]
name = "serde_json"
version = "1.0.140"
@@ -4070,7 +4136,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"digest 0.10.7",
]
@@ -4081,7 +4147,7 @@ version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"digest 0.10.7",
]
@@ -4132,7 +4198,7 @@ dependencies = [
"fragile",
"js-sys",
"once_cell",
"parking_lot",
"parking_lot 0.12.3",
"thiserror 2.0.12",
"tokio",
"wasm-bindgen",
@@ -4253,7 +4319,7 @@ version = "3.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"fastrand",
"getrandom 0.3.1",
"once_cell",
@@ -4706,31 +4772,6 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "tsify-next"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8bf7232b89b86f63b5f0ef22c64960f9cf4fb52c6698f1e7f60de93bc3292f"
dependencies = [
"gloo-utils",
"serde",
"serde_json",
"tsify-next-macros",
"wasm-bindgen",
]
[[package]]
name = "tsify-next-macros"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2d85ebe93eedca20d3fe6d65814c856467a649674aa7763ebd42e3bb815fec"
dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.99",
]
[[package]]
name = "tungstenite"
version = "0.21.0"
@@ -4901,6 +4942,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
dependencies = [
"getrandom 0.3.1",
"js-sys",
"wasm-bindgen",
]
[[package]]
@@ -4955,7 +4998,7 @@ version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
@@ -4981,7 +5024,7 @@ version = "0.4.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"js-sys",
"once_cell",
"wasm-bindgen",
@@ -5335,7 +5378,7 @@ version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"windows-sys 0.48.0",
]

404
lib/Cargo.lock generated
View File

@@ -33,7 +33,7 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cipher",
"cpufeatures",
]
@@ -285,7 +285,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -344,7 +344,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
"synstructure",
]
@@ -356,7 +356,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -378,7 +378,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -389,7 +389,7 @@ checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -520,7 +520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
"cfg-if",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object",
@@ -799,6 +799,7 @@ dependencies = [
"bip39",
"boltz-client",
"chrono",
"console_log",
"derivative",
"ecies",
"electrum-client",
@@ -812,12 +813,14 @@ dependencies = [
"lwk_common",
"lwk_signer",
"lwk_wollet",
"maybe-sync",
"paste",
"prost 0.13.4",
"reqwest 0.12.7",
"rusqlite",
"rusqlite_migration",
"sdk-common",
"sdk-macros",
"security-framework",
"security-framework-sys",
"semver",
@@ -835,6 +838,7 @@ dependencies = [
"tonic-build 0.12.3",
"url",
"uuid",
"wasm-bindgen-test",
"x509-parser",
"zbase32",
]
@@ -860,7 +864,14 @@ dependencies = [
name = "breez-sdk-liquid-wasm"
version = "0.7.1"
dependencies = [
"anyhow",
"breez-sdk-liquid",
"console_log",
"js-sys",
"log",
"sdk-macros",
"serde",
"tsify-next",
"wasm-bindgen",
"wasm-bindgen-futures",
]
@@ -945,6 +956,12 @@ dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
@@ -957,7 +974,7 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cipher",
"cpufeatures",
]
@@ -1061,7 +1078,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -1079,6 +1096,15 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "colorchoice"
version = "1.0.2"
@@ -1091,10 +1117,20 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"wasm-bindgen",
]
[[package]]
name = "console_log"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
dependencies = [
"log",
"web-sys",
]
[[package]]
name = "cookie-factory"
version = "0.3.3"
@@ -1135,7 +1171,7 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
]
[[package]]
@@ -1182,7 +1218,7 @@ version = "4.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"curve25519-dalek-derive",
"fiat-crypto",
@@ -1199,7 +1235,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -1217,7 +1253,7 @@ version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"num_cpus",
]
@@ -1227,12 +1263,12 @@ version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"crossbeam-utils",
"hashbrown 0.14.5",
"lock_api",
"lock_api 0.4.12",
"once_cell",
"parking_lot_core",
"parking_lot_core 0.9.10",
]
[[package]]
@@ -1249,7 +1285,7 @@ checksum = "51aac4c99b2e6775164b412ea33ae8441b2fde2dbf05a20bc0052a63d08c475b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -1314,7 +1350,17 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
name = "dns-parser"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea"
dependencies = [
"byteorder",
"quick-error",
]
[[package]]
@@ -1328,7 +1374,7 @@ dependencies = [
"hkdf",
"libsecp256k1",
"once_cell",
"parking_lot",
"parking_lot 0.12.3",
"rand_core 0.6.4",
"sha2",
"typenum",
@@ -1389,7 +1435,7 @@ version = "0.8.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
]
[[package]]
@@ -1401,7 +1447,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -1599,7 +1645,7 @@ dependencies = [
"md-5",
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -1715,7 +1761,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -1773,7 +1819,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"js-sys",
"libc",
"wasi",
@@ -1949,7 +1995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447afdcdb8afb9d0a852af6dc65d9b285ce720ed7a59e42a8bf2e931c67bc1b5"
dependencies = [
"async-trait",
"cfg-if",
"cfg-if 1.0.0",
"data-encoding",
"enum-as-inner",
"futures-channel",
@@ -1973,13 +2019,13 @@ version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2e2aba9c389ce5267d31cf1e4dace82390ae276b0b364ea55630b1fa1b44b4"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"futures-util",
"hickory-proto",
"ipconfig",
"lru-cache",
"once_cell",
"parking_lot",
"parking_lot 0.12.3",
"rand 0.8.5",
"resolv-conf",
"smallvec",
@@ -2197,19 +2243,6 @@ dependencies = [
"tower-service",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper 0.14.30",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
@@ -2272,7 +2305,7 @@ dependencies = [
"i18n-embed-impl",
"intl-memoizer",
"log",
"parking_lot",
"parking_lot 0.12.3",
"rust-embed",
"thiserror 1.0.63",
"unic-langid",
@@ -2295,7 +2328,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.11.1",
"syn 2.0.87",
"syn 2.0.98",
"unic-langid",
]
@@ -2309,7 +2342,7 @@ dependencies = [
"i18n-config",
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -2450,7 +2483,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -2761,6 +2794,15 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
[[package]]
name = "lock_api"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
dependencies = [
"scopeguard",
]
[[package]]
name = "lock_api"
version = "0.4.12"
@@ -2857,13 +2899,22 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "maybe-sync"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7551d6fcc47ecf769e6c8b2e5dd7f56f90361d3d1360e3a280c8d0d7c8e680b7"
dependencies = [
"parking_lot 0.10.2",
]
[[package]]
name = "md-5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"digest 0.10.7",
]
@@ -2889,6 +2940,16 @@ dependencies = [
"unicase",
]
[[package]]
name = "minicov"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b"
dependencies = [
"cc",
"walkdir",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@@ -3061,7 +3122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"cfg-if 1.0.0",
"foreign-types",
"libc",
"once_cell",
@@ -3077,7 +3138,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -3125,14 +3186,38 @@ dependencies = [
"log",
]
[[package]]
name = "parking_lot"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
dependencies = [
"lock_api 0.3.4",
"parking_lot_core 0.7.3",
]
[[package]]
name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
"lock_api 0.4.12",
"parking_lot_core 0.9.10",
]
[[package]]
name = "parking_lot_core"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b93f386bb233083c799e6e642a9d73db98c24a5deeb95ffc85bf281255dffc98"
dependencies = [
"cfg-if 0.1.10",
"cloudabi",
"libc",
"redox_syscall 0.1.57",
"smallvec",
"winapi",
]
[[package]]
@@ -3141,9 +3226,9 @@ version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"redox_syscall",
"redox_syscall 0.5.10",
"smallvec",
"windows-targets 0.52.6",
]
@@ -3203,7 +3288,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -3247,7 +3332,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"opaque-debug",
"universal-hash",
@@ -3291,7 +3376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
dependencies = [
"proc-macro2",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -3337,14 +3422,14 @@ dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
name = "proc-macro2"
version = "1.0.86"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
@@ -3407,7 +3492,7 @@ dependencies = [
"prost 0.13.4",
"prost-types 0.13.4",
"regex",
"syn 2.0.87",
"syn 2.0.98",
"tempfile",
]
@@ -3434,7 +3519,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -3602,9 +3687,15 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.3"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_syscall"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
dependencies = [
"bitflags 2.6.0",
]
@@ -3653,43 +3744,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "reqwest"
version = "0.11.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
dependencies = [
"base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.30",
"hyper-tls 0.5.0",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
[[package]]
name = "reqwest"
version = "0.12.7"
@@ -3708,7 +3762,7 @@ dependencies = [
"http-body-util",
"hyper 1.4.1",
"hyper-rustls",
"hyper-tls 0.6.0",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
@@ -3739,6 +3793,49 @@ dependencies = [
"windows-registry",
]
[[package]]
name = "reqwest"
version = "0.12.12"
source = "git+https://github.com/seanmonstar/reqwest?rev=1e7e9653e5b7ee3175131052c097a8d9a07ecbcd#1e7e9653e5b7ee3175131052c097a8d9a07ecbcd"
dependencies = [
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.4.6",
"http 1.1.0",
"http-body 1.0.1",
"http-body-util",
"hyper 1.4.1",
"hyper-rustls",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile 2.1.3",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 1.0.1",
"system-configuration",
"tokio",
"tokio-native-tls",
"tower 0.5.2",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-registry",
]
[[package]]
name = "resolv-conf"
version = "0.7.0"
@@ -3771,7 +3868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"cfg-if 1.0.0",
"getrandom",
"libc",
"spin 0.9.8",
@@ -3822,7 +3919,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.87",
"syn 2.0.98",
"walkdir",
]
@@ -4044,7 +4141,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4071,7 +4168,7 @@ dependencies = [
[[package]]
name = "sdk-common"
version = "0.6.2"
source = "git+https://github.com/breez/breez-sdk?rev=19ed955c6fa854ad6cd2beb2eca9127d8099c506#19ed955c6fa854ad6cd2beb2eca9127d8099c506"
source = "git+https://github.com/breez/breez-sdk?rev=0017f7d3f76a1f0094ad9ff25422b72c31acc60e#0017f7d3f76a1f0094ad9ff25422b72c31acc60e"
dependencies = [
"aes",
"anyhow",
@@ -4080,6 +4177,7 @@ dependencies = [
"bip21",
"bitcoin 0.29.2",
"cbc",
"dns-parser",
"elements",
"getrandom",
"hex",
@@ -4094,7 +4192,8 @@ dependencies = [
"prost 0.13.4",
"querystring",
"regex",
"reqwest 0.11.20",
"reqwest 0.12.12",
"sdk-macros",
"serde",
"serde_json",
"strum_macros",
@@ -4105,12 +4204,21 @@ dependencies = [
"tonic-build 0.12.3",
"tonic-build 0.8.4",
"tonic-web-wasm-client",
"tsify-next",
"url",
"urlencoding",
"wasm-bindgen",
]
[[package]]
name = "sdk-macros"
version = "0.6.2"
source = "git+https://github.com/breez/breez-sdk?rev=0017f7d3f76a1f0094ad9ff25422b72c31acc60e#0017f7d3f76a1f0094ad9ff25422b72c31acc60e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "secp256k1"
version = "0.24.3"
@@ -4245,7 +4353,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4256,7 +4364,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4289,7 +4397,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"digest 0.10.7",
]
@@ -4300,7 +4408,7 @@ version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"cpufeatures",
"digest 0.10.7",
]
@@ -4372,7 +4480,7 @@ dependencies = [
"fragile",
"js-sys",
"once_cell",
"parking_lot",
"parking_lot 0.12.3",
"thiserror 2.0.11",
"tokio",
"wasm-bindgen",
@@ -4421,7 +4529,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4443,9 +4551,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.87"
version = "2.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
dependencies = [
"proc-macro2",
"quote",
@@ -4475,7 +4583,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4515,7 +4623,7 @@ version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"fastrand",
"once_cell",
"rustix",
@@ -4563,7 +4671,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4574,7 +4682,7 @@ checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4652,7 +4760,7 @@ dependencies = [
"bytes",
"libc",
"mio",
"parking_lot",
"parking_lot 0.12.3",
"pin-project-lite",
"signal-hook-registry",
"socket2",
@@ -4678,7 +4786,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4854,7 +4962,7 @@ dependencies = [
"prost-build 0.13.4",
"prost-types 0.13.4",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4912,6 +5020,7 @@ dependencies = [
"futures-util",
"pin-project-lite",
"sync_wrapper 1.0.1",
"tokio",
"tower-layer",
"tower-service",
]
@@ -4947,7 +5056,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -4997,7 +5106,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -5217,7 +5326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c"
dependencies = [
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -5284,7 +5393,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.87",
"syn 2.0.98",
"toml",
"uniffi_build 0.25.3",
"uniffi_meta 0.25.3",
@@ -5442,6 +5551,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
dependencies = [
"getrandom",
"wasm-bindgen",
]
[[package]]
@@ -5487,7 +5597,7 @@ version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
@@ -5503,7 +5613,7 @@ dependencies = [
"log",
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
"wasm-bindgen-shared",
]
@@ -5513,7 +5623,7 @@ version = "0.4.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"js-sys",
"once_cell",
"wasm-bindgen",
@@ -5538,7 +5648,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -5552,6 +5662,30 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "wasm-bindgen-test"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3"
dependencies = [
"js-sys",
"minicov",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test-macro",
]
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "wasm-streams"
version = "0.4.1"
@@ -5860,7 +5994,7 @@ version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"windows-sys 0.48.0",
]
@@ -5940,7 +6074,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
"synstructure",
]
@@ -5968,7 +6102,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -5988,7 +6122,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
"synstructure",
]
@@ -6009,7 +6143,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]
[[package]]
@@ -6031,5 +6165,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"syn 2.0.98",
]

View File

@@ -36,6 +36,9 @@ unexpected_cfgs = { level = "allow", check-cfg = ['cfg(frb_expand)'] }
anyhow = "1.0"
log = "0.4.20"
once_cell = "1.19"
serde = { version = "1.0", features = ["derive"] }
sdk-common = { git = "https://github.com/breez/breez-sdk", rev = "0017f7d3f76a1f0094ad9ff25422b72c31acc60e", features = ["liquid"] }
sdk-macros = { git = "https://github.com/breez/breez-sdk", rev = "0017f7d3f76a1f0094ad9ff25422b72c31acc60e" }
thiserror = "1.0"
# Version must match that used by uniffi-bindgen-go
uniffi = "0.25.0"

View File

@@ -28,8 +28,8 @@ lwk_common = "0.8.0"
lwk_signer = { version = "0.8.0", default-features = false }
rusqlite = { git = "https://github.com/Spxg/rusqlite", rev = "e36644127f31fa6e7ea0999b59432deb4a07f220", features = [ "backup", "bundled" ] }
tokio = { version = "1", default-features = false, features = ["rt", "macros"] }
# TODO: Change on top of main once PR is merged
sdk-common = { git = "https://github.com/breez/breez-sdk", rev = "19ed955c6fa854ad6cd2beb2eca9127d8099c506", features = ["liquid"] }
sdk-common = { workspace = true }
sdk-macros = { workspace = true }
rusqlite_migration = { git = "https://github.com/hydra-yse/rusqlite_migration", branch = "rusqlite-v0.33.0" }
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.116"
@@ -52,25 +52,36 @@ ecies = { version = "0.2.7", default-features = false, features = ["pure"] }
semver = "1.0.23"
lazy_static = "1.5.0"
# Non-WASM dependencies
[target.'cfg(not(all(target_family = "wasm", target_os = "unknown")))'.dependencies]
electrum-client = { version = "0.21.0", default-features = false, features = [
"use-rustls-ring",
"proxy",
] }
boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "12c9e546f15706b563ba7e49f2be7e8a5e7ada90" }
lwk_wollet = { git = "https://github.com/breez/lwk", branch = "breez-sdk-liquid-0.6.3" }
maybe-sync = { version = "0.1.1", features = ["sync"] }
tokio-stream = { version = "0.1.14", features = ["sync"] }
tokio-tungstenite = { version = "0.21.0", features = ["native-tls-vendored"] }
tonic = { version = "0.12.3", features = ["tls", "tls-webpki-roots"] }
uuid = { version = "1.8.0", features = ["v4"] }
lwk_wollet = { git = "https://github.com/breez/lwk", branch = "breez-sdk-liquid-0.6.3" }
# WASM dependencies
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies]
console_log = "1"
lwk_wollet = { git = "https://github.com/breez/lwk", branch = "breez-sdk-liquid-0.6.3", default-features = false, features = [ "esplora" ] }
maybe-sync = "0.1.1"
uuid = { version = "1.8.0", features = ["v4", "js"] }
[dev-dependencies]
sdk-common = { workspace = true, features = ["test-utils"] }
paste = "1.0.15"
tempdir = "0.3.7"
# WASM dev dependencies
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dev-dependencies]
wasm-bindgen-test = "0.3.33"
[build-dependencies]
anyhow = { version = "1.0.79", features = ["backtrace"] }
glob = "0.3.1"

View File

@@ -1,7 +1,6 @@
use std::sync::Arc;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use sdk_common::prelude::{BreezServer, BuyBitcoinProviderApi, MoonpayProvider};
use crate::{
@@ -9,7 +8,7 @@ use crate::{
prelude::LiquidNetwork,
};
#[async_trait]
#[sdk_macros::async_trait]
pub(crate) trait BuyBitcoinApi: Send + Sync {
/// Initiate buying Bitcoin and return a URL to the selected third party provider
async fn buy_bitcoin(
@@ -35,7 +34,7 @@ impl BuyBitcoinService {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl BuyBitcoinApi for BuyBitcoinService {
async fn buy_bitcoin(
&self,

View File

@@ -1,11 +1,10 @@
use std::{
collections::HashMap,
sync::{Mutex, OnceLock},
sync::{Arc, Mutex, OnceLock},
time::Duration,
};
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use electrum_client::{
bitcoin::{
consensus::{deserialize, serialize},
@@ -16,7 +15,10 @@ use electrum_client::{
};
use log::info;
use lwk_wollet::{bitcoin::ScriptBuf, ElectrumOptions, ElectrumUrl, Error, History};
use sdk_common::{bitcoin::hashes::hex::ToHex, prelude::get_parse_and_log_response};
use sdk_common::{
bitcoin::hashes::hex::ToHex,
prelude::{get_and_check_success, parse_json, RestClient},
};
use crate::{
model::{Config, LiquidNetwork, RecommendedFees},
@@ -25,7 +27,7 @@ use crate::{
/// Trait implemented by types that can fetch data from a blockchain data source.
#[allow(dead_code)]
#[async_trait]
#[sdk_macros::async_trait]
pub trait BitcoinChainService: Send + Sync {
/// Get the blockchain latest block
fn tip(&self) -> Result<HeaderNotification>;
@@ -82,14 +84,16 @@ pub trait BitcoinChainService: Send + Sync {
}
pub(crate) struct HybridBitcoinChainService {
client: OnceLock<Client>,
config: Config,
rest_client: Arc<dyn RestClient>,
client: OnceLock<Client>,
last_known_tip: Mutex<Option<HeaderNotification>>,
}
impl HybridBitcoinChainService {
pub fn new(config: Config) -> Result<Self, Error> {
pub fn new(config: Config, rest_client: Arc<dyn RestClient>) -> Result<Self, Error> {
Ok(Self {
config,
rest_client,
client: OnceLock::new(),
last_known_tip: Mutex::new(None),
})
@@ -112,7 +116,7 @@ impl HybridBitcoinChainService {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl BitcoinChainService for HybridBitcoinChainService {
fn tip(&self) -> Result<HeaderNotification> {
let client = self.get_client()?;
@@ -364,11 +368,11 @@ impl BitcoinChainService for HybridBitcoinChainService {
}
async fn recommended_fees(&self) -> Result<RecommendedFees> {
get_parse_and_log_response(
let (response, _) = get_and_check_success(
self.rest_client.as_ref(),
&format!("{}/v1/fees/recommended", self.config.mempoolspace_url),
true,
)
.await
.map_err(Into::into)
.await?;
Ok(parse_json(&response)?)
}
}

View File

@@ -2,7 +2,6 @@ use std::sync::{Mutex, OnceLock};
use std::time::Duration;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use boltz_client::ToHex;
use electrum_client::{Client, ElectrumApi};
use elements::encode::serialize as elements_serialize;
@@ -19,7 +18,7 @@ use crate::model::LiquidNetwork;
use crate::prelude::Utxo;
use crate::{model::Config, utils};
#[async_trait]
#[sdk_macros::async_trait]
pub trait LiquidChainService: Send + Sync {
/// Get the blockchain latest block
async fn tip(&self) -> Result<u32>;
@@ -93,7 +92,7 @@ impl HybridLiquidChainService {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl LiquidChainService for HybridLiquidChainService {
async fn tip(&self) -> Result<u32> {
let client = self.get_client()?;

View File

@@ -1,7 +1,6 @@
use std::{str::FromStr, sync::Arc};
use anyhow::{anyhow, bail, Context, Result};
use async_trait::async_trait;
use boltz_client::{
boltz::{self},
swaps::boltz::{ChainSwapStates, CreateChainResponse, SwapUpdateTxDetails},
@@ -46,7 +45,7 @@ pub(crate) struct ChainSwapHandler {
subscription_notifier: broadcast::Sender<String>,
}
#[async_trait]
#[sdk_macros::async_trait]
impl BlockListener for ChainSwapHandler {
async fn on_bitcoin_block(&self, height: u32) {
if let Err(e) = self.claim_outgoing(height).await {
@@ -1491,7 +1490,10 @@ mod tests {
},
};
#[tokio::test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::async_test_all]
async fn test_chain_swap_state_transitions() -> Result<()> {
create_persister!(persister);

View File

@@ -1,10 +1,10 @@
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
use anyhow::Result;
use log::{debug, info};
use tokio::sync::{broadcast, RwLock};
use uuid::Uuid;
use crate::model::{EventListener, SdkEvent};
@@ -26,10 +26,7 @@ impl EventManager {
}
pub async fn add(&self, listener: Box<dyn EventListener>) -> Result<String> {
let id = format!(
"{:X}",
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
);
let id = Uuid::new_v4().to_string();
(*self.listeners.write().await).insert(id.clone(), listener);
Ok(id)
}

View File

@@ -1,6 +1,5 @@
use std::sync::Arc;
use async_trait::async_trait;
use sdk_common::{
bitcoin::util::bip32::{ChildNumber, DerivationPath},
prelude::{LnUrlResult, LnurlAuthSigner},
@@ -18,7 +17,7 @@ impl SdkLnurlAuthSigner {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl LnurlAuthSigner for SdkLnurlAuthSigner {
async fn derive_bip32_pub_key(&self, derivation_path: &[ChildNumber]) -> LnUrlResult<Vec<u8>> {
let derivation: DerivationPath = derivation_path.to_vec().into();

View File

@@ -1,5 +1,4 @@
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use boltz_client::{
bitcoin::ScriptBuf,
boltz::{ChainPair, BOLTZ_MAINNET_URL_V2, BOLTZ_REGTEST, BOLTZ_TESTNET_URL_V2},
@@ -13,6 +12,7 @@ use boltz_client::{BtcSwapScript, Keypair, LBtcSwapScript};
use derivative::Derivative;
use lwk_wollet::elements::AssetId;
use lwk_wollet::{bitcoin::bip32, ElementsNetwork};
use maybe_sync::{MaybeSend, MaybeSync};
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSqlOutput, ValueRef};
use rusqlite::ToSql;
use sdk_common::prelude::*;
@@ -281,7 +281,7 @@ impl From<LiquidNetwork> for boltz_client::bitcoin::Network {
}
/// Trait that can be used to react to various [SdkEvent]s emitted by the SDK.
pub trait EventListener: Send + Sync {
pub trait EventListener: MaybeSend + MaybeSync {
fn on_event(&self, e: SdkEvent);
}
@@ -324,7 +324,7 @@ impl From<bip32::Error> for SignerError {
/// A trait that can be used to sign messages and verify signatures.
/// The sdk user can implement this trait to use their own signer.
pub trait Signer: Send + Sync {
pub trait Signer: MaybeSend + MaybeSync {
/// The master xpub encoded as 78 bytes length as defined in bip32 specification.
/// For reference: <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#user-content-Serialization_format>
fn xpub(&self) -> Result<Vec<u8>, SignerError>;
@@ -783,7 +783,7 @@ pub enum GetPaymentRequest {
}
/// Trait that can be used to react to new blocks from Bitcoin and Liquid chains
#[async_trait]
#[sdk_macros::async_trait]
pub(crate) trait BlockListener: Send + Sync {
async fn on_bitcoin_block(&self, height: u32);
async fn on_liquid_block(&self, height: u32);

View File

@@ -102,7 +102,10 @@ mod tests {
use crate::test_utils::persist::create_persister;
#[test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::test_all]
fn test_next_expired_reserved_address() -> Result<()> {
create_persister!(storage);
let address = "tlq1pq2amlulhea6ltq7x3eu9atsc2nnrer7yt7xve363zxedqwu2mk6ctcyv9awl8xf28cythreqklt5q0qqwsxzlm6wu4z6d574adl9zh2zmr0h85gt534n";
@@ -128,7 +131,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_delete_reserved_address() -> Result<()> {
create_persister!(storage);
let address = "tlq1pq2amlulhea6ltq7x3eu9atsc2nnrer7yt7xve363zxedqwu2mk6ctcyv9awl8xf28cythreqklt5q0qqwsxzlm6wu4z6d574adl9zh2zmr0h85gt534n";

View File

@@ -44,7 +44,10 @@ mod tests {
test_utils::persist::{create_persister, new_receive_swap, new_send_swap},
};
#[test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::test_all]
fn test_backup_and_restore() -> Result<()> {
create_persister!(local);

View File

@@ -194,7 +194,10 @@ mod tests {
use crate::test_utils::persist::create_persister;
#[test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::test_all]
fn test_cached_items() -> Result<()> {
create_persister!(persister);
@@ -209,7 +212,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_get_last_derivation_index() -> Result<()> {
create_persister!(persister);
@@ -231,7 +234,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_next_derivation_index() -> Result<()> {
create_persister!(persister);

View File

@@ -512,7 +512,10 @@ mod tests {
use crate::test_utils::persist::create_persister;
use anyhow::Result;
#[tokio::test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::async_test_all]
async fn test_writing_stale_swap() -> Result<()> {
create_persister!(storage);
@@ -538,7 +541,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_list_local_swaps() -> Result<()> {
create_persister!(storage);

View File

@@ -1032,7 +1032,10 @@ mod tests {
use super::{PaymentState, PaymentType};
#[test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::test_all]
fn test_get_payments() -> Result<()> {
create_persister!(storage);
@@ -1056,7 +1059,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_list_ongoing_swaps() -> Result<()> {
create_persister!(storage);

View File

@@ -396,7 +396,10 @@ mod tests {
use super::PaymentState;
#[test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::test_all]
fn test_fetch_receive_swap() -> Result<()> {
create_persister!(storage);
@@ -413,7 +416,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_list_receive_swap() -> Result<()> {
create_persister!(storage);
@@ -436,7 +439,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_update_receive_swap() -> Result<()> {
create_persister!(storage);
@@ -466,7 +469,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_writing_stale_swap() -> Result<()> {
create_persister!(storage);

View File

@@ -407,7 +407,10 @@ mod tests {
use super::PaymentState;
#[test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::test_all]
fn test_fetch_send_swap() -> Result<()> {
create_persister!(storage);
let send_swap = new_send_swap(None, None);
@@ -423,7 +426,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_list_send_swap() -> Result<()> {
create_persister!(storage);
@@ -449,7 +452,7 @@ mod tests {
Ok(())
}
#[test]
#[sdk_macros::test_all]
fn test_update_send_swap() -> Result<()> {
create_persister!(storage);
@@ -492,7 +495,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_writing_stale_swap() -> Result<()> {
create_persister!(storage);

View File

@@ -1,7 +1,6 @@
use std::{str::FromStr, sync::Arc};
use anyhow::{anyhow, bail, Result};
use async_trait::async_trait;
use boltz_client::swaps::boltz::RevSwapStates;
use boltz_client::{boltz, Serialize, ToHex};
use log::{debug, error, info, warn};
@@ -33,7 +32,7 @@ pub(crate) struct ReceiveSwapHandler {
liquid_chain_service: Arc<dyn LiquidChainService>,
}
#[async_trait]
#[sdk_macros::async_trait]
impl BlockListener for ReceiveSwapHandler {
async fn on_bitcoin_block(&self, _height: u32) {}
@@ -546,7 +545,10 @@ mod tests {
},
};
#[tokio::test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::async_test_all]
async fn test_receive_swap_state_transitions() -> Result<()> {
create_persister!(persister);

View File

@@ -72,11 +72,284 @@ pub const DEFAULT_EXTERNAL_INPUT_PARSERS: &[(&str, &str, &str)] = &[(
pub(crate) const NETWORK_PROPAGATION_GRACE_PERIOD: Duration = Duration::from_secs(30);
pub(crate) struct LiquidSdkBuilder {
config: Config,
signer: Arc<Box<dyn Signer>>,
breez_server: Arc<BreezServer>,
bitcoin_chain_service: Option<Arc<dyn BitcoinChainService>>,
liquid_chain_service: Option<Arc<dyn LiquidChainService>>,
onchain_wallet: Option<Arc<dyn OnchainWallet>>,
persister: Option<Arc<Persister>>,
recoverer: Option<Arc<Recoverer>>,
rest_client: Option<Arc<dyn RestClient>>,
status_stream: Option<Arc<dyn SwapperStatusStream>>,
swapper: Option<Arc<dyn Swapper>>,
sync_service: Option<Arc<SyncService>>,
}
#[allow(dead_code)]
impl LiquidSdkBuilder {
pub fn new(
config: Config,
server_url: String,
signer: Arc<Box<dyn Signer>>,
) -> Result<LiquidSdkBuilder> {
let breez_server = Arc::new(BreezServer::new(server_url, None)?);
Ok(LiquidSdkBuilder {
config,
signer,
breez_server,
bitcoin_chain_service: None,
liquid_chain_service: None,
onchain_wallet: None,
persister: None,
recoverer: None,
rest_client: None,
status_stream: None,
swapper: None,
sync_service: None,
})
}
pub fn bitcoin_chain_service(
&mut self,
bitcoin_chain_service: Arc<dyn BitcoinChainService>,
) -> &mut Self {
self.bitcoin_chain_service = Some(bitcoin_chain_service.clone());
self
}
pub fn liquid_chain_service(
&mut self,
liquid_chain_service: Arc<dyn LiquidChainService>,
) -> &mut Self {
self.liquid_chain_service = Some(liquid_chain_service.clone());
self
}
pub fn recoverer(&mut self, recoverer: Arc<Recoverer>) -> &mut Self {
self.recoverer = Some(recoverer.clone());
self
}
pub fn onchain_wallet(&mut self, onchain_wallet: Arc<dyn OnchainWallet>) -> &mut Self {
self.onchain_wallet = Some(onchain_wallet.clone());
self
}
pub fn persister(&mut self, persister: Arc<Persister>) -> &mut Self {
self.persister = Some(persister.clone());
self
}
pub fn rest_client(&mut self, rest_client: Arc<dyn RestClient>) -> &mut Self {
self.rest_client = Some(rest_client.clone());
self
}
pub fn status_stream(&mut self, status_stream: Arc<dyn SwapperStatusStream>) -> &mut Self {
self.status_stream = Some(status_stream.clone());
self
}
pub fn swapper(&mut self, swapper: Arc<dyn Swapper>) -> &mut Self {
self.swapper = Some(swapper.clone());
self
}
pub fn sync_service(&mut self, sync_service: Arc<SyncService>) -> &mut Self {
self.sync_service = Some(sync_service.clone());
self
}
pub fn build(&self) -> Result<Arc<LiquidSdk>> {
if let Some(breez_api_key) = &self.config.breez_api_key {
LiquidSdk::validate_breez_api_key(breez_api_key)?
}
fs::create_dir_all(&self.config.working_dir)?;
let fingerprint_hex: String =
Xpub::decode(self.signer.xpub()?.as_slice())?.identifier()[0..4].to_hex();
let working_dir = self
.config
.get_wallet_dir(&self.config.working_dir, &fingerprint_hex)?;
let cache_dir = self.config.get_wallet_dir(
self.config
.cache_dir
.as_ref()
.unwrap_or(&self.config.working_dir),
&fingerprint_hex,
)?;
let sync_enabled = self
.config
.sync_service_url
.clone()
.map(|_| true)
.unwrap_or(false);
let persister = match self.persister.clone() {
Some(persister) => persister,
None => {
let persister = Arc::new(Persister::new(
&working_dir,
self.config.network,
sync_enabled,
)?);
persister.init()?;
persister.replace_asset_metadata(self.config.asset_metadata.clone())?;
persister
}
};
let rest_client: Arc<dyn RestClient> = match self.rest_client.clone() {
Some(rest_client) => rest_client,
None => Arc::new(ReqwestRestClient::new()?),
};
let bitcoin_chain_service: Arc<dyn BitcoinChainService> =
match self.bitcoin_chain_service.clone() {
Some(bitcoin_chain_service) => bitcoin_chain_service,
None => Arc::new(HybridBitcoinChainService::new(
self.config.clone(),
rest_client.clone(),
)?),
};
let liquid_chain_service: Arc<dyn LiquidChainService> =
match self.liquid_chain_service.clone() {
Some(liquid_chain_service) => liquid_chain_service,
None => Arc::new(HybridLiquidChainService::new(self.config.clone())?),
};
let onchain_wallet: Arc<dyn OnchainWallet> = match self.onchain_wallet.clone() {
Some(onchain_wallet) => onchain_wallet,
None => Arc::new(LiquidOnchainWallet::new(
self.config.clone(),
&cache_dir,
persister.clone(),
self.signer.clone(),
)?),
};
let event_manager = Arc::new(EventManager::new());
let (shutdown_sender, shutdown_receiver) = watch::channel::<()>(());
let swapper: Arc<dyn Swapper> = match self.swapper.clone() {
Some(swapper) => swapper,
None => {
let proxy_url_fetcher = Arc::new(BoltzProxyFetcher::new(persister.clone()));
Arc::new(BoltzSwapper::new(self.config.clone(), proxy_url_fetcher))
}
};
let status_stream: Arc<dyn SwapperStatusStream> = match self.status_stream.clone() {
Some(status_stream) => status_stream,
None => Arc::from(swapper.create_status_stream()),
};
let recoverer = match self.recoverer.clone() {
Some(recoverer) => recoverer,
None => Arc::new(Recoverer::new(
self.signer.slip77_master_blinding_key()?,
swapper.clone(),
onchain_wallet.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
)?),
};
let sync_service = match self.sync_service.clone() {
Some(sync_service) => Some(sync_service),
None => match self.config.sync_service_url.clone() {
Some(sync_service_url) => {
if BREEZ_SYNC_SERVICE_URL == sync_service_url
&& self.config.breez_api_key.is_none()
{
anyhow::bail!(
"Cannot start the Breez real-time sync service without providing a valid API key. See https://sdk-doc-liquid.breez.technology/guide/getting_started.html#api-key",
);
}
let syncer_client =
Box::new(BreezSyncerClient::new(self.config.breez_api_key.clone()));
Some(Arc::new(SyncService::new(
sync_service_url,
persister.clone(),
recoverer.clone(),
self.signer.clone(),
syncer_client,
)))
}
None => None,
},
};
let send_swap_handler = SendSwapHandler::new(
self.config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
);
let receive_swap_handler = ReceiveSwapHandler::new(
self.config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
);
let chain_swap_handler = Arc::new(ChainSwapHandler::new(
self.config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
)?);
let buy_bitcoin_service = Arc::new(BuyBitcoinService::new(
self.config.clone(),
self.breez_server.clone(),
));
let external_input_parsers = self.config.get_all_external_input_parsers();
let sdk = Arc::new(LiquidSdk {
config: self.config.clone(),
onchain_wallet,
signer: self.signer.clone(),
persister: persister.clone(),
rest_client,
event_manager,
status_stream: status_stream.clone(),
swapper,
recoverer,
bitcoin_chain_service,
liquid_chain_service,
fiat_api: self.breez_server.clone(),
is_started: RwLock::new(false),
shutdown_sender,
shutdown_receiver,
send_swap_handler,
receive_swap_handler,
sync_service,
chain_swap_handler,
buy_bitcoin_service,
external_input_parsers,
});
Ok(sdk)
}
}
pub struct LiquidSdk {
pub(crate) config: Config,
pub(crate) onchain_wallet: Arc<dyn OnchainWallet>,
pub(crate) signer: Arc<Box<dyn Signer>>,
pub(crate) persister: Arc<Persister>,
pub(crate) rest_client: Arc<dyn RestClient>,
pub(crate) event_manager: Arc<EventManager>,
pub(crate) status_stream: Arc<dyn SwapperStatusStream>,
pub(crate) swapper: Arc<dyn Swapper>,
@@ -135,7 +408,12 @@ impl LiquidSdk {
req: ConnectWithSignerRequest,
signer: Box<dyn Signer>,
) -> Result<Arc<LiquidSdk>> {
let sdk = LiquidSdk::new(req.config, Arc::new(signer))?;
let sdk = LiquidSdkBuilder::new(
req.config,
PRODUCTION_BREEZSERVER_URL.into(),
Arc::new(signer),
)?
.build()?;
sdk.start()
.inspect_err(|e| error!("Failed to start an SDK instance: {:?}", e))
.await?;
@@ -167,129 +445,6 @@ impl LiquidSdk {
Ok(())
}
fn new(config: Config, signer: Arc<Box<dyn Signer>>) -> Result<Arc<Self>> {
if let Some(breez_api_key) = &config.breez_api_key {
Self::validate_breez_api_key(breez_api_key)?
}
fs::create_dir_all(&config.working_dir)?;
let fingerprint_hex: String =
Xpub::decode(signer.xpub()?.as_slice())?.identifier()[0..4].to_hex();
let working_dir = config.get_wallet_dir(&config.working_dir, &fingerprint_hex)?;
let cache_dir = config.get_wallet_dir(
config.cache_dir.as_ref().unwrap_or(&config.working_dir),
&fingerprint_hex,
)?;
let sync_enabled = config
.sync_service_url
.clone()
.map(|_| true)
.unwrap_or(false);
let persister = Arc::new(Persister::new(&working_dir, config.network, sync_enabled)?);
persister.init()?;
persister.replace_asset_metadata(config.asset_metadata.clone())?;
let liquid_chain_service = Arc::new(HybridLiquidChainService::new(config.clone())?);
let bitcoin_chain_service = Arc::new(HybridBitcoinChainService::new(config.clone())?);
let onchain_wallet = Arc::new(LiquidOnchainWallet::new(
config.clone(),
&cache_dir,
persister.clone(),
signer.clone(),
)?);
let event_manager = Arc::new(EventManager::new());
let (shutdown_sender, shutdown_receiver) = watch::channel::<()>(());
let proxy_url_fetcher = Arc::new(BoltzProxyFetcher::new(persister.clone()));
let swapper = Arc::new(BoltzSwapper::new(config.clone(), proxy_url_fetcher));
let status_stream = Arc::<dyn SwapperStatusStream>::from(swapper.create_status_stream());
let recoverer = Arc::new(Recoverer::new(
signer.slip77_master_blinding_key()?,
swapper.clone(),
onchain_wallet.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
)?);
let mut sync_service = None;
if let Some(sync_service_url) = config.sync_service_url.clone() {
if BREEZ_SYNC_SERVICE_URL == sync_service_url && config.breez_api_key.is_none() {
anyhow::bail!(
"Cannot start the Breez real-time sync service without providing a valid API key. See https://sdk-doc-liquid.breez.technology/guide/getting_started.html#api-key",
);
}
let syncer_client = Box::new(BreezSyncerClient::new(config.breez_api_key.clone()));
sync_service = Some(Arc::new(SyncService::new(
sync_service_url,
persister.clone(),
recoverer.clone(),
signer.clone(),
syncer_client,
)));
}
let send_swap_handler = SendSwapHandler::new(
config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
);
let receive_swap_handler = ReceiveSwapHandler::new(
config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
);
let chain_swap_handler = Arc::new(ChainSwapHandler::new(
config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
)?);
let breez_server = Arc::new(BreezServer::new(PRODUCTION_BREEZSERVER_URL.into(), None)?);
let buy_bitcoin_service =
Arc::new(BuyBitcoinService::new(config.clone(), breez_server.clone()));
let external_input_parsers = config.get_all_external_input_parsers();
let sdk = Arc::new(LiquidSdk {
config: config.clone(),
onchain_wallet,
signer: signer.clone(),
persister: persister.clone(),
event_manager,
status_stream: status_stream.clone(),
swapper,
recoverer,
bitcoin_chain_service,
liquid_chain_service,
fiat_api: breez_server,
is_started: RwLock::new(false),
shutdown_sender,
shutdown_receiver,
send_swap_handler,
receive_swap_handler,
sync_service,
chain_swap_handler,
buy_bitcoin_service,
external_input_parsers,
});
Ok(sdk)
}
/// Starts an SDK instance.
///
/// Internal method. Should only be called once per instance.
@@ -3296,6 +3451,7 @@ impl LiquidSdk {
};
match validate_lnurl_pay(
self.rest_client.as_ref(),
amount_msat,
&req.comment,
&req.data,
@@ -3492,7 +3648,9 @@ impl LiquidSdk {
});
};
let res = validate_lnurl_withdraw(req.data.clone(), invoice.clone()).await?;
let res =
validate_lnurl_withdraw(self.rest_client.as_ref(), req.data.clone(), invoice.clone())
.await?;
if let LnUrlWithdrawResult::Ok { data: _ } = res {
if let Some(ReceiveSwap {
claim_tx_id: Some(tx_id),
@@ -3526,7 +3684,12 @@ impl LiquidSdk {
&self,
req_data: LnUrlAuthRequestData,
) -> Result<LnUrlCallbackStatus, LnUrlAuthError> {
Ok(perform_lnurl_auth(&req_data, &SdkLnurlAuthSigner::new(self.signer.clone())).await?)
Ok(perform_lnurl_auth(
self.rest_client.as_ref(),
&req_data,
&SdkLnurlAuthSigner::new(self.signer.clone()),
)
.await?)
}
/// Register for webhook callbacks at the given `webhook_url`. Each created swap after registering the
@@ -3591,9 +3754,10 @@ impl LiquidSdk {
/// Can optionally be configured to use external input parsers by providing `external_input_parsers` in [Config].
pub async fn parse(&self, input: &str) -> Result<InputType, PaymentError> {
let external_parsers = &self.external_input_parsers;
let input_type = parse(input, Some(external_parsers))
.await
.map_err(|e| PaymentError::generic(&e.to_string()))?;
let input_type =
parse_with_rest_client(self.rest_client.as_ref(), input, Some(external_parsers))
.await
.map_err(|e| PaymentError::generic(&e.to_string()))?;
let res = match input_type {
InputType::LiquidAddress { ref address } => match &address.asset_id {
@@ -3691,6 +3855,9 @@ mod tests {
};
use paste::paste;
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
struct NewSwapArgs {
direction: Direction,
accepts_zero_conf: bool,
@@ -3811,7 +3978,7 @@ mod tests {
}};
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_receive_swap_update_tracking() -> Result<()> {
create_persister!(persister);
let swapper = Arc::new(MockSwapper::default());
@@ -3819,14 +3986,14 @@ mod tests {
let liquid_chain_service = Arc::new(MockLiquidChainService::new());
let bitcoin_chain_service = Arc::new(MockBitcoinChainService::new());
let sdk = Arc::new(new_liquid_sdk_with_chain_services(
let sdk = new_liquid_sdk_with_chain_services(
persister.clone(),
swapper.clone(),
status_stream.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
None,
)?);
)?;
LiquidSdk::track_swap_updates(&sdk);
@@ -3927,7 +4094,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_send_swap_update_tracking() -> Result<()> {
create_persister!(persister);
let swapper = Arc::new(MockSwapper::default());
@@ -3983,7 +4150,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_chain_swap_update_tracking() -> Result<()> {
create_persister!(persister);
let swapper = Arc::new(MockSwapper::default());
@@ -3991,14 +4158,14 @@ mod tests {
let liquid_chain_service = Arc::new(MockLiquidChainService::new());
let bitcoin_chain_service = Arc::new(MockBitcoinChainService::new());
let sdk = Arc::new(new_liquid_sdk_with_chain_services(
let sdk = new_liquid_sdk_with_chain_services(
persister.clone(),
swapper.clone(),
status_stream.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
None,
)?);
)?;
LiquidSdk::track_swap_updates(&sdk);
@@ -4214,7 +4381,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_zero_amount_chain_swap_zero_leeway() -> Result<()> {
let user_lockup_sat = 50_000;
@@ -4224,14 +4391,14 @@ mod tests {
let liquid_chain_service = Arc::new(MockLiquidChainService::new());
let bitcoin_chain_service = Arc::new(MockBitcoinChainService::new());
let sdk = Arc::new(new_liquid_sdk_with_chain_services(
let sdk = new_liquid_sdk_with_chain_services(
persister.clone(),
swapper.clone(),
status_stream.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
None,
)?);
)?;
LiquidSdk::track_swap_updates(&sdk);
@@ -4274,7 +4441,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_zero_amount_chain_swap_with_leeway() -> Result<()> {
let user_lockup_sat = 50_000;
let onchain_fee_rate_leeway_sat_per_vbyte = 5;
@@ -4285,14 +4452,14 @@ mod tests {
let liquid_chain_service = Arc::new(MockLiquidChainService::new());
let bitcoin_chain_service = Arc::new(MockBitcoinChainService::new());
let sdk = Arc::new(new_liquid_sdk_with_chain_services(
let sdk = new_liquid_sdk_with_chain_services(
persister.clone(),
swapper.clone(),
status_stream.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
Some(onchain_fee_rate_leeway_sat_per_vbyte),
)?);
)?;
LiquidSdk::track_swap_updates(&sdk);

View File

@@ -2,7 +2,6 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::{str::FromStr, sync::Arc};
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use boltz_client::swaps::boltz;
use boltz_client::swaps::{boltz::CreateSubmarineResponse, boltz::SubSwapStates};
use futures_util::TryFutureExt;
@@ -38,7 +37,7 @@ pub(crate) struct SendSwapHandler {
subscription_notifier: broadcast::Sender<String>,
}
#[async_trait]
#[sdk_macros::async_trait]
impl BlockListener for SendSwapHandler {
async fn on_bitcoin_block(&self, _height: u32) {}
@@ -610,7 +609,10 @@ mod tests {
},
};
#[tokio::test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::async_test_all]
async fn test_send_swap_state_transitions() -> Result<()> {
create_persister!(storage);
let send_swap_handler = new_send_swap_handler(storage.clone())?;

View File

@@ -299,6 +299,9 @@ mod tests {
};
use std::collections::BTreeMap;
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
fn get_descriptor<S: LwkSigner>(
signer: &S,
is_mainnet: bool,
@@ -363,7 +366,7 @@ mod tests {
pset
}
#[test]
#[sdk_macros::test_all]
fn test_invalid_signer() {
let mut rng = rand::thread_rng();
@@ -382,7 +385,7 @@ mod tests {
assert!(SdkSigner::new_with_seed(seed2.to_vec(), false).is_ok());
}
#[test]
#[sdk_macros::test_all]
fn test_sign() {
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
let (sw_signer, sdk_signer) = create_signers(mnemonic);
@@ -408,7 +411,7 @@ mod tests {
assert_eq!(tx_sw, tx_sdk);
}
#[test]
#[sdk_macros::test_all]
fn test_slip77_master_blinding_key() {
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
let (sw_signer, sdk_signer) = create_signers(mnemonic);
@@ -422,7 +425,7 @@ mod tests {
);
}
#[test]
#[sdk_macros::test_all]
fn test_derive_xpub() {
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
let (sw_signer, sdk_signer) = create_signers(mnemonic);
@@ -434,7 +437,7 @@ mod tests {
assert_eq!(sw_xpub, sdk_xpub, "Derived xpubs should be identical");
}
#[test]
#[sdk_macros::test_all]
fn test_identifier() {
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
let (sw_signer, sdk_signer) = create_signers(mnemonic);
@@ -448,7 +451,7 @@ mod tests {
);
}
#[test]
#[sdk_macros::test_all]
fn test_fingerprint() {
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
let (sw_signer, sdk_signer) = create_signers(mnemonic);
@@ -469,7 +472,7 @@ mod tests {
);
}
#[test]
#[sdk_macros::test_all]
fn test_sdk_signer_vs_sw_signer() {
// Use a test mnemonic (don't use this in production!)
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

View File

@@ -6,7 +6,6 @@ use crate::{
prelude::{ChainSwap, Config, Direction, LiquidNetwork, SendSwap, Swap, Transaction, Utxo},
};
use anyhow::Result;
use async_trait::async_trait;
use boltz_client::{
boltz::{
BoltzApiClientV2, ChainPair, Cooperative, CreateChainRequest, CreateChainResponse,
@@ -154,7 +153,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
/// Create a new chain swap
async fn create_chain_swap(

View File

@@ -1,7 +1,6 @@
use std::sync::{Arc, OnceLock};
use anyhow::Result;
use async_trait::async_trait;
use sdk_common::prelude::BreezServer;
use url::Url;
@@ -37,7 +36,7 @@ impl BoltzProxyFetcher {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl ProxyUrlFetcher for BoltzProxyFetcher {
async fn fetch(&self) -> Result<&Option<String>> {
if let Some(swapper_proxy_url) = self.url.get() {

View File

@@ -1,7 +1,6 @@
use std::sync::Arc;
use anyhow::Result;
use async_trait::async_trait;
use boltz_client::{
boltz::{
ChainPair, CreateChainRequest, CreateChainResponse, CreateReverseRequest,
@@ -23,7 +22,7 @@ pub(crate) use subscription_handler::*;
pub(crate) mod boltz;
pub(crate) mod subscription_handler;
#[async_trait]
#[sdk_macros::async_trait]
pub trait Swapper: Send + Sync {
/// Create a new chain swap
async fn create_chain_swap(
@@ -144,7 +143,7 @@ pub trait SwapperStatusStream: Send + Sync {
fn subscribe_swap_updates(&self) -> broadcast::Receiver<boltz_client::boltz::Update>;
}
#[async_trait]
#[sdk_macros::async_trait]
pub(crate) trait ProxyUrlFetcher: Send + Sync + 'static {
async fn fetch(&self) -> Result<&Option<String>>;
}

View File

@@ -1,13 +1,12 @@
use std::sync::Arc;
use async_trait::async_trait;
use log::{error, info};
use crate::persist::Persister;
use super::SwapperStatusStream;
#[async_trait]
#[sdk_macros::async_trait]
pub trait SubscriptionHandler: Send + Sync {
async fn subscribe_swaps(&self);
}
@@ -30,7 +29,7 @@ impl SwapperSubscriptionHandler {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl SubscriptionHandler for SwapperSubscriptionHandler {
async fn subscribe_swaps(&self) {
match self.persister.list_ongoing_swaps() {

View File

@@ -2,7 +2,6 @@ use std::time::Duration;
use anyhow::{anyhow, Error, Result};
use async_trait::async_trait;
use log::debug;
use tokio::sync::Mutex;
use tonic::{
@@ -17,7 +16,7 @@ use super::model::{
ListenChangesRequest, Notification, SetRecordReply, SetRecordRequest,
};
#[async_trait]
#[sdk_macros::async_trait]
pub(crate) trait SyncerClient: Send + Sync {
async fn connect(&self, connect_url: String) -> Result<()>;
async fn push(&self, req: SetRecordRequest) -> Result<SetRecordReply>;
@@ -78,7 +77,7 @@ impl BreezSyncerClient {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl SyncerClient for BreezSyncerClient {
async fn connect(&self, connect_url: String) -> Result<()> {
let mut grpc_channel = self.grpc_channel.lock().await;

View File

@@ -556,7 +556,10 @@ mod tests {
use super::model::{data::SyncData, Record, RecordType};
#[tokio::test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::async_test_all]
async fn test_incoming_sync_create_and_update() -> Result<()> {
create_persister!(persister);
let signer: Arc<Box<dyn Signer>> = Arc::new(Box::new(MockSigner::new()?));
@@ -656,7 +659,7 @@ mod tests {
Ok(record)
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_outgoing_sync() -> Result<()> {
create_persister!(persister);
let signer: Arc<Box<dyn Signer>> = Arc::new(Box::new(MockSigner::new()?));
@@ -776,7 +779,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_sync_clean() -> Result<()> {
create_persister!(persister);
let signer: Arc<Box<dyn Signer>> = Arc::new(Box::new(MockSigner::new()?));
@@ -843,7 +846,7 @@ mod tests {
Ok(())
}
#[tokio::test]
#[sdk_macros::async_test_all]
async fn test_last_derivation_index_update() -> Result<()> {
create_persister!(persister);
let signer: Arc<Box<dyn Signer>> = Arc::new(Box::new(MockSigner::new()?));

View File

@@ -3,7 +3,6 @@
use std::sync::Mutex;
use anyhow::Result;
use async_trait::async_trait;
use boltz_client::{
elements::{
hex::FromHex, OutPoint as ElementsOutPoint, Script as ElementsScript,
@@ -67,7 +66,7 @@ impl MockLiquidChainService {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl LiquidChainService for MockLiquidChainService {
async fn tip(&self) -> Result<u32> {
Ok(0)
@@ -165,7 +164,7 @@ impl MockBitcoinChainService {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl BitcoinChainService for MockBitcoinChainService {
fn tip(&self) -> Result<HeaderNotification> {
Ok(HeaderNotification {

View File

@@ -1,21 +1,14 @@
#![cfg(test)]
use anyhow::{anyhow, Result};
use sdk_common::prelude::{BreezServer, STAGING_BREEZSERVER_URL};
use sdk_common::prelude::{MockRestClient, RestClient, STAGING_BREEZSERVER_URL};
use std::sync::Arc;
use tokio::sync::{watch, RwLock};
use crate::{
buy::BuyBitcoinService,
chain_swap::ChainSwapHandler,
event::EventManager,
model::{Config, Signer},
persist::Persister,
receive_swap::ReceiveSwapHandler,
recover::recoverer::Recoverer,
sdk::LiquidSdk,
send_swap::SendSwapHandler,
sdk::{LiquidSdk, LiquidSdkBuilder},
};
use super::{
@@ -30,7 +23,7 @@ pub(crate) fn new_liquid_sdk(
persister: Arc<Persister>,
swapper: Arc<MockSwapper>,
status_stream: Arc<MockStatusStream>,
) -> Result<LiquidSdk> {
) -> Result<Arc<LiquidSdk>> {
let liquid_chain_service = Arc::new(MockLiquidChainService::new());
let bitcoin_chain_service = Arc::new(MockBitcoinChainService::new());
@@ -51,7 +44,7 @@ pub(crate) fn new_liquid_sdk_with_chain_services(
liquid_chain_service: Arc<MockLiquidChainService>,
bitcoin_chain_service: Arc<MockBitcoinChainService>,
onchain_fee_rate_leeway_sat_per_vbyte: Option<u32>,
) -> Result<LiquidSdk> {
) -> Result<Arc<LiquidSdk>> {
let mut config = Config::testnet(None);
config.working_dir = persister
.get_database_dir()
@@ -61,33 +54,8 @@ pub(crate) fn new_liquid_sdk_with_chain_services(
config.onchain_fee_rate_leeway_sat_per_vbyte = onchain_fee_rate_leeway_sat_per_vbyte;
let signer: Arc<Box<dyn Signer>> = Arc::new(Box::new(MockSigner::new()?));
let rest_client: Arc<dyn RestClient> = Arc::new(MockRestClient::new());
let onchain_wallet = Arc::new(MockWallet::new(signer.clone())?);
let send_swap_handler = SendSwapHandler::new(
config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
);
let receive_swap_handler = ReceiveSwapHandler::new(
config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
);
let chain_swap_handler = Arc::new(ChainSwapHandler::new(
config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
)?);
let recoverer = Arc::new(Recoverer::new(
signer.slip77_master_blinding_key()?,
swapper.clone(),
@@ -96,38 +64,19 @@ pub(crate) fn new_liquid_sdk_with_chain_services(
bitcoin_chain_service.clone(),
)?);
let event_manager = Arc::new(EventManager::new());
let (shutdown_sender, shutdown_receiver) = watch::channel::<()>(());
let breez_server = Arc::new(BreezServer::new(STAGING_BREEZSERVER_URL.into(), None)?);
let buy_bitcoin_service =
Arc::new(BuyBitcoinService::new(config.clone(), breez_server.clone()));
let (_incoming_tx, _outgoing_records, sync_service) =
new_sync_service(persister.clone(), recoverer.clone(), signer.clone())?;
let sync_service = Some(Arc::new(sync_service));
let sync_service = Arc::new(sync_service);
Ok(LiquidSdk {
config,
onchain_wallet,
signer,
persister,
event_manager,
status_stream,
swapper,
recoverer,
liquid_chain_service,
bitcoin_chain_service,
fiat_api: breez_server,
is_started: RwLock::new(true),
shutdown_sender,
shutdown_receiver,
send_swap_handler,
receive_swap_handler,
sync_service,
chain_swap_handler,
buy_bitcoin_service,
external_input_parsers: Vec::new(),
})
LiquidSdkBuilder::new(config, STAGING_BREEZSERVER_URL.into(), signer)?
.bitcoin_chain_service(bitcoin_chain_service)
.liquid_chain_service(liquid_chain_service)
.onchain_wallet(onchain_wallet)
.persister(persister)
.recoverer(recoverer)
.rest_client(rest_client)
.status_stream(status_stream)
.swapper(swapper)
.sync_service(sync_service)
.build()
}

View File

@@ -1,7 +1,6 @@
#![cfg(test)]
use anyhow::Result;
use async_trait::async_trait;
use boltz_client::{
boltz::{
ChainFees, ChainMinerFees, ChainPair, ChainSwapDetails, CreateChainResponse,
@@ -113,7 +112,7 @@ impl MockSwapper {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl Swapper for MockSwapper {
async fn create_chain_swap(
&self,
@@ -385,7 +384,7 @@ impl MockProxyUrlFetcher {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl ProxyUrlFetcher for MockProxyUrlFetcher {
async fn fetch(&self) -> Result<&Option<String>> {
Ok(&None)

View File

@@ -17,7 +17,6 @@ use crate::{
},
};
use anyhow::Result;
use async_trait::async_trait;
use tokio::sync::{
mpsc::{self, Receiver, Sender},
Mutex,
@@ -41,7 +40,7 @@ impl MockSyncerClient {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl SyncerClient for MockSyncerClient {
async fn connect(&self, _connect_url: String) -> Result<()> {
todo!()

View File

@@ -10,7 +10,6 @@ use crate::{
wallet::OnchainWallet,
};
use anyhow::Result;
use async_trait::async_trait;
use bip39::Mnemonic;
use boltz_client::{Keypair, Secp256k1};
use lazy_static::lazy_static;
@@ -42,7 +41,7 @@ impl MockWallet {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl OnchainWallet for MockWallet {
async fn transactions(&self) -> Result<Vec<WalletTx>, PaymentError> {
Ok(vec![])

View File

@@ -176,7 +176,10 @@ mod tests {
use crate::error::PaymentError;
use crate::utils::verify_payment_hash;
#[test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::test_all]
fn test_verify_payment_hash() -> anyhow::Result<()> {
let bolt11_invoice = "lnbc10u1pnczjaupp55392fur38rc2y9vzmhdy0tclvfels0lvlmzgvmhpg6q2mndxzmrsdqqcqzzsxqyz5vqsp5ya6pvchlsvl3mzqh3zw4hg3tz5pww77q6rcwfr52qchyrp7s6krs9p4gqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqysgqgnp0sskk0ljjew8vkc3udhzgquzs79evf5wezfaex9q4gjk5qcn8m3luauyte93lgassd8skh5m90glhtt52ry2wtftzrjn4h076z7sqdjry3d";
let bolt11_preimage = "c17a0a28d0523596ec909c2d439c0c2315b5bd996bf4ff48be50b2df08fb8ac1";

View File

@@ -6,7 +6,6 @@ use std::time::Instant;
use std::{path::Path, str::FromStr, sync::Arc};
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use boltz_client::ElementsAddress;
use log::{debug, info, warn};
use lwk_common::Signer as LwkSigner;
@@ -34,7 +33,7 @@ use lwk_wollet::secp256k1::Message;
static LN_MESSAGE_PREFIX: &[u8] = b"Lightning Signed Message:";
#[async_trait]
#[sdk_macros::async_trait]
pub trait OnchainWallet: Send + Sync {
/// List all transactions in the wallet
async fn transactions(&self) -> Result<Vec<WalletTx>, PaymentError>;
@@ -183,7 +182,7 @@ impl LiquidOnchainWallet {
}
}
#[async_trait]
#[sdk_macros::async_trait]
impl OnchainWallet for LiquidOnchainWallet {
/// List all transactions in the wallet
async fn transactions(&self) -> Result<Vec<WalletTx>, PaymentError> {
@@ -441,7 +440,10 @@ mod tests {
use anyhow::Result;
use tempdir::TempDir;
#[tokio::test]
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[sdk_macros::async_test_all]
async fn test_sign_and_check_message() -> Result<()> {
let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
let sdk_signer: Box<dyn Signer> = Box::new(SdkSigner::new(mnemonic, "", false).unwrap());

View File

@@ -11,6 +11,13 @@ crate-type = ["cdylib"]
workspace = true
[dependencies]
anyhow = { workspace = true }
breez-sdk-liquid = { path = "../core" }
console_log = "1"
js-sys = "0.3.77"
log = { workspace = true }
sdk-macros = { workspace = true }
serde = { workspace = true }
tsify-next = "0.5.5"
wasm-bindgen = "0.2.100"
wasm-bindgen-futures = "0.4.50"

23
lib/wasm/Makefile Normal file
View File

@@ -0,0 +1,23 @@
UNAME := $(shell uname)
ifeq ($(UNAME), Darwin)
CLANG_PREFIX += AR=$(shell brew --prefix llvm)/bin/llvm-ar CC=$(shell brew --prefix llvm)/bin/clang
endif
init:
cargo install wasm-pack
clippy:
$(CLANG_PREFIX) cargo clippy --target=wasm32-unknown-unknown -- -D warnings
pack:
$(CLANG_PREFIX) wasm-pack build --weak-refs --target web --scope @breeztech
test:
$(CLANG_PREFIX) wasm-pack test --headless --firefox
test-chrome:
$(CLANG_PREFIX) wasm-pack test --headless --chrome
test-safari:
$(CLANG_PREFIX) wasm-pack test --headless --safari

51
lib/wasm/src/error.rs Normal file
View File

@@ -0,0 +1,51 @@
use breez_sdk_liquid::{
error::{PaymentError, SdkError},
LnUrlAuthError, LnUrlPayError, LnUrlWithdrawError,
};
use std::fmt::Display;
use wasm_bindgen::{JsError, JsValue};
#[derive(Clone, Debug)]
pub struct WasmError(JsValue);
impl WasmError {
pub fn new<T: Display>(val: T) -> Self {
WasmError(JsValue::from(format!("{}", val)))
}
}
impl From<WasmError> for JsValue {
fn from(err: WasmError) -> Self {
err.0
}
}
impl From<JsValue> for WasmError {
fn from(err: JsValue) -> Self {
Self(err)
}
}
macro_rules! wasm_error_wrapper {
($($t:ty),*) => {
$(
impl From<$t> for WasmError {
fn from(err: $t) -> Self {
WasmError(JsError::new(format!("{}", err).as_str()).into())
}
}
)*
}
}
wasm_error_wrapper!(
anyhow::Error,
LnUrlAuthError,
LnUrlPayError,
LnUrlWithdrawError,
log::ParseLevelError,
PaymentError,
SdkError,
&str,
String
);

27
lib/wasm/src/event.rs Normal file
View File

@@ -0,0 +1,27 @@
use wasm_bindgen::prelude::*;
use crate::model::SdkEvent;
pub struct WasmEventListener {
pub listener: EventListener,
}
impl breez_sdk_liquid::prelude::EventListener for WasmEventListener {
fn on_event(&self, e: breez_sdk_liquid::prelude::SdkEvent) {
self.listener.on_event(e.into());
}
}
#[wasm_bindgen(typescript_custom_section)]
const EVENT_INTERFACE: &'static str = r#"export interface EventListener {
onEvent: (e: SdkEvent) => void;
}"#;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(typescript_type = "EventListener")]
pub type EventListener;
#[wasm_bindgen(structural, method, js_name = onEvent)]
pub fn on_event(this: &EventListener, e: SdkEvent);
}

View File

@@ -1,6 +1,320 @@
mod error;
mod event;
pub mod model;
mod signer;
use std::str::FromStr;
use std::sync::Arc;
use anyhow::anyhow;
use breez_sdk_liquid::sdk::LiquidSdk;
use log::Level;
use signer::{Signer, WasmSigner};
use wasm_bindgen::prelude::*;
use crate::event::{EventListener, WasmEventListener};
use crate::model::*;
#[wasm_bindgen]
pub struct LiquidSdk {
_inner: breez_sdk_liquid::sdk::LiquidSdk,
pub struct BindingLiquidSdk {
sdk: Arc<LiquidSdk>,
}
#[wasm_bindgen(js_name = "connect")]
pub async fn connect(req: ConnectRequest) -> WasmResult<BindingLiquidSdk> {
let sdk = LiquidSdk::connect(req.into()).await?;
Ok(BindingLiquidSdk { sdk })
}
#[wasm_bindgen(js_name = "connectWithSigner")]
pub async fn connect_with_signer(
req: ConnectWithSignerRequest,
signer: Signer,
) -> WasmResult<BindingLiquidSdk> {
let wasm_signer = Box::new(WasmSigner { signer });
let sdk = LiquidSdk::connect_with_signer(req.into(), wasm_signer).await?;
Ok(BindingLiquidSdk { sdk })
}
#[wasm_bindgen(js_name = "defaultConfig")]
pub fn default_config(network: LiquidNetwork, breez_api_key: Option<String>) -> WasmResult<Config> {
Ok(LiquidSdk::default_config(network.into(), breez_api_key)?.into())
}
#[wasm_bindgen(js_name = "parseInvoice")]
pub fn parse_invoice(input: String) -> WasmResult<LNInvoice> {
Ok(LiquidSdk::parse_invoice(&input)?.into())
}
#[wasm_bindgen(js_name = "initLogger")]
pub fn init_logger(level: String) -> WasmResult<()> {
Ok(console_log::init_with_level(Level::from_str(&level)?)
.map_err(|_| anyhow!("Logger already created"))?)
}
#[wasm_bindgen]
impl BindingLiquidSdk {
#[wasm_bindgen(js_name = "getInfo")]
pub async fn get_info(&self) -> WasmResult<GetInfoResponse> {
Ok(self.sdk.get_info().await?.into())
}
#[wasm_bindgen(js_name = "signMessage")]
pub fn sign_message(&self, req: SignMessageRequest) -> WasmResult<SignMessageResponse> {
Ok(self.sdk.sign_message(&req.into())?.into())
}
#[wasm_bindgen(js_name = "checkMessage")]
pub fn check_message(&self, req: CheckMessageRequest) -> WasmResult<CheckMessageResponse> {
Ok(self.sdk.check_message(&req.into())?.into())
}
#[wasm_bindgen(js_name = "parse")]
pub async fn parse(&self, input: String) -> WasmResult<InputType> {
Ok(self.sdk.parse(&input).await?.into())
}
#[wasm_bindgen(js_name = "addEventListener")]
pub async fn add_event_listener(&self, listener: EventListener) -> WasmResult<String> {
Ok(self
.sdk
.add_event_listener(Box::new(WasmEventListener { listener }))
.await?)
}
#[wasm_bindgen(js_name = "removeEventListener")]
pub async fn remove_event_listener(&self, id: String) -> WasmResult<()> {
self.sdk.remove_event_listener(id).await?;
Ok(())
}
#[wasm_bindgen(js_name = "prepareSendPayment")]
pub async fn prepare_send_payment(
&self,
req: PrepareSendRequest,
) -> WasmResult<PrepareSendResponse> {
Ok(self.sdk.prepare_send_payment(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "sendPayment")]
pub async fn send_payment(&self, req: SendPaymentRequest) -> WasmResult<SendPaymentResponse> {
Ok(self.sdk.send_payment(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "preparePeceivePayment")]
pub async fn prepare_receive_payment(
&self,
req: PrepareReceiveRequest,
) -> WasmResult<PrepareReceiveResponse> {
Ok(self.sdk.prepare_receive_payment(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "receivePayment")]
pub async fn receive_payment(
&self,
req: ReceivePaymentRequest,
) -> WasmResult<ReceivePaymentResponse> {
Ok(self.sdk.receive_payment(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "fetchLightningLimits")]
pub async fn fetch_lightning_limits(&self) -> WasmResult<LightningPaymentLimitsResponse> {
Ok(self.sdk.fetch_lightning_limits().await?.into())
}
#[wasm_bindgen(js_name = "fetchOnchainLimits")]
pub async fn fetch_onchain_limits(&self) -> WasmResult<OnchainPaymentLimitsResponse> {
Ok(self.sdk.fetch_onchain_limits().await?.into())
}
#[wasm_bindgen(js_name = "preparePayOnchain")]
pub async fn prepare_pay_onchain(
&self,
req: PreparePayOnchainRequest,
) -> WasmResult<PreparePayOnchainResponse> {
Ok(self.sdk.prepare_pay_onchain(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "payOnchain")]
pub async fn pay_onchain(&self, req: PayOnchainRequest) -> WasmResult<SendPaymentResponse> {
Ok(self.sdk.pay_onchain(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "prepareBuyBitcoin")]
pub async fn prepare_buy_bitcoin(
&self,
req: PrepareBuyBitcoinRequest,
) -> WasmResult<PrepareBuyBitcoinResponse> {
Ok(self.sdk.prepare_buy_bitcoin(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "buyBitcoin")]
pub async fn buy_bitcoin(&self, req: BuyBitcoinRequest) -> WasmResult<String> {
Ok(self.sdk.buy_bitcoin(&req.into()).await?)
}
#[wasm_bindgen(js_name = "listPayments")]
pub async fn list_payments(&self, req: ListPaymentsRequest) -> WasmResult<Vec<Payment>> {
Ok(self
.sdk
.list_payments(&req.into())
.await?
.into_iter()
.map(|r| r.into())
.collect())
}
#[wasm_bindgen(js_name = "getPayment")]
pub async fn get_payment(&self, req: GetPaymentRequest) -> WasmResult<Option<Payment>> {
Ok(self.sdk.get_payment(&req.into()).await?.map(|r| r.into()))
}
#[wasm_bindgen(js_name = "fetchPaymentProposedFees")]
pub async fn fetch_payment_proposed_fees(
&self,
req: FetchPaymentProposedFeesRequest,
) -> WasmResult<FetchPaymentProposedFeesResponse> {
Ok(self
.sdk
.fetch_payment_proposed_fees(&req.into())
.await?
.into())
}
#[wasm_bindgen(js_name = "acceptPaymentProposedFees")]
pub async fn accept_payment_proposed_fees(
&self,
req: AcceptPaymentProposedFeesRequest,
) -> WasmResult<()> {
self.sdk.accept_payment_proposed_fees(&req.into()).await?;
Ok(())
}
#[wasm_bindgen(js_name = "prepareLnurlPay")]
pub async fn prepare_lnurl_pay(
&self,
req: PrepareLnUrlPayRequest,
) -> WasmResult<PrepareLnUrlPayResponse> {
Ok(self.sdk.prepare_lnurl_pay(req.into()).await?.into())
}
#[wasm_bindgen(js_name = "lnurlPay")]
pub async fn lnurl_pay(&self, req: LnUrlPayRequest) -> WasmResult<LnUrlPayResult> {
Ok(self.sdk.lnurl_pay(req.into()).await?.into())
}
#[wasm_bindgen(js_name = "lnurlWithdraw")]
pub async fn lnurl_withdraw(
&self,
req: LnUrlWithdrawRequest,
) -> WasmResult<LnUrlWithdrawResult> {
Ok(self.sdk.lnurl_withdraw(req.into()).await?.into())
}
#[wasm_bindgen(js_name = "lnurlAuth")]
pub async fn lnurl_auth(
&self,
req_data: LnUrlAuthRequestData,
) -> WasmResult<LnUrlCallbackStatus> {
Ok(self.sdk.lnurl_auth(req_data.into()).await?.into())
}
#[wasm_bindgen(js_name = "registerWebhook")]
pub async fn register_webhook(&self, webhook_url: String) -> WasmResult<()> {
self.sdk.register_webhook(webhook_url).await?;
Ok(())
}
#[wasm_bindgen(js_name = "unregisterWebhook")]
pub async fn unregister_webhook(&self) -> WasmResult<()> {
self.sdk.unregister_webhook().await?;
Ok(())
}
#[wasm_bindgen(js_name = "fetchFiatRates")]
pub async fn fetch_fiat_rates(&self) -> WasmResult<Vec<Rate>> {
Ok(self
.sdk
.fetch_fiat_rates()
.await?
.into_iter()
.map(|r| r.into())
.collect())
}
#[wasm_bindgen(js_name = "listFiatCurrencies")]
pub async fn list_fiat_currencies(&self) -> WasmResult<Vec<FiatCurrency>> {
Ok(self
.sdk
.list_fiat_currencies()
.await?
.into_iter()
.map(|r| r.into())
.collect())
}
#[wasm_bindgen(js_name = "listRefundables")]
pub async fn list_refundables(&self) -> WasmResult<Vec<RefundableSwap>> {
Ok(self
.sdk
.list_refundables()
.await?
.into_iter()
.map(|r| r.into())
.collect())
}
#[wasm_bindgen(js_name = "prepareRefund")]
pub async fn prepare_refund(
&self,
req: PrepareRefundRequest,
) -> WasmResult<PrepareRefundResponse> {
Ok(self.sdk.prepare_refund(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "refund")]
pub async fn refund(&self, req: RefundRequest) -> WasmResult<RefundResponse> {
Ok(self.sdk.refund(&req.into()).await?.into())
}
#[wasm_bindgen(js_name = "rescanOnchainSwaps")]
pub async fn rescan_onchain_swaps(&self) -> WasmResult<()> {
self.sdk.rescan_onchain_swaps().await?;
Ok(())
}
#[wasm_bindgen(js_name = "sync")]
pub async fn sync(&self) -> WasmResult<()> {
self.sdk.sync(false).await?;
Ok(())
}
#[wasm_bindgen(js_name = "recommendedFees")]
pub async fn recommended_fees(&self) -> WasmResult<RecommendedFees> {
Ok(self.sdk.recommended_fees().await?.into())
}
#[wasm_bindgen(js_name = "emptyWalletCache")]
pub fn empty_wallet_cache(&self) -> WasmResult<()> {
self.sdk.empty_wallet_cache()?;
Ok(())
}
#[wasm_bindgen(js_name = "backup")]
pub fn backup(&self, req: BackupRequest) -> WasmResult<()> {
self.sdk.backup(req.into())?;
Ok(())
}
#[wasm_bindgen(js_name = "restore")]
pub fn restore(&self, req: RestoreRequest) -> WasmResult<()> {
self.sdk.restore(req.into())?;
Ok(())
}
#[wasm_bindgen(js_name = "disconnect")]
pub async fn disconnect(&self) -> WasmResult<()> {
self.sdk.disconnect().await?;
Ok(())
}
}

798
lib/wasm/src/model.rs Normal file
View File

@@ -0,0 +1,798 @@
use crate::error::WasmError;
pub type WasmResult<T> = Result<T, WasmError>;
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::Network)]
pub enum Network {
Bitcoin,
Testnet,
Signet,
Regtest,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ExternalInputParser)]
pub struct ExternalInputParser {
pub provider_id: String,
pub input_regex: String,
pub parser_url: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LNInvoice)]
pub struct LNInvoice {
pub bolt11: String,
pub network: Network,
pub payee_pubkey: String,
pub payment_hash: String,
pub description: Option<String>,
pub description_hash: Option<String>,
pub amount_msat: Option<u64>,
pub timestamp: u64,
pub expiry: u64,
pub routing_hints: Vec<RouteHint>,
pub payment_secret: Vec<u8>,
pub min_final_cltv_expiry_delta: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::RouteHint)]
pub struct RouteHint {
pub hops: Vec<RouteHintHop>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::RouteHintHop)]
pub struct RouteHintHop {
pub src_node_id: String,
pub short_channel_id: String,
pub fees_base_msat: u32,
pub fees_proportional_millionths: u32,
pub cltv_expiry_delta: u64,
pub htlc_minimum_msat: Option<u64>,
pub htlc_maximum_msat: Option<u64>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::Amount)]
pub enum Amount {
Bitcoin {
amount_msat: u64,
},
Currency {
iso4217_code: String,
fractional_amount: u64,
},
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnOfferBlindedPath)]
pub struct LnOfferBlindedPath {
pub blinded_hops: Vec<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LNOffer)]
pub struct LNOffer {
pub offer: String,
pub chains: Vec<String>,
pub min_amount: Option<Amount>,
pub description: Option<String>,
pub absolute_expiry: Option<u64>,
pub issuer: Option<String>,
pub signing_pubkey: Option<String>,
pub paths: Vec<LnOfferBlindedPath>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::InputType)]
pub enum InputType {
BitcoinAddress {
address: BitcoinAddressData,
},
LiquidAddress {
address: LiquidAddressData,
},
Bolt11 {
invoice: LNInvoice,
},
Bolt12Offer {
offer: LNOffer,
bip353_address: Option<String>,
},
NodeId {
node_id: String,
},
Url {
url: String,
},
LnUrlPay {
data: LnUrlPayRequestData,
bip353_address: Option<String>,
},
LnUrlWithdraw {
data: LnUrlWithdrawRequestData,
},
LnUrlAuth {
data: LnUrlAuthRequestData,
},
LnUrlError {
data: LnUrlErrorData,
},
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::BitcoinAddressData)]
pub struct BitcoinAddressData {
pub address: String,
pub network: breez_sdk_liquid::prelude::Network,
pub amount_sat: Option<u64>,
pub label: Option<String>,
pub message: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LiquidAddressData)]
pub struct LiquidAddressData {
pub address: String,
pub network: Network,
pub asset_id: Option<String>,
pub amount: Option<f64>,
pub amount_sat: Option<u64>,
pub label: Option<String>,
pub message: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlPayRequestData)]
pub struct LnUrlPayRequestData {
pub callback: String,
pub min_sendable: u64,
pub max_sendable: u64,
pub metadata_str: String,
pub comment_allowed: u16,
pub domain: String,
pub allows_nostr: bool,
pub nostr_pubkey: Option<String>,
pub ln_address: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SuccessAction)]
pub enum SuccessAction {
Aes { data: AesSuccessActionData },
Message { data: MessageSuccessActionData },
Url { data: UrlSuccessActionData },
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SuccessActionProcessed)]
pub enum SuccessActionProcessed {
Aes { result: AesSuccessActionDataResult },
Message { data: MessageSuccessActionData },
Url { data: UrlSuccessActionData },
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::AesSuccessActionData)]
pub struct AesSuccessActionData {
pub description: String,
pub ciphertext: String,
pub iv: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::AesSuccessActionDataResult)]
pub enum AesSuccessActionDataResult {
Decrypted { data: AesSuccessActionDataDecrypted },
ErrorStatus { reason: String },
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::AesSuccessActionDataDecrypted)]
pub struct AesSuccessActionDataDecrypted {
pub description: String,
pub plaintext: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::MessageSuccessActionData)]
pub struct MessageSuccessActionData {
pub message: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::UrlSuccessActionData)]
pub struct UrlSuccessActionData {
pub description: String,
pub url: String,
pub matches_callback_domain: bool,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlPayErrorData)]
pub struct LnUrlPayErrorData {
pub payment_hash: String,
pub reason: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlWithdrawRequestData)]
pub struct LnUrlWithdrawRequestData {
pub callback: String,
pub k1: String,
pub default_description: String,
pub min_withdrawable: u64,
pub max_withdrawable: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlCallbackStatus)]
pub enum LnUrlCallbackStatus {
Ok,
#[serde(rename = "ERROR")]
ErrorStatus {
#[serde(flatten)]
data: LnUrlErrorData,
},
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlAuthRequestData)]
pub struct LnUrlAuthRequestData {
pub k1: String,
pub action: Option<String>,
pub domain: String,
pub url: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlErrorData)]
pub struct LnUrlErrorData {
pub reason: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlWithdrawRequest)]
pub struct LnUrlWithdrawRequest {
pub data: LnUrlWithdrawRequestData,
pub amount_msat: u64,
pub description: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlWithdrawSuccessData)]
pub struct LnUrlWithdrawSuccessData {
pub invoice: LNInvoice,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlWithdrawResult)]
pub enum LnUrlWithdrawResult {
Ok { data: LnUrlWithdrawSuccessData },
Timeout { data: LnUrlWithdrawSuccessData },
ErrorStatus { data: LnUrlErrorData },
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::Rate)]
pub struct Rate {
pub coin: String,
pub value: f64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::FiatCurrency)]
pub struct FiatCurrency {
pub id: String,
pub info: CurrencyInfo,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::CurrencyInfo)]
pub struct CurrencyInfo {
pub name: String,
pub fraction_size: u32,
pub spacing: Option<u32>,
pub symbol: Option<Symbol>,
pub uniq_symbol: Option<Symbol>,
pub localized_name: Vec<LocalizedName>,
pub locale_overrides: Vec<LocaleOverrides>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LocaleOverrides)]
pub struct LocaleOverrides {
pub locale: String,
pub spacing: Option<u32>,
pub symbol: Symbol,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LocalizedName)]
pub struct LocalizedName {
pub locale: String,
pub name: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::Symbol)]
pub struct Symbol {
pub grapheme: Option<String>,
pub template: Option<String>,
pub rtl: Option<bool>,
pub position: Option<u32>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::Config)]
pub struct Config {
pub liquid_electrum_url: String,
pub bitcoin_electrum_url: String,
pub mempoolspace_url: String,
pub working_dir: String,
pub cache_dir: Option<String>,
pub network: LiquidNetwork,
pub payment_timeout_sec: u64,
pub sync_service_url: Option<String>,
pub zero_conf_max_amount_sat: Option<u64>,
pub breez_api_key: Option<String>,
pub external_input_parsers: Option<Vec<ExternalInputParser>>,
pub use_default_external_input_parsers: bool,
pub onchain_fee_rate_leeway_sat_per_vbyte: Option<u32>,
pub asset_metadata: Option<Vec<AssetMetadata>>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LiquidNetwork)]
pub enum LiquidNetwork {
Mainnet,
Testnet,
Regtest,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SdkEvent)]
pub enum SdkEvent {
PaymentFailed { details: Payment },
PaymentPending { details: Payment },
PaymentRefundable { details: Payment },
PaymentRefunded { details: Payment },
PaymentRefundPending { details: Payment },
PaymentSucceeded { details: Payment },
PaymentWaitingConfirmation { details: Payment },
PaymentWaitingFeeAcceptance { details: Payment },
Synced,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ConnectRequest)]
pub struct ConnectRequest {
pub config: Config,
pub mnemonic: Option<String>,
pub passphrase: Option<String>,
pub seed: Option<Vec<u8>>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ConnectWithSignerRequest)]
pub struct ConnectWithSignerRequest {
pub config: Config,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PaymentMethod)]
pub enum PaymentMethod {
Lightning,
BitcoinAddress,
LiquidAddress,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ReceiveAmount)]
pub enum ReceiveAmount {
Bitcoin {
payer_amount_sat: u64,
},
Asset {
asset_id: String,
payer_amount: Option<f64>,
},
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareReceiveRequest)]
pub struct PrepareReceiveRequest {
pub payment_method: PaymentMethod,
pub amount: Option<ReceiveAmount>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareReceiveResponse)]
pub struct PrepareReceiveResponse {
pub payment_method: PaymentMethod,
pub amount: Option<ReceiveAmount>,
pub fees_sat: u64,
pub min_payer_amount_sat: Option<u64>,
pub max_payer_amount_sat: Option<u64>,
pub swapper_feerate: Option<f64>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ReceivePaymentRequest)]
pub struct ReceivePaymentRequest {
pub prepare_response: PrepareReceiveResponse,
pub description: Option<String>,
pub use_description_hash: Option<bool>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ReceivePaymentResponse)]
pub struct ReceivePaymentResponse {
pub destination: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::Limits)]
pub struct Limits {
pub min_sat: u64,
pub max_sat: u64,
pub max_zero_conf_sat: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LightningPaymentLimitsResponse)]
pub struct LightningPaymentLimitsResponse {
pub send: Limits,
pub receive: Limits,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::OnchainPaymentLimitsResponse)]
pub struct OnchainPaymentLimitsResponse {
pub send: Limits,
pub receive: Limits,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareSendRequest)]
pub struct PrepareSendRequest {
pub destination: String,
pub amount: Option<PayAmount>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SendDestination)]
pub enum SendDestination {
LiquidAddress {
address_data: LiquidAddressData,
},
Bolt11 {
invoice: LNInvoice,
bip353_address: Option<String>,
},
Bolt12 {
offer: LNOffer,
receiver_amount_sat: u64,
bip353_address: Option<String>,
},
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareSendResponse)]
pub struct PrepareSendResponse {
pub destination: SendDestination,
pub fees_sat: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SendPaymentRequest)]
pub struct SendPaymentRequest {
pub prepare_response: PrepareSendResponse,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SendPaymentResponse)]
pub struct SendPaymentResponse {
pub payment: Payment,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PayAmount)]
pub enum PayAmount {
Bitcoin {
receiver_amount_sat: u64,
},
Asset {
asset_id: String,
receiver_amount: f64,
},
Drain,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PreparePayOnchainRequest)]
pub struct PreparePayOnchainRequest {
pub amount: PayAmount,
pub fee_rate_sat_per_vbyte: Option<u32>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PreparePayOnchainResponse)]
pub struct PreparePayOnchainResponse {
pub receiver_amount_sat: u64,
pub claim_fees_sat: u64,
pub total_fees_sat: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PayOnchainRequest)]
pub struct PayOnchainRequest {
pub address: String,
pub prepare_response: PreparePayOnchainResponse,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareRefundRequest)]
pub struct PrepareRefundRequest {
pub swap_address: String,
pub refund_address: String,
pub fee_rate_sat_per_vbyte: u32,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareRefundResponse)]
pub struct PrepareRefundResponse {
pub tx_vsize: u32,
pub tx_fee_sat: u64,
pub last_refund_tx_id: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::RefundRequest)]
pub struct RefundRequest {
pub swap_address: String,
pub refund_address: String,
pub fee_rate_sat_per_vbyte: u32,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::RefundResponse)]
pub struct RefundResponse {
pub refund_tx_id: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::AssetBalance)]
pub struct AssetBalance {
pub asset_id: String,
pub balance_sat: u64,
pub name: Option<String>,
pub ticker: Option<String>,
pub balance: Option<f64>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::BlockchainInfo)]
pub struct BlockchainInfo {
pub liquid_tip: u32,
pub bitcoin_tip: u32,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::WalletInfo)]
pub struct WalletInfo {
pub balance_sat: u64,
pub pending_send_sat: u64,
pub pending_receive_sat: u64,
pub fingerprint: String,
pub pubkey: String,
pub asset_balances: Vec<AssetBalance>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::GetInfoResponse)]
pub struct GetInfoResponse {
pub wallet_info: WalletInfo,
pub blockchain_info: BlockchainInfo,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SignMessageRequest)]
pub struct SignMessageRequest {
pub message: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::SignMessageResponse)]
pub struct SignMessageResponse {
pub signature: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::CheckMessageRequest)]
pub struct CheckMessageRequest {
pub message: String,
pub pubkey: String,
pub signature: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::CheckMessageResponse)]
pub struct CheckMessageResponse {
pub is_valid: bool,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::BackupRequest)]
pub struct BackupRequest {
pub backup_path: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::RestoreRequest)]
pub struct RestoreRequest {
pub backup_path: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ListPaymentsRequest)]
pub struct ListPaymentsRequest {
pub filters: Option<Vec<PaymentType>>,
pub states: Option<Vec<PaymentState>>,
pub from_timestamp: Option<i64>,
pub to_timestamp: Option<i64>,
pub offset: Option<u32>,
pub limit: Option<u32>,
pub details: Option<ListPaymentDetails>,
pub sort_ascending: Option<bool>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::ListPaymentDetails)]
pub enum ListPaymentDetails {
Liquid {
asset_id: Option<String>,
destination: Option<String>,
},
Bitcoin {
address: Option<String>,
},
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::GetPaymentRequest)]
pub enum GetPaymentRequest {
PaymentHash { payment_hash: String },
SwapId { swap_id: String },
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::RefundableSwap)]
pub struct RefundableSwap {
pub swap_address: String,
pub timestamp: u32,
pub amount_sat: u64,
pub last_refund_tx_id: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PaymentState)]
pub enum PaymentState {
Created = 0,
Pending = 1,
Complete = 2,
Failed = 3,
TimedOut = 4,
Refundable = 5,
RefundPending = 6,
WaitingFeeAcceptance = 7,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PaymentType)]
pub enum PaymentType {
Receive = 0,
Send = 1,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PaymentStatus)]
pub enum PaymentStatus {
Pending = 0,
Complete = 1,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LnUrlInfo)]
pub struct LnUrlInfo {
pub ln_address: Option<String>,
pub lnurl_pay_comment: Option<String>,
pub lnurl_pay_domain: Option<String>,
pub lnurl_pay_metadata: Option<String>,
pub lnurl_pay_success_action: Option<SuccessActionProcessed>,
pub lnurl_pay_unprocessed_success_action: Option<SuccessAction>,
pub lnurl_withdraw_endpoint: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::AssetMetadata)]
pub struct AssetMetadata {
pub asset_id: String,
pub name: String,
pub ticker: String,
pub precision: u8,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::AssetInfo)]
pub struct AssetInfo {
pub name: String,
pub ticker: String,
pub amount: f64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PaymentDetails)]
#[allow(clippy::large_enum_variant)]
pub enum PaymentDetails {
Lightning {
swap_id: String,
description: String,
liquid_expiration_blockheight: u32,
preimage: Option<String>,
invoice: Option<String>,
bolt12_offer: Option<String>,
payment_hash: Option<String>,
destination_pubkey: Option<String>,
lnurl_info: Option<LnUrlInfo>,
bip353_address: Option<String>,
claim_tx_id: Option<String>,
refund_tx_id: Option<String>,
refund_tx_amount_sat: Option<u64>,
},
Liquid {
destination: String,
description: String,
asset_id: String,
asset_info: Option<AssetInfo>,
},
Bitcoin {
swap_id: String,
description: String,
auto_accepted_fees: bool,
liquid_expiration_blockheight: Option<u32>,
bitcoin_expiration_blockheight: Option<u32>,
claim_tx_id: Option<String>,
refund_tx_id: Option<String>,
refund_tx_amount_sat: Option<u64>,
},
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::Payment)]
pub struct Payment {
pub destination: Option<String>,
pub tx_id: Option<String>,
pub unblinding_data: Option<String>,
pub timestamp: u32,
pub amount_sat: u64,
pub fees_sat: u64,
pub swapper_fees_sat: Option<u64>,
pub payment_type: PaymentType,
pub status: PaymentState,
pub details: PaymentDetails,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::RecommendedFees)]
pub struct RecommendedFees {
pub fastest_fee: u64,
pub half_hour_fee: u64,
pub hour_fee: u64,
pub economy_fee: u64,
pub minimum_fee: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::BuyBitcoinProvider)]
pub enum BuyBitcoinProvider {
Moonpay,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareBuyBitcoinRequest)]
pub struct PrepareBuyBitcoinRequest {
pub provider: BuyBitcoinProvider,
pub amount_sat: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareBuyBitcoinResponse)]
pub struct PrepareBuyBitcoinResponse {
pub provider: BuyBitcoinProvider,
pub amount_sat: u64,
pub fees_sat: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::BuyBitcoinRequest)]
pub struct BuyBitcoinRequest {
pub prepare_response: PrepareBuyBitcoinResponse,
pub redirect_url: Option<String>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::LogEntry)]
pub struct LogEntry {
pub line: String,
pub level: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareLnUrlPayRequest)]
pub struct PrepareLnUrlPayRequest {
pub data: LnUrlPayRequestData,
pub amount: PayAmount,
pub bip353_address: Option<String>,
pub comment: Option<String>,
pub validate_success_action_url: Option<bool>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::PrepareLnUrlPayResponse)]
pub struct PrepareLnUrlPayResponse {
pub destination: SendDestination,
pub fees_sat: u64,
pub data: LnUrlPayRequestData,
pub comment: Option<String>,
pub success_action: Option<SuccessAction>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::model::LnUrlPayRequest)]
pub struct LnUrlPayRequest {
pub prepare_response: PrepareLnUrlPayResponse,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::model::LnUrlPayResult)]
#[allow(clippy::large_enum_variant)]
pub enum LnUrlPayResult {
EndpointSuccess { data: LnUrlPaySuccessData },
EndpointError { data: LnUrlErrorData },
PayError { data: LnUrlPayErrorData },
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::model::LnUrlPaySuccessData)]
pub struct LnUrlPaySuccessData {
pub payment: Payment,
pub success_action: Option<SuccessActionProcessed>,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::FetchPaymentProposedFeesRequest)]
pub struct FetchPaymentProposedFeesRequest {
pub swap_id: String,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::FetchPaymentProposedFeesResponse)]
pub struct FetchPaymentProposedFeesResponse {
pub swap_id: String,
pub fees_sat: u64,
pub payer_amount_sat: u64,
pub receiver_amount_sat: u64,
}
#[sdk_macros::extern_wasm_bindgen(breez_sdk_liquid::prelude::AcceptPaymentProposedFeesRequest)]
pub struct AcceptPaymentProposedFeesRequest {
pub response: FetchPaymentProposedFeesResponse,
}

120
lib/wasm/src/signer.rs Normal file
View File

@@ -0,0 +1,120 @@
use breez_sdk_liquid::prelude::SignerError;
use wasm_bindgen::prelude::*;
pub struct WasmSigner {
pub signer: Signer,
}
impl breez_sdk_liquid::prelude::Signer for WasmSigner {
fn xpub(&self) -> Result<Vec<u8>, SignerError> {
self.signer.xpub().map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
fn derive_xpub(&self, derivation_path: String) -> Result<Vec<u8>, SignerError> {
self.signer
.derive_xpub(derivation_path)
.map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
fn sign_ecdsa(&self, msg: Vec<u8>, derivation_path: String) -> Result<Vec<u8>, SignerError> {
self.signer
.sign_ecdsa(msg, derivation_path)
.map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
fn sign_ecdsa_recoverable(&self, msg: Vec<u8>) -> Result<Vec<u8>, SignerError> {
self.signer
.sign_ecdsa_recoverable(msg)
.map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
fn slip77_master_blinding_key(&self) -> Result<Vec<u8>, SignerError> {
self.signer
.slip77_master_blinding_key()
.map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
fn hmac_sha256(&self, msg: Vec<u8>, derivation_path: String) -> Result<Vec<u8>, SignerError> {
self.signer
.hmac_sha256(msg, derivation_path)
.map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
fn ecies_encrypt(&self, msg: Vec<u8>) -> Result<Vec<u8>, SignerError> {
self.signer
.ecies_encrypt(msg)
.map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
fn ecies_decrypt(&self, msg: Vec<u8>) -> Result<Vec<u8>, SignerError> {
self.signer
.ecies_decrypt(msg)
.map_err(|e| SignerError::Generic {
err: e.to_string().into(),
})
}
}
#[wasm_bindgen(typescript_custom_section)]
const SIGNER_INTERFACE: &'static str = r#"export interface Signer {
xpub: () => number[];
deriveXpub: (derivationPath: string) => number[];
signEcdsa: (msg: number[], derivationPath: string) => number[];
signEcdsaRecoverable: (msg: number[]) => number[];
slip77MasterBlindingKey: () => number[];
hmacSha256: (msg: number[], derivationPath: string) => number[];
eciesEncrypt: (msg: number[]) => number[];
eciesDecrypt: (msg: number[]) => number[];
}"#;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(typescript_type = "Signer")]
pub type Signer;
#[wasm_bindgen(structural, catch, method, js_name = xpub)]
pub fn xpub(this: &Signer) -> Result<Vec<u8>, js_sys::Error>;
#[wasm_bindgen(structural, catch, method, js_name = deriveXpub)]
fn derive_xpub(this: &Signer, derivation_path: String) -> Result<Vec<u8>, js_sys::Error>;
#[wasm_bindgen(structural, catch, method, js_name = signEcdsa)]
fn sign_ecdsa(
this: &Signer,
msg: Vec<u8>,
derivation_path: String,
) -> Result<Vec<u8>, js_sys::Error>;
#[wasm_bindgen(structural, catch, method, js_name = signEcdsaRecoverable)]
fn sign_ecdsa_recoverable(this: &Signer, msg: Vec<u8>) -> Result<Vec<u8>, js_sys::Error>;
#[wasm_bindgen(structural, catch, method, js_name = slip77MasterBlindingKey)]
fn slip77_master_blinding_key(this: &Signer) -> Result<Vec<u8>, js_sys::Error>;
#[wasm_bindgen(structural, catch, method, js_name = hmacSha256)]
fn hmac_sha256(
this: &Signer,
msg: Vec<u8>,
derivation_path: String,
) -> Result<Vec<u8>, js_sys::Error>;
#[wasm_bindgen(structural, catch, method, js_name = eciesEncrypt)]
fn ecies_encrypt(this: &Signer, msg: Vec<u8>) -> Result<Vec<u8>, js_sys::Error>;
#[wasm_bindgen(structural, catch, method, js_name = eciesDecrypt)]
fn ecies_decrypt(this: &Signer, msg: Vec<u8>) -> Result<Vec<u8>, js_sys::Error>;
}