diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index f703074..987830d 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -39,6 +39,8 @@ jobs: - name: Set up Android SDK uses: android-actions/setup-android@v4 + with: + packages: platform-tools - name: Set up Android NDK id: setup-ndk @@ -80,10 +82,33 @@ jobs: path: bindings/android/native-debug-symbols.zip - name: Upload native debug symbols to release - if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} - run: gh release upload "${{ github.event.release.tag_name }}" bindings/android/native-debug-symbols.zip --clobber + TAG: ${{ github.event.release.tag_name || inputs.version }} + IS_RELEASE_EVENT: ${{ github.event_name == 'release' }} + shell: bash + run: | + # A release event always has a release to attach to, so upload straight + # away and let any failure fail the step. A manual publish may target a + # version with no release; skip the upload only in that case, so the + # package still reaches GitHub Packages. Any other lookup failure (auth, + # network, rate limiting) has to fail rather than silently publish + # without symbols. + if [ "$IS_RELEASE_EVENT" != "true" ]; then + if ! lookup=$(gh release view "$TAG" 2>&1 >/dev/null); then + case "${lookup,,}" in + *"not found"*) + echo "No release for $TAG; skipping the native debug symbols upload" + exit 0 + ;; + *) + echo "gh release view $TAG failed: $lookup" >&2 + exit 1 + ;; + esac + fi + fi + gh release upload "$TAG" bindings/android/native-debug-symbols.zip --clobber # same credentials env vars used in the publishing section of build.gradle.kts - name: Publish to GitHub Packages diff --git a/AGENTS.md b/AGENTS.md index 8af2db3..c182e83 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,7 +20,7 @@ Android bindings are built and published by `.github/workflows/gradle-publish.ym ```bash cargo test # All tests -cargo test modules:: # Single module (scanner, lnurl, onchain, activity, blocktank, trezor, pubky) +cargo test modules:: # Single module (scanner, lnurl, onchain, activity, blocktank, boltz, trezor, jade, hardware_wallet, ur, pubky) ``` ## Lint & Format @@ -35,7 +35,7 @@ Android bindings use ktlint via Gradle plugin (`org.jlleitschuh.gradle.ktlint`), ## Architecture - `src/lib.rs` — UniFFI exports and module re-exports -- `src/modules/` — Core modules: scanner, lnurl, onchain, activity, blocktank, trezor, pubky +- `src/modules/`: core modules: scanner, lnurl, onchain, activity, blocktank, boltz, trezor, jade, hardware_wallet, ur, pubky - `bindings/` — Platform-specific binding outputs (ios/, android/, python/) - `build.sh`, `build_ios.sh`, `build_android.sh`, `build_python.sh` — Build scripts @@ -43,7 +43,8 @@ Android bindings use ktlint via Gradle plugin (`org.jlleitschuh.gradle.ktlint`), - **Version sync**: Version must match across `Cargo.toml`, `Package.swift`, and `bindings/android/gradle.properties`. Use `build.sh -r` to bump all three. - **UniFFI**: Public types exposed to bindings are declared in `src/lib.rs`. Follow existing UniFFI patterns when adding new types. -- **Platform-specific deps**: Trezor uses Bluetooth-only on iOS, USB+Bluetooth on other platforms (see `Cargo.toml` target-specific dependencies). +- **Platform-specific deps**: Trezor uses Bluetooth-only on iOS, USB+Bluetooth on other platforms (see `Cargo.toml` target-specific dependencies). Jade's serial transport is desktop-only; `serialport` must keep `default-features = false` or CI loses `libudev`. +- **No cfg-gated UniFFI exports**: bindings are generated from the host library, so a host-only `#[uniffi::export]` would appear in the Swift and Kotlin output while being absent from the device library. - **Android build**: `build_android.sh` temporarily modifies `Cargo.toml` crate-type and removes `example/main.rs` during build — don't run concurrent builds. - **Android bindings**: Keep `bindings/android/lib/src/main/jniLibs/` untracked. GitHub Actions generates the JNI libraries before publishing the Android package. diff --git a/CHANGELOG.md b/CHANGELOG.md index 183e6fe..9577b40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog -## Unreleased +## 0.5.16 - 2026-09-14 + +- Serialize Jade discovery, connection setup, and teardown. A disconnect now cancels connection attempts that are in progress or queued, and a transport opened by a cancelled attempt is closed instead of leaked. A scan started while another lifecycle operation is running returns `DeviceBusy`. +- Bump `jade-client-rs` to `d52ccd9`, now sourced from `synonymdev/jade-client-rs`. The client closes transports after handshake or post-connect failures, bounds fragment and pinserver responses under absolute deadlines, rejects PSBTs without key origins, and releases serial descriptors on close. + +## 0.5.15 - 2026-09-07 + +- Add Blockstream Jade hardware wallet support: device discovery, connect, PIN unlock via the blind pinserver, extended public key and account export, on-device address verification, message signing, and PSBT signing, over Bluetooth on every platform and USB CDC serial on desktop and Python. Signed PSBTs feed the existing `finalize_psbt` path. The protocol lives in the `jade-client-rs` crate; this repo carries the UniFFI adapter. +- Add `HardwareWalletVendor.Blockstream` and catalog entries for Jade and Jade Plus. Note that adding an enum case makes exhaustive Kotlin `when` and Swift `switch` statements over `HardwareWalletVendor` non-exhaustive, which is source breaking for consumers. ## 0.5.14 - 2026-09-02 diff --git a/Cargo.lock b/Cargo.lock index 3896201..b2a0909 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "bitkitcore" -version = "0.5.14" +version = "0.5.17" dependencies = [ "android_logger", "async-trait", @@ -602,6 +602,7 @@ dependencies = [ "btleplug", "chrono", "hex", + "jade-client-rs", "jni", "lazy-regex", "lightning-invoice 0.32.0", @@ -967,6 +968,33 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -1204,6 +1232,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -1910,7 +1944,7 @@ dependencies = [ "libc", "log", "rustversion", - "windows-link 0.2.1", + "windows-link 0.1.3", "windows-result 0.4.1", ] @@ -2016,6 +2050,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + [[package]] name = "hash32" version = "0.2.1" @@ -2452,6 +2497,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -2489,6 +2544,29 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +[[package]] +name = "jade-client-rs" +version = "0.2.0" +source = "git+https://github.com/synonymdev/jade-client-rs?rev=d46d02a#d46d02a33b373805c487262390a85f9cec0f7723" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bitcoin 0.32.8", + "ciborium", + "log", + "minicbor", + "rand 0.8.5", + "reqwest", + "serde", + "serde_bytes", + "serde_json", + "serialport", + "thiserror 2.0.18", + "tokio", + "url", + "zeroize", +] + [[package]] name = "jiff" version = "0.2.29" @@ -2828,6 +2906,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + [[package]] name = "mainline" version = "5.4.0" @@ -2948,6 +3035,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -3748,7 +3846,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -4595,6 +4693,24 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "serialport" +version = "4.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a2f4ac56b5d3af3c40fbbee17be96d532cba02fa5853926aacdb77d926272ab" +dependencies = [ + "bitflags 2.11.0", + "cfg-if", + "core-foundation", + "core-foundation-sys", + "io-kit-sys", + "mach2", + "nix", + "scopeguard", + "unescaper", + "windows-sys 0.52.0", +] + [[package]] name = "sha1" version = "0.10.6" @@ -5342,6 +5458,15 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +[[package]] +name = "unescaper" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7285e83a80ce76f5e7bce79fa41f68d78ba62d1003cf27bf748ab24413808cf4" +dependencies = [ + "thiserror 2.0.18", +] + [[package]] name = "unicode-ident" version = "1.0.24" @@ -5976,7 +6101,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -5985,16 +6110,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -6012,31 +6128,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link 0.2.1", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -6054,96 +6153,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" version = "0.7.15" diff --git a/Cargo.toml b/Cargo.toml index 4a24f98..6eee7ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bitkitcore" -version = "0.5.14" +version = "0.5.17" edition = "2021" [lib] @@ -12,7 +12,7 @@ path = "src/lib.rs" uniffi = { version = "0.29.4", features = [ "cli", "bindgen" ] } serde_json = "1.0.114" serde = { version = "^1.0.209", features = ["derive"] } -tokio = { version = "1.40.0", features = ["rt", "rt-multi-thread", "macros"] } +tokio = { version = "1.40.0", features = ["rt", "rt-multi-thread", "macros", "time", "sync"] } bitcoin = "0.32.4" miniscript = "12.3.7" chrono = "0.4" @@ -62,6 +62,16 @@ trezor-connect-rs = { version = "0.4.0", default-features = false, features = [" jni = "0.19" android_logger = "0.14" +# Jade hardware wallet protocol. Bluetooth is driven by the native application +# through JadeTransportCallback, so the crate's own serial transport is only +# wanted where a Rust side serial port makes sense. +[target.'cfg(any(target_os = "ios", target_os = "android"))'.dependencies] +jade-client-rs = { git = "https://github.com/synonymdev/jade-client-rs", rev = "d46d02a", default-features = false, features = ["reqwest-pinserver"] } + +# Desktop and Python additionally get the crate's serial transport. +[target.'cfg(not(any(target_os = "ios", target_os = "android")))'.dependencies] +jade-client-rs = { git = "https://github.com/synonymdev/jade-client-rs", rev = "d46d02a", features = ["reqwest-pinserver", "serial"] } + [dev-dependencies] tokio = { version = "1.40.0", features = ["full"] } serde_json = "1.0.114" diff --git a/Package.swift b/Package.swift index 18395bb..c961ae8 100644 --- a/Package.swift +++ b/Package.swift @@ -3,8 +3,8 @@ import PackageDescription -let tag = "v0.5.14" -let checksum = "2e5d3a3e263d2de044c3d5b9a9ddcc789c8cf651b6bbd240fb7fe407b5e9be84" +let tag = "v0.5.17" +let checksum = "b1cd6d47d2fb3e9772805f6bf14041dd5125a21c130543ee26a4d8ac3398d66f" let url = "https://github.com/synonymdev/bitkit-core/releases/download/\(tag)/BitkitCore.xcframework.zip" let package = Package( diff --git a/bindings/android/gradle.properties b/bindings/android/gradle.properties index 8c3a0e2..f88afeb 100644 --- a/bindings/android/gradle.properties +++ b/bindings/android/gradle.properties @@ -3,4 +3,4 @@ android.useAndroidX=true android.enableJetifier=true kotlin.code.style=official group=com.synonym -version=0.5.14 +version=0.5.17 diff --git a/bindings/ios/bitkitcore.swift b/bindings/ios/bitkitcore.swift index 8db98fc..615cf91 100644 --- a/bindings/ios/bitkitcore.swift +++ b/bindings/ios/bitkitcore.swift @@ -975,153 +975,110 @@ public func FfiConverterTypeEventListener_lower(_ value: EventListener) -> Unsaf /** - * Callback interface for native Trezor transport operations + * Native transport for Jade. * - * This trait must be implemented by the native iOS/Android code. - * The implementation handles actual USB or Bluetooth communication. + * # Bluetooth contract * - * # Android Implementation - * Use Android USB Host API for USB devices: - * - Enumerate devices with vendorId 0x1209 (0x534c for older), productId 0x53c1 - * - Request USB permission, claim interface, get endpoints - * - Chunk size: 64 bytes for USB + * Jade advertises the Nordic UART Service: * - * Use Android BLE API for Bluetooth: - * - Scan for Trezor BLE service UUID: 8c000001-a59b-4d58-a9ad-073df69fa1b1 - * - Connect and discover characteristics - * - Read from: 8c000002-a59b-4d58-a9ad-073df69fa1b1 - * - Write to: 8c000003-a59b-4d58-a9ad-073df69fa1b1 - * - Chunk size: 244 bytes for BLE + * - service `6e400001-b5a3-f393-e0a9-e50e24dcca9e` + * - write `6e400002-b5a3-f393-e0a9-e50e24dcca9e` (host to Jade) + * - notify `6e400003-b5a3-f393-e0a9-e50e24dcca9e` (Jade to host) * - * # iOS Implementation - * Use IOKit/CoreBluetooth with same service/characteristic UUIDs. + * Devices advertise as "Jade" or "Jade ". + * + * Three requirements that are easy to miss and break signing on real hardware: + * + * 1. **Write with response.** Write-without-response silently drops chunks on + * the ESP32 GATT stack. + * 2. **Do not pause between chunks.** Firmware discards a partially received + * message after two seconds of silence, three on Jade v1, and answers with + * an unattributed error. A 30 KB PSBT is roughly 60 writes, so any UI thread + * stall in the middle of a send breaks the operation. + * 3. **`read_chunk` must return promptly.** Honour `timeout_ms`, which this + * crate caps at 250ms. The long per-operation deadline is enforced in Rust + * so the user can cancel. + * + * Once `close_device` has been called for a path, this crate issues no further + * reads or writes for it and discards the result of one already in flight, so + * a transport that keeps reporting empty reads after closing does not hold a + * disconnect open until the handshake deadline. A `read_chunk` that has + * already started cannot be interrupted, though, so requirement 3 is what + * bounds a disconnect issued mid-handshake: an implementation that ignores + * `timeout_ms` delays it for as long as that call takes to return. */ -public protocol TrezorTransportCallback: AnyObject, Sendable { - - /** - * Enumerate all connected Trezor devices - */ - func enumerateDevices() -> [NativeDeviceInfo] - - /** - * Open a connection to a device - */ - func openDevice(path: String) -> TrezorTransportWriteResult - - /** - * Close the connection to a device - */ - func closeDevice(path: String) -> TrezorTransportWriteResult - - /** - * Read a chunk of data from the device - */ - func readChunk(path: String) -> TrezorTransportReadResult +public protocol JadeTransportCallback: AnyObject, Sendable { /** - * Write a chunk of data to the device - */ - func writeChunk(path: String, data: Data) -> TrezorTransportWriteResult - - /** - * Get the chunk size for a device (64 for USB, 244 for Bluetooth) + * Discover devices, blocking up to `timeout_ms`. */ - func getChunkSize(path: String) -> UInt32 + func scanDevices(timeoutMs: UInt32) -> [JadeNativeDevice] /** - * High-level message call for BLE/THP devices. - * - * For BLE devices that use THP protocol (encrypted communication), - * the native layer should handle encryption/decryption via - * android-trezor-connect and return the raw protobuf response. - * - * Returns None if not supported (will fall back to Protocol V1 chunks). - * Returns Some(result) to use native THP handling. - * - * # Arguments - * * `path` - Device path - * * `message_type` - Protobuf message type (e.g., GetAddress = 29) - * * `data` - Serialized protobuf message data + * Open a connection and enable notifications. */ - func callMessage(path: String, messageType: UInt16, data: Data) -> TrezorCallMessageResult? + func openDevice(path: String) -> JadeTransportResult /** - * Get pairing code from user during BLE THP pairing. - * - * This is called when the Trezor device displays a 6-digit code - * that must be entered to complete Bluetooth pairing. - * - * The native layer should display a UI for the user to enter the code - * shown on the Trezor screen. - * - * Returns the 6-digit code as a string, or empty string to cancel. + * Close the connection and release the device. */ - func getPairingCode() -> String + func closeDevice(path: String) -> JadeTransportResult /** - * Save THP pairing credentials for a device. - * - * Called after successful BLE pairing to store credentials for reconnection. - * The credential_json is a JSON string containing the serialized ThpCredentials. - * - * # Arguments - * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") - * * `credential_json` - JSON string with credential data - * - * Returns true if credentials were saved successfully. + * Write one chunk, no larger than `get_chunk_size`. */ - func saveThpCredential(deviceId: String, credentialJson: String) -> Bool + func writeChunk(path: String, data: Data) -> JadeTransportResult /** - * Load THP pairing credentials for a device. - * - * Called before BLE handshake to check for stored credentials. - * If credentials are found, they will be used to skip the pairing dialog. - * - * # Arguments - * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") + * Read whatever has arrived, waiting at most `timeout_ms`. * - * Returns the JSON string containing ThpCredentials, or None if not found. + * Returning success with an empty vector is normal and means "nothing yet". */ - func loadThpCredential(deviceId: String) -> String? + func readChunk(path: String, timeoutMs: UInt32) -> JadeTransportReadResult /** - * Log a debug message from the Rust THP handshake layer. - * - * This forwards Rust-level errors and state information to the native - * debug UI (e.g., TrezorDebugLog on Android) so they are visible - * alongside the Kotlin-level logs. + * Maximum bytes per write. * - * # Arguments - * * `tag` - Short tag identifying the subsystem (e.g., "HANDSHAKE", "THP") - * * `message` - Human-readable debug message + * For Bluetooth this is `min(negotiated_mtu - 3, 509)`. The value is + * clamped into a usable range, so an unnegotiated `0` is not fatal. */ - func logDebug(tag: String, message: String) + func getChunkSize(path: String) -> UInt32 } /** - * Callback interface for native Trezor transport operations + * Native transport for Jade. * - * This trait must be implemented by the native iOS/Android code. - * The implementation handles actual USB or Bluetooth communication. + * # Bluetooth contract * - * # Android Implementation - * Use Android USB Host API for USB devices: - * - Enumerate devices with vendorId 0x1209 (0x534c for older), productId 0x53c1 - * - Request USB permission, claim interface, get endpoints - * - Chunk size: 64 bytes for USB + * Jade advertises the Nordic UART Service: * - * Use Android BLE API for Bluetooth: - * - Scan for Trezor BLE service UUID: 8c000001-a59b-4d58-a9ad-073df69fa1b1 - * - Connect and discover characteristics - * - Read from: 8c000002-a59b-4d58-a9ad-073df69fa1b1 - * - Write to: 8c000003-a59b-4d58-a9ad-073df69fa1b1 - * - Chunk size: 244 bytes for BLE + * - service `6e400001-b5a3-f393-e0a9-e50e24dcca9e` + * - write `6e400002-b5a3-f393-e0a9-e50e24dcca9e` (host to Jade) + * - notify `6e400003-b5a3-f393-e0a9-e50e24dcca9e` (Jade to host) * - * # iOS Implementation - * Use IOKit/CoreBluetooth with same service/characteristic UUIDs. + * Devices advertise as "Jade" or "Jade ". + * + * Three requirements that are easy to miss and break signing on real hardware: + * + * 1. **Write with response.** Write-without-response silently drops chunks on + * the ESP32 GATT stack. + * 2. **Do not pause between chunks.** Firmware discards a partially received + * message after two seconds of silence, three on Jade v1, and answers with + * an unattributed error. A 30 KB PSBT is roughly 60 writes, so any UI thread + * stall in the middle of a send breaks the operation. + * 3. **`read_chunk` must return promptly.** Honour `timeout_ms`, which this + * crate caps at 250ms. The long per-operation deadline is enforced in Rust + * so the user can cancel. + * + * Once `close_device` has been called for a path, this crate issues no further + * reads or writes for it and discards the result of one already in flight, so + * a transport that keeps reporting empty reads after closing does not hold a + * disconnect open until the handshake deadline. A `read_chunk` that has + * already started cannot be interrupted, though, so requirement 3 is what + * bounds a disconnect issued mid-handshake: an implementation that ignores + * `timeout_ms` delays it for as long as that call takes to return. */ -open class TrezorTransportCallbackImpl: TrezorTransportCallback, @unchecked Sendable { +open class JadeTransportCallbackImpl: JadeTransportCallback, @unchecked Sendable { fileprivate let pointer: UnsafeMutableRawPointer! /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly. @@ -1158,7 +1115,7 @@ open class TrezorTransportCallbackImpl: TrezorTransportCallback, @unchecked Send @_documentation(visibility: private) #endif public func uniffiClonePointer() -> UnsafeMutableRawPointer { - return try! rustCall { uniffi_bitkitcore_fn_clone_trezortransportcallback(self.pointer, $0) } + return try! rustCall { uniffi_bitkitcore_fn_clone_jadetransportcallback(self.pointer, $0) } } // No primary constructor declared for this class. @@ -1167,61 +1124,51 @@ open class TrezorTransportCallbackImpl: TrezorTransportCallback, @unchecked Send return } - try! rustCall { uniffi_bitkitcore_fn_free_trezortransportcallback(pointer, $0) } + try! rustCall { uniffi_bitkitcore_fn_free_jadetransportcallback(pointer, $0) } } /** - * Enumerate all connected Trezor devices - */ -open func enumerateDevices() -> [NativeDeviceInfo] { - return try! FfiConverterSequenceTypeNativeDeviceInfo.lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_enumerate_devices(self.uniffiClonePointer(),$0 - ) -}) -} - - /** - * Open a connection to a device + * Discover devices, blocking up to `timeout_ms`. */ -open func openDevice(path: String) -> TrezorTransportWriteResult { - return try! FfiConverterTypeTrezorTransportWriteResult_lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_open_device(self.uniffiClonePointer(), - FfiConverterString.lower(path),$0 +open func scanDevices(timeoutMs: UInt32) -> [JadeNativeDevice] { + return try! FfiConverterSequenceTypeJadeNativeDevice.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_jadetransportcallback_scan_devices(self.uniffiClonePointer(), + FfiConverterUInt32.lower(timeoutMs),$0 ) }) } /** - * Close the connection to a device + * Open a connection and enable notifications. */ -open func closeDevice(path: String) -> TrezorTransportWriteResult { - return try! FfiConverterTypeTrezorTransportWriteResult_lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_close_device(self.uniffiClonePointer(), +open func openDevice(path: String) -> JadeTransportResult { + return try! FfiConverterTypeJadeTransportResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_jadetransportcallback_open_device(self.uniffiClonePointer(), FfiConverterString.lower(path),$0 ) }) } /** - * Read a chunk of data from the device + * Close the connection and release the device. */ -open func readChunk(path: String) -> TrezorTransportReadResult { - return try! FfiConverterTypeTrezorTransportReadResult_lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_read_chunk(self.uniffiClonePointer(), +open func closeDevice(path: String) -> JadeTransportResult { + return try! FfiConverterTypeJadeTransportResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_jadetransportcallback_close_device(self.uniffiClonePointer(), FfiConverterString.lower(path),$0 ) }) } /** - * Write a chunk of data to the device + * Write one chunk, no larger than `get_chunk_size`. */ -open func writeChunk(path: String, data: Data) -> TrezorTransportWriteResult { - return try! FfiConverterTypeTrezorTransportWriteResult_lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_write_chunk(self.uniffiClonePointer(), +open func writeChunk(path: String, data: Data) -> JadeTransportResult { + return try! FfiConverterTypeJadeTransportResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_jadetransportcallback_write_chunk(self.uniffiClonePointer(), FfiConverterString.lower(path), FfiConverterData.lower(data),$0 ) @@ -1229,147 +1176,64 @@ open func writeChunk(path: String, data: Data) -> TrezorTransportWriteResult { } /** - * Get the chunk size for a device (64 for USB, 244 for Bluetooth) - */ -open func getChunkSize(path: String) -> UInt32 { - return try! FfiConverterUInt32.lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_get_chunk_size(self.uniffiClonePointer(), - FfiConverterString.lower(path),$0 - ) -}) -} - - /** - * High-level message call for BLE/THP devices. - * - * For BLE devices that use THP protocol (encrypted communication), - * the native layer should handle encryption/decryption via - * android-trezor-connect and return the raw protobuf response. - * - * Returns None if not supported (will fall back to Protocol V1 chunks). - * Returns Some(result) to use native THP handling. + * Read whatever has arrived, waiting at most `timeout_ms`. * - * # Arguments - * * `path` - Device path - * * `message_type` - Protobuf message type (e.g., GetAddress = 29) - * * `data` - Serialized protobuf message data + * Returning success with an empty vector is normal and means "nothing yet". */ -open func callMessage(path: String, messageType: UInt16, data: Data) -> TrezorCallMessageResult? { - return try! FfiConverterOptionTypeTrezorCallMessageResult.lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_call_message(self.uniffiClonePointer(), +open func readChunk(path: String, timeoutMs: UInt32) -> JadeTransportReadResult { + return try! FfiConverterTypeJadeTransportReadResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_jadetransportcallback_read_chunk(self.uniffiClonePointer(), FfiConverterString.lower(path), - FfiConverterUInt16.lower(messageType), - FfiConverterData.lower(data),$0 - ) -}) -} - - /** - * Get pairing code from user during BLE THP pairing. - * - * This is called when the Trezor device displays a 6-digit code - * that must be entered to complete Bluetooth pairing. - * - * The native layer should display a UI for the user to enter the code - * shown on the Trezor screen. - * - * Returns the 6-digit code as a string, or empty string to cancel. - */ -open func getPairingCode() -> String { - return try! FfiConverterString.lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_get_pairing_code(self.uniffiClonePointer(),$0 - ) -}) -} - - /** - * Save THP pairing credentials for a device. - * - * Called after successful BLE pairing to store credentials for reconnection. - * The credential_json is a JSON string containing the serialized ThpCredentials. - * - * # Arguments - * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") - * * `credential_json` - JSON string with credential data - * - * Returns true if credentials were saved successfully. - */ -open func saveThpCredential(deviceId: String, credentialJson: String) -> Bool { - return try! FfiConverterBool.lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_save_thp_credential(self.uniffiClonePointer(), - FfiConverterString.lower(deviceId), - FfiConverterString.lower(credentialJson),$0 + FfiConverterUInt32.lower(timeoutMs),$0 ) }) } /** - * Load THP pairing credentials for a device. - * - * Called before BLE handshake to check for stored credentials. - * If credentials are found, they will be used to skip the pairing dialog. - * - * # Arguments - * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") + * Maximum bytes per write. * - * Returns the JSON string containing ThpCredentials, or None if not found. + * For Bluetooth this is `min(negotiated_mtu - 3, 509)`. The value is + * clamped into a usable range, so an unnegotiated `0` is not fatal. */ -open func loadThpCredential(deviceId: String) -> String? { - return try! FfiConverterOptionString.lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_load_thp_credential(self.uniffiClonePointer(), - FfiConverterString.lower(deviceId),$0 +open func getChunkSize(path: String) -> UInt32 { + return try! FfiConverterUInt32.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_jadetransportcallback_get_chunk_size(self.uniffiClonePointer(), + FfiConverterString.lower(path),$0 ) }) } - /** - * Log a debug message from the Rust THP handshake layer. - * - * This forwards Rust-level errors and state information to the native - * debug UI (e.g., TrezorDebugLog on Android) so they are visible - * alongside the Kotlin-level logs. - * - * # Arguments - * * `tag` - Short tag identifying the subsystem (e.g., "HANDSHAKE", "THP") - * * `message` - Human-readable debug message - */ -open func logDebug(tag: String, message: String) {try! rustCall() { - uniffi_bitkitcore_fn_method_trezortransportcallback_log_debug(self.uniffiClonePointer(), - FfiConverterString.lower(tag), - FfiConverterString.lower(message),$0 - ) -} -} - } // Put the implementation in a struct so we don't pollute the top-level namespace -fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { +fileprivate struct UniffiCallbackInterfaceJadeTransportCallback { // Create the VTable using a series of closures. // Swift automatically converts these into C callback functions. // // This creates 1-element array, since this seems to be the only way to construct a const // pointer that we can pass to the Rust code. - static let vtable: [UniffiVTableCallbackInterfaceTrezorTransportCallback] = [UniffiVTableCallbackInterfaceTrezorTransportCallback( - enumerateDevices: { ( + static let vtable: [UniffiVTableCallbackInterfaceJadeTransportCallback] = [UniffiVTableCallbackInterfaceJadeTransportCallback( + scanDevices: { ( uniffiHandle: UInt64, + timeoutMs: UInt32, uniffiOutReturn: UnsafeMutablePointer, uniffiCallStatus: UnsafeMutablePointer ) in let makeCall = { - () throws -> [NativeDeviceInfo] in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + () throws -> [JadeNativeDevice] in + guard let uniffiObj = try? FfiConverterTypeJadeTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } - return uniffiObj.enumerateDevices( + return uniffiObj.scanDevices( + timeoutMs: try FfiConverterUInt32.lift(timeoutMs) ) } - let writeReturn = { uniffiOutReturn.pointee = FfiConverterSequenceTypeNativeDeviceInfo.lower($0) } + let writeReturn = { uniffiOutReturn.pointee = FfiConverterSequenceTypeJadeNativeDevice.lower($0) } uniffiTraitInterfaceCall( callStatus: uniffiCallStatus, makeCall: makeCall, @@ -1383,8 +1247,8 @@ fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { uniffiCallStatus: UnsafeMutablePointer ) in let makeCall = { - () throws -> TrezorTransportWriteResult in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + () throws -> JadeTransportResult in + guard let uniffiObj = try? FfiConverterTypeJadeTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } return uniffiObj.openDevice( @@ -1393,7 +1257,7 @@ fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { } - let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportWriteResult_lower($0) } + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeJadeTransportResult_lower($0) } uniffiTraitInterfaceCall( callStatus: uniffiCallStatus, makeCall: makeCall, @@ -1407,8 +1271,8 @@ fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { uniffiCallStatus: UnsafeMutablePointer ) in let makeCall = { - () throws -> TrezorTransportWriteResult in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + () throws -> JadeTransportResult in + guard let uniffiObj = try? FfiConverterTypeJadeTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } return uniffiObj.closeDevice( @@ -1417,57 +1281,59 @@ fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { } - let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportWriteResult_lower($0) } + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeJadeTransportResult_lower($0) } uniffiTraitInterfaceCall( callStatus: uniffiCallStatus, makeCall: makeCall, writeReturn: writeReturn ) }, - readChunk: { ( + writeChunk: { ( uniffiHandle: UInt64, path: RustBuffer, + data: RustBuffer, uniffiOutReturn: UnsafeMutablePointer, uniffiCallStatus: UnsafeMutablePointer ) in let makeCall = { - () throws -> TrezorTransportReadResult in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + () throws -> JadeTransportResult in + guard let uniffiObj = try? FfiConverterTypeJadeTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } - return uniffiObj.readChunk( - path: try FfiConverterString.lift(path) + return uniffiObj.writeChunk( + path: try FfiConverterString.lift(path), + data: try FfiConverterData.lift(data) ) } - let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportReadResult_lower($0) } + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeJadeTransportResult_lower($0) } uniffiTraitInterfaceCall( callStatus: uniffiCallStatus, makeCall: makeCall, writeReturn: writeReturn ) }, - writeChunk: { ( + readChunk: { ( uniffiHandle: UInt64, path: RustBuffer, - data: RustBuffer, + timeoutMs: UInt32, uniffiOutReturn: UnsafeMutablePointer, uniffiCallStatus: UnsafeMutablePointer ) in let makeCall = { - () throws -> TrezorTransportWriteResult in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + () throws -> JadeTransportReadResult in + guard let uniffiObj = try? FfiConverterTypeJadeTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } - return uniffiObj.writeChunk( + return uniffiObj.readChunk( path: try FfiConverterString.lift(path), - data: try FfiConverterData.lift(data) + timeoutMs: try FfiConverterUInt32.lift(timeoutMs) ) } - let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportWriteResult_lower($0) } + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeJadeTransportReadResult_lower($0) } uniffiTraitInterfaceCall( callStatus: uniffiCallStatus, makeCall: makeCall, @@ -1482,7 +1348,7 @@ fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { ) in let makeCall = { () throws -> UInt32 in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + guard let uniffiObj = try? FfiConverterTypeJadeTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } return uniffiObj.getChunkSize( @@ -1498,167 +1364,41 @@ fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { writeReturn: writeReturn ) }, - callMessage: { ( - uniffiHandle: UInt64, - path: RustBuffer, - messageType: UInt16, - data: RustBuffer, - uniffiOutReturn: UnsafeMutablePointer, - uniffiCallStatus: UnsafeMutablePointer - ) in - let makeCall = { - () throws -> TrezorCallMessageResult? in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { - throw UniffiInternalError.unexpectedStaleHandle - } - return uniffiObj.callMessage( - path: try FfiConverterString.lift(path), - messageType: try FfiConverterUInt16.lift(messageType), - data: try FfiConverterData.lift(data) - ) - } - - - let writeReturn = { uniffiOutReturn.pointee = FfiConverterOptionTypeTrezorCallMessageResult.lower($0) } - uniffiTraitInterfaceCall( - callStatus: uniffiCallStatus, - makeCall: makeCall, - writeReturn: writeReturn - ) - }, - getPairingCode: { ( - uniffiHandle: UInt64, - uniffiOutReturn: UnsafeMutablePointer, - uniffiCallStatus: UnsafeMutablePointer - ) in - let makeCall = { - () throws -> String in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { - throw UniffiInternalError.unexpectedStaleHandle - } - return uniffiObj.getPairingCode( - ) - } - - - let writeReturn = { uniffiOutReturn.pointee = FfiConverterString.lower($0) } - uniffiTraitInterfaceCall( - callStatus: uniffiCallStatus, - makeCall: makeCall, - writeReturn: writeReturn - ) - }, - saveThpCredential: { ( - uniffiHandle: UInt64, - deviceId: RustBuffer, - credentialJson: RustBuffer, - uniffiOutReturn: UnsafeMutablePointer, - uniffiCallStatus: UnsafeMutablePointer - ) in - let makeCall = { - () throws -> Bool in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { - throw UniffiInternalError.unexpectedStaleHandle - } - return uniffiObj.saveThpCredential( - deviceId: try FfiConverterString.lift(deviceId), - credentialJson: try FfiConverterString.lift(credentialJson) - ) - } - - - let writeReturn = { uniffiOutReturn.pointee = FfiConverterBool.lower($0) } - uniffiTraitInterfaceCall( - callStatus: uniffiCallStatus, - makeCall: makeCall, - writeReturn: writeReturn - ) - }, - loadThpCredential: { ( - uniffiHandle: UInt64, - deviceId: RustBuffer, - uniffiOutReturn: UnsafeMutablePointer, - uniffiCallStatus: UnsafeMutablePointer - ) in - let makeCall = { - () throws -> String? in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { - throw UniffiInternalError.unexpectedStaleHandle - } - return uniffiObj.loadThpCredential( - deviceId: try FfiConverterString.lift(deviceId) - ) - } - - - let writeReturn = { uniffiOutReturn.pointee = FfiConverterOptionString.lower($0) } - uniffiTraitInterfaceCall( - callStatus: uniffiCallStatus, - makeCall: makeCall, - writeReturn: writeReturn - ) - }, - logDebug: { ( - uniffiHandle: UInt64, - tag: RustBuffer, - message: RustBuffer, - uniffiOutReturn: UnsafeMutableRawPointer, - uniffiCallStatus: UnsafeMutablePointer - ) in - let makeCall = { - () throws -> () in - guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { - throw UniffiInternalError.unexpectedStaleHandle - } - return uniffiObj.logDebug( - tag: try FfiConverterString.lift(tag), - message: try FfiConverterString.lift(message) - ) - } - - - let writeReturn = { () } - uniffiTraitInterfaceCall( - callStatus: uniffiCallStatus, - makeCall: makeCall, - writeReturn: writeReturn - ) - }, uniffiFree: { (uniffiHandle: UInt64) -> () in - let result = try? FfiConverterTypeTrezorTransportCallback.handleMap.remove(handle: uniffiHandle) + let result = try? FfiConverterTypeJadeTransportCallback.handleMap.remove(handle: uniffiHandle) if result == nil { - print("Uniffi callback interface TrezorTransportCallback: handle missing in uniffiFree") + print("Uniffi callback interface JadeTransportCallback: handle missing in uniffiFree") } } )] } -private func uniffiCallbackInitTrezorTransportCallback() { - uniffi_bitkitcore_fn_init_callback_vtable_trezortransportcallback(UniffiCallbackInterfaceTrezorTransportCallback.vtable) +private func uniffiCallbackInitJadeTransportCallback() { + uniffi_bitkitcore_fn_init_callback_vtable_jadetransportcallback(UniffiCallbackInterfaceJadeTransportCallback.vtable) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorTransportCallback: FfiConverter { - fileprivate static let handleMap = UniffiHandleMap() +public struct FfiConverterTypeJadeTransportCallback: FfiConverter { + fileprivate static let handleMap = UniffiHandleMap() typealias FfiType = UnsafeMutableRawPointer - typealias SwiftType = TrezorTransportCallback + typealias SwiftType = JadeTransportCallback - public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> TrezorTransportCallback { - return TrezorTransportCallbackImpl(unsafeFromRawPointer: pointer) + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> JadeTransportCallback { + return JadeTransportCallbackImpl(unsafeFromRawPointer: pointer) } - public static func lower(_ value: TrezorTransportCallback) -> UnsafeMutableRawPointer { + public static func lower(_ value: JadeTransportCallback) -> UnsafeMutableRawPointer { guard let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: handleMap.insert(obj: value))) else { fatalError("Cast to UnsafeMutableRawPointer failed") } return ptr } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTransportCallback { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeTransportCallback { let v: UInt64 = try readInt(&buf) // The Rust code won't compile if a pointer won't fit in a UInt64. // We have to go via `UInt` because that's the thing that's the size of a pointer. @@ -1669,7 +1409,7 @@ public struct FfiConverterTypeTrezorTransportCallback: FfiConverter { return try lift(ptr!) } - public static func write(_ value: TrezorTransportCallback, into buf: inout [UInt8]) { + public static func write(_ value: JadeTransportCallback, into buf: inout [UInt8]) { // This fiddling is because `Int` is the thing that's the same size as a pointer. // The Rust code won't compile if a pointer won't fit in a `UInt64`. writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) @@ -1680,15 +1420,15 @@ public struct FfiConverterTypeTrezorTransportCallback: FfiConverter { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTransportCallback_lift(_ pointer: UnsafeMutableRawPointer) throws -> TrezorTransportCallback { - return try FfiConverterTypeTrezorTransportCallback.lift(pointer) +public func FfiConverterTypeJadeTransportCallback_lift(_ pointer: UnsafeMutableRawPointer) throws -> JadeTransportCallback { + return try FfiConverterTypeJadeTransportCallback.lift(pointer) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTransportCallback_lower(_ value: TrezorTransportCallback) -> UnsafeMutableRawPointer { - return FfiConverterTypeTrezorTransportCallback.lower(value) +public func FfiConverterTypeJadeTransportCallback_lower(_ value: JadeTransportCallback) -> UnsafeMutableRawPointer { + return FfiConverterTypeJadeTransportCallback.lower(value) } @@ -1697,43 +1437,155 @@ public func FfiConverterTypeTrezorTransportCallback_lower(_ value: TrezorTranspo /** - * Callback interface for handling PIN and passphrase requests from the Trezor device. + * Callback interface for native Trezor transport operations * - * The native layer (iOS/Android) should implement this to show PIN/passphrase - * input UI when the device requests it during operations like signing. + * This trait must be implemented by the native iOS/Android code. + * The implementation handles actual USB or Bluetooth communication. + * + * # Android Implementation + * Use Android USB Host API for USB devices: + * - Enumerate devices with vendorId 0x1209 (0x534c for older), productId 0x53c1 + * - Request USB permission, claim interface, get endpoints + * - Chunk size: 64 bytes for USB + * + * Use Android BLE API for Bluetooth: + * - Scan for Trezor BLE service UUID: 8c000001-a59b-4d58-a9ad-073df69fa1b1 + * - Connect and discover characteristics + * - Read from: 8c000002-a59b-4d58-a9ad-073df69fa1b1 + * - Write to: 8c000003-a59b-4d58-a9ad-073df69fa1b1 + * - Chunk size: 244 bytes for BLE + * + * # iOS Implementation + * Use IOKit/CoreBluetooth with same service/characteristic UUIDs. */ -public protocol TrezorUiCallback: AnyObject, Sendable { +public protocol TrezorTransportCallback: AnyObject, Sendable { /** - * Called when the device requests a PIN. - * - * Show a PIN matrix UI and return the matrix-encoded PIN string. - * Return empty string to cancel. + * Enumerate all connected Trezor devices */ - func onPinRequest() -> String + func enumerateDevices() -> [NativeDeviceInfo] /** - * Called when the device requests a passphrase. + * Open a connection to a device + */ + func openDevice(path: String) -> TrezorTransportWriteResult + + /** + * Close the connection to a device + */ + func closeDevice(path: String) -> TrezorTransportWriteResult + + /** + * Read a chunk of data from the device + */ + func readChunk(path: String) -> TrezorTransportReadResult + + /** + * Write a chunk of data to the device + */ + func writeChunk(path: String, data: Data) -> TrezorTransportWriteResult + + /** + * Get the chunk size for a device (64 for USB, 244 for Bluetooth) + */ + func getChunkSize(path: String) -> UInt32 + + /** + * High-level message call for BLE/THP devices. * - * If `on_device` is true, the device is asking for the passphrase to be - * entered on the Trezor itself — return `PassphraseResponse::OnDevice`. + * For BLE devices that use THP protocol (encrypted communication), + * the native layer should handle encryption/decryption via + * android-trezor-connect and return the raw protobuf response. * - * If `on_device` is false, show a passphrase input UI and return - * `Standard` (no passphrase), `Hidden { value }` (host-entered passphrase), - * `OnDevice` (defer entry to the Trezor), or `Cancel`. + * Returns None if not supported (will fall back to Protocol V1 chunks). + * Returns Some(result) to use native THP handling. + * + * # Arguments + * * `path` - Device path + * * `message_type` - Protobuf message type (e.g., GetAddress = 29) + * * `data` - Serialized protobuf message data */ - func onPassphraseRequest(onDevice: Bool) -> PassphraseResponse + func callMessage(path: String, messageType: UInt16, data: Data) -> TrezorCallMessageResult? -} -/** - * Callback interface for handling PIN and passphrase requests from the Trezor device. - * - * The native layer (iOS/Android) should implement this to show PIN/passphrase - * input UI when the device requests it during operations like signing. - */ -open class TrezorUiCallbackImpl: TrezorUiCallback, @unchecked Sendable { - fileprivate let pointer: UnsafeMutableRawPointer! - + /** + * Get pairing code from user during BLE THP pairing. + * + * This is called when the Trezor device displays a 6-digit code + * that must be entered to complete Bluetooth pairing. + * + * The native layer should display a UI for the user to enter the code + * shown on the Trezor screen. + * + * Returns the 6-digit code as a string, or empty string to cancel. + */ + func getPairingCode() -> String + + /** + * Save THP pairing credentials for a device. + * + * Called after successful BLE pairing to store credentials for reconnection. + * The credential_json is a JSON string containing the serialized ThpCredentials. + * + * # Arguments + * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") + * * `credential_json` - JSON string with credential data + * + * Returns true if credentials were saved successfully. + */ + func saveThpCredential(deviceId: String, credentialJson: String) -> Bool + + /** + * Load THP pairing credentials for a device. + * + * Called before BLE handshake to check for stored credentials. + * If credentials are found, they will be used to skip the pairing dialog. + * + * # Arguments + * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") + * + * Returns the JSON string containing ThpCredentials, or None if not found. + */ + func loadThpCredential(deviceId: String) -> String? + + /** + * Log a debug message from the Rust THP handshake layer. + * + * This forwards Rust-level errors and state information to the native + * debug UI (e.g., TrezorDebugLog on Android) so they are visible + * alongside the Kotlin-level logs. + * + * # Arguments + * * `tag` - Short tag identifying the subsystem (e.g., "HANDSHAKE", "THP") + * * `message` - Human-readable debug message + */ + func logDebug(tag: String, message: String) + +} +/** + * Callback interface for native Trezor transport operations + * + * This trait must be implemented by the native iOS/Android code. + * The implementation handles actual USB or Bluetooth communication. + * + * # Android Implementation + * Use Android USB Host API for USB devices: + * - Enumerate devices with vendorId 0x1209 (0x534c for older), productId 0x53c1 + * - Request USB permission, claim interface, get endpoints + * - Chunk size: 64 bytes for USB + * + * Use Android BLE API for Bluetooth: + * - Scan for Trezor BLE service UUID: 8c000001-a59b-4d58-a9ad-073df69fa1b1 + * - Connect and discover characteristics + * - Read from: 8c000002-a59b-4d58-a9ad-073df69fa1b1 + * - Write to: 8c000003-a59b-4d58-a9ad-073df69fa1b1 + * - Chunk size: 244 bytes for BLE + * + * # iOS Implementation + * Use IOKit/CoreBluetooth with same service/characteristic UUIDs. + */ +open class TrezorTransportCallbackImpl: TrezorTransportCallback, @unchecked Sendable { + fileprivate let pointer: UnsafeMutableRawPointer! + /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly. #if swift(>=5.8) @_documentation(visibility: private) @@ -1768,7 +1620,7 @@ open class TrezorUiCallbackImpl: TrezorUiCallback, @unchecked Sendable { @_documentation(visibility: private) #endif public func uniffiClonePointer() -> UnsafeMutableRawPointer { - return try! rustCall { uniffi_bitkitcore_fn_clone_trezoruicallback(self.pointer, $0) } + return try! rustCall { uniffi_bitkitcore_fn_clone_trezortransportcallback(self.pointer, $0) } } // No primary constructor declared for this class. @@ -1777,67 +1629,376 @@ open class TrezorUiCallbackImpl: TrezorUiCallback, @unchecked Sendable { return } - try! rustCall { uniffi_bitkitcore_fn_free_trezoruicallback(pointer, $0) } + try! rustCall { uniffi_bitkitcore_fn_free_trezortransportcallback(pointer, $0) } } /** - * Called when the device requests a PIN. + * Enumerate all connected Trezor devices + */ +open func enumerateDevices() -> [NativeDeviceInfo] { + return try! FfiConverterSequenceTypeNativeDeviceInfo.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_enumerate_devices(self.uniffiClonePointer(),$0 + ) +}) +} + + /** + * Open a connection to a device + */ +open func openDevice(path: String) -> TrezorTransportWriteResult { + return try! FfiConverterTypeTrezorTransportWriteResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_open_device(self.uniffiClonePointer(), + FfiConverterString.lower(path),$0 + ) +}) +} + + /** + * Close the connection to a device + */ +open func closeDevice(path: String) -> TrezorTransportWriteResult { + return try! FfiConverterTypeTrezorTransportWriteResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_close_device(self.uniffiClonePointer(), + FfiConverterString.lower(path),$0 + ) +}) +} + + /** + * Read a chunk of data from the device + */ +open func readChunk(path: String) -> TrezorTransportReadResult { + return try! FfiConverterTypeTrezorTransportReadResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_read_chunk(self.uniffiClonePointer(), + FfiConverterString.lower(path),$0 + ) +}) +} + + /** + * Write a chunk of data to the device + */ +open func writeChunk(path: String, data: Data) -> TrezorTransportWriteResult { + return try! FfiConverterTypeTrezorTransportWriteResult_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_write_chunk(self.uniffiClonePointer(), + FfiConverterString.lower(path), + FfiConverterData.lower(data),$0 + ) +}) +} + + /** + * Get the chunk size for a device (64 for USB, 244 for Bluetooth) + */ +open func getChunkSize(path: String) -> UInt32 { + return try! FfiConverterUInt32.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_get_chunk_size(self.uniffiClonePointer(), + FfiConverterString.lower(path),$0 + ) +}) +} + + /** + * High-level message call for BLE/THP devices. * - * Show a PIN matrix UI and return the matrix-encoded PIN string. - * Return empty string to cancel. + * For BLE devices that use THP protocol (encrypted communication), + * the native layer should handle encryption/decryption via + * android-trezor-connect and return the raw protobuf response. + * + * Returns None if not supported (will fall back to Protocol V1 chunks). + * Returns Some(result) to use native THP handling. + * + * # Arguments + * * `path` - Device path + * * `message_type` - Protobuf message type (e.g., GetAddress = 29) + * * `data` - Serialized protobuf message data */ -open func onPinRequest() -> String { +open func callMessage(path: String, messageType: UInt16, data: Data) -> TrezorCallMessageResult? { + return try! FfiConverterOptionTypeTrezorCallMessageResult.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_call_message(self.uniffiClonePointer(), + FfiConverterString.lower(path), + FfiConverterUInt16.lower(messageType), + FfiConverterData.lower(data),$0 + ) +}) +} + + /** + * Get pairing code from user during BLE THP pairing. + * + * This is called when the Trezor device displays a 6-digit code + * that must be entered to complete Bluetooth pairing. + * + * The native layer should display a UI for the user to enter the code + * shown on the Trezor screen. + * + * Returns the 6-digit code as a string, or empty string to cancel. + */ +open func getPairingCode() -> String { return try! FfiConverterString.lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezoruicallback_on_pin_request(self.uniffiClonePointer(),$0 + uniffi_bitkitcore_fn_method_trezortransportcallback_get_pairing_code(self.uniffiClonePointer(),$0 ) }) } /** - * Called when the device requests a passphrase. + * Save THP pairing credentials for a device. * - * If `on_device` is true, the device is asking for the passphrase to be - * entered on the Trezor itself — return `PassphraseResponse::OnDevice`. + * Called after successful BLE pairing to store credentials for reconnection. + * The credential_json is a JSON string containing the serialized ThpCredentials. * - * If `on_device` is false, show a passphrase input UI and return - * `Standard` (no passphrase), `Hidden { value }` (host-entered passphrase), - * `OnDevice` (defer entry to the Trezor), or `Cancel`. + * # Arguments + * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") + * * `credential_json` - JSON string with credential data + * + * Returns true if credentials were saved successfully. */ -open func onPassphraseRequest(onDevice: Bool) -> PassphraseResponse { - return try! FfiConverterTypePassphraseResponse_lift(try! rustCall() { - uniffi_bitkitcore_fn_method_trezoruicallback_on_passphrase_request(self.uniffiClonePointer(), - FfiConverterBool.lower(onDevice),$0 +open func saveThpCredential(deviceId: String, credentialJson: String) -> Bool { + return try! FfiConverterBool.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_save_thp_credential(self.uniffiClonePointer(), + FfiConverterString.lower(deviceId), + FfiConverterString.lower(credentialJson),$0 + ) +}) +} + + /** + * Load THP pairing credentials for a device. + * + * Called before BLE handshake to check for stored credentials. + * If credentials are found, they will be used to skip the pairing dialog. + * + * # Arguments + * * `device_id` - Device identifier (e.g., BLE address like "ble:AA:BB:CC:DD:EE:FF") + * + * Returns the JSON string containing ThpCredentials, or None if not found. + */ +open func loadThpCredential(deviceId: String) -> String? { + return try! FfiConverterOptionString.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_load_thp_credential(self.uniffiClonePointer(), + FfiConverterString.lower(deviceId),$0 ) }) } + /** + * Log a debug message from the Rust THP handshake layer. + * + * This forwards Rust-level errors and state information to the native + * debug UI (e.g., TrezorDebugLog on Android) so they are visible + * alongside the Kotlin-level logs. + * + * # Arguments + * * `tag` - Short tag identifying the subsystem (e.g., "HANDSHAKE", "THP") + * * `message` - Human-readable debug message + */ +open func logDebug(tag: String, message: String) {try! rustCall() { + uniffi_bitkitcore_fn_method_trezortransportcallback_log_debug(self.uniffiClonePointer(), + FfiConverterString.lower(tag), + FfiConverterString.lower(message),$0 + ) +} +} + } // Put the implementation in a struct so we don't pollute the top-level namespace -fileprivate struct UniffiCallbackInterfaceTrezorUiCallback { +fileprivate struct UniffiCallbackInterfaceTrezorTransportCallback { // Create the VTable using a series of closures. // Swift automatically converts these into C callback functions. // // This creates 1-element array, since this seems to be the only way to construct a const // pointer that we can pass to the Rust code. - static let vtable: [UniffiVTableCallbackInterfaceTrezorUiCallback] = [UniffiVTableCallbackInterfaceTrezorUiCallback( - onPinRequest: { ( + static let vtable: [UniffiVTableCallbackInterfaceTrezorTransportCallback] = [UniffiVTableCallbackInterfaceTrezorTransportCallback( + enumerateDevices: { ( + uniffiHandle: UInt64, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> [NativeDeviceInfo] in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.enumerateDevices( + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterSequenceTypeNativeDeviceInfo.lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + openDevice: { ( + uniffiHandle: UInt64, + path: RustBuffer, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> TrezorTransportWriteResult in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.openDevice( + path: try FfiConverterString.lift(path) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportWriteResult_lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + closeDevice: { ( + uniffiHandle: UInt64, + path: RustBuffer, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> TrezorTransportWriteResult in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.closeDevice( + path: try FfiConverterString.lift(path) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportWriteResult_lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + readChunk: { ( + uniffiHandle: UInt64, + path: RustBuffer, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> TrezorTransportReadResult in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.readChunk( + path: try FfiConverterString.lift(path) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportReadResult_lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + writeChunk: { ( + uniffiHandle: UInt64, + path: RustBuffer, + data: RustBuffer, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> TrezorTransportWriteResult in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.writeChunk( + path: try FfiConverterString.lift(path), + data: try FfiConverterData.lift(data) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypeTrezorTransportWriteResult_lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + getChunkSize: { ( + uniffiHandle: UInt64, + path: RustBuffer, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> UInt32 in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.getChunkSize( + path: try FfiConverterString.lift(path) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterUInt32.lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + callMessage: { ( + uniffiHandle: UInt64, + path: RustBuffer, + messageType: UInt16, + data: RustBuffer, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> TrezorCallMessageResult? in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.callMessage( + path: try FfiConverterString.lift(path), + messageType: try FfiConverterUInt16.lift(messageType), + data: try FfiConverterData.lift(data) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterOptionTypeTrezorCallMessageResult.lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + getPairingCode: { ( uniffiHandle: UInt64, uniffiOutReturn: UnsafeMutablePointer, uniffiCallStatus: UnsafeMutablePointer ) in let makeCall = { () throws -> String in - guard let uniffiObj = try? FfiConverterTypeTrezorUiCallback.handleMap.get(handle: uniffiHandle) else { + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } - return uniffiObj.onPinRequest( + return uniffiObj.getPairingCode( ) } @@ -1849,24 +2010,76 @@ fileprivate struct UniffiCallbackInterfaceTrezorUiCallback { writeReturn: writeReturn ) }, - onPassphraseRequest: { ( + saveThpCredential: { ( uniffiHandle: UInt64, - onDevice: Int8, + deviceId: RustBuffer, + credentialJson: RustBuffer, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> Bool in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.saveThpCredential( + deviceId: try FfiConverterString.lift(deviceId), + credentialJson: try FfiConverterString.lift(credentialJson) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterBool.lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + loadThpCredential: { ( + uniffiHandle: UInt64, + deviceId: RustBuffer, uniffiOutReturn: UnsafeMutablePointer, uniffiCallStatus: UnsafeMutablePointer ) in let makeCall = { - () throws -> PassphraseResponse in - guard let uniffiObj = try? FfiConverterTypeTrezorUiCallback.handleMap.get(handle: uniffiHandle) else { + () throws -> String? in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { throw UniffiInternalError.unexpectedStaleHandle } - return uniffiObj.onPassphraseRequest( - onDevice: try FfiConverterBool.lift(onDevice) + return uniffiObj.loadThpCredential( + deviceId: try FfiConverterString.lift(deviceId) ) } - let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypePassphraseResponse_lower($0) } + let writeReturn = { uniffiOutReturn.pointee = FfiConverterOptionString.lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + logDebug: { ( + uniffiHandle: UInt64, + tag: RustBuffer, + message: RustBuffer, + uniffiOutReturn: UnsafeMutableRawPointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> () in + guard let uniffiObj = try? FfiConverterTypeTrezorTransportCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.logDebug( + tag: try FfiConverterString.lift(tag), + message: try FfiConverterString.lift(message) + ) + } + + + let writeReturn = { () } uniffiTraitInterfaceCall( callStatus: uniffiCallStatus, makeCall: makeCall, @@ -1874,27 +2087,276 @@ fileprivate struct UniffiCallbackInterfaceTrezorUiCallback { ) }, uniffiFree: { (uniffiHandle: UInt64) -> () in - let result = try? FfiConverterTypeTrezorUiCallback.handleMap.remove(handle: uniffiHandle) + let result = try? FfiConverterTypeTrezorTransportCallback.handleMap.remove(handle: uniffiHandle) if result == nil { - print("Uniffi callback interface TrezorUiCallback: handle missing in uniffiFree") + print("Uniffi callback interface TrezorTransportCallback: handle missing in uniffiFree") } } )] } -private func uniffiCallbackInitTrezorUiCallback() { - uniffi_bitkitcore_fn_init_callback_vtable_trezoruicallback(UniffiCallbackInterfaceTrezorUiCallback.vtable) +private func uniffiCallbackInitTrezorTransportCallback() { + uniffi_bitkitcore_fn_init_callback_vtable_trezortransportcallback(UniffiCallbackInterfaceTrezorTransportCallback.vtable) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorUiCallback: FfiConverter { - fileprivate static let handleMap = UniffiHandleMap() +public struct FfiConverterTypeTrezorTransportCallback: FfiConverter { + fileprivate static let handleMap = UniffiHandleMap() typealias FfiType = UnsafeMutableRawPointer - typealias SwiftType = TrezorUiCallback + typealias SwiftType = TrezorTransportCallback + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> TrezorTransportCallback { + return TrezorTransportCallbackImpl(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: TrezorTransportCallback) -> UnsafeMutableRawPointer { + guard let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: handleMap.insert(obj: value))) else { + fatalError("Cast to UnsafeMutableRawPointer failed") + } + return ptr + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTransportCallback { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: TrezorTransportCallback, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTrezorTransportCallback_lift(_ pointer: UnsafeMutableRawPointer) throws -> TrezorTransportCallback { + return try FfiConverterTypeTrezorTransportCallback.lift(pointer) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTrezorTransportCallback_lower(_ value: TrezorTransportCallback) -> UnsafeMutableRawPointer { + return FfiConverterTypeTrezorTransportCallback.lower(value) +} + + + + + + +/** + * Callback interface for handling PIN and passphrase requests from the Trezor device. + * + * The native layer (iOS/Android) should implement this to show PIN/passphrase + * input UI when the device requests it during operations like signing. + */ +public protocol TrezorUiCallback: AnyObject, Sendable { + + /** + * Called when the device requests a PIN. + * + * Show a PIN matrix UI and return the matrix-encoded PIN string. + * Return empty string to cancel. + */ + func onPinRequest() -> String + + /** + * Called when the device requests a passphrase. + * + * If `on_device` is true, the device is asking for the passphrase to be + * entered on the Trezor itself — return `PassphraseResponse::OnDevice`. + * + * If `on_device` is false, show a passphrase input UI and return + * `Standard` (no passphrase), `Hidden { value }` (host-entered passphrase), + * `OnDevice` (defer entry to the Trezor), or `Cancel`. + */ + func onPassphraseRequest(onDevice: Bool) -> PassphraseResponse + +} +/** + * Callback interface for handling PIN and passphrase requests from the Trezor device. + * + * The native layer (iOS/Android) should implement this to show PIN/passphrase + * input UI when the device requests it during operations like signing. + */ +open class TrezorUiCallbackImpl: TrezorUiCallback, @unchecked Sendable { + fileprivate let pointer: UnsafeMutableRawPointer! + + /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public struct NoPointer { + public init() {} + } + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + required public init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + // This constructor can be used to instantiate a fake object. + // - Parameter noPointer: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject]. + // + // - Warning: + // Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing [Pointer] the FFI lower functions will crash. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public init(noPointer: NoPointer) { + self.pointer = nil + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public func uniffiClonePointer() -> UnsafeMutableRawPointer { + return try! rustCall { uniffi_bitkitcore_fn_clone_trezoruicallback(self.pointer, $0) } + } + // No primary constructor declared for this class. + + deinit { + guard let pointer = pointer else { + return + } + + try! rustCall { uniffi_bitkitcore_fn_free_trezoruicallback(pointer, $0) } + } + + + + + /** + * Called when the device requests a PIN. + * + * Show a PIN matrix UI and return the matrix-encoded PIN string. + * Return empty string to cancel. + */ +open func onPinRequest() -> String { + return try! FfiConverterString.lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezoruicallback_on_pin_request(self.uniffiClonePointer(),$0 + ) +}) +} + + /** + * Called when the device requests a passphrase. + * + * If `on_device` is true, the device is asking for the passphrase to be + * entered on the Trezor itself — return `PassphraseResponse::OnDevice`. + * + * If `on_device` is false, show a passphrase input UI and return + * `Standard` (no passphrase), `Hidden { value }` (host-entered passphrase), + * `OnDevice` (defer entry to the Trezor), or `Cancel`. + */ +open func onPassphraseRequest(onDevice: Bool) -> PassphraseResponse { + return try! FfiConverterTypePassphraseResponse_lift(try! rustCall() { + uniffi_bitkitcore_fn_method_trezoruicallback_on_passphrase_request(self.uniffiClonePointer(), + FfiConverterBool.lower(onDevice),$0 + ) +}) +} + + +} + + +// Put the implementation in a struct so we don't pollute the top-level namespace +fileprivate struct UniffiCallbackInterfaceTrezorUiCallback { + + // Create the VTable using a series of closures. + // Swift automatically converts these into C callback functions. + // + // This creates 1-element array, since this seems to be the only way to construct a const + // pointer that we can pass to the Rust code. + static let vtable: [UniffiVTableCallbackInterfaceTrezorUiCallback] = [UniffiVTableCallbackInterfaceTrezorUiCallback( + onPinRequest: { ( + uniffiHandle: UInt64, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> String in + guard let uniffiObj = try? FfiConverterTypeTrezorUiCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.onPinRequest( + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterString.lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + onPassphraseRequest: { ( + uniffiHandle: UInt64, + onDevice: Int8, + uniffiOutReturn: UnsafeMutablePointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws -> PassphraseResponse in + guard let uniffiObj = try? FfiConverterTypeTrezorUiCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return uniffiObj.onPassphraseRequest( + onDevice: try FfiConverterBool.lift(onDevice) + ) + } + + + let writeReturn = { uniffiOutReturn.pointee = FfiConverterTypePassphraseResponse_lower($0) } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + uniffiFree: { (uniffiHandle: UInt64) -> () in + let result = try? FfiConverterTypeTrezorUiCallback.handleMap.remove(handle: uniffiHandle) + if result == nil { + print("Uniffi callback interface TrezorUiCallback: handle missing in uniffiFree") + } + } + )] +} + +private func uniffiCallbackInitTrezorUiCallback() { + uniffi_bitkitcore_fn_init_callback_vtable_trezoruicallback(UniffiCallbackInterfaceTrezorUiCallback.vtable) +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTrezorUiCallback: FfiConverter { + fileprivate static let handleMap = UniffiHandleMap() + + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = TrezorUiCallback public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> TrezorUiCallback { return TrezorUiCallbackImpl(unsafeFromRawPointer: pointer) @@ -7649,71 +8111,67 @@ public func FfiConverterTypeIManualRefund_lower(_ value: IManualRefund) -> RustB } -public struct LegacyRnCloseRecoveryScanResult { - /** - * Total balance found in legacy RN P2WPKH close outputs (in satoshis). - */ - public var totalAmount: UInt64 - /** - * Number of P2WPKH outputs found. - */ - public var outputsCount: UInt32 +public struct JadeAccount { + public var variant: JadeAddressVariant + public var xpub: String + public var derivationPath: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * Total balance found in legacy RN P2WPKH close outputs (in satoshis). - */totalAmount: UInt64, - /** - * Number of P2WPKH outputs found. - */outputsCount: UInt32) { - self.totalAmount = totalAmount - self.outputsCount = outputsCount + public init(variant: JadeAddressVariant, xpub: String, derivationPath: String) { + self.variant = variant + self.xpub = xpub + self.derivationPath = derivationPath } } #if compiler(>=6) -extension LegacyRnCloseRecoveryScanResult: Sendable {} +extension JadeAccount: Sendable {} #endif -extension LegacyRnCloseRecoveryScanResult: Equatable, Hashable { - public static func ==(lhs: LegacyRnCloseRecoveryScanResult, rhs: LegacyRnCloseRecoveryScanResult) -> Bool { - if lhs.totalAmount != rhs.totalAmount { +extension JadeAccount: Equatable, Hashable { + public static func ==(lhs: JadeAccount, rhs: JadeAccount) -> Bool { + if lhs.variant != rhs.variant { return false } - if lhs.outputsCount != rhs.outputsCount { + if lhs.xpub != rhs.xpub { + return false + } + if lhs.derivationPath != rhs.derivationPath { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(totalAmount) - hasher.combine(outputsCount) + hasher.combine(variant) + hasher.combine(xpub) + hasher.combine(derivationPath) } } -extension LegacyRnCloseRecoveryScanResult: Codable {} +extension JadeAccount: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLegacyRnCloseRecoveryScanResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LegacyRnCloseRecoveryScanResult { +public struct FfiConverterTypeJadeAccount: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeAccount { return - try LegacyRnCloseRecoveryScanResult( - totalAmount: FfiConverterUInt64.read(from: &buf), - outputsCount: FfiConverterUInt32.read(from: &buf) + try JadeAccount( + variant: FfiConverterTypeJadeAddressVariant.read(from: &buf), + xpub: FfiConverterString.read(from: &buf), + derivationPath: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: LegacyRnCloseRecoveryScanResult, into buf: inout [UInt8]) { - FfiConverterUInt64.write(value.totalAmount, into: &buf) - FfiConverterUInt32.write(value.outputsCount, into: &buf) + public static func write(_ value: JadeAccount, into buf: inout [UInt8]) { + FfiConverterTypeJadeAddressVariant.write(value.variant, into: &buf) + FfiConverterString.write(value.xpub, into: &buf) + FfiConverterString.write(value.derivationPath, into: &buf) } } @@ -7721,167 +8179,79 @@ public struct FfiConverterTypeLegacyRnCloseRecoveryScanResult: FfiConverterRustB #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLegacyRnCloseRecoveryScanResult_lift(_ buf: RustBuffer) throws -> LegacyRnCloseRecoveryScanResult { - return try FfiConverterTypeLegacyRnCloseRecoveryScanResult.lift(buf) +public func FfiConverterTypeJadeAccount_lift(_ buf: RustBuffer) throws -> JadeAccount { + return try FfiConverterTypeJadeAccount.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLegacyRnCloseRecoveryScanResult_lower(_ value: LegacyRnCloseRecoveryScanResult) -> RustBuffer { - return FfiConverterTypeLegacyRnCloseRecoveryScanResult.lower(value) +public func FfiConverterTypeJadeAccount_lower(_ value: JadeAccount) -> RustBuffer { + return FfiConverterTypeJadeAccount.lower(value) } -public struct LegacyRnCloseRecoverySweepPreview { - /** - * Fully signed raw sweep transaction hex. Broadcast only after user confirmation. - */ - public var txHex: String - /** - * Transaction id of the sweep transaction. - */ - public var txid: String - /** - * Total input amount in satoshis. - */ - public var totalAmount: UInt64 - /** - * Fee in satoshis. - */ - public var estimatedFee: UInt64 - /** - * Transaction virtual size in vbytes. - */ - public var estimatedVsize: UInt64 - /** - * Number of recovered outputs swept. - */ - public var outputsCount: UInt32 - /** - * Destination address receiving the sweep. - */ - public var destinationAddress: String - /** - * Amount sent to destination after fees. - */ - public var amountAfterFees: UInt64 +public struct JadeAccountExport { + public var masterFingerprint: String + public var accountIndex: UInt32 + public var accounts: [JadeAccount] // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * Fully signed raw sweep transaction hex. Broadcast only after user confirmation. - */txHex: String, - /** - * Transaction id of the sweep transaction. - */txid: String, - /** - * Total input amount in satoshis. - */totalAmount: UInt64, - /** - * Fee in satoshis. - */estimatedFee: UInt64, - /** - * Transaction virtual size in vbytes. - */estimatedVsize: UInt64, - /** - * Number of recovered outputs swept. - */outputsCount: UInt32, - /** - * Destination address receiving the sweep. - */destinationAddress: String, - /** - * Amount sent to destination after fees. - */amountAfterFees: UInt64) { - self.txHex = txHex - self.txid = txid - self.totalAmount = totalAmount - self.estimatedFee = estimatedFee - self.estimatedVsize = estimatedVsize - self.outputsCount = outputsCount - self.destinationAddress = destinationAddress - self.amountAfterFees = amountAfterFees + public init(masterFingerprint: String, accountIndex: UInt32, accounts: [JadeAccount]) { + self.masterFingerprint = masterFingerprint + self.accountIndex = accountIndex + self.accounts = accounts } } #if compiler(>=6) -extension LegacyRnCloseRecoverySweepPreview: Sendable {} +extension JadeAccountExport: Sendable {} #endif -extension LegacyRnCloseRecoverySweepPreview: Equatable, Hashable { - public static func ==(lhs: LegacyRnCloseRecoverySweepPreview, rhs: LegacyRnCloseRecoverySweepPreview) -> Bool { - if lhs.txHex != rhs.txHex { - return false - } - if lhs.txid != rhs.txid { - return false - } - if lhs.totalAmount != rhs.totalAmount { - return false - } - if lhs.estimatedFee != rhs.estimatedFee { - return false - } - if lhs.estimatedVsize != rhs.estimatedVsize { - return false - } - if lhs.outputsCount != rhs.outputsCount { +extension JadeAccountExport: Equatable, Hashable { + public static func ==(lhs: JadeAccountExport, rhs: JadeAccountExport) -> Bool { + if lhs.masterFingerprint != rhs.masterFingerprint { return false } - if lhs.destinationAddress != rhs.destinationAddress { + if lhs.accountIndex != rhs.accountIndex { return false } - if lhs.amountAfterFees != rhs.amountAfterFees { + if lhs.accounts != rhs.accounts { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(txHex) - hasher.combine(txid) - hasher.combine(totalAmount) - hasher.combine(estimatedFee) - hasher.combine(estimatedVsize) - hasher.combine(outputsCount) - hasher.combine(destinationAddress) - hasher.combine(amountAfterFees) + hasher.combine(masterFingerprint) + hasher.combine(accountIndex) + hasher.combine(accounts) } } -extension LegacyRnCloseRecoverySweepPreview: Codable {} +extension JadeAccountExport: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLegacyRnCloseRecoverySweepPreview: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LegacyRnCloseRecoverySweepPreview { +public struct FfiConverterTypeJadeAccountExport: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeAccountExport { return - try LegacyRnCloseRecoverySweepPreview( - txHex: FfiConverterString.read(from: &buf), - txid: FfiConverterString.read(from: &buf), - totalAmount: FfiConverterUInt64.read(from: &buf), - estimatedFee: FfiConverterUInt64.read(from: &buf), - estimatedVsize: FfiConverterUInt64.read(from: &buf), - outputsCount: FfiConverterUInt32.read(from: &buf), - destinationAddress: FfiConverterString.read(from: &buf), - amountAfterFees: FfiConverterUInt64.read(from: &buf) + try JadeAccountExport( + masterFingerprint: FfiConverterString.read(from: &buf), + accountIndex: FfiConverterUInt32.read(from: &buf), + accounts: FfiConverterSequenceTypeJadeAccount.read(from: &buf) ) } - public static func write(_ value: LegacyRnCloseRecoverySweepPreview, into buf: inout [UInt8]) { - FfiConverterString.write(value.txHex, into: &buf) - FfiConverterString.write(value.txid, into: &buf) - FfiConverterUInt64.write(value.totalAmount, into: &buf) - FfiConverterUInt64.write(value.estimatedFee, into: &buf) - FfiConverterUInt64.write(value.estimatedVsize, into: &buf) - FfiConverterUInt32.write(value.outputsCount, into: &buf) - FfiConverterString.write(value.destinationAddress, into: &buf) - FfiConverterUInt64.write(value.amountAfterFees, into: &buf) + public static func write(_ value: JadeAccountExport, into buf: inout [UInt8]) { + FfiConverterString.write(value.masterFingerprint, into: &buf) + FfiConverterUInt32.write(value.accountIndex, into: &buf) + FfiConverterSequenceTypeJadeAccount.write(value.accounts, into: &buf) } } @@ -7889,167 +8259,87 @@ public struct FfiConverterTypeLegacyRnCloseRecoverySweepPreview: FfiConverterRus #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLegacyRnCloseRecoverySweepPreview_lift(_ buf: RustBuffer) throws -> LegacyRnCloseRecoverySweepPreview { - return try FfiConverterTypeLegacyRnCloseRecoverySweepPreview.lift(buf) +public func FfiConverterTypeJadeAccountExport_lift(_ buf: RustBuffer) throws -> JadeAccountExport { + return try FfiConverterTypeJadeAccountExport.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLegacyRnCloseRecoverySweepPreview_lower(_ value: LegacyRnCloseRecoverySweepPreview) -> RustBuffer { - return FfiConverterTypeLegacyRnCloseRecoverySweepPreview.lower(value) +public func FfiConverterTypeJadeAccountExport_lower(_ value: JadeAccountExport) -> RustBuffer { + return FfiConverterTypeJadeAccountExport.lower(value) } -public struct LightningActivity { - public var walletId: String - public var id: String - public var txType: PaymentType - public var status: PaymentState - public var value: UInt64 - public var fee: UInt64? - public var invoice: String - public var message: String - public var timestamp: UInt64 - public var preimage: String? - public var contact: String? - public var createdAt: UInt64? - public var updatedAt: UInt64? - public var seenAt: UInt64? +public struct JadeDeviceInfo { + public var path: String + public var transport: JadeTransportKind + public var name: String? + public var serialNumber: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(walletId: String, id: String, txType: PaymentType, status: PaymentState, value: UInt64, fee: UInt64?, invoice: String, message: String, timestamp: UInt64, preimage: String?, contact: String?, createdAt: UInt64?, updatedAt: UInt64?, seenAt: UInt64?) { - self.walletId = walletId - self.id = id - self.txType = txType - self.status = status - self.value = value - self.fee = fee - self.invoice = invoice - self.message = message - self.timestamp = timestamp - self.preimage = preimage - self.contact = contact - self.createdAt = createdAt - self.updatedAt = updatedAt - self.seenAt = seenAt + public init(path: String, transport: JadeTransportKind, name: String?, serialNumber: String?) { + self.path = path + self.transport = transport + self.name = name + self.serialNumber = serialNumber } } #if compiler(>=6) -extension LightningActivity: Sendable {} +extension JadeDeviceInfo: Sendable {} #endif -extension LightningActivity: Equatable, Hashable { - public static func ==(lhs: LightningActivity, rhs: LightningActivity) -> Bool { - if lhs.walletId != rhs.walletId { - return false - } - if lhs.id != rhs.id { - return false - } - if lhs.txType != rhs.txType { - return false - } - if lhs.status != rhs.status { - return false - } - if lhs.value != rhs.value { - return false - } - if lhs.fee != rhs.fee { - return false - } - if lhs.invoice != rhs.invoice { - return false - } - if lhs.message != rhs.message { - return false - } - if lhs.timestamp != rhs.timestamp { - return false - } - if lhs.preimage != rhs.preimage { - return false - } - if lhs.contact != rhs.contact { +extension JadeDeviceInfo: Equatable, Hashable { + public static func ==(lhs: JadeDeviceInfo, rhs: JadeDeviceInfo) -> Bool { + if lhs.path != rhs.path { return false } - if lhs.createdAt != rhs.createdAt { + if lhs.transport != rhs.transport { return false } - if lhs.updatedAt != rhs.updatedAt { + if lhs.name != rhs.name { return false } - if lhs.seenAt != rhs.seenAt { + if lhs.serialNumber != rhs.serialNumber { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(walletId) - hasher.combine(id) - hasher.combine(txType) - hasher.combine(status) - hasher.combine(value) - hasher.combine(fee) - hasher.combine(invoice) - hasher.combine(message) - hasher.combine(timestamp) - hasher.combine(preimage) - hasher.combine(contact) - hasher.combine(createdAt) - hasher.combine(updatedAt) - hasher.combine(seenAt) + hasher.combine(path) + hasher.combine(transport) + hasher.combine(name) + hasher.combine(serialNumber) } } -extension LightningActivity: Codable {} +extension JadeDeviceInfo: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLightningActivity: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LightningActivity { +public struct FfiConverterTypeJadeDeviceInfo: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeDeviceInfo { return - try LightningActivity( - walletId: FfiConverterString.read(from: &buf), - id: FfiConverterString.read(from: &buf), - txType: FfiConverterTypePaymentType.read(from: &buf), - status: FfiConverterTypePaymentState.read(from: &buf), - value: FfiConverterUInt64.read(from: &buf), - fee: FfiConverterOptionUInt64.read(from: &buf), - invoice: FfiConverterString.read(from: &buf), - message: FfiConverterString.read(from: &buf), - timestamp: FfiConverterUInt64.read(from: &buf), - preimage: FfiConverterOptionString.read(from: &buf), - contact: FfiConverterOptionString.read(from: &buf), - createdAt: FfiConverterOptionUInt64.read(from: &buf), - updatedAt: FfiConverterOptionUInt64.read(from: &buf), - seenAt: FfiConverterOptionUInt64.read(from: &buf) + try JadeDeviceInfo( + path: FfiConverterString.read(from: &buf), + transport: FfiConverterTypeJadeTransportKind.read(from: &buf), + name: FfiConverterOptionString.read(from: &buf), + serialNumber: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: LightningActivity, into buf: inout [UInt8]) { - FfiConverterString.write(value.walletId, into: &buf) - FfiConverterString.write(value.id, into: &buf) - FfiConverterTypePaymentType.write(value.txType, into: &buf) - FfiConverterTypePaymentState.write(value.status, into: &buf) - FfiConverterUInt64.write(value.value, into: &buf) - FfiConverterOptionUInt64.write(value.fee, into: &buf) - FfiConverterString.write(value.invoice, into: &buf) - FfiConverterString.write(value.message, into: &buf) - FfiConverterUInt64.write(value.timestamp, into: &buf) - FfiConverterOptionString.write(value.preimage, into: &buf) - FfiConverterOptionString.write(value.contact, into: &buf) - FfiConverterOptionUInt64.write(value.createdAt, into: &buf) - FfiConverterOptionUInt64.write(value.updatedAt, into: &buf) - FfiConverterOptionUInt64.write(value.seenAt, into: &buf) + public static func write(_ value: JadeDeviceInfo, into buf: inout [UInt8]) { + FfiConverterString.write(value.path, into: &buf) + FfiConverterTypeJadeTransportKind.write(value.transport, into: &buf) + FfiConverterOptionString.write(value.name, into: &buf) + FfiConverterOptionString.write(value.serialNumber, into: &buf) } } @@ -8057,127 +8347,102 @@ public struct FfiConverterTypeLightningActivity: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLightningActivity_lift(_ buf: RustBuffer) throws -> LightningActivity { - return try FfiConverterTypeLightningActivity.lift(buf) +public func FfiConverterTypeJadeDeviceInfo_lift(_ buf: RustBuffer) throws -> JadeDeviceInfo { + return try FfiConverterTypeJadeDeviceInfo.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLightningActivity_lower(_ value: LightningActivity) -> RustBuffer { - return FfiConverterTypeLightningActivity.lower(value) +public func FfiConverterTypeJadeDeviceInfo_lower(_ value: JadeDeviceInfo) -> RustBuffer { + return FfiConverterTypeJadeDeviceInfo.lower(value) } -public struct LightningInvoice { - public var bolt11: String - public var paymentHash: Data - public var amountSatoshis: UInt64 - public var timestampSeconds: UInt64 - public var expirySeconds: UInt64 - public var isExpired: Bool - public var description: String? - public var networkType: NetworkType - public var payeeNodeId: Data? +/** + * A device the native layer discovered. + */ +public struct JadeNativeDevice { + /** + * Transport specific address: a BLE identifier or a serial device path. + */ + public var path: String + public var transport: JadeTransportKind + /** + * Advertised or descriptor name, for example "Jade C0FFEE". + */ + public var name: String? + public var serialNumber: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(bolt11: String, paymentHash: Data, amountSatoshis: UInt64, timestampSeconds: UInt64, expirySeconds: UInt64, isExpired: Bool, description: String?, networkType: NetworkType, payeeNodeId: Data?) { - self.bolt11 = bolt11 - self.paymentHash = paymentHash - self.amountSatoshis = amountSatoshis - self.timestampSeconds = timestampSeconds - self.expirySeconds = expirySeconds - self.isExpired = isExpired - self.description = description - self.networkType = networkType - self.payeeNodeId = payeeNodeId + public init( + /** + * Transport specific address: a BLE identifier or a serial device path. + */path: String, transport: JadeTransportKind, + /** + * Advertised or descriptor name, for example "Jade C0FFEE". + */name: String?, serialNumber: String?) { + self.path = path + self.transport = transport + self.name = name + self.serialNumber = serialNumber } } #if compiler(>=6) -extension LightningInvoice: Sendable {} +extension JadeNativeDevice: Sendable {} #endif -extension LightningInvoice: Equatable, Hashable { - public static func ==(lhs: LightningInvoice, rhs: LightningInvoice) -> Bool { - if lhs.bolt11 != rhs.bolt11 { - return false - } - if lhs.paymentHash != rhs.paymentHash { - return false - } - if lhs.amountSatoshis != rhs.amountSatoshis { - return false - } - if lhs.timestampSeconds != rhs.timestampSeconds { - return false - } - if lhs.expirySeconds != rhs.expirySeconds { - return false - } - if lhs.isExpired != rhs.isExpired { +extension JadeNativeDevice: Equatable, Hashable { + public static func ==(lhs: JadeNativeDevice, rhs: JadeNativeDevice) -> Bool { + if lhs.path != rhs.path { return false } - if lhs.description != rhs.description { + if lhs.transport != rhs.transport { return false } - if lhs.networkType != rhs.networkType { + if lhs.name != rhs.name { return false } - if lhs.payeeNodeId != rhs.payeeNodeId { + if lhs.serialNumber != rhs.serialNumber { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(bolt11) - hasher.combine(paymentHash) - hasher.combine(amountSatoshis) - hasher.combine(timestampSeconds) - hasher.combine(expirySeconds) - hasher.combine(isExpired) - hasher.combine(description) - hasher.combine(networkType) - hasher.combine(payeeNodeId) + hasher.combine(path) + hasher.combine(transport) + hasher.combine(name) + hasher.combine(serialNumber) } } -extension LightningInvoice: Codable {} +extension JadeNativeDevice: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLightningInvoice: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LightningInvoice { +public struct FfiConverterTypeJadeNativeDevice: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeNativeDevice { return - try LightningInvoice( - bolt11: FfiConverterString.read(from: &buf), - paymentHash: FfiConverterData.read(from: &buf), - amountSatoshis: FfiConverterUInt64.read(from: &buf), - timestampSeconds: FfiConverterUInt64.read(from: &buf), - expirySeconds: FfiConverterUInt64.read(from: &buf), - isExpired: FfiConverterBool.read(from: &buf), - description: FfiConverterOptionString.read(from: &buf), - networkType: FfiConverterTypeNetworkType.read(from: &buf), - payeeNodeId: FfiConverterOptionData.read(from: &buf) + try JadeNativeDevice( + path: FfiConverterString.read(from: &buf), + transport: FfiConverterTypeJadeTransportKind.read(from: &buf), + name: FfiConverterOptionString.read(from: &buf), + serialNumber: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: LightningInvoice, into buf: inout [UInt8]) { - FfiConverterString.write(value.bolt11, into: &buf) - FfiConverterData.write(value.paymentHash, into: &buf) - FfiConverterUInt64.write(value.amountSatoshis, into: &buf) - FfiConverterUInt64.write(value.timestampSeconds, into: &buf) - FfiConverterUInt64.write(value.expirySeconds, into: &buf) - FfiConverterBool.write(value.isExpired, into: &buf) - FfiConverterOptionString.write(value.description, into: &buf) - FfiConverterTypeNetworkType.write(value.networkType, into: &buf) - FfiConverterOptionData.write(value.payeeNodeId, into: &buf) + public static func write(_ value: JadeNativeDevice, into buf: inout [UInt8]) { + FfiConverterString.write(value.path, into: &buf) + FfiConverterTypeJadeTransportKind.write(value.transport, into: &buf) + FfiConverterOptionString.write(value.name, into: &buf) + FfiConverterOptionString.write(value.serialNumber, into: &buf) } } @@ -8185,79 +8450,79 @@ public struct FfiConverterTypeLightningInvoice: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLightningInvoice_lift(_ buf: RustBuffer) throws -> LightningInvoice { - return try FfiConverterTypeLightningInvoice.lift(buf) +public func FfiConverterTypeJadeNativeDevice_lift(_ buf: RustBuffer) throws -> JadeNativeDevice { + return try FfiConverterTypeJadeNativeDevice.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLightningInvoice_lower(_ value: LightningInvoice) -> RustBuffer { - return FfiConverterTypeLightningInvoice.lower(value) +public func FfiConverterTypeJadeNativeDevice_lower(_ value: JadeNativeDevice) -> RustBuffer { + return FfiConverterTypeJadeNativeDevice.lower(value) } -public struct LnurlAddressData { - public var uri: String - public var domain: String - public var username: String +public struct JadeSignedMessage { + public var signature: String + public var address: String + public var derivationPath: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init(uri: String, domain: String, username: String) { - self.uri = uri - self.domain = domain - self.username = username + public init(signature: String, address: String, derivationPath: String) { + self.signature = signature + self.address = address + self.derivationPath = derivationPath } } #if compiler(>=6) -extension LnurlAddressData: Sendable {} +extension JadeSignedMessage: Sendable {} #endif -extension LnurlAddressData: Equatable, Hashable { - public static func ==(lhs: LnurlAddressData, rhs: LnurlAddressData) -> Bool { - if lhs.uri != rhs.uri { +extension JadeSignedMessage: Equatable, Hashable { + public static func ==(lhs: JadeSignedMessage, rhs: JadeSignedMessage) -> Bool { + if lhs.signature != rhs.signature { return false } - if lhs.domain != rhs.domain { + if lhs.address != rhs.address { return false } - if lhs.username != rhs.username { + if lhs.derivationPath != rhs.derivationPath { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(uri) - hasher.combine(domain) - hasher.combine(username) + hasher.combine(signature) + hasher.combine(address) + hasher.combine(derivationPath) } } -extension LnurlAddressData: Codable {} +extension JadeSignedMessage: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLnurlAddressData: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlAddressData { +public struct FfiConverterTypeJadeSignedMessage: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeSignedMessage { return - try LnurlAddressData( - uri: FfiConverterString.read(from: &buf), - domain: FfiConverterString.read(from: &buf), - username: FfiConverterString.read(from: &buf) + try JadeSignedMessage( + signature: FfiConverterString.read(from: &buf), + address: FfiConverterString.read(from: &buf), + derivationPath: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: LnurlAddressData, into buf: inout [UInt8]) { - FfiConverterString.write(value.uri, into: &buf) - FfiConverterString.write(value.domain, into: &buf) - FfiConverterString.write(value.username, into: &buf) + public static func write(_ value: JadeSignedMessage, into buf: inout [UInt8]) { + FfiConverterString.write(value.signature, into: &buf) + FfiConverterString.write(value.address, into: &buf) + FfiConverterString.write(value.derivationPath, into: &buf) } } @@ -8265,87 +8530,104 @@ public struct FfiConverterTypeLnurlAddressData: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlAddressData_lift(_ buf: RustBuffer) throws -> LnurlAddressData { - return try FfiConverterTypeLnurlAddressData.lift(buf) +public func FfiConverterTypeJadeSignedMessage_lift(_ buf: RustBuffer) throws -> JadeSignedMessage { + return try FfiConverterTypeJadeSignedMessage.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlAddressData_lower(_ value: LnurlAddressData) -> RustBuffer { - return FfiConverterTypeLnurlAddressData.lower(value) +public func FfiConverterTypeJadeSignedMessage_lower(_ value: JadeSignedMessage) -> RustBuffer { + return FfiConverterTypeJadeSignedMessage.lower(value) } -public struct LnurlAuthData { - public var uri: String - public var tag: String - public var k1: String - public var domain: String +/** + * Outcome of a read. + */ +public struct JadeTransportReadResult { + public var success: Bool + /** + * Bytes read. Success with an empty vector means nothing has arrived yet, + * which is the normal case while the user is deciding on the device. + */ + public var data: Data + /** + * Empty on success. + */ + public var error: String + public var errorCode: JadeTransportErrorCode? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(uri: String, tag: String, k1: String, domain: String) { - self.uri = uri - self.tag = tag - self.k1 = k1 - self.domain = domain + public init(success: Bool, + /** + * Bytes read. Success with an empty vector means nothing has arrived yet, + * which is the normal case while the user is deciding on the device. + */data: Data, + /** + * Empty on success. + */error: String, errorCode: JadeTransportErrorCode?) { + self.success = success + self.data = data + self.error = error + self.errorCode = errorCode } } #if compiler(>=6) -extension LnurlAuthData: Sendable {} +extension JadeTransportReadResult: Sendable {} #endif -extension LnurlAuthData: Equatable, Hashable { - public static func ==(lhs: LnurlAuthData, rhs: LnurlAuthData) -> Bool { - if lhs.uri != rhs.uri { +extension JadeTransportReadResult: Equatable, Hashable { + public static func ==(lhs: JadeTransportReadResult, rhs: JadeTransportReadResult) -> Bool { + if lhs.success != rhs.success { return false } - if lhs.tag != rhs.tag { + if lhs.data != rhs.data { return false } - if lhs.k1 != rhs.k1 { + if lhs.error != rhs.error { return false } - if lhs.domain != rhs.domain { + if lhs.errorCode != rhs.errorCode { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(uri) - hasher.combine(tag) - hasher.combine(k1) - hasher.combine(domain) + hasher.combine(success) + hasher.combine(data) + hasher.combine(error) + hasher.combine(errorCode) } } -extension LnurlAuthData: Codable {} +extension JadeTransportReadResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLnurlAuthData: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlAuthData { +public struct FfiConverterTypeJadeTransportReadResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeTransportReadResult { return - try LnurlAuthData( - uri: FfiConverterString.read(from: &buf), - tag: FfiConverterString.read(from: &buf), - k1: FfiConverterString.read(from: &buf), - domain: FfiConverterString.read(from: &buf) + try JadeTransportReadResult( + success: FfiConverterBool.read(from: &buf), + data: FfiConverterData.read(from: &buf), + error: FfiConverterString.read(from: &buf), + errorCode: FfiConverterOptionTypeJadeTransportErrorCode.read(from: &buf) ) } - public static func write(_ value: LnurlAuthData, into buf: inout [UInt8]) { - FfiConverterString.write(value.uri, into: &buf) - FfiConverterString.write(value.tag, into: &buf) - FfiConverterString.write(value.k1, into: &buf) - FfiConverterString.write(value.domain, into: &buf) + public static func write(_ value: JadeTransportReadResult, into buf: inout [UInt8]) { + FfiConverterBool.write(value.success, into: &buf) + FfiConverterData.write(value.data, into: &buf) + FfiConverterString.write(value.error, into: &buf) + FfiConverterOptionTypeJadeTransportErrorCode.write(value.errorCode, into: &buf) } } @@ -8353,87 +8635,88 @@ public struct FfiConverterTypeLnurlAuthData: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlAuthData_lift(_ buf: RustBuffer) throws -> LnurlAuthData { - return try FfiConverterTypeLnurlAuthData.lift(buf) +public func FfiConverterTypeJadeTransportReadResult_lift(_ buf: RustBuffer) throws -> JadeTransportReadResult { + return try FfiConverterTypeJadeTransportReadResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlAuthData_lower(_ value: LnurlAuthData) -> RustBuffer { - return FfiConverterTypeLnurlAuthData.lower(value) +public func FfiConverterTypeJadeTransportReadResult_lower(_ value: JadeTransportReadResult) -> RustBuffer { + return FfiConverterTypeJadeTransportReadResult.lower(value) } -public struct LnurlChannelData { - public var uri: String - public var callback: String - public var k1: String - public var tag: String +/** + * Outcome of an operation that returns no data. + */ +public struct JadeTransportResult { + public var success: Bool + /** + * Empty on success. + */ + public var error: String + public var errorCode: JadeTransportErrorCode? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(uri: String, callback: String, k1: String, tag: String) { - self.uri = uri - self.callback = callback - self.k1 = k1 - self.tag = tag + public init(success: Bool, + /** + * Empty on success. + */error: String, errorCode: JadeTransportErrorCode?) { + self.success = success + self.error = error + self.errorCode = errorCode } } #if compiler(>=6) -extension LnurlChannelData: Sendable {} +extension JadeTransportResult: Sendable {} #endif -extension LnurlChannelData: Equatable, Hashable { - public static func ==(lhs: LnurlChannelData, rhs: LnurlChannelData) -> Bool { - if lhs.uri != rhs.uri { - return false - } - if lhs.callback != rhs.callback { +extension JadeTransportResult: Equatable, Hashable { + public static func ==(lhs: JadeTransportResult, rhs: JadeTransportResult) -> Bool { + if lhs.success != rhs.success { return false } - if lhs.k1 != rhs.k1 { + if lhs.error != rhs.error { return false } - if lhs.tag != rhs.tag { + if lhs.errorCode != rhs.errorCode { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(uri) - hasher.combine(callback) - hasher.combine(k1) - hasher.combine(tag) + hasher.combine(success) + hasher.combine(error) + hasher.combine(errorCode) } } -extension LnurlChannelData: Codable {} +extension JadeTransportResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLnurlChannelData: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlChannelData { +public struct FfiConverterTypeJadeTransportResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeTransportResult { return - try LnurlChannelData( - uri: FfiConverterString.read(from: &buf), - callback: FfiConverterString.read(from: &buf), - k1: FfiConverterString.read(from: &buf), - tag: FfiConverterString.read(from: &buf) + try JadeTransportResult( + success: FfiConverterBool.read(from: &buf), + error: FfiConverterString.read(from: &buf), + errorCode: FfiConverterOptionTypeJadeTransportErrorCode.read(from: &buf) ) } - public static func write(_ value: LnurlChannelData, into buf: inout [UInt8]) { - FfiConverterString.write(value.uri, into: &buf) - FfiConverterString.write(value.callback, into: &buf) - FfiConverterString.write(value.k1, into: &buf) - FfiConverterString.write(value.tag, into: &buf) + public static func write(_ value: JadeTransportResult, into buf: inout [UInt8]) { + FfiConverterBool.write(value.success, into: &buf) + FfiConverterString.write(value.error, into: &buf) + FfiConverterOptionTypeJadeTransportErrorCode.write(value.errorCode, into: &buf) } } @@ -8441,119 +8724,151 @@ public struct FfiConverterTypeLnurlChannelData: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlChannelData_lift(_ buf: RustBuffer) throws -> LnurlChannelData { - return try FfiConverterTypeLnurlChannelData.lift(buf) +public func FfiConverterTypeJadeTransportResult_lift(_ buf: RustBuffer) throws -> JadeTransportResult { + return try FfiConverterTypeJadeTransportResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlChannelData_lower(_ value: LnurlChannelData) -> RustBuffer { - return FfiConverterTypeLnurlChannelData.lower(value) +public func FfiConverterTypeJadeTransportResult_lower(_ value: JadeTransportResult) -> RustBuffer { + return FfiConverterTypeJadeTransportResult.lower(value) } -public struct LnurlPayData { - public var uri: String - public var callback: String - public var minSendable: UInt64 - public var maxSendable: UInt64 - public var metadataStr: String - public var commentAllowed: UInt32? - public var allowsNostr: Bool - public var nostrPubkey: Data? +public struct JadeVersionInfo { + public var jadeVersion: String + public var jadeState: JadeState + public var jadeNetworks: String? + public var jadeHasPin: Bool? + public var boardType: String? + public var jadeConfig: String? + public var jadeFeatures: String? + public var idfVersion: String? + public var chipFeatures: String? + public var efuseMac: String? + public var batteryStatus: UInt32? + public var jadeOtaMaxChunk: UInt32? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(uri: String, callback: String, minSendable: UInt64, maxSendable: UInt64, metadataStr: String, commentAllowed: UInt32?, allowsNostr: Bool, nostrPubkey: Data?) { - self.uri = uri - self.callback = callback - self.minSendable = minSendable - self.maxSendable = maxSendable - self.metadataStr = metadataStr - self.commentAllowed = commentAllowed - self.allowsNostr = allowsNostr - self.nostrPubkey = nostrPubkey + public init(jadeVersion: String, jadeState: JadeState, jadeNetworks: String?, jadeHasPin: Bool?, boardType: String?, jadeConfig: String?, jadeFeatures: String?, idfVersion: String?, chipFeatures: String?, efuseMac: String?, batteryStatus: UInt32?, jadeOtaMaxChunk: UInt32?) { + self.jadeVersion = jadeVersion + self.jadeState = jadeState + self.jadeNetworks = jadeNetworks + self.jadeHasPin = jadeHasPin + self.boardType = boardType + self.jadeConfig = jadeConfig + self.jadeFeatures = jadeFeatures + self.idfVersion = idfVersion + self.chipFeatures = chipFeatures + self.efuseMac = efuseMac + self.batteryStatus = batteryStatus + self.jadeOtaMaxChunk = jadeOtaMaxChunk } } #if compiler(>=6) -extension LnurlPayData: Sendable {} +extension JadeVersionInfo: Sendable {} #endif -extension LnurlPayData: Equatable, Hashable { - public static func ==(lhs: LnurlPayData, rhs: LnurlPayData) -> Bool { - if lhs.uri != rhs.uri { +extension JadeVersionInfo: Equatable, Hashable { + public static func ==(lhs: JadeVersionInfo, rhs: JadeVersionInfo) -> Bool { + if lhs.jadeVersion != rhs.jadeVersion { return false } - if lhs.callback != rhs.callback { + if lhs.jadeState != rhs.jadeState { return false } - if lhs.minSendable != rhs.minSendable { + if lhs.jadeNetworks != rhs.jadeNetworks { return false } - if lhs.maxSendable != rhs.maxSendable { + if lhs.jadeHasPin != rhs.jadeHasPin { return false } - if lhs.metadataStr != rhs.metadataStr { + if lhs.boardType != rhs.boardType { return false } - if lhs.commentAllowed != rhs.commentAllowed { + if lhs.jadeConfig != rhs.jadeConfig { return false } - if lhs.allowsNostr != rhs.allowsNostr { + if lhs.jadeFeatures != rhs.jadeFeatures { return false } - if lhs.nostrPubkey != rhs.nostrPubkey { + if lhs.idfVersion != rhs.idfVersion { + return false + } + if lhs.chipFeatures != rhs.chipFeatures { + return false + } + if lhs.efuseMac != rhs.efuseMac { + return false + } + if lhs.batteryStatus != rhs.batteryStatus { + return false + } + if lhs.jadeOtaMaxChunk != rhs.jadeOtaMaxChunk { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(uri) - hasher.combine(callback) - hasher.combine(minSendable) - hasher.combine(maxSendable) - hasher.combine(metadataStr) - hasher.combine(commentAllowed) - hasher.combine(allowsNostr) - hasher.combine(nostrPubkey) + hasher.combine(jadeVersion) + hasher.combine(jadeState) + hasher.combine(jadeNetworks) + hasher.combine(jadeHasPin) + hasher.combine(boardType) + hasher.combine(jadeConfig) + hasher.combine(jadeFeatures) + hasher.combine(idfVersion) + hasher.combine(chipFeatures) + hasher.combine(efuseMac) + hasher.combine(batteryStatus) + hasher.combine(jadeOtaMaxChunk) } } -extension LnurlPayData: Codable {} +extension JadeVersionInfo: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLnurlPayData: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlPayData { +public struct FfiConverterTypeJadeVersionInfo: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeVersionInfo { return - try LnurlPayData( - uri: FfiConverterString.read(from: &buf), - callback: FfiConverterString.read(from: &buf), - minSendable: FfiConverterUInt64.read(from: &buf), - maxSendable: FfiConverterUInt64.read(from: &buf), - metadataStr: FfiConverterString.read(from: &buf), - commentAllowed: FfiConverterOptionUInt32.read(from: &buf), - allowsNostr: FfiConverterBool.read(from: &buf), - nostrPubkey: FfiConverterOptionData.read(from: &buf) + try JadeVersionInfo( + jadeVersion: FfiConverterString.read(from: &buf), + jadeState: FfiConverterTypeJadeState.read(from: &buf), + jadeNetworks: FfiConverterOptionString.read(from: &buf), + jadeHasPin: FfiConverterOptionBool.read(from: &buf), + boardType: FfiConverterOptionString.read(from: &buf), + jadeConfig: FfiConverterOptionString.read(from: &buf), + jadeFeatures: FfiConverterOptionString.read(from: &buf), + idfVersion: FfiConverterOptionString.read(from: &buf), + chipFeatures: FfiConverterOptionString.read(from: &buf), + efuseMac: FfiConverterOptionString.read(from: &buf), + batteryStatus: FfiConverterOptionUInt32.read(from: &buf), + jadeOtaMaxChunk: FfiConverterOptionUInt32.read(from: &buf) ) } - public static func write(_ value: LnurlPayData, into buf: inout [UInt8]) { - FfiConverterString.write(value.uri, into: &buf) - FfiConverterString.write(value.callback, into: &buf) - FfiConverterUInt64.write(value.minSendable, into: &buf) - FfiConverterUInt64.write(value.maxSendable, into: &buf) - FfiConverterString.write(value.metadataStr, into: &buf) - FfiConverterOptionUInt32.write(value.commentAllowed, into: &buf) - FfiConverterBool.write(value.allowsNostr, into: &buf) - FfiConverterOptionData.write(value.nostrPubkey, into: &buf) + public static func write(_ value: JadeVersionInfo, into buf: inout [UInt8]) { + FfiConverterString.write(value.jadeVersion, into: &buf) + FfiConverterTypeJadeState.write(value.jadeState, into: &buf) + FfiConverterOptionString.write(value.jadeNetworks, into: &buf) + FfiConverterOptionBool.write(value.jadeHasPin, into: &buf) + FfiConverterOptionString.write(value.boardType, into: &buf) + FfiConverterOptionString.write(value.jadeConfig, into: &buf) + FfiConverterOptionString.write(value.jadeFeatures, into: &buf) + FfiConverterOptionString.write(value.idfVersion, into: &buf) + FfiConverterOptionString.write(value.chipFeatures, into: &buf) + FfiConverterOptionString.write(value.efuseMac, into: &buf) + FfiConverterOptionUInt32.write(value.batteryStatus, into: &buf) + FfiConverterOptionUInt32.write(value.jadeOtaMaxChunk, into: &buf) } } @@ -8561,111 +8876,79 @@ public struct FfiConverterTypeLnurlPayData: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlPayData_lift(_ buf: RustBuffer) throws -> LnurlPayData { - return try FfiConverterTypeLnurlPayData.lift(buf) +public func FfiConverterTypeJadeVersionInfo_lift(_ buf: RustBuffer) throws -> JadeVersionInfo { + return try FfiConverterTypeJadeVersionInfo.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlPayData_lower(_ value: LnurlPayData) -> RustBuffer { - return FfiConverterTypeLnurlPayData.lower(value) +public func FfiConverterTypeJadeVersionInfo_lower(_ value: JadeVersionInfo) -> RustBuffer { + return FfiConverterTypeJadeVersionInfo.lower(value) } -public struct LnurlWithdrawData { - public var uri: String - public var callback: String - public var k1: String - public var defaultDescription: String - public var minWithdrawable: UInt64? - public var maxWithdrawable: UInt64 - public var tag: String +public struct JadeXpubResponse { + public var xpub: String + public var derivationPath: String + public var masterFingerprint: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init(uri: String, callback: String, k1: String, defaultDescription: String, minWithdrawable: UInt64?, maxWithdrawable: UInt64, tag: String) { - self.uri = uri - self.callback = callback - self.k1 = k1 - self.defaultDescription = defaultDescription - self.minWithdrawable = minWithdrawable - self.maxWithdrawable = maxWithdrawable - self.tag = tag + public init(xpub: String, derivationPath: String, masterFingerprint: String) { + self.xpub = xpub + self.derivationPath = derivationPath + self.masterFingerprint = masterFingerprint } } #if compiler(>=6) -extension LnurlWithdrawData: Sendable {} +extension JadeXpubResponse: Sendable {} #endif -extension LnurlWithdrawData: Equatable, Hashable { - public static func ==(lhs: LnurlWithdrawData, rhs: LnurlWithdrawData) -> Bool { - if lhs.uri != rhs.uri { - return false - } - if lhs.callback != rhs.callback { - return false - } - if lhs.k1 != rhs.k1 { - return false - } - if lhs.defaultDescription != rhs.defaultDescription { - return false - } - if lhs.minWithdrawable != rhs.minWithdrawable { +extension JadeXpubResponse: Equatable, Hashable { + public static func ==(lhs: JadeXpubResponse, rhs: JadeXpubResponse) -> Bool { + if lhs.xpub != rhs.xpub { return false } - if lhs.maxWithdrawable != rhs.maxWithdrawable { + if lhs.derivationPath != rhs.derivationPath { return false } - if lhs.tag != rhs.tag { + if lhs.masterFingerprint != rhs.masterFingerprint { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(uri) - hasher.combine(callback) - hasher.combine(k1) - hasher.combine(defaultDescription) - hasher.combine(minWithdrawable) - hasher.combine(maxWithdrawable) - hasher.combine(tag) + hasher.combine(xpub) + hasher.combine(derivationPath) + hasher.combine(masterFingerprint) } } -extension LnurlWithdrawData: Codable {} +extension JadeXpubResponse: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLnurlWithdrawData: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlWithdrawData { +public struct FfiConverterTypeJadeXpubResponse: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeXpubResponse { return - try LnurlWithdrawData( - uri: FfiConverterString.read(from: &buf), - callback: FfiConverterString.read(from: &buf), - k1: FfiConverterString.read(from: &buf), - defaultDescription: FfiConverterString.read(from: &buf), - minWithdrawable: FfiConverterOptionUInt64.read(from: &buf), - maxWithdrawable: FfiConverterUInt64.read(from: &buf), - tag: FfiConverterString.read(from: &buf) + try JadeXpubResponse( + xpub: FfiConverterString.read(from: &buf), + derivationPath: FfiConverterString.read(from: &buf), + masterFingerprint: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: LnurlWithdrawData, into buf: inout [UInt8]) { - FfiConverterString.write(value.uri, into: &buf) - FfiConverterString.write(value.callback, into: &buf) - FfiConverterString.write(value.k1, into: &buf) - FfiConverterString.write(value.defaultDescription, into: &buf) - FfiConverterOptionUInt64.write(value.minWithdrawable, into: &buf) - FfiConverterUInt64.write(value.maxWithdrawable, into: &buf) - FfiConverterString.write(value.tag, into: &buf) + public static func write(_ value: JadeXpubResponse, into buf: inout [UInt8]) { + FfiConverterString.write(value.xpub, into: &buf) + FfiConverterString.write(value.derivationPath, into: &buf) + FfiConverterString.write(value.masterFingerprint, into: &buf) } } @@ -8673,128 +8956,83 @@ public struct FfiConverterTypeLnurlWithdrawData: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlWithdrawData_lift(_ buf: RustBuffer) throws -> LnurlWithdrawData { - return try FfiConverterTypeLnurlWithdrawData.lift(buf) +public func FfiConverterTypeJadeXpubResponse_lift(_ buf: RustBuffer) throws -> JadeXpubResponse { + return try FfiConverterTypeJadeXpubResponse.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLnurlWithdrawData_lower(_ value: LnurlWithdrawData) -> RustBuffer { - return FfiConverterTypeLnurlWithdrawData.lower(value) +public func FfiConverterTypeJadeXpubResponse_lower(_ value: JadeXpubResponse) -> RustBuffer { + return FfiConverterTypeJadeXpubResponse.lower(value) } -/** - * Native device information returned from enumeration - */ -public struct NativeDeviceInfo { - /** - * Unique path/identifier for this device - */ - public var path: String - /** - * Transport type: "usb" or "bluetooth" - */ - public var transportType: String - /** - * Optional device name (from BLE advertisement or USB descriptor) - */ - public var name: String? +public struct LegacyRnCloseRecoveryScanResult { /** - * USB Vendor ID (for USB devices) + * Total balance found in legacy RN P2WPKH close outputs (in satoshis). */ - public var vendorId: UInt16? + public var totalAmount: UInt64 /** - * USB Product ID (for USB devices) + * Number of P2WPKH outputs found. */ - public var productId: UInt16? + public var outputsCount: UInt32 // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Unique path/identifier for this device - */path: String, + * Total balance found in legacy RN P2WPKH close outputs (in satoshis). + */totalAmount: UInt64, /** - * Transport type: "usb" or "bluetooth" - */transportType: String, - /** - * Optional device name (from BLE advertisement or USB descriptor) - */name: String?, - /** - * USB Vendor ID (for USB devices) - */vendorId: UInt16?, - /** - * USB Product ID (for USB devices) - */productId: UInt16?) { - self.path = path - self.transportType = transportType - self.name = name - self.vendorId = vendorId - self.productId = productId + * Number of P2WPKH outputs found. + */outputsCount: UInt32) { + self.totalAmount = totalAmount + self.outputsCount = outputsCount } } #if compiler(>=6) -extension NativeDeviceInfo: Sendable {} +extension LegacyRnCloseRecoveryScanResult: Sendable {} #endif -extension NativeDeviceInfo: Equatable, Hashable { - public static func ==(lhs: NativeDeviceInfo, rhs: NativeDeviceInfo) -> Bool { - if lhs.path != rhs.path { - return false - } - if lhs.transportType != rhs.transportType { - return false - } - if lhs.name != rhs.name { - return false - } - if lhs.vendorId != rhs.vendorId { +extension LegacyRnCloseRecoveryScanResult: Equatable, Hashable { + public static func ==(lhs: LegacyRnCloseRecoveryScanResult, rhs: LegacyRnCloseRecoveryScanResult) -> Bool { + if lhs.totalAmount != rhs.totalAmount { return false } - if lhs.productId != rhs.productId { + if lhs.outputsCount != rhs.outputsCount { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(path) - hasher.combine(transportType) - hasher.combine(name) - hasher.combine(vendorId) - hasher.combine(productId) + hasher.combine(totalAmount) + hasher.combine(outputsCount) } } -extension NativeDeviceInfo: Codable {} +extension LegacyRnCloseRecoveryScanResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeNativeDeviceInfo: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativeDeviceInfo { +public struct FfiConverterTypeLegacyRnCloseRecoveryScanResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LegacyRnCloseRecoveryScanResult { return - try NativeDeviceInfo( - path: FfiConverterString.read(from: &buf), - transportType: FfiConverterString.read(from: &buf), - name: FfiConverterOptionString.read(from: &buf), - vendorId: FfiConverterOptionUInt16.read(from: &buf), - productId: FfiConverterOptionUInt16.read(from: &buf) + try LegacyRnCloseRecoveryScanResult( + totalAmount: FfiConverterUInt64.read(from: &buf), + outputsCount: FfiConverterUInt32.read(from: &buf) ) } - public static func write(_ value: NativeDeviceInfo, into buf: inout [UInt8]) { - FfiConverterString.write(value.path, into: &buf) - FfiConverterString.write(value.transportType, into: &buf) - FfiConverterOptionString.write(value.name, into: &buf) - FfiConverterOptionUInt16.write(value.vendorId, into: &buf) - FfiConverterOptionUInt16.write(value.productId, into: &buf) + public static func write(_ value: LegacyRnCloseRecoveryScanResult, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.totalAmount, into: &buf) + FfiConverterUInt32.write(value.outputsCount, into: &buf) } } @@ -8802,95 +9040,167 @@ public struct FfiConverterTypeNativeDeviceInfo: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeNativeDeviceInfo_lift(_ buf: RustBuffer) throws -> NativeDeviceInfo { - return try FfiConverterTypeNativeDeviceInfo.lift(buf) +public func FfiConverterTypeLegacyRnCloseRecoveryScanResult_lift(_ buf: RustBuffer) throws -> LegacyRnCloseRecoveryScanResult { + return try FfiConverterTypeLegacyRnCloseRecoveryScanResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeNativeDeviceInfo_lower(_ value: NativeDeviceInfo) -> RustBuffer { - return FfiConverterTypeNativeDeviceInfo.lower(value) +public func FfiConverterTypeLegacyRnCloseRecoveryScanResult_lower(_ value: LegacyRnCloseRecoveryScanResult) -> RustBuffer { + return FfiConverterTypeLegacyRnCloseRecoveryScanResult.lower(value) } -public struct OnChainInvoice { - public var address: String - public var amountSatoshis: UInt64 - public var label: String? - public var message: String? - public var params: [String: String]? +public struct LegacyRnCloseRecoverySweepPreview { + /** + * Fully signed raw sweep transaction hex. Broadcast only after user confirmation. + */ + public var txHex: String + /** + * Transaction id of the sweep transaction. + */ + public var txid: String + /** + * Total input amount in satoshis. + */ + public var totalAmount: UInt64 + /** + * Fee in satoshis. + */ + public var estimatedFee: UInt64 + /** + * Transaction virtual size in vbytes. + */ + public var estimatedVsize: UInt64 + /** + * Number of recovered outputs swept. + */ + public var outputsCount: UInt32 + /** + * Destination address receiving the sweep. + */ + public var destinationAddress: String + /** + * Amount sent to destination after fees. + */ + public var amountAfterFees: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. - public init(address: String, amountSatoshis: UInt64, label: String?, message: String?, params: [String: String]?) { - self.address = address - self.amountSatoshis = amountSatoshis - self.label = label - self.message = message - self.params = params + public init( + /** + * Fully signed raw sweep transaction hex. Broadcast only after user confirmation. + */txHex: String, + /** + * Transaction id of the sweep transaction. + */txid: String, + /** + * Total input amount in satoshis. + */totalAmount: UInt64, + /** + * Fee in satoshis. + */estimatedFee: UInt64, + /** + * Transaction virtual size in vbytes. + */estimatedVsize: UInt64, + /** + * Number of recovered outputs swept. + */outputsCount: UInt32, + /** + * Destination address receiving the sweep. + */destinationAddress: String, + /** + * Amount sent to destination after fees. + */amountAfterFees: UInt64) { + self.txHex = txHex + self.txid = txid + self.totalAmount = totalAmount + self.estimatedFee = estimatedFee + self.estimatedVsize = estimatedVsize + self.outputsCount = outputsCount + self.destinationAddress = destinationAddress + self.amountAfterFees = amountAfterFees } } #if compiler(>=6) -extension OnChainInvoice: Sendable {} +extension LegacyRnCloseRecoverySweepPreview: Sendable {} #endif -extension OnChainInvoice: Equatable, Hashable { - public static func ==(lhs: OnChainInvoice, rhs: OnChainInvoice) -> Bool { - if lhs.address != rhs.address { +extension LegacyRnCloseRecoverySweepPreview: Equatable, Hashable { + public static func ==(lhs: LegacyRnCloseRecoverySweepPreview, rhs: LegacyRnCloseRecoverySweepPreview) -> Bool { + if lhs.txHex != rhs.txHex { return false } - if lhs.amountSatoshis != rhs.amountSatoshis { + if lhs.txid != rhs.txid { return false } - if lhs.label != rhs.label { + if lhs.totalAmount != rhs.totalAmount { return false } - if lhs.message != rhs.message { + if lhs.estimatedFee != rhs.estimatedFee { return false } - if lhs.params != rhs.params { + if lhs.estimatedVsize != rhs.estimatedVsize { + return false + } + if lhs.outputsCount != rhs.outputsCount { + return false + } + if lhs.destinationAddress != rhs.destinationAddress { + return false + } + if lhs.amountAfterFees != rhs.amountAfterFees { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(address) - hasher.combine(amountSatoshis) - hasher.combine(label) - hasher.combine(message) - hasher.combine(params) + hasher.combine(txHex) + hasher.combine(txid) + hasher.combine(totalAmount) + hasher.combine(estimatedFee) + hasher.combine(estimatedVsize) + hasher.combine(outputsCount) + hasher.combine(destinationAddress) + hasher.combine(amountAfterFees) } } -extension OnChainInvoice: Codable {} +extension LegacyRnCloseRecoverySweepPreview: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeOnChainInvoice: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OnChainInvoice { +public struct FfiConverterTypeLegacyRnCloseRecoverySweepPreview: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LegacyRnCloseRecoverySweepPreview { return - try OnChainInvoice( - address: FfiConverterString.read(from: &buf), - amountSatoshis: FfiConverterUInt64.read(from: &buf), - label: FfiConverterOptionString.read(from: &buf), - message: FfiConverterOptionString.read(from: &buf), - params: FfiConverterOptionDictionaryStringString.read(from: &buf) + try LegacyRnCloseRecoverySweepPreview( + txHex: FfiConverterString.read(from: &buf), + txid: FfiConverterString.read(from: &buf), + totalAmount: FfiConverterUInt64.read(from: &buf), + estimatedFee: FfiConverterUInt64.read(from: &buf), + estimatedVsize: FfiConverterUInt64.read(from: &buf), + outputsCount: FfiConverterUInt32.read(from: &buf), + destinationAddress: FfiConverterString.read(from: &buf), + amountAfterFees: FfiConverterUInt64.read(from: &buf) ) } - public static func write(_ value: OnChainInvoice, into buf: inout [UInt8]) { - FfiConverterString.write(value.address, into: &buf) - FfiConverterUInt64.write(value.amountSatoshis, into: &buf) - FfiConverterOptionString.write(value.label, into: &buf) - FfiConverterOptionString.write(value.message, into: &buf) - FfiConverterOptionDictionaryStringString.write(value.params, into: &buf) + public static func write(_ value: LegacyRnCloseRecoverySweepPreview, into buf: inout [UInt8]) { + FfiConverterString.write(value.txHex, into: &buf) + FfiConverterString.write(value.txid, into: &buf) + FfiConverterUInt64.write(value.totalAmount, into: &buf) + FfiConverterUInt64.write(value.estimatedFee, into: &buf) + FfiConverterUInt64.write(value.estimatedVsize, into: &buf) + FfiConverterUInt32.write(value.outputsCount, into: &buf) + FfiConverterString.write(value.destinationAddress, into: &buf) + FfiConverterUInt64.write(value.amountAfterFees, into: &buf) } } @@ -8898,36 +9208,29 @@ public struct FfiConverterTypeOnChainInvoice: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOnChainInvoice_lift(_ buf: RustBuffer) throws -> OnChainInvoice { - return try FfiConverterTypeOnChainInvoice.lift(buf) +public func FfiConverterTypeLegacyRnCloseRecoverySweepPreview_lift(_ buf: RustBuffer) throws -> LegacyRnCloseRecoverySweepPreview { + return try FfiConverterTypeLegacyRnCloseRecoverySweepPreview.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOnChainInvoice_lower(_ value: OnChainInvoice) -> RustBuffer { - return FfiConverterTypeOnChainInvoice.lower(value) +public func FfiConverterTypeLegacyRnCloseRecoverySweepPreview_lower(_ value: LegacyRnCloseRecoverySweepPreview) -> RustBuffer { + return FfiConverterTypeLegacyRnCloseRecoverySweepPreview.lower(value) } -public struct OnchainActivity { +public struct LightningActivity { public var walletId: String public var id: String public var txType: PaymentType - public var txId: String + public var status: PaymentState public var value: UInt64 - public var fee: UInt64 - public var feeRate: UInt64 - public var address: String - public var confirmed: Bool + public var fee: UInt64? + public var invoice: String + public var message: String public var timestamp: UInt64 - public var isBoosted: Bool - public var boostTxIds: [String] - public var isTransfer: Bool - public var doesExist: Bool - public var confirmTimestamp: UInt64? - public var channelId: String? - public var transferTxId: String? + public var preimage: String? public var contact: String? public var createdAt: UInt64? public var updatedAt: UInt64? @@ -8935,24 +9238,17 @@ public struct OnchainActivity { // Default memberwise initializers are never public by default, so we // declare one manually. - public init(walletId: String, id: String, txType: PaymentType, txId: String, value: UInt64, fee: UInt64, feeRate: UInt64, address: String, confirmed: Bool, timestamp: UInt64, isBoosted: Bool, boostTxIds: [String], isTransfer: Bool, doesExist: Bool, confirmTimestamp: UInt64?, channelId: String?, transferTxId: String?, contact: String?, createdAt: UInt64?, updatedAt: UInt64?, seenAt: UInt64?) { + public init(walletId: String, id: String, txType: PaymentType, status: PaymentState, value: UInt64, fee: UInt64?, invoice: String, message: String, timestamp: UInt64, preimage: String?, contact: String?, createdAt: UInt64?, updatedAt: UInt64?, seenAt: UInt64?) { self.walletId = walletId self.id = id self.txType = txType - self.txId = txId + self.status = status self.value = value self.fee = fee - self.feeRate = feeRate - self.address = address - self.confirmed = confirmed + self.invoice = invoice + self.message = message self.timestamp = timestamp - self.isBoosted = isBoosted - self.boostTxIds = boostTxIds - self.isTransfer = isTransfer - self.doesExist = doesExist - self.confirmTimestamp = confirmTimestamp - self.channelId = channelId - self.transferTxId = transferTxId + self.preimage = preimage self.contact = contact self.createdAt = createdAt self.updatedAt = updatedAt @@ -8961,12 +9257,12 @@ public struct OnchainActivity { } #if compiler(>=6) -extension OnchainActivity: Sendable {} +extension LightningActivity: Sendable {} #endif -extension OnchainActivity: Equatable, Hashable { - public static func ==(lhs: OnchainActivity, rhs: OnchainActivity) -> Bool { +extension LightningActivity: Equatable, Hashable { + public static func ==(lhs: LightningActivity, rhs: LightningActivity) -> Bool { if lhs.walletId != rhs.walletId { return false } @@ -8976,7 +9272,7 @@ extension OnchainActivity: Equatable, Hashable { if lhs.txType != rhs.txType { return false } - if lhs.txId != rhs.txId { + if lhs.status != rhs.status { return false } if lhs.value != rhs.value { @@ -8985,37 +9281,16 @@ extension OnchainActivity: Equatable, Hashable { if lhs.fee != rhs.fee { return false } - if lhs.feeRate != rhs.feeRate { - return false - } - if lhs.address != rhs.address { + if lhs.invoice != rhs.invoice { return false } - if lhs.confirmed != rhs.confirmed { + if lhs.message != rhs.message { return false } if lhs.timestamp != rhs.timestamp { return false } - if lhs.isBoosted != rhs.isBoosted { - return false - } - if lhs.boostTxIds != rhs.boostTxIds { - return false - } - if lhs.isTransfer != rhs.isTransfer { - return false - } - if lhs.doesExist != rhs.doesExist { - return false - } - if lhs.confirmTimestamp != rhs.confirmTimestamp { - return false - } - if lhs.channelId != rhs.channelId { - return false - } - if lhs.transferTxId != rhs.transferTxId { + if lhs.preimage != rhs.preimage { return false } if lhs.contact != rhs.contact { @@ -9037,20 +9312,13 @@ extension OnchainActivity: Equatable, Hashable { hasher.combine(walletId) hasher.combine(id) hasher.combine(txType) - hasher.combine(txId) + hasher.combine(status) hasher.combine(value) hasher.combine(fee) - hasher.combine(feeRate) - hasher.combine(address) - hasher.combine(confirmed) + hasher.combine(invoice) + hasher.combine(message) hasher.combine(timestamp) - hasher.combine(isBoosted) - hasher.combine(boostTxIds) - hasher.combine(isTransfer) - hasher.combine(doesExist) - hasher.combine(confirmTimestamp) - hasher.combine(channelId) - hasher.combine(transferTxId) + hasher.combine(preimage) hasher.combine(contact) hasher.combine(createdAt) hasher.combine(updatedAt) @@ -9058,34 +9326,27 @@ extension OnchainActivity: Equatable, Hashable { } } -extension OnchainActivity: Codable {} +extension LightningActivity: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeOnchainActivity: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OnchainActivity { +public struct FfiConverterTypeLightningActivity: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LightningActivity { return - try OnchainActivity( + try LightningActivity( walletId: FfiConverterString.read(from: &buf), id: FfiConverterString.read(from: &buf), txType: FfiConverterTypePaymentType.read(from: &buf), - txId: FfiConverterString.read(from: &buf), + status: FfiConverterTypePaymentState.read(from: &buf), value: FfiConverterUInt64.read(from: &buf), - fee: FfiConverterUInt64.read(from: &buf), - feeRate: FfiConverterUInt64.read(from: &buf), - address: FfiConverterString.read(from: &buf), - confirmed: FfiConverterBool.read(from: &buf), + fee: FfiConverterOptionUInt64.read(from: &buf), + invoice: FfiConverterString.read(from: &buf), + message: FfiConverterString.read(from: &buf), timestamp: FfiConverterUInt64.read(from: &buf), - isBoosted: FfiConverterBool.read(from: &buf), - boostTxIds: FfiConverterSequenceString.read(from: &buf), - isTransfer: FfiConverterBool.read(from: &buf), - doesExist: FfiConverterBool.read(from: &buf), - confirmTimestamp: FfiConverterOptionUInt64.read(from: &buf), - channelId: FfiConverterOptionString.read(from: &buf), - transferTxId: FfiConverterOptionString.read(from: &buf), + preimage: FfiConverterOptionString.read(from: &buf), contact: FfiConverterOptionString.read(from: &buf), createdAt: FfiConverterOptionUInt64.read(from: &buf), updatedAt: FfiConverterOptionUInt64.read(from: &buf), @@ -9093,24 +9354,17 @@ public struct FfiConverterTypeOnchainActivity: FfiConverterRustBuffer { ) } - public static func write(_ value: OnchainActivity, into buf: inout [UInt8]) { + public static func write(_ value: LightningActivity, into buf: inout [UInt8]) { FfiConverterString.write(value.walletId, into: &buf) FfiConverterString.write(value.id, into: &buf) FfiConverterTypePaymentType.write(value.txType, into: &buf) - FfiConverterString.write(value.txId, into: &buf) + FfiConverterTypePaymentState.write(value.status, into: &buf) FfiConverterUInt64.write(value.value, into: &buf) - FfiConverterUInt64.write(value.fee, into: &buf) - FfiConverterUInt64.write(value.feeRate, into: &buf) - FfiConverterString.write(value.address, into: &buf) - FfiConverterBool.write(value.confirmed, into: &buf) + FfiConverterOptionUInt64.write(value.fee, into: &buf) + FfiConverterString.write(value.invoice, into: &buf) + FfiConverterString.write(value.message, into: &buf) FfiConverterUInt64.write(value.timestamp, into: &buf) - FfiConverterBool.write(value.isBoosted, into: &buf) - FfiConverterSequenceString.write(value.boostTxIds, into: &buf) - FfiConverterBool.write(value.isTransfer, into: &buf) - FfiConverterBool.write(value.doesExist, into: &buf) - FfiConverterOptionUInt64.write(value.confirmTimestamp, into: &buf) - FfiConverterOptionString.write(value.channelId, into: &buf) - FfiConverterOptionString.write(value.transferTxId, into: &buf) + FfiConverterOptionString.write(value.preimage, into: &buf) FfiConverterOptionString.write(value.contact, into: &buf) FfiConverterOptionUInt64.write(value.createdAt, into: &buf) FfiConverterOptionUInt64.write(value.updatedAt, into: &buf) @@ -9122,94 +9376,127 @@ public struct FfiConverterTypeOnchainActivity: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOnchainActivity_lift(_ buf: RustBuffer) throws -> OnchainActivity { - return try FfiConverterTypeOnchainActivity.lift(buf) +public func FfiConverterTypeLightningActivity_lift(_ buf: RustBuffer) throws -> LightningActivity { + return try FfiConverterTypeLightningActivity.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOnchainActivity_lower(_ value: OnchainActivity) -> RustBuffer { - return FfiConverterTypeOnchainActivity.lower(value) +public func FfiConverterTypeLightningActivity_lower(_ value: LightningActivity) -> RustBuffer { + return FfiConverterTypeLightningActivity.lower(value) } -/** - * One single-signature account in Passport's generic JSON export. - */ -public struct PassportAccount { - public var accountType: AccountType - /** - * Standard xpub/tpub encoding used by Passport's export. - */ - public var xpub: String - /** - * Account-level BIP32 path, such as `m/84'/0'/0'`. - */ - public var derivationPath: String +public struct LightningInvoice { + public var bolt11: String + public var paymentHash: Data + public var amountSatoshis: UInt64 + public var timestampSeconds: UInt64 + public var expirySeconds: UInt64 + public var isExpired: Bool + public var description: String? + public var networkType: NetworkType + public var payeeNodeId: Data? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(accountType: AccountType, - /** - * Standard xpub/tpub encoding used by Passport's export. - */xpub: String, - /** - * Account-level BIP32 path, such as `m/84'/0'/0'`. - */derivationPath: String) { - self.accountType = accountType - self.xpub = xpub - self.derivationPath = derivationPath + public init(bolt11: String, paymentHash: Data, amountSatoshis: UInt64, timestampSeconds: UInt64, expirySeconds: UInt64, isExpired: Bool, description: String?, networkType: NetworkType, payeeNodeId: Data?) { + self.bolt11 = bolt11 + self.paymentHash = paymentHash + self.amountSatoshis = amountSatoshis + self.timestampSeconds = timestampSeconds + self.expirySeconds = expirySeconds + self.isExpired = isExpired + self.description = description + self.networkType = networkType + self.payeeNodeId = payeeNodeId } } #if compiler(>=6) -extension PassportAccount: Sendable {} +extension LightningInvoice: Sendable {} #endif -extension PassportAccount: Equatable, Hashable { - public static func ==(lhs: PassportAccount, rhs: PassportAccount) -> Bool { - if lhs.accountType != rhs.accountType { +extension LightningInvoice: Equatable, Hashable { + public static func ==(lhs: LightningInvoice, rhs: LightningInvoice) -> Bool { + if lhs.bolt11 != rhs.bolt11 { return false } - if lhs.xpub != rhs.xpub { + if lhs.paymentHash != rhs.paymentHash { return false } - if lhs.derivationPath != rhs.derivationPath { + if lhs.amountSatoshis != rhs.amountSatoshis { + return false + } + if lhs.timestampSeconds != rhs.timestampSeconds { + return false + } + if lhs.expirySeconds != rhs.expirySeconds { + return false + } + if lhs.isExpired != rhs.isExpired { + return false + } + if lhs.description != rhs.description { + return false + } + if lhs.networkType != rhs.networkType { + return false + } + if lhs.payeeNodeId != rhs.payeeNodeId { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(accountType) - hasher.combine(xpub) - hasher.combine(derivationPath) + hasher.combine(bolt11) + hasher.combine(paymentHash) + hasher.combine(amountSatoshis) + hasher.combine(timestampSeconds) + hasher.combine(expirySeconds) + hasher.combine(isExpired) + hasher.combine(description) + hasher.combine(networkType) + hasher.combine(payeeNodeId) } } -extension PassportAccount: Codable {} +extension LightningInvoice: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePassportAccount: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PassportAccount { +public struct FfiConverterTypeLightningInvoice: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LightningInvoice { return - try PassportAccount( - accountType: FfiConverterTypeAccountType.read(from: &buf), - xpub: FfiConverterString.read(from: &buf), - derivationPath: FfiConverterString.read(from: &buf) + try LightningInvoice( + bolt11: FfiConverterString.read(from: &buf), + paymentHash: FfiConverterData.read(from: &buf), + amountSatoshis: FfiConverterUInt64.read(from: &buf), + timestampSeconds: FfiConverterUInt64.read(from: &buf), + expirySeconds: FfiConverterUInt64.read(from: &buf), + isExpired: FfiConverterBool.read(from: &buf), + description: FfiConverterOptionString.read(from: &buf), + networkType: FfiConverterTypeNetworkType.read(from: &buf), + payeeNodeId: FfiConverterOptionData.read(from: &buf) ) } - public static func write(_ value: PassportAccount, into buf: inout [UInt8]) { - FfiConverterTypeAccountType.write(value.accountType, into: &buf) - FfiConverterString.write(value.xpub, into: &buf) - FfiConverterString.write(value.derivationPath, into: &buf) + public static func write(_ value: LightningInvoice, into buf: inout [UInt8]) { + FfiConverterString.write(value.bolt11, into: &buf) + FfiConverterData.write(value.paymentHash, into: &buf) + FfiConverterUInt64.write(value.amountSatoshis, into: &buf) + FfiConverterUInt64.write(value.timestampSeconds, into: &buf) + FfiConverterUInt64.write(value.expirySeconds, into: &buf) + FfiConverterBool.write(value.isExpired, into: &buf) + FfiConverterOptionString.write(value.description, into: &buf) + FfiConverterTypeNetworkType.write(value.networkType, into: &buf) + FfiConverterOptionData.write(value.payeeNodeId, into: &buf) } } @@ -9217,88 +9504,79 @@ public struct FfiConverterTypePassportAccount: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePassportAccount_lift(_ buf: RustBuffer) throws -> PassportAccount { - return try FfiConverterTypePassportAccount.lift(buf) +public func FfiConverterTypeLightningInvoice_lift(_ buf: RustBuffer) throws -> LightningInvoice { + return try FfiConverterTypeLightningInvoice.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePassportAccount_lower(_ value: PassportAccount) -> RustBuffer { - return FfiConverterTypePassportAccount.lower(value) +public func FfiConverterTypeLightningInvoice_lower(_ value: LightningInvoice) -> RustBuffer { + return FfiConverterTypeLightningInvoice.lower(value) } -/** - * The single-signature accounts exported by Passport for one account index. - */ -public struct PassportAccountExport { - /** - * Root fingerprint used in descriptors and PSBT key origins. - */ - public var masterFingerprint: String - public var accountIndex: UInt32 - public var accounts: [PassportAccount] - +public struct LnurlAddressData { + public var uri: String + public var domain: String + public var username: String + // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * Root fingerprint used in descriptors and PSBT key origins. - */masterFingerprint: String, accountIndex: UInt32, accounts: [PassportAccount]) { - self.masterFingerprint = masterFingerprint - self.accountIndex = accountIndex - self.accounts = accounts + public init(uri: String, domain: String, username: String) { + self.uri = uri + self.domain = domain + self.username = username } } #if compiler(>=6) -extension PassportAccountExport: Sendable {} +extension LnurlAddressData: Sendable {} #endif -extension PassportAccountExport: Equatable, Hashable { - public static func ==(lhs: PassportAccountExport, rhs: PassportAccountExport) -> Bool { - if lhs.masterFingerprint != rhs.masterFingerprint { +extension LnurlAddressData: Equatable, Hashable { + public static func ==(lhs: LnurlAddressData, rhs: LnurlAddressData) -> Bool { + if lhs.uri != rhs.uri { return false } - if lhs.accountIndex != rhs.accountIndex { + if lhs.domain != rhs.domain { return false } - if lhs.accounts != rhs.accounts { + if lhs.username != rhs.username { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(masterFingerprint) - hasher.combine(accountIndex) - hasher.combine(accounts) + hasher.combine(uri) + hasher.combine(domain) + hasher.combine(username) } } -extension PassportAccountExport: Codable {} +extension LnurlAddressData: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePassportAccountExport: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PassportAccountExport { +public struct FfiConverterTypeLnurlAddressData: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlAddressData { return - try PassportAccountExport( - masterFingerprint: FfiConverterString.read(from: &buf), - accountIndex: FfiConverterUInt32.read(from: &buf), - accounts: FfiConverterSequenceTypePassportAccount.read(from: &buf) + try LnurlAddressData( + uri: FfiConverterString.read(from: &buf), + domain: FfiConverterString.read(from: &buf), + username: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: PassportAccountExport, into buf: inout [UInt8]) { - FfiConverterString.write(value.masterFingerprint, into: &buf) - FfiConverterUInt32.write(value.accountIndex, into: &buf) - FfiConverterSequenceTypePassportAccount.write(value.accounts, into: &buf) + public static func write(_ value: LnurlAddressData, into buf: inout [UInt8]) { + FfiConverterString.write(value.uri, into: &buf) + FfiConverterString.write(value.domain, into: &buf) + FfiConverterString.write(value.username, into: &buf) } } @@ -9306,143 +9584,87 @@ public struct FfiConverterTypePassportAccountExport: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePassportAccountExport_lift(_ buf: RustBuffer) throws -> PassportAccountExport { - return try FfiConverterTypePassportAccountExport.lift(buf) +public func FfiConverterTypeLnurlAddressData_lift(_ buf: RustBuffer) throws -> LnurlAddressData { + return try FfiConverterTypeLnurlAddressData.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePassportAccountExport_lower(_ value: PassportAccountExport) -> RustBuffer { - return FfiConverterTypePassportAccountExport.lower(value) +public func FfiConverterTypeLnurlAddressData_lower(_ value: LnurlAddressData) -> RustBuffer { + return FfiConverterTypeLnurlAddressData.lower(value) } -public struct PreActivityMetadata { - public var walletId: String - public var paymentId: String - public var tags: [String] - public var paymentHash: String? - public var txId: String? - public var address: String? - public var isReceive: Bool - public var feeRate: UInt64 - public var isTransfer: Bool - public var channelId: String? - public var createdAt: UInt64 +public struct LnurlAuthData { + public var uri: String + public var tag: String + public var k1: String + public var domain: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init(walletId: String, paymentId: String, tags: [String], paymentHash: String?, txId: String?, address: String?, isReceive: Bool, feeRate: UInt64, isTransfer: Bool, channelId: String?, createdAt: UInt64) { - self.walletId = walletId - self.paymentId = paymentId - self.tags = tags - self.paymentHash = paymentHash - self.txId = txId - self.address = address - self.isReceive = isReceive - self.feeRate = feeRate - self.isTransfer = isTransfer - self.channelId = channelId - self.createdAt = createdAt + public init(uri: String, tag: String, k1: String, domain: String) { + self.uri = uri + self.tag = tag + self.k1 = k1 + self.domain = domain } } #if compiler(>=6) -extension PreActivityMetadata: Sendable {} +extension LnurlAuthData: Sendable {} #endif -extension PreActivityMetadata: Equatable, Hashable { - public static func ==(lhs: PreActivityMetadata, rhs: PreActivityMetadata) -> Bool { - if lhs.walletId != rhs.walletId { - return false - } - if lhs.paymentId != rhs.paymentId { - return false - } - if lhs.tags != rhs.tags { - return false - } - if lhs.paymentHash != rhs.paymentHash { - return false - } - if lhs.txId != rhs.txId { - return false - } - if lhs.address != rhs.address { - return false - } - if lhs.isReceive != rhs.isReceive { - return false - } - if lhs.feeRate != rhs.feeRate { +extension LnurlAuthData: Equatable, Hashable { + public static func ==(lhs: LnurlAuthData, rhs: LnurlAuthData) -> Bool { + if lhs.uri != rhs.uri { return false } - if lhs.isTransfer != rhs.isTransfer { + if lhs.tag != rhs.tag { return false } - if lhs.channelId != rhs.channelId { + if lhs.k1 != rhs.k1 { return false } - if lhs.createdAt != rhs.createdAt { + if lhs.domain != rhs.domain { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(walletId) - hasher.combine(paymentId) - hasher.combine(tags) - hasher.combine(paymentHash) - hasher.combine(txId) - hasher.combine(address) - hasher.combine(isReceive) - hasher.combine(feeRate) - hasher.combine(isTransfer) - hasher.combine(channelId) - hasher.combine(createdAt) + hasher.combine(uri) + hasher.combine(tag) + hasher.combine(k1) + hasher.combine(domain) } } -extension PreActivityMetadata: Codable {} +extension LnurlAuthData: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePreActivityMetadata: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PreActivityMetadata { +public struct FfiConverterTypeLnurlAuthData: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlAuthData { return - try PreActivityMetadata( - walletId: FfiConverterString.read(from: &buf), - paymentId: FfiConverterString.read(from: &buf), - tags: FfiConverterSequenceString.read(from: &buf), - paymentHash: FfiConverterOptionString.read(from: &buf), - txId: FfiConverterOptionString.read(from: &buf), - address: FfiConverterOptionString.read(from: &buf), - isReceive: FfiConverterBool.read(from: &buf), - feeRate: FfiConverterUInt64.read(from: &buf), - isTransfer: FfiConverterBool.read(from: &buf), - channelId: FfiConverterOptionString.read(from: &buf), - createdAt: FfiConverterUInt64.read(from: &buf) + try LnurlAuthData( + uri: FfiConverterString.read(from: &buf), + tag: FfiConverterString.read(from: &buf), + k1: FfiConverterString.read(from: &buf), + domain: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: PreActivityMetadata, into buf: inout [UInt8]) { - FfiConverterString.write(value.walletId, into: &buf) - FfiConverterString.write(value.paymentId, into: &buf) - FfiConverterSequenceString.write(value.tags, into: &buf) - FfiConverterOptionString.write(value.paymentHash, into: &buf) - FfiConverterOptionString.write(value.txId, into: &buf) - FfiConverterOptionString.write(value.address, into: &buf) - FfiConverterBool.write(value.isReceive, into: &buf) - FfiConverterUInt64.write(value.feeRate, into: &buf) - FfiConverterBool.write(value.isTransfer, into: &buf) - FfiConverterOptionString.write(value.channelId, into: &buf) - FfiConverterUInt64.write(value.createdAt, into: &buf) + public static func write(_ value: LnurlAuthData, into buf: inout [UInt8]) { + FfiConverterString.write(value.uri, into: &buf) + FfiConverterString.write(value.tag, into: &buf) + FfiConverterString.write(value.k1, into: &buf) + FfiConverterString.write(value.domain, into: &buf) } } @@ -9450,63 +9672,87 @@ public struct FfiConverterTypePreActivityMetadata: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePreActivityMetadata_lift(_ buf: RustBuffer) throws -> PreActivityMetadata { - return try FfiConverterTypePreActivityMetadata.lift(buf) +public func FfiConverterTypeLnurlAuthData_lift(_ buf: RustBuffer) throws -> LnurlAuthData { + return try FfiConverterTypeLnurlAuthData.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePreActivityMetadata_lower(_ value: PreActivityMetadata) -> RustBuffer { - return FfiConverterTypePreActivityMetadata.lower(value) +public func FfiConverterTypeLnurlAuthData_lower(_ value: LnurlAuthData) -> RustBuffer { + return FfiConverterTypeLnurlAuthData.lower(value) } -public struct PubkyAuth { - public var data: String +public struct LnurlChannelData { + public var uri: String + public var callback: String + public var k1: String + public var tag: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init(data: String) { - self.data = data + public init(uri: String, callback: String, k1: String, tag: String) { + self.uri = uri + self.callback = callback + self.k1 = k1 + self.tag = tag } } #if compiler(>=6) -extension PubkyAuth: Sendable {} +extension LnurlChannelData: Sendable {} #endif -extension PubkyAuth: Equatable, Hashable { - public static func ==(lhs: PubkyAuth, rhs: PubkyAuth) -> Bool { - if lhs.data != rhs.data { +extension LnurlChannelData: Equatable, Hashable { + public static func ==(lhs: LnurlChannelData, rhs: LnurlChannelData) -> Bool { + if lhs.uri != rhs.uri { + return false + } + if lhs.callback != rhs.callback { + return false + } + if lhs.k1 != rhs.k1 { + return false + } + if lhs.tag != rhs.tag { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(data) + hasher.combine(uri) + hasher.combine(callback) + hasher.combine(k1) + hasher.combine(tag) } } -extension PubkyAuth: Codable {} +extension LnurlChannelData: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePubkyAuth: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyAuth { +public struct FfiConverterTypeLnurlChannelData: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlChannelData { return - try PubkyAuth( - data: FfiConverterString.read(from: &buf) + try LnurlChannelData( + uri: FfiConverterString.read(from: &buf), + callback: FfiConverterString.read(from: &buf), + k1: FfiConverterString.read(from: &buf), + tag: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: PubkyAuth, into buf: inout [UInt8]) { - FfiConverterString.write(value.data, into: &buf) + public static func write(_ value: LnurlChannelData, into buf: inout [UInt8]) { + FfiConverterString.write(value.uri, into: &buf) + FfiConverterString.write(value.callback, into: &buf) + FfiConverterString.write(value.k1, into: &buf) + FfiConverterString.write(value.tag, into: &buf) } } @@ -9514,128 +9760,119 @@ public struct FfiConverterTypePubkyAuth: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyAuth_lift(_ buf: RustBuffer) throws -> PubkyAuth { - return try FfiConverterTypePubkyAuth.lift(buf) +public func FfiConverterTypeLnurlChannelData_lift(_ buf: RustBuffer) throws -> LnurlChannelData { + return try FfiConverterTypeLnurlChannelData.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyAuth_lower(_ value: PubkyAuth) -> RustBuffer { - return FfiConverterTypePubkyAuth.lower(value) +public func FfiConverterTypeLnurlChannelData_lower(_ value: LnurlChannelData) -> RustBuffer { + return FfiConverterTypeLnurlChannelData.lower(value) } -/** - * Details extracted from a `pubkyauth://` deep-link URL. - */ -public struct PubkyAuthDetails { - /** - * Whether this is a signin or signup flow. - */ - public var kind: PubkyAuthKind - /** - * Requested capabilities (e.g. `"/pub/pubky.app/:rw"`). - */ - public var capabilities: String - /** - * Relay URL used for the auth exchange. - */ - public var relay: String - /** - * Homeserver public key (z32-encoded). Present only for signup flows. - */ - public var homeserver: String? - /** - * Signup token. Present only for signup flows. - */ - public var signupToken: String? +public struct LnurlPayData { + public var uri: String + public var callback: String + public var minSendable: UInt64 + public var maxSendable: UInt64 + public var metadataStr: String + public var commentAllowed: UInt32? + public var allowsNostr: Bool + public var nostrPubkey: Data? // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * Whether this is a signin or signup flow. - */kind: PubkyAuthKind, - /** - * Requested capabilities (e.g. `"/pub/pubky.app/:rw"`). - */capabilities: String, - /** - * Relay URL used for the auth exchange. - */relay: String, - /** - * Homeserver public key (z32-encoded). Present only for signup flows. - */homeserver: String?, - /** - * Signup token. Present only for signup flows. - */signupToken: String?) { - self.kind = kind - self.capabilities = capabilities - self.relay = relay - self.homeserver = homeserver - self.signupToken = signupToken + public init(uri: String, callback: String, minSendable: UInt64, maxSendable: UInt64, metadataStr: String, commentAllowed: UInt32?, allowsNostr: Bool, nostrPubkey: Data?) { + self.uri = uri + self.callback = callback + self.minSendable = minSendable + self.maxSendable = maxSendable + self.metadataStr = metadataStr + self.commentAllowed = commentAllowed + self.allowsNostr = allowsNostr + self.nostrPubkey = nostrPubkey } } #if compiler(>=6) -extension PubkyAuthDetails: Sendable {} +extension LnurlPayData: Sendable {} #endif -extension PubkyAuthDetails: Equatable, Hashable { - public static func ==(lhs: PubkyAuthDetails, rhs: PubkyAuthDetails) -> Bool { - if lhs.kind != rhs.kind { +extension LnurlPayData: Equatable, Hashable { + public static func ==(lhs: LnurlPayData, rhs: LnurlPayData) -> Bool { + if lhs.uri != rhs.uri { return false } - if lhs.capabilities != rhs.capabilities { + if lhs.callback != rhs.callback { return false } - if lhs.relay != rhs.relay { + if lhs.minSendable != rhs.minSendable { return false } - if lhs.homeserver != rhs.homeserver { + if lhs.maxSendable != rhs.maxSendable { return false } - if lhs.signupToken != rhs.signupToken { + if lhs.metadataStr != rhs.metadataStr { + return false + } + if lhs.commentAllowed != rhs.commentAllowed { + return false + } + if lhs.allowsNostr != rhs.allowsNostr { + return false + } + if lhs.nostrPubkey != rhs.nostrPubkey { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(kind) - hasher.combine(capabilities) - hasher.combine(relay) - hasher.combine(homeserver) - hasher.combine(signupToken) + hasher.combine(uri) + hasher.combine(callback) + hasher.combine(minSendable) + hasher.combine(maxSendable) + hasher.combine(metadataStr) + hasher.combine(commentAllowed) + hasher.combine(allowsNostr) + hasher.combine(nostrPubkey) } } -extension PubkyAuthDetails: Codable {} +extension LnurlPayData: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePubkyAuthDetails: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyAuthDetails { +public struct FfiConverterTypeLnurlPayData: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlPayData { return - try PubkyAuthDetails( - kind: FfiConverterTypePubkyAuthKind.read(from: &buf), - capabilities: FfiConverterString.read(from: &buf), - relay: FfiConverterString.read(from: &buf), - homeserver: FfiConverterOptionString.read(from: &buf), - signupToken: FfiConverterOptionString.read(from: &buf) + try LnurlPayData( + uri: FfiConverterString.read(from: &buf), + callback: FfiConverterString.read(from: &buf), + minSendable: FfiConverterUInt64.read(from: &buf), + maxSendable: FfiConverterUInt64.read(from: &buf), + metadataStr: FfiConverterString.read(from: &buf), + commentAllowed: FfiConverterOptionUInt32.read(from: &buf), + allowsNostr: FfiConverterBool.read(from: &buf), + nostrPubkey: FfiConverterOptionData.read(from: &buf) ) } - public static func write(_ value: PubkyAuthDetails, into buf: inout [UInt8]) { - FfiConverterTypePubkyAuthKind.write(value.kind, into: &buf) - FfiConverterString.write(value.capabilities, into: &buf) - FfiConverterString.write(value.relay, into: &buf) - FfiConverterOptionString.write(value.homeserver, into: &buf) - FfiConverterOptionString.write(value.signupToken, into: &buf) + public static func write(_ value: LnurlPayData, into buf: inout [UInt8]) { + FfiConverterString.write(value.uri, into: &buf) + FfiConverterString.write(value.callback, into: &buf) + FfiConverterUInt64.write(value.minSendable, into: &buf) + FfiConverterUInt64.write(value.maxSendable, into: &buf) + FfiConverterString.write(value.metadataStr, into: &buf) + FfiConverterOptionUInt32.write(value.commentAllowed, into: &buf) + FfiConverterBool.write(value.allowsNostr, into: &buf) + FfiConverterOptionData.write(value.nostrPubkey, into: &buf) } } @@ -9643,95 +9880,111 @@ public struct FfiConverterTypePubkyAuthDetails: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyAuthDetails_lift(_ buf: RustBuffer) throws -> PubkyAuthDetails { - return try FfiConverterTypePubkyAuthDetails.lift(buf) +public func FfiConverterTypeLnurlPayData_lift(_ buf: RustBuffer) throws -> LnurlPayData { + return try FfiConverterTypeLnurlPayData.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyAuthDetails_lower(_ value: PubkyAuthDetails) -> RustBuffer { - return FfiConverterTypePubkyAuthDetails.lower(value) +public func FfiConverterTypeLnurlPayData_lower(_ value: LnurlPayData) -> RustBuffer { + return FfiConverterTypeLnurlPayData.lower(value) } -public struct PubkyProfile { - public var name: String - public var bio: String? - public var image: String? - public var links: [PubkyProfileLink]? - public var status: String? +public struct LnurlWithdrawData { + public var uri: String + public var callback: String + public var k1: String + public var defaultDescription: String + public var minWithdrawable: UInt64? + public var maxWithdrawable: UInt64 + public var tag: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init(name: String, bio: String?, image: String?, links: [PubkyProfileLink]?, status: String?) { - self.name = name - self.bio = bio - self.image = image - self.links = links - self.status = status + public init(uri: String, callback: String, k1: String, defaultDescription: String, minWithdrawable: UInt64?, maxWithdrawable: UInt64, tag: String) { + self.uri = uri + self.callback = callback + self.k1 = k1 + self.defaultDescription = defaultDescription + self.minWithdrawable = minWithdrawable + self.maxWithdrawable = maxWithdrawable + self.tag = tag } } #if compiler(>=6) -extension PubkyProfile: Sendable {} +extension LnurlWithdrawData: Sendable {} #endif -extension PubkyProfile: Equatable, Hashable { - public static func ==(lhs: PubkyProfile, rhs: PubkyProfile) -> Bool { - if lhs.name != rhs.name { +extension LnurlWithdrawData: Equatable, Hashable { + public static func ==(lhs: LnurlWithdrawData, rhs: LnurlWithdrawData) -> Bool { + if lhs.uri != rhs.uri { return false } - if lhs.bio != rhs.bio { + if lhs.callback != rhs.callback { return false } - if lhs.image != rhs.image { + if lhs.k1 != rhs.k1 { return false } - if lhs.links != rhs.links { + if lhs.defaultDescription != rhs.defaultDescription { return false } - if lhs.status != rhs.status { + if lhs.minWithdrawable != rhs.minWithdrawable { + return false + } + if lhs.maxWithdrawable != rhs.maxWithdrawable { + return false + } + if lhs.tag != rhs.tag { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(name) - hasher.combine(bio) - hasher.combine(image) - hasher.combine(links) - hasher.combine(status) + hasher.combine(uri) + hasher.combine(callback) + hasher.combine(k1) + hasher.combine(defaultDescription) + hasher.combine(minWithdrawable) + hasher.combine(maxWithdrawable) + hasher.combine(tag) } } -extension PubkyProfile: Codable {} +extension LnurlWithdrawData: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePubkyProfile: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyProfile { +public struct FfiConverterTypeLnurlWithdrawData: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LnurlWithdrawData { return - try PubkyProfile( - name: FfiConverterString.read(from: &buf), - bio: FfiConverterOptionString.read(from: &buf), - image: FfiConverterOptionString.read(from: &buf), - links: FfiConverterOptionSequenceTypePubkyProfileLink.read(from: &buf), - status: FfiConverterOptionString.read(from: &buf) + try LnurlWithdrawData( + uri: FfiConverterString.read(from: &buf), + callback: FfiConverterString.read(from: &buf), + k1: FfiConverterString.read(from: &buf), + defaultDescription: FfiConverterString.read(from: &buf), + minWithdrawable: FfiConverterOptionUInt64.read(from: &buf), + maxWithdrawable: FfiConverterUInt64.read(from: &buf), + tag: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: PubkyProfile, into buf: inout [UInt8]) { - FfiConverterString.write(value.name, into: &buf) - FfiConverterOptionString.write(value.bio, into: &buf) - FfiConverterOptionString.write(value.image, into: &buf) - FfiConverterOptionSequenceTypePubkyProfileLink.write(value.links, into: &buf) - FfiConverterOptionString.write(value.status, into: &buf) + public static func write(_ value: LnurlWithdrawData, into buf: inout [UInt8]) { + FfiConverterString.write(value.uri, into: &buf) + FfiConverterString.write(value.callback, into: &buf) + FfiConverterString.write(value.k1, into: &buf) + FfiConverterString.write(value.defaultDescription, into: &buf) + FfiConverterOptionUInt64.write(value.minWithdrawable, into: &buf) + FfiConverterUInt64.write(value.maxWithdrawable, into: &buf) + FfiConverterString.write(value.tag, into: &buf) } } @@ -9739,71 +9992,128 @@ public struct FfiConverterTypePubkyProfile: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyProfile_lift(_ buf: RustBuffer) throws -> PubkyProfile { - return try FfiConverterTypePubkyProfile.lift(buf) +public func FfiConverterTypeLnurlWithdrawData_lift(_ buf: RustBuffer) throws -> LnurlWithdrawData { + return try FfiConverterTypeLnurlWithdrawData.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyProfile_lower(_ value: PubkyProfile) -> RustBuffer { - return FfiConverterTypePubkyProfile.lower(value) +public func FfiConverterTypeLnurlWithdrawData_lower(_ value: LnurlWithdrawData) -> RustBuffer { + return FfiConverterTypeLnurlWithdrawData.lower(value) } -public struct PubkyProfileLink { - public var title: String - public var url: String +/** + * Native device information returned from enumeration + */ +public struct NativeDeviceInfo { + /** + * Unique path/identifier for this device + */ + public var path: String + /** + * Transport type: "usb" or "bluetooth" + */ + public var transportType: String + /** + * Optional device name (from BLE advertisement or USB descriptor) + */ + public var name: String? + /** + * USB Vendor ID (for USB devices) + */ + public var vendorId: UInt16? + /** + * USB Product ID (for USB devices) + */ + public var productId: UInt16? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(title: String, url: String) { - self.title = title - self.url = url + public init( + /** + * Unique path/identifier for this device + */path: String, + /** + * Transport type: "usb" or "bluetooth" + */transportType: String, + /** + * Optional device name (from BLE advertisement or USB descriptor) + */name: String?, + /** + * USB Vendor ID (for USB devices) + */vendorId: UInt16?, + /** + * USB Product ID (for USB devices) + */productId: UInt16?) { + self.path = path + self.transportType = transportType + self.name = name + self.vendorId = vendorId + self.productId = productId } } #if compiler(>=6) -extension PubkyProfileLink: Sendable {} +extension NativeDeviceInfo: Sendable {} #endif -extension PubkyProfileLink: Equatable, Hashable { - public static func ==(lhs: PubkyProfileLink, rhs: PubkyProfileLink) -> Bool { - if lhs.title != rhs.title { +extension NativeDeviceInfo: Equatable, Hashable { + public static func ==(lhs: NativeDeviceInfo, rhs: NativeDeviceInfo) -> Bool { + if lhs.path != rhs.path { return false } - if lhs.url != rhs.url { + if lhs.transportType != rhs.transportType { + return false + } + if lhs.name != rhs.name { + return false + } + if lhs.vendorId != rhs.vendorId { + return false + } + if lhs.productId != rhs.productId { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(title) - hasher.combine(url) + hasher.combine(path) + hasher.combine(transportType) + hasher.combine(name) + hasher.combine(vendorId) + hasher.combine(productId) } } -extension PubkyProfileLink: Codable {} +extension NativeDeviceInfo: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePubkyProfileLink: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyProfileLink { +public struct FfiConverterTypeNativeDeviceInfo: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> NativeDeviceInfo { return - try PubkyProfileLink( - title: FfiConverterString.read(from: &buf), - url: FfiConverterString.read(from: &buf) + try NativeDeviceInfo( + path: FfiConverterString.read(from: &buf), + transportType: FfiConverterString.read(from: &buf), + name: FfiConverterOptionString.read(from: &buf), + vendorId: FfiConverterOptionUInt16.read(from: &buf), + productId: FfiConverterOptionUInt16.read(from: &buf) ) } - public static func write(_ value: PubkyProfileLink, into buf: inout [UInt8]) { - FfiConverterString.write(value.title, into: &buf) - FfiConverterString.write(value.url, into: &buf) + public static func write(_ value: NativeDeviceInfo, into buf: inout [UInt8]) { + FfiConverterString.write(value.path, into: &buf) + FfiConverterString.write(value.transportType, into: &buf) + FfiConverterOptionString.write(value.name, into: &buf) + FfiConverterOptionUInt16.write(value.vendorId, into: &buf) + FfiConverterOptionUInt16.write(value.productId, into: &buf) } } @@ -9811,125 +10121,95 @@ public struct FfiConverterTypePubkyProfileLink: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyProfileLink_lift(_ buf: RustBuffer) throws -> PubkyProfileLink { - return try FfiConverterTypePubkyProfileLink.lift(buf) +public func FfiConverterTypeNativeDeviceInfo_lift(_ buf: RustBuffer) throws -> NativeDeviceInfo { + return try FfiConverterTypeNativeDeviceInfo.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePubkyProfileLink_lower(_ value: PubkyProfileLink) -> RustBuffer { - return FfiConverterTypePubkyProfileLink.lower(value) +public func FfiConverterTypeNativeDeviceInfo_lower(_ value: NativeDeviceInfo) -> RustBuffer { + return FfiConverterTypeNativeDeviceInfo.lower(value) } -/** - * Result of creating a reverse swap (Lightning -> onchain). - * - * The caller pays `invoice` from its Lightning node; once Boltz locks funds at - * `lockup_address`, the module claims them to the provided onchain address. - */ -public struct ReverseSwapResponse { - public var id: String - /** - * Hold invoice the caller must pay via Lightning. - */ - public var invoice: String - /** - * Address Boltz locks the onchain funds to. - */ - public var lockupAddress: String - /** - * Amount in satoshis that will be received onchain (after Boltz fees). - */ - public var onchainAmountSat: UInt64 - /** - * Onchain timeout height for the swap. - */ - public var timeoutBlockHeight: UInt64 +public struct OnChainInvoice { + public var address: String + public var amountSatoshis: UInt64 + public var label: String? + public var message: String? + public var params: [String: String]? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(id: String, - /** - * Hold invoice the caller must pay via Lightning. - */invoice: String, - /** - * Address Boltz locks the onchain funds to. - */lockupAddress: String, - /** - * Amount in satoshis that will be received onchain (after Boltz fees). - */onchainAmountSat: UInt64, - /** - * Onchain timeout height for the swap. - */timeoutBlockHeight: UInt64) { - self.id = id - self.invoice = invoice - self.lockupAddress = lockupAddress - self.onchainAmountSat = onchainAmountSat - self.timeoutBlockHeight = timeoutBlockHeight + public init(address: String, amountSatoshis: UInt64, label: String?, message: String?, params: [String: String]?) { + self.address = address + self.amountSatoshis = amountSatoshis + self.label = label + self.message = message + self.params = params } } #if compiler(>=6) -extension ReverseSwapResponse: Sendable {} +extension OnChainInvoice: Sendable {} #endif -extension ReverseSwapResponse: Equatable, Hashable { - public static func ==(lhs: ReverseSwapResponse, rhs: ReverseSwapResponse) -> Bool { - if lhs.id != rhs.id { +extension OnChainInvoice: Equatable, Hashable { + public static func ==(lhs: OnChainInvoice, rhs: OnChainInvoice) -> Bool { + if lhs.address != rhs.address { return false } - if lhs.invoice != rhs.invoice { + if lhs.amountSatoshis != rhs.amountSatoshis { return false } - if lhs.lockupAddress != rhs.lockupAddress { + if lhs.label != rhs.label { return false } - if lhs.onchainAmountSat != rhs.onchainAmountSat { + if lhs.message != rhs.message { return false } - if lhs.timeoutBlockHeight != rhs.timeoutBlockHeight { + if lhs.params != rhs.params { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(id) - hasher.combine(invoice) - hasher.combine(lockupAddress) - hasher.combine(onchainAmountSat) - hasher.combine(timeoutBlockHeight) + hasher.combine(address) + hasher.combine(amountSatoshis) + hasher.combine(label) + hasher.combine(message) + hasher.combine(params) } } -extension ReverseSwapResponse: Codable {} +extension OnChainInvoice: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeReverseSwapResponse: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ReverseSwapResponse { +public struct FfiConverterTypeOnChainInvoice: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OnChainInvoice { return - try ReverseSwapResponse( - id: FfiConverterString.read(from: &buf), - invoice: FfiConverterString.read(from: &buf), - lockupAddress: FfiConverterString.read(from: &buf), - onchainAmountSat: FfiConverterUInt64.read(from: &buf), - timeoutBlockHeight: FfiConverterUInt64.read(from: &buf) + try OnChainInvoice( + address: FfiConverterString.read(from: &buf), + amountSatoshis: FfiConverterUInt64.read(from: &buf), + label: FfiConverterOptionString.read(from: &buf), + message: FfiConverterOptionString.read(from: &buf), + params: FfiConverterOptionDictionaryStringString.read(from: &buf) ) } - public static func write(_ value: ReverseSwapResponse, into buf: inout [UInt8]) { - FfiConverterString.write(value.id, into: &buf) - FfiConverterString.write(value.invoice, into: &buf) - FfiConverterString.write(value.lockupAddress, into: &buf) - FfiConverterUInt64.write(value.onchainAmountSat, into: &buf) - FfiConverterUInt64.write(value.timeoutBlockHeight, into: &buf) + public static func write(_ value: OnChainInvoice, into buf: inout [UInt8]) { + FfiConverterString.write(value.address, into: &buf) + FfiConverterUInt64.write(value.amountSatoshis, into: &buf) + FfiConverterOptionString.write(value.label, into: &buf) + FfiConverterOptionString.write(value.message, into: &buf) + FfiConverterOptionDictionaryStringString.write(value.params, into: &buf) } } @@ -9937,128 +10217,223 @@ public struct FfiConverterTypeReverseSwapResponse: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeReverseSwapResponse_lift(_ buf: RustBuffer) throws -> ReverseSwapResponse { - return try FfiConverterTypeReverseSwapResponse.lift(buf) +public func FfiConverterTypeOnChainInvoice_lift(_ buf: RustBuffer) throws -> OnChainInvoice { + return try FfiConverterTypeOnChainInvoice.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeReverseSwapResponse_lower(_ value: ReverseSwapResponse) -> RustBuffer { - return FfiConverterTypeReverseSwapResponse.lower(value) +public func FfiConverterTypeOnChainInvoice_lower(_ value: OnChainInvoice) -> RustBuffer { + return FfiConverterTypeOnChainInvoice.lower(value) } -/** - * Result from querying a single Bitcoin address. - */ -public struct SingleAddressInfoResult { - /** - * The queried address - */ +public struct OnchainActivity { + public var walletId: String + public var id: String + public var txType: PaymentType + public var txId: String + public var value: UInt64 + public var fee: UInt64 + public var feeRate: UInt64 public var address: String - /** - * Total confirmed balance in satoshis - */ - public var balance: UInt64 - /** - * UTXOs for this address - */ - public var utxos: [AccountUtxo] - /** - * Number of transactions involving this address - */ - public var transfers: UInt32 - /** - * Current blockchain tip height - */ - public var blockHeight: UInt32 - + public var confirmed: Bool + public var timestamp: UInt64 + public var isBoosted: Bool + public var boostTxIds: [String] + public var isTransfer: Bool + public var doesExist: Bool + public var confirmTimestamp: UInt64? + public var channelId: String? + public var transferTxId: String? + public var contact: String? + public var createdAt: UInt64? + public var updatedAt: UInt64? + public var seenAt: UInt64? + // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * The queried address - */address: String, - /** - * Total confirmed balance in satoshis - */balance: UInt64, - /** - * UTXOs for this address - */utxos: [AccountUtxo], - /** - * Number of transactions involving this address - */transfers: UInt32, - /** - * Current blockchain tip height - */blockHeight: UInt32) { + public init(walletId: String, id: String, txType: PaymentType, txId: String, value: UInt64, fee: UInt64, feeRate: UInt64, address: String, confirmed: Bool, timestamp: UInt64, isBoosted: Bool, boostTxIds: [String], isTransfer: Bool, doesExist: Bool, confirmTimestamp: UInt64?, channelId: String?, transferTxId: String?, contact: String?, createdAt: UInt64?, updatedAt: UInt64?, seenAt: UInt64?) { + self.walletId = walletId + self.id = id + self.txType = txType + self.txId = txId + self.value = value + self.fee = fee + self.feeRate = feeRate self.address = address - self.balance = balance - self.utxos = utxos - self.transfers = transfers - self.blockHeight = blockHeight + self.confirmed = confirmed + self.timestamp = timestamp + self.isBoosted = isBoosted + self.boostTxIds = boostTxIds + self.isTransfer = isTransfer + self.doesExist = doesExist + self.confirmTimestamp = confirmTimestamp + self.channelId = channelId + self.transferTxId = transferTxId + self.contact = contact + self.createdAt = createdAt + self.updatedAt = updatedAt + self.seenAt = seenAt } } #if compiler(>=6) -extension SingleAddressInfoResult: Sendable {} +extension OnchainActivity: Sendable {} #endif -extension SingleAddressInfoResult: Equatable, Hashable { - public static func ==(lhs: SingleAddressInfoResult, rhs: SingleAddressInfoResult) -> Bool { +extension OnchainActivity: Equatable, Hashable { + public static func ==(lhs: OnchainActivity, rhs: OnchainActivity) -> Bool { + if lhs.walletId != rhs.walletId { + return false + } + if lhs.id != rhs.id { + return false + } + if lhs.txType != rhs.txType { + return false + } + if lhs.txId != rhs.txId { + return false + } + if lhs.value != rhs.value { + return false + } + if lhs.fee != rhs.fee { + return false + } + if lhs.feeRate != rhs.feeRate { + return false + } if lhs.address != rhs.address { return false } - if lhs.balance != rhs.balance { + if lhs.confirmed != rhs.confirmed { return false } - if lhs.utxos != rhs.utxos { + if lhs.timestamp != rhs.timestamp { return false } - if lhs.transfers != rhs.transfers { + if lhs.isBoosted != rhs.isBoosted { return false } - if lhs.blockHeight != rhs.blockHeight { + if lhs.boostTxIds != rhs.boostTxIds { + return false + } + if lhs.isTransfer != rhs.isTransfer { + return false + } + if lhs.doesExist != rhs.doesExist { + return false + } + if lhs.confirmTimestamp != rhs.confirmTimestamp { + return false + } + if lhs.channelId != rhs.channelId { + return false + } + if lhs.transferTxId != rhs.transferTxId { + return false + } + if lhs.contact != rhs.contact { + return false + } + if lhs.createdAt != rhs.createdAt { + return false + } + if lhs.updatedAt != rhs.updatedAt { + return false + } + if lhs.seenAt != rhs.seenAt { return false } return true } public func hash(into hasher: inout Hasher) { + hasher.combine(walletId) + hasher.combine(id) + hasher.combine(txType) + hasher.combine(txId) + hasher.combine(value) + hasher.combine(fee) + hasher.combine(feeRate) hasher.combine(address) - hasher.combine(balance) - hasher.combine(utxos) - hasher.combine(transfers) - hasher.combine(blockHeight) + hasher.combine(confirmed) + hasher.combine(timestamp) + hasher.combine(isBoosted) + hasher.combine(boostTxIds) + hasher.combine(isTransfer) + hasher.combine(doesExist) + hasher.combine(confirmTimestamp) + hasher.combine(channelId) + hasher.combine(transferTxId) + hasher.combine(contact) + hasher.combine(createdAt) + hasher.combine(updatedAt) + hasher.combine(seenAt) } } -extension SingleAddressInfoResult: Codable {} +extension OnchainActivity: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeSingleAddressInfoResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SingleAddressInfoResult { +public struct FfiConverterTypeOnchainActivity: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OnchainActivity { return - try SingleAddressInfoResult( + try OnchainActivity( + walletId: FfiConverterString.read(from: &buf), + id: FfiConverterString.read(from: &buf), + txType: FfiConverterTypePaymentType.read(from: &buf), + txId: FfiConverterString.read(from: &buf), + value: FfiConverterUInt64.read(from: &buf), + fee: FfiConverterUInt64.read(from: &buf), + feeRate: FfiConverterUInt64.read(from: &buf), address: FfiConverterString.read(from: &buf), - balance: FfiConverterUInt64.read(from: &buf), - utxos: FfiConverterSequenceTypeAccountUtxo.read(from: &buf), - transfers: FfiConverterUInt32.read(from: &buf), - blockHeight: FfiConverterUInt32.read(from: &buf) + confirmed: FfiConverterBool.read(from: &buf), + timestamp: FfiConverterUInt64.read(from: &buf), + isBoosted: FfiConverterBool.read(from: &buf), + boostTxIds: FfiConverterSequenceString.read(from: &buf), + isTransfer: FfiConverterBool.read(from: &buf), + doesExist: FfiConverterBool.read(from: &buf), + confirmTimestamp: FfiConverterOptionUInt64.read(from: &buf), + channelId: FfiConverterOptionString.read(from: &buf), + transferTxId: FfiConverterOptionString.read(from: &buf), + contact: FfiConverterOptionString.read(from: &buf), + createdAt: FfiConverterOptionUInt64.read(from: &buf), + updatedAt: FfiConverterOptionUInt64.read(from: &buf), + seenAt: FfiConverterOptionUInt64.read(from: &buf) ) } - public static func write(_ value: SingleAddressInfoResult, into buf: inout [UInt8]) { + public static func write(_ value: OnchainActivity, into buf: inout [UInt8]) { + FfiConverterString.write(value.walletId, into: &buf) + FfiConverterString.write(value.id, into: &buf) + FfiConverterTypePaymentType.write(value.txType, into: &buf) + FfiConverterString.write(value.txId, into: &buf) + FfiConverterUInt64.write(value.value, into: &buf) + FfiConverterUInt64.write(value.fee, into: &buf) + FfiConverterUInt64.write(value.feeRate, into: &buf) FfiConverterString.write(value.address, into: &buf) - FfiConverterUInt64.write(value.balance, into: &buf) - FfiConverterSequenceTypeAccountUtxo.write(value.utxos, into: &buf) - FfiConverterUInt32.write(value.transfers, into: &buf) - FfiConverterUInt32.write(value.blockHeight, into: &buf) + FfiConverterBool.write(value.confirmed, into: &buf) + FfiConverterUInt64.write(value.timestamp, into: &buf) + FfiConverterBool.write(value.isBoosted, into: &buf) + FfiConverterSequenceString.write(value.boostTxIds, into: &buf) + FfiConverterBool.write(value.isTransfer, into: &buf) + FfiConverterBool.write(value.doesExist, into: &buf) + FfiConverterOptionUInt64.write(value.confirmTimestamp, into: &buf) + FfiConverterOptionString.write(value.channelId, into: &buf) + FfiConverterOptionString.write(value.transferTxId, into: &buf) + FfiConverterOptionString.write(value.contact, into: &buf) + FfiConverterOptionUInt64.write(value.createdAt, into: &buf) + FfiConverterOptionUInt64.write(value.updatedAt, into: &buf) + FfiConverterOptionUInt64.write(value.seenAt, into: &buf) } } @@ -10066,139 +10441,94 @@ public struct FfiConverterTypeSingleAddressInfoResult: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSingleAddressInfoResult_lift(_ buf: RustBuffer) throws -> SingleAddressInfoResult { - return try FfiConverterTypeSingleAddressInfoResult.lift(buf) +public func FfiConverterTypeOnchainActivity_lift(_ buf: RustBuffer) throws -> OnchainActivity { + return try FfiConverterTypeOnchainActivity.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSingleAddressInfoResult_lower(_ value: SingleAddressInfoResult) -> RustBuffer { - return FfiConverterTypeSingleAddressInfoResult.lower(value) +public func FfiConverterTypeOnchainActivity_lower(_ value: OnchainActivity) -> RustBuffer { + return FfiConverterTypeOnchainActivity.lower(value) } /** - * Result of creating a submarine swap (onchain -> Lightning). - * - * The caller funds `address` with `expected_amount_sat` from its onchain - * wallet; Boltz then pays the Lightning invoice supplied at creation. + * One single-signature account in Passport's generic JSON export. */ -public struct SubmarineSwapResponse { - public var id: String - /** - * Onchain lockup address to send funds to. - */ - public var address: String - /** - * BIP21 URI for the lockup payment. - */ - public var bip21: String - /** - * Exact amount in satoshis the caller must send to `address`. - */ - public var expectedAmountSat: UInt64 +public struct PassportAccount { + public var accountType: AccountType /** - * Whether Boltz will accept a zero-conf lockup. + * Standard xpub/tpub encoding used by Passport's export. */ - public var acceptZeroConf: Bool + public var xpub: String /** - * Onchain timeout height after which a refund is possible. + * Account-level BIP32 path, such as `m/84'/0'/0'`. */ - public var timeoutBlockHeight: UInt64 + public var derivationPath: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init(id: String, - /** - * Onchain lockup address to send funds to. - */address: String, - /** - * BIP21 URI for the lockup payment. - */bip21: String, - /** - * Exact amount in satoshis the caller must send to `address`. - */expectedAmountSat: UInt64, + public init(accountType: AccountType, /** - * Whether Boltz will accept a zero-conf lockup. - */acceptZeroConf: Bool, + * Standard xpub/tpub encoding used by Passport's export. + */xpub: String, /** - * Onchain timeout height after which a refund is possible. - */timeoutBlockHeight: UInt64) { - self.id = id - self.address = address - self.bip21 = bip21 - self.expectedAmountSat = expectedAmountSat - self.acceptZeroConf = acceptZeroConf - self.timeoutBlockHeight = timeoutBlockHeight + * Account-level BIP32 path, such as `m/84'/0'/0'`. + */derivationPath: String) { + self.accountType = accountType + self.xpub = xpub + self.derivationPath = derivationPath } } #if compiler(>=6) -extension SubmarineSwapResponse: Sendable {} +extension PassportAccount: Sendable {} #endif -extension SubmarineSwapResponse: Equatable, Hashable { - public static func ==(lhs: SubmarineSwapResponse, rhs: SubmarineSwapResponse) -> Bool { - if lhs.id != rhs.id { - return false - } - if lhs.address != rhs.address { - return false - } - if lhs.bip21 != rhs.bip21 { - return false - } - if lhs.expectedAmountSat != rhs.expectedAmountSat { +extension PassportAccount: Equatable, Hashable { + public static func ==(lhs: PassportAccount, rhs: PassportAccount) -> Bool { + if lhs.accountType != rhs.accountType { return false } - if lhs.acceptZeroConf != rhs.acceptZeroConf { + if lhs.xpub != rhs.xpub { return false } - if lhs.timeoutBlockHeight != rhs.timeoutBlockHeight { + if lhs.derivationPath != rhs.derivationPath { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(id) - hasher.combine(address) - hasher.combine(bip21) - hasher.combine(expectedAmountSat) - hasher.combine(acceptZeroConf) - hasher.combine(timeoutBlockHeight) + hasher.combine(accountType) + hasher.combine(xpub) + hasher.combine(derivationPath) } } -extension SubmarineSwapResponse: Codable {} +extension PassportAccount: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeSubmarineSwapResponse: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SubmarineSwapResponse { +public struct FfiConverterTypePassportAccount: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PassportAccount { return - try SubmarineSwapResponse( - id: FfiConverterString.read(from: &buf), - address: FfiConverterString.read(from: &buf), - bip21: FfiConverterString.read(from: &buf), - expectedAmountSat: FfiConverterUInt64.read(from: &buf), - acceptZeroConf: FfiConverterBool.read(from: &buf), - timeoutBlockHeight: FfiConverterUInt64.read(from: &buf) + try PassportAccount( + accountType: FfiConverterTypeAccountType.read(from: &buf), + xpub: FfiConverterString.read(from: &buf), + derivationPath: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: SubmarineSwapResponse, into buf: inout [UInt8]) { - FfiConverterString.write(value.id, into: &buf) - FfiConverterString.write(value.address, into: &buf) - FfiConverterString.write(value.bip21, into: &buf) - FfiConverterUInt64.write(value.expectedAmountSat, into: &buf) - FfiConverterBool.write(value.acceptZeroConf, into: &buf) - FfiConverterUInt64.write(value.timeoutBlockHeight, into: &buf) + public static func write(_ value: PassportAccount, into buf: inout [UInt8]) { + FfiConverterTypeAccountType.write(value.accountType, into: &buf) + FfiConverterString.write(value.xpub, into: &buf) + FfiConverterString.write(value.derivationPath, into: &buf) } } @@ -10206,122 +10536,88 @@ public struct FfiConverterTypeSubmarineSwapResponse: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSubmarineSwapResponse_lift(_ buf: RustBuffer) throws -> SubmarineSwapResponse { - return try FfiConverterTypeSubmarineSwapResponse.lift(buf) +public func FfiConverterTypePassportAccount_lift(_ buf: RustBuffer) throws -> PassportAccount { + return try FfiConverterTypePassportAccount.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSubmarineSwapResponse_lower(_ value: SubmarineSwapResponse) -> RustBuffer { - return FfiConverterTypeSubmarineSwapResponse.lower(value) +public func FfiConverterTypePassportAccount_lower(_ value: PassportAccount) -> RustBuffer { + return FfiConverterTypePassportAccount.lower(value) } /** - * A hardware-wallet model Bitkit supports. + * The single-signature accounts exported by Passport for one account index. */ -public struct SupportedHardwareWallet { - public var vendor: HardwareWalletVendor - /** - * Human-readable manufacturer name, e.g. "Foundation". - */ - public var vendorName: String - /** - * Stable model identifier that applications can map to bundled assets. - */ - public var model: String - /** - * Full user-facing name. - */ - public var displayName: String +public struct PassportAccountExport { /** - * Transports over which the application can interact with this model. + * Root fingerprint used in descriptors and PSBT key origins. */ - public var transports: [HardwareWalletTransport] + public var masterFingerprint: String + public var accountIndex: UInt32 + public var accounts: [PassportAccount] // Default memberwise initializers are never public by default, so we // declare one manually. - public init(vendor: HardwareWalletVendor, - /** - * Human-readable manufacturer name, e.g. "Foundation". - */vendorName: String, - /** - * Stable model identifier that applications can map to bundled assets. - */model: String, - /** - * Full user-facing name. - */displayName: String, + public init( /** - * Transports over which the application can interact with this model. - */transports: [HardwareWalletTransport]) { - self.vendor = vendor - self.vendorName = vendorName - self.model = model - self.displayName = displayName - self.transports = transports + * Root fingerprint used in descriptors and PSBT key origins. + */masterFingerprint: String, accountIndex: UInt32, accounts: [PassportAccount]) { + self.masterFingerprint = masterFingerprint + self.accountIndex = accountIndex + self.accounts = accounts } } #if compiler(>=6) -extension SupportedHardwareWallet: Sendable {} +extension PassportAccountExport: Sendable {} #endif -extension SupportedHardwareWallet: Equatable, Hashable { - public static func ==(lhs: SupportedHardwareWallet, rhs: SupportedHardwareWallet) -> Bool { - if lhs.vendor != rhs.vendor { - return false - } - if lhs.vendorName != rhs.vendorName { - return false - } - if lhs.model != rhs.model { +extension PassportAccountExport: Equatable, Hashable { + public static func ==(lhs: PassportAccountExport, rhs: PassportAccountExport) -> Bool { + if lhs.masterFingerprint != rhs.masterFingerprint { return false } - if lhs.displayName != rhs.displayName { + if lhs.accountIndex != rhs.accountIndex { return false } - if lhs.transports != rhs.transports { + if lhs.accounts != rhs.accounts { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(vendor) - hasher.combine(vendorName) - hasher.combine(model) - hasher.combine(displayName) - hasher.combine(transports) + hasher.combine(masterFingerprint) + hasher.combine(accountIndex) + hasher.combine(accounts) } } -extension SupportedHardwareWallet: Codable {} +extension PassportAccountExport: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeSupportedHardwareWallet: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SupportedHardwareWallet { +public struct FfiConverterTypePassportAccountExport: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PassportAccountExport { return - try SupportedHardwareWallet( - vendor: FfiConverterTypeHardwareWalletVendor.read(from: &buf), - vendorName: FfiConverterString.read(from: &buf), - model: FfiConverterString.read(from: &buf), - displayName: FfiConverterString.read(from: &buf), - transports: FfiConverterSequenceTypeHardwareWalletTransport.read(from: &buf) + try PassportAccountExport( + masterFingerprint: FfiConverterString.read(from: &buf), + accountIndex: FfiConverterUInt32.read(from: &buf), + accounts: FfiConverterSequenceTypePassportAccount.read(from: &buf) ) } - public static func write(_ value: SupportedHardwareWallet, into buf: inout [UInt8]) { - FfiConverterTypeHardwareWalletVendor.write(value.vendor, into: &buf) - FfiConverterString.write(value.vendorName, into: &buf) - FfiConverterString.write(value.model, into: &buf) - FfiConverterString.write(value.displayName, into: &buf) - FfiConverterSequenceTypeHardwareWalletTransport.write(value.transports, into: &buf) + public static func write(_ value: PassportAccountExport, into buf: inout [UInt8]) { + FfiConverterString.write(value.masterFingerprint, into: &buf) + FfiConverterUInt32.write(value.accountIndex, into: &buf) + FfiConverterSequenceTypePassportAccount.write(value.accounts, into: &buf) } } @@ -10329,111 +10625,143 @@ public struct FfiConverterTypeSupportedHardwareWallet: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSupportedHardwareWallet_lift(_ buf: RustBuffer) throws -> SupportedHardwareWallet { - return try FfiConverterTypeSupportedHardwareWallet.lift(buf) +public func FfiConverterTypePassportAccountExport_lift(_ buf: RustBuffer) throws -> PassportAccountExport { + return try FfiConverterTypePassportAccountExport.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSupportedHardwareWallet_lower(_ value: SupportedHardwareWallet) -> RustBuffer { - return FfiConverterTypeSupportedHardwareWallet.lower(value) +public func FfiConverterTypePassportAccountExport_lower(_ value: PassportAccountExport) -> RustBuffer { + return FfiConverterTypePassportAccountExport.lower(value) } -public struct SweepResult { - /** - * The transaction ID of the sweep transaction - */ - public var txid: String - /** - * The total amount swept (in satoshis) - */ - public var amountSwept: UInt64 - /** - * The fee paid (in satoshis) - */ - public var feePaid: UInt64 - /** - * The number of UTXOs swept - */ - public var utxosSwept: UInt32 +public struct PreActivityMetadata { + public var walletId: String + public var paymentId: String + public var tags: [String] + public var paymentHash: String? + public var txId: String? + public var address: String? + public var isReceive: Bool + public var feeRate: UInt64 + public var isTransfer: Bool + public var channelId: String? + public var createdAt: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * The transaction ID of the sweep transaction - */txid: String, - /** - * The total amount swept (in satoshis) - */amountSwept: UInt64, - /** - * The fee paid (in satoshis) - */feePaid: UInt64, - /** - * The number of UTXOs swept - */utxosSwept: UInt32) { - self.txid = txid - self.amountSwept = amountSwept - self.feePaid = feePaid - self.utxosSwept = utxosSwept + public init(walletId: String, paymentId: String, tags: [String], paymentHash: String?, txId: String?, address: String?, isReceive: Bool, feeRate: UInt64, isTransfer: Bool, channelId: String?, createdAt: UInt64) { + self.walletId = walletId + self.paymentId = paymentId + self.tags = tags + self.paymentHash = paymentHash + self.txId = txId + self.address = address + self.isReceive = isReceive + self.feeRate = feeRate + self.isTransfer = isTransfer + self.channelId = channelId + self.createdAt = createdAt } } #if compiler(>=6) -extension SweepResult: Sendable {} +extension PreActivityMetadata: Sendable {} #endif -extension SweepResult: Equatable, Hashable { - public static func ==(lhs: SweepResult, rhs: SweepResult) -> Bool { - if lhs.txid != rhs.txid { +extension PreActivityMetadata: Equatable, Hashable { + public static func ==(lhs: PreActivityMetadata, rhs: PreActivityMetadata) -> Bool { + if lhs.walletId != rhs.walletId { return false } - if lhs.amountSwept != rhs.amountSwept { + if lhs.paymentId != rhs.paymentId { return false } - if lhs.feePaid != rhs.feePaid { + if lhs.tags != rhs.tags { return false } - if lhs.utxosSwept != rhs.utxosSwept { + if lhs.paymentHash != rhs.paymentHash { return false } - return true - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(txid) - hasher.combine(amountSwept) - hasher.combine(feePaid) - hasher.combine(utxosSwept) + if lhs.txId != rhs.txId { + return false + } + if lhs.address != rhs.address { + return false + } + if lhs.isReceive != rhs.isReceive { + return false + } + if lhs.feeRate != rhs.feeRate { + return false + } + if lhs.isTransfer != rhs.isTransfer { + return false + } + if lhs.channelId != rhs.channelId { + return false + } + if lhs.createdAt != rhs.createdAt { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(walletId) + hasher.combine(paymentId) + hasher.combine(tags) + hasher.combine(paymentHash) + hasher.combine(txId) + hasher.combine(address) + hasher.combine(isReceive) + hasher.combine(feeRate) + hasher.combine(isTransfer) + hasher.combine(channelId) + hasher.combine(createdAt) } } -extension SweepResult: Codable {} +extension PreActivityMetadata: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeSweepResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SweepResult { +public struct FfiConverterTypePreActivityMetadata: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PreActivityMetadata { return - try SweepResult( - txid: FfiConverterString.read(from: &buf), - amountSwept: FfiConverterUInt64.read(from: &buf), - feePaid: FfiConverterUInt64.read(from: &buf), - utxosSwept: FfiConverterUInt32.read(from: &buf) + try PreActivityMetadata( + walletId: FfiConverterString.read(from: &buf), + paymentId: FfiConverterString.read(from: &buf), + tags: FfiConverterSequenceString.read(from: &buf), + paymentHash: FfiConverterOptionString.read(from: &buf), + txId: FfiConverterOptionString.read(from: &buf), + address: FfiConverterOptionString.read(from: &buf), + isReceive: FfiConverterBool.read(from: &buf), + feeRate: FfiConverterUInt64.read(from: &buf), + isTransfer: FfiConverterBool.read(from: &buf), + channelId: FfiConverterOptionString.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf) ) } - public static func write(_ value: SweepResult, into buf: inout [UInt8]) { - FfiConverterString.write(value.txid, into: &buf) - FfiConverterUInt64.write(value.amountSwept, into: &buf) - FfiConverterUInt64.write(value.feePaid, into: &buf) - FfiConverterUInt32.write(value.utxosSwept, into: &buf) + public static func write(_ value: PreActivityMetadata, into buf: inout [UInt8]) { + FfiConverterString.write(value.walletId, into: &buf) + FfiConverterString.write(value.paymentId, into: &buf) + FfiConverterSequenceString.write(value.tags, into: &buf) + FfiConverterOptionString.write(value.paymentHash, into: &buf) + FfiConverterOptionString.write(value.txId, into: &buf) + FfiConverterOptionString.write(value.address, into: &buf) + FfiConverterBool.write(value.isReceive, into: &buf) + FfiConverterUInt64.write(value.feeRate, into: &buf) + FfiConverterBool.write(value.isTransfer, into: &buf) + FfiConverterOptionString.write(value.channelId, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) } } @@ -10441,153 +10769,63 @@ public struct FfiConverterTypeSweepResult: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSweepResult_lift(_ buf: RustBuffer) throws -> SweepResult { - return try FfiConverterTypeSweepResult.lift(buf) +public func FfiConverterTypePreActivityMetadata_lift(_ buf: RustBuffer) throws -> PreActivityMetadata { + return try FfiConverterTypePreActivityMetadata.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSweepResult_lower(_ value: SweepResult) -> RustBuffer { - return FfiConverterTypeSweepResult.lower(value) +public func FfiConverterTypePreActivityMetadata_lower(_ value: PreActivityMetadata) -> RustBuffer { + return FfiConverterTypePreActivityMetadata.lower(value) } -public struct SweepTransactionPreview { - /** - * The PSBT (Partially Signed Bitcoin Transaction) in base64 format - */ - public var psbt: String - /** - * The total amount available to sweep (in satoshis) - */ - public var totalAmount: UInt64 - /** - * The estimated fee for the transaction (in satoshis) - */ - public var estimatedFee: UInt64 - /** - * The estimated virtual size of the transaction (in vbytes) - */ - public var estimatedVsize: UInt64 - /** - * The number of UTXOs that will be swept - */ - public var utxosCount: UInt32 - /** - * The destination address - */ - public var destinationAddress: String - /** - * The amount that will be sent to destination after fees (in satoshis) - */ - public var amountAfterFees: UInt64 +public struct PubkyAuth { + public var data: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * The PSBT (Partially Signed Bitcoin Transaction) in base64 format - */psbt: String, - /** - * The total amount available to sweep (in satoshis) - */totalAmount: UInt64, - /** - * The estimated fee for the transaction (in satoshis) - */estimatedFee: UInt64, - /** - * The estimated virtual size of the transaction (in vbytes) - */estimatedVsize: UInt64, - /** - * The number of UTXOs that will be swept - */utxosCount: UInt32, - /** - * The destination address - */destinationAddress: String, - /** - * The amount that will be sent to destination after fees (in satoshis) - */amountAfterFees: UInt64) { - self.psbt = psbt - self.totalAmount = totalAmount - self.estimatedFee = estimatedFee - self.estimatedVsize = estimatedVsize - self.utxosCount = utxosCount - self.destinationAddress = destinationAddress - self.amountAfterFees = amountAfterFees + public init(data: String) { + self.data = data } } #if compiler(>=6) -extension SweepTransactionPreview: Sendable {} +extension PubkyAuth: Sendable {} #endif -extension SweepTransactionPreview: Equatable, Hashable { - public static func ==(lhs: SweepTransactionPreview, rhs: SweepTransactionPreview) -> Bool { - if lhs.psbt != rhs.psbt { - return false - } - if lhs.totalAmount != rhs.totalAmount { - return false - } - if lhs.estimatedFee != rhs.estimatedFee { - return false - } - if lhs.estimatedVsize != rhs.estimatedVsize { - return false - } - if lhs.utxosCount != rhs.utxosCount { - return false - } - if lhs.destinationAddress != rhs.destinationAddress { - return false - } - if lhs.amountAfterFees != rhs.amountAfterFees { +extension PubkyAuth: Equatable, Hashable { + public static func ==(lhs: PubkyAuth, rhs: PubkyAuth) -> Bool { + if lhs.data != rhs.data { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(psbt) - hasher.combine(totalAmount) - hasher.combine(estimatedFee) - hasher.combine(estimatedVsize) - hasher.combine(utxosCount) - hasher.combine(destinationAddress) - hasher.combine(amountAfterFees) + hasher.combine(data) } } -extension SweepTransactionPreview: Codable {} +extension PubkyAuth: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeSweepTransactionPreview: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SweepTransactionPreview { +public struct FfiConverterTypePubkyAuth: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyAuth { return - try SweepTransactionPreview( - psbt: FfiConverterString.read(from: &buf), - totalAmount: FfiConverterUInt64.read(from: &buf), - estimatedFee: FfiConverterUInt64.read(from: &buf), - estimatedVsize: FfiConverterUInt64.read(from: &buf), - utxosCount: FfiConverterUInt32.read(from: &buf), - destinationAddress: FfiConverterString.read(from: &buf), - amountAfterFees: FfiConverterUInt64.read(from: &buf) + try PubkyAuth( + data: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: SweepTransactionPreview, into buf: inout [UInt8]) { - FfiConverterString.write(value.psbt, into: &buf) - FfiConverterUInt64.write(value.totalAmount, into: &buf) - FfiConverterUInt64.write(value.estimatedFee, into: &buf) - FfiConverterUInt64.write(value.estimatedVsize, into: &buf) - FfiConverterUInt32.write(value.utxosCount, into: &buf) - FfiConverterString.write(value.destinationAddress, into: &buf) - FfiConverterUInt64.write(value.amountAfterFees, into: &buf) + public static func write(_ value: PubkyAuth, into buf: inout [UInt8]) { + FfiConverterString.write(value.data, into: &buf) } } @@ -10595,167 +10833,224 @@ public struct FfiConverterTypeSweepTransactionPreview: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSweepTransactionPreview_lift(_ buf: RustBuffer) throws -> SweepTransactionPreview { - return try FfiConverterTypeSweepTransactionPreview.lift(buf) +public func FfiConverterTypePubkyAuth_lift(_ buf: RustBuffer) throws -> PubkyAuth { + return try FfiConverterTypePubkyAuth.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSweepTransactionPreview_lower(_ value: SweepTransactionPreview) -> RustBuffer { - return FfiConverterTypeSweepTransactionPreview.lower(value) +public func FfiConverterTypePubkyAuth_lower(_ value: PubkyAuth) -> RustBuffer { + return FfiConverterTypePubkyAuth.lower(value) } -public struct SweepableBalances { - /** - * Balance in legacy (P2PKH) addresses (in satoshis) - */ - public var legacyBalance: UInt64 - /** - * Balance in P2SH-SegWit (P2SH-P2WPKH) addresses (in satoshis) - */ - public var p2shBalance: UInt64 - /** - * Balance in Taproot (P2TR) addresses (in satoshis) - */ - public var taprootBalance: UInt64 +/** + * Details extracted from a `pubkyauth://` deep-link URL. + */ +public struct PubkyAuthDetails { /** - * Total balance across all wallet types (in satoshis) + * Whether this is a signin or signup flow. */ - public var totalBalance: UInt64 + public var kind: PubkyAuthKind /** - * Number of UTXOs in legacy wallet + * Requested capabilities (e.g. `"/pub/pubky.app/:rw"`). */ - public var legacyUtxosCount: UInt32 + public var capabilities: String /** - * Number of UTXOs in P2SH-SegWit wallet + * Relay URL used for the auth exchange. */ - public var p2shUtxosCount: UInt32 + public var relay: String /** - * Number of UTXOs in Taproot wallet + * Homeserver public key (z32-encoded). Present only for signup flows. */ - public var taprootUtxosCount: UInt32 + public var homeserver: String? /** - * Total number of UTXOs across all wallet types + * Signup token. Present only for signup flows. */ - public var totalUtxosCount: UInt32 + public var signupToken: String? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Balance in legacy (P2PKH) addresses (in satoshis) - */legacyBalance: UInt64, - /** - * Balance in P2SH-SegWit (P2SH-P2WPKH) addresses (in satoshis) - */p2shBalance: UInt64, - /** - * Balance in Taproot (P2TR) addresses (in satoshis) - */taprootBalance: UInt64, - /** - * Total balance across all wallet types (in satoshis) - */totalBalance: UInt64, + * Whether this is a signin or signup flow. + */kind: PubkyAuthKind, /** - * Number of UTXOs in legacy wallet - */legacyUtxosCount: UInt32, + * Requested capabilities (e.g. `"/pub/pubky.app/:rw"`). + */capabilities: String, /** - * Number of UTXOs in P2SH-SegWit wallet - */p2shUtxosCount: UInt32, + * Relay URL used for the auth exchange. + */relay: String, /** - * Number of UTXOs in Taproot wallet - */taprootUtxosCount: UInt32, + * Homeserver public key (z32-encoded). Present only for signup flows. + */homeserver: String?, /** - * Total number of UTXOs across all wallet types - */totalUtxosCount: UInt32) { - self.legacyBalance = legacyBalance - self.p2shBalance = p2shBalance - self.taprootBalance = taprootBalance - self.totalBalance = totalBalance - self.legacyUtxosCount = legacyUtxosCount - self.p2shUtxosCount = p2shUtxosCount - self.taprootUtxosCount = taprootUtxosCount - self.totalUtxosCount = totalUtxosCount + * Signup token. Present only for signup flows. + */signupToken: String?) { + self.kind = kind + self.capabilities = capabilities + self.relay = relay + self.homeserver = homeserver + self.signupToken = signupToken } } #if compiler(>=6) -extension SweepableBalances: Sendable {} +extension PubkyAuthDetails: Sendable {} #endif -extension SweepableBalances: Equatable, Hashable { - public static func ==(lhs: SweepableBalances, rhs: SweepableBalances) -> Bool { - if lhs.legacyBalance != rhs.legacyBalance { +extension PubkyAuthDetails: Equatable, Hashable { + public static func ==(lhs: PubkyAuthDetails, rhs: PubkyAuthDetails) -> Bool { + if lhs.kind != rhs.kind { return false } - if lhs.p2shBalance != rhs.p2shBalance { + if lhs.capabilities != rhs.capabilities { return false } - if lhs.taprootBalance != rhs.taprootBalance { + if lhs.relay != rhs.relay { return false } - if lhs.totalBalance != rhs.totalBalance { + if lhs.homeserver != rhs.homeserver { return false } - if lhs.legacyUtxosCount != rhs.legacyUtxosCount { + if lhs.signupToken != rhs.signupToken { return false } - if lhs.p2shUtxosCount != rhs.p2shUtxosCount { + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(kind) + hasher.combine(capabilities) + hasher.combine(relay) + hasher.combine(homeserver) + hasher.combine(signupToken) + } +} + +extension PubkyAuthDetails: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePubkyAuthDetails: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyAuthDetails { + return + try PubkyAuthDetails( + kind: FfiConverterTypePubkyAuthKind.read(from: &buf), + capabilities: FfiConverterString.read(from: &buf), + relay: FfiConverterString.read(from: &buf), + homeserver: FfiConverterOptionString.read(from: &buf), + signupToken: FfiConverterOptionString.read(from: &buf) + ) + } + + public static func write(_ value: PubkyAuthDetails, into buf: inout [UInt8]) { + FfiConverterTypePubkyAuthKind.write(value.kind, into: &buf) + FfiConverterString.write(value.capabilities, into: &buf) + FfiConverterString.write(value.relay, into: &buf) + FfiConverterOptionString.write(value.homeserver, into: &buf) + FfiConverterOptionString.write(value.signupToken, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePubkyAuthDetails_lift(_ buf: RustBuffer) throws -> PubkyAuthDetails { + return try FfiConverterTypePubkyAuthDetails.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePubkyAuthDetails_lower(_ value: PubkyAuthDetails) -> RustBuffer { + return FfiConverterTypePubkyAuthDetails.lower(value) +} + + +public struct PubkyProfile { + public var name: String + public var bio: String? + public var image: String? + public var links: [PubkyProfileLink]? + public var status: String? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, bio: String?, image: String?, links: [PubkyProfileLink]?, status: String?) { + self.name = name + self.bio = bio + self.image = image + self.links = links + self.status = status + } +} + +#if compiler(>=6) +extension PubkyProfile: Sendable {} +#endif + + +extension PubkyProfile: Equatable, Hashable { + public static func ==(lhs: PubkyProfile, rhs: PubkyProfile) -> Bool { + if lhs.name != rhs.name { return false } - if lhs.taprootUtxosCount != rhs.taprootUtxosCount { + if lhs.bio != rhs.bio { return false } - if lhs.totalUtxosCount != rhs.totalUtxosCount { + if lhs.image != rhs.image { + return false + } + if lhs.links != rhs.links { + return false + } + if lhs.status != rhs.status { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(legacyBalance) - hasher.combine(p2shBalance) - hasher.combine(taprootBalance) - hasher.combine(totalBalance) - hasher.combine(legacyUtxosCount) - hasher.combine(p2shUtxosCount) - hasher.combine(taprootUtxosCount) - hasher.combine(totalUtxosCount) + hasher.combine(name) + hasher.combine(bio) + hasher.combine(image) + hasher.combine(links) + hasher.combine(status) } } -extension SweepableBalances: Codable {} +extension PubkyProfile: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeSweepableBalances: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SweepableBalances { +public struct FfiConverterTypePubkyProfile: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyProfile { return - try SweepableBalances( - legacyBalance: FfiConverterUInt64.read(from: &buf), - p2shBalance: FfiConverterUInt64.read(from: &buf), - taprootBalance: FfiConverterUInt64.read(from: &buf), - totalBalance: FfiConverterUInt64.read(from: &buf), - legacyUtxosCount: FfiConverterUInt32.read(from: &buf), - p2shUtxosCount: FfiConverterUInt32.read(from: &buf), - taprootUtxosCount: FfiConverterUInt32.read(from: &buf), - totalUtxosCount: FfiConverterUInt32.read(from: &buf) + try PubkyProfile( + name: FfiConverterString.read(from: &buf), + bio: FfiConverterOptionString.read(from: &buf), + image: FfiConverterOptionString.read(from: &buf), + links: FfiConverterOptionSequenceTypePubkyProfileLink.read(from: &buf), + status: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: SweepableBalances, into buf: inout [UInt8]) { - FfiConverterUInt64.write(value.legacyBalance, into: &buf) - FfiConverterUInt64.write(value.p2shBalance, into: &buf) - FfiConverterUInt64.write(value.taprootBalance, into: &buf) - FfiConverterUInt64.write(value.totalBalance, into: &buf) - FfiConverterUInt32.write(value.legacyUtxosCount, into: &buf) - FfiConverterUInt32.write(value.p2shUtxosCount, into: &buf) - FfiConverterUInt32.write(value.taprootUtxosCount, into: &buf) - FfiConverterUInt32.write(value.totalUtxosCount, into: &buf) + public static func write(_ value: PubkyProfile, into buf: inout [UInt8]) { + FfiConverterString.write(value.name, into: &buf) + FfiConverterOptionString.write(value.bio, into: &buf) + FfiConverterOptionString.write(value.image, into: &buf) + FfiConverterOptionSequenceTypePubkyProfileLink.write(value.links, into: &buf) + FfiConverterOptionString.write(value.status, into: &buf) } } @@ -10763,282 +11058,71 @@ public struct FfiConverterTypeSweepableBalances: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSweepableBalances_lift(_ buf: RustBuffer) throws -> SweepableBalances { - return try FfiConverterTypeSweepableBalances.lift(buf) +public func FfiConverterTypePubkyProfile_lift(_ buf: RustBuffer) throws -> PubkyProfile { + return try FfiConverterTypePubkyProfile.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSweepableBalances_lower(_ value: SweepableBalances) -> RustBuffer { - return FfiConverterTypeSweepableBalances.lower(value) +public func FfiConverterTypePubkyProfile_lower(_ value: PubkyProfile) -> RustBuffer { + return FfiConverterTypePubkyProfile.lower(value) } -/** - * Full details for a single transaction, including raw inputs/outputs and size metrics. - */ -public struct TransactionDetail { - /** - * Transaction ID (hex) - */ - public var txid: String - /** - * Amount received by the wallet (sats) - */ - public var received: UInt64 - /** - * Amount sent by the wallet (sats) — includes change sent back to self - */ - public var sent: UInt64 - /** - * Net value from wallet's perspective: received - sent (positive = inflow, negative = outflow) - */ - public var net: Int64 - /** - * Display amount in sats (same semantics as HistoryTransaction.amount) - */ - public var amount: UInt64 - /** - * Transaction fee in sats (None if not available) - */ - public var fee: UInt64? - /** - * Transaction direction - */ - public var direction: TxDirection - /** - * Block height (None if unconfirmed/mempool) - */ - public var blockHeight: UInt32? - /** - * Block timestamp as unix epoch seconds (None if unconfirmed) - */ - public var timestamp: UInt64? - /** - * Number of confirmations (0 if unconfirmed) - */ - public var confirmations: UInt32 - /** - * Transaction inputs - */ - public var inputs: [TxDetailInput] - /** - * Transaction outputs - */ - public var outputs: [TxDetailOutput] - /** - * Serialized transaction size in bytes - */ - public var size: UInt32 - /** - * Virtual size in vbytes (ceil(weight / 4)) - */ - public var vsize: UInt32 - /** - * Transaction weight in weight units - */ - public var weight: UInt32 - /** - * Fee rate in sat/vB (fee / vsize), None if fee is unavailable or vsize is zero - */ - public var feeRate: Double? +public struct PubkyProfileLink { + public var title: String + public var url: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * Transaction ID (hex) - */txid: String, - /** - * Amount received by the wallet (sats) - */received: UInt64, - /** - * Amount sent by the wallet (sats) — includes change sent back to self - */sent: UInt64, - /** - * Net value from wallet's perspective: received - sent (positive = inflow, negative = outflow) - */net: Int64, - /** - * Display amount in sats (same semantics as HistoryTransaction.amount) - */amount: UInt64, - /** - * Transaction fee in sats (None if not available) - */fee: UInt64?, - /** - * Transaction direction - */direction: TxDirection, - /** - * Block height (None if unconfirmed/mempool) - */blockHeight: UInt32?, - /** - * Block timestamp as unix epoch seconds (None if unconfirmed) - */timestamp: UInt64?, - /** - * Number of confirmations (0 if unconfirmed) - */confirmations: UInt32, - /** - * Transaction inputs - */inputs: [TxDetailInput], - /** - * Transaction outputs - */outputs: [TxDetailOutput], - /** - * Serialized transaction size in bytes - */size: UInt32, - /** - * Virtual size in vbytes (ceil(weight / 4)) - */vsize: UInt32, - /** - * Transaction weight in weight units - */weight: UInt32, - /** - * Fee rate in sat/vB (fee / vsize), None if fee is unavailable or vsize is zero - */feeRate: Double?) { - self.txid = txid - self.received = received - self.sent = sent - self.net = net - self.amount = amount - self.fee = fee - self.direction = direction - self.blockHeight = blockHeight - self.timestamp = timestamp - self.confirmations = confirmations - self.inputs = inputs - self.outputs = outputs - self.size = size - self.vsize = vsize - self.weight = weight - self.feeRate = feeRate + public init(title: String, url: String) { + self.title = title + self.url = url } } #if compiler(>=6) -extension TransactionDetail: Sendable {} +extension PubkyProfileLink: Sendable {} #endif -extension TransactionDetail: Equatable, Hashable { - public static func ==(lhs: TransactionDetail, rhs: TransactionDetail) -> Bool { - if lhs.txid != rhs.txid { - return false - } - if lhs.received != rhs.received { - return false - } - if lhs.sent != rhs.sent { - return false - } - if lhs.net != rhs.net { - return false - } - if lhs.amount != rhs.amount { - return false - } - if lhs.fee != rhs.fee { - return false - } - if lhs.direction != rhs.direction { - return false - } - if lhs.blockHeight != rhs.blockHeight { - return false - } - if lhs.timestamp != rhs.timestamp { - return false - } - if lhs.confirmations != rhs.confirmations { - return false - } - if lhs.inputs != rhs.inputs { - return false - } - if lhs.outputs != rhs.outputs { - return false - } - if lhs.size != rhs.size { - return false - } - if lhs.vsize != rhs.vsize { - return false - } - if lhs.weight != rhs.weight { +extension PubkyProfileLink: Equatable, Hashable { + public static func ==(lhs: PubkyProfileLink, rhs: PubkyProfileLink) -> Bool { + if lhs.title != rhs.title { return false } - if lhs.feeRate != rhs.feeRate { + if lhs.url != rhs.url { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(txid) - hasher.combine(received) - hasher.combine(sent) - hasher.combine(net) - hasher.combine(amount) - hasher.combine(fee) - hasher.combine(direction) - hasher.combine(blockHeight) - hasher.combine(timestamp) - hasher.combine(confirmations) - hasher.combine(inputs) - hasher.combine(outputs) - hasher.combine(size) - hasher.combine(vsize) - hasher.combine(weight) - hasher.combine(feeRate) + hasher.combine(title) + hasher.combine(url) } } -extension TransactionDetail: Codable {} +extension PubkyProfileLink: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTransactionDetail: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionDetail { +public struct FfiConverterTypePubkyProfileLink: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyProfileLink { return - try TransactionDetail( - txid: FfiConverterString.read(from: &buf), - received: FfiConverterUInt64.read(from: &buf), - sent: FfiConverterUInt64.read(from: &buf), - net: FfiConverterInt64.read(from: &buf), - amount: FfiConverterUInt64.read(from: &buf), - fee: FfiConverterOptionUInt64.read(from: &buf), - direction: FfiConverterTypeTxDirection.read(from: &buf), - blockHeight: FfiConverterOptionUInt32.read(from: &buf), - timestamp: FfiConverterOptionUInt64.read(from: &buf), - confirmations: FfiConverterUInt32.read(from: &buf), - inputs: FfiConverterSequenceTypeTxDetailInput.read(from: &buf), - outputs: FfiConverterSequenceTypeTxDetailOutput.read(from: &buf), - size: FfiConverterUInt32.read(from: &buf), - vsize: FfiConverterUInt32.read(from: &buf), - weight: FfiConverterUInt32.read(from: &buf), - feeRate: FfiConverterOptionDouble.read(from: &buf) + try PubkyProfileLink( + title: FfiConverterString.read(from: &buf), + url: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: TransactionDetail, into buf: inout [UInt8]) { - FfiConverterString.write(value.txid, into: &buf) - FfiConverterUInt64.write(value.received, into: &buf) - FfiConverterUInt64.write(value.sent, into: &buf) - FfiConverterInt64.write(value.net, into: &buf) - FfiConverterUInt64.write(value.amount, into: &buf) - FfiConverterOptionUInt64.write(value.fee, into: &buf) - FfiConverterTypeTxDirection.write(value.direction, into: &buf) - FfiConverterOptionUInt32.write(value.blockHeight, into: &buf) - FfiConverterOptionUInt64.write(value.timestamp, into: &buf) - FfiConverterUInt32.write(value.confirmations, into: &buf) - FfiConverterSequenceTypeTxDetailInput.write(value.inputs, into: &buf) - FfiConverterSequenceTypeTxDetailOutput.write(value.outputs, into: &buf) - FfiConverterUInt32.write(value.size, into: &buf) - FfiConverterUInt32.write(value.vsize, into: &buf) - FfiConverterUInt32.write(value.weight, into: &buf) - FfiConverterOptionDouble.write(value.feeRate, into: &buf) + public static func write(_ value: PubkyProfileLink, into buf: inout [UInt8]) { + FfiConverterString.write(value.title, into: &buf) + FfiConverterString.write(value.url, into: &buf) } } @@ -11046,132 +11130,125 @@ public struct FfiConverterTypeTransactionDetail: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionDetail_lift(_ buf: RustBuffer) throws -> TransactionDetail { - return try FfiConverterTypeTransactionDetail.lift(buf) +public func FfiConverterTypePubkyProfileLink_lift(_ buf: RustBuffer) throws -> PubkyProfileLink { + return try FfiConverterTypePubkyProfileLink.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionDetail_lower(_ value: TransactionDetail) -> RustBuffer { - return FfiConverterTypeTransactionDetail.lower(value) +public func FfiConverterTypePubkyProfileLink_lower(_ value: PubkyProfileLink) -> RustBuffer { + return FfiConverterTypePubkyProfileLink.lower(value) } /** - * Details about an onchain transaction. + * Result of creating a reverse swap (Lightning -> onchain). + * + * The caller pays `invoice` from its Lightning node; once Boltz locks funds at + * `lockup_address`, the module claims them to the provided onchain address. */ -public struct TransactionDetails { - public var walletId: String +public struct ReverseSwapResponse { + public var id: String /** - * The transaction ID. + * Hold invoice the caller must pay via Lightning. */ - public var txId: String + public var invoice: String /** - * The net amount in this transaction (in satoshis). - * - * This is calculated as: (received - sent). For incoming payments, - * this will be positive. For outgoing payments, this will be negative. - * - * Note: This amount does NOT include transaction fees. + * Address Boltz locks the onchain funds to. */ - public var amountSats: Int64 + public var lockupAddress: String /** - * The transaction inputs with full details. + * Amount in satoshis that will be received onchain (after Boltz fees). */ - public var inputs: [TxInput] + public var onchainAmountSat: UInt64 /** - * The transaction outputs with full details. + * Onchain timeout height for the swap. */ - public var outputs: [TxOutput] + public var timeoutBlockHeight: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. - public init(walletId: String, + public init(id: String, /** - * The transaction ID. - */txId: String, + * Hold invoice the caller must pay via Lightning. + */invoice: String, /** - * The net amount in this transaction (in satoshis). - * - * This is calculated as: (received - sent). For incoming payments, - * this will be positive. For outgoing payments, this will be negative. - * - * Note: This amount does NOT include transaction fees. - */amountSats: Int64, + * Address Boltz locks the onchain funds to. + */lockupAddress: String, /** - * The transaction inputs with full details. - */inputs: [TxInput], + * Amount in satoshis that will be received onchain (after Boltz fees). + */onchainAmountSat: UInt64, /** - * The transaction outputs with full details. - */outputs: [TxOutput]) { - self.walletId = walletId - self.txId = txId - self.amountSats = amountSats - self.inputs = inputs - self.outputs = outputs + * Onchain timeout height for the swap. + */timeoutBlockHeight: UInt64) { + self.id = id + self.invoice = invoice + self.lockupAddress = lockupAddress + self.onchainAmountSat = onchainAmountSat + self.timeoutBlockHeight = timeoutBlockHeight } } #if compiler(>=6) -extension TransactionDetails: Sendable {} +extension ReverseSwapResponse: Sendable {} #endif -extension TransactionDetails: Equatable, Hashable { - public static func ==(lhs: TransactionDetails, rhs: TransactionDetails) -> Bool { - if lhs.walletId != rhs.walletId { +extension ReverseSwapResponse: Equatable, Hashable { + public static func ==(lhs: ReverseSwapResponse, rhs: ReverseSwapResponse) -> Bool { + if lhs.id != rhs.id { return false } - if lhs.txId != rhs.txId { + if lhs.invoice != rhs.invoice { return false } - if lhs.amountSats != rhs.amountSats { + if lhs.lockupAddress != rhs.lockupAddress { return false } - if lhs.inputs != rhs.inputs { + if lhs.onchainAmountSat != rhs.onchainAmountSat { return false } - if lhs.outputs != rhs.outputs { + if lhs.timeoutBlockHeight != rhs.timeoutBlockHeight { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(walletId) - hasher.combine(txId) - hasher.combine(amountSats) - hasher.combine(inputs) - hasher.combine(outputs) + hasher.combine(id) + hasher.combine(invoice) + hasher.combine(lockupAddress) + hasher.combine(onchainAmountSat) + hasher.combine(timeoutBlockHeight) } } -extension TransactionDetails: Codable {} +extension ReverseSwapResponse: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTransactionDetails: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionDetails { +public struct FfiConverterTypeReverseSwapResponse: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ReverseSwapResponse { return - try TransactionDetails( - walletId: FfiConverterString.read(from: &buf), - txId: FfiConverterString.read(from: &buf), - amountSats: FfiConverterInt64.read(from: &buf), - inputs: FfiConverterSequenceTypeTxInput.read(from: &buf), - outputs: FfiConverterSequenceTypeTxOutput.read(from: &buf) + try ReverseSwapResponse( + id: FfiConverterString.read(from: &buf), + invoice: FfiConverterString.read(from: &buf), + lockupAddress: FfiConverterString.read(from: &buf), + onchainAmountSat: FfiConverterUInt64.read(from: &buf), + timeoutBlockHeight: FfiConverterUInt64.read(from: &buf) ) } - public static func write(_ value: TransactionDetails, into buf: inout [UInt8]) { - FfiConverterString.write(value.walletId, into: &buf) - FfiConverterString.write(value.txId, into: &buf) - FfiConverterInt64.write(value.amountSats, into: &buf) - FfiConverterSequenceTypeTxInput.write(value.inputs, into: &buf) - FfiConverterSequenceTypeTxOutput.write(value.outputs, into: &buf) + public static func write(_ value: ReverseSwapResponse, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterString.write(value.invoice, into: &buf) + FfiConverterString.write(value.lockupAddress, into: &buf) + FfiConverterUInt64.write(value.onchainAmountSat, into: &buf) + FfiConverterUInt64.write(value.timeoutBlockHeight, into: &buf) } } @@ -11179,128 +11256,128 @@ public struct FfiConverterTypeTransactionDetails: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionDetails_lift(_ buf: RustBuffer) throws -> TransactionDetails { - return try FfiConverterTypeTransactionDetails.lift(buf) +public func FfiConverterTypeReverseSwapResponse_lift(_ buf: RustBuffer) throws -> ReverseSwapResponse { + return try FfiConverterTypeReverseSwapResponse.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionDetails_lower(_ value: TransactionDetails) -> RustBuffer { - return FfiConverterTypeTransactionDetails.lower(value) +public func FfiConverterTypeReverseSwapResponse_lower(_ value: ReverseSwapResponse) -> RustBuffer { + return FfiConverterTypeReverseSwapResponse.lower(value) } /** - * Result from querying transaction history for an xpub. + * Result from querying a single Bitcoin address. */ -public struct TransactionHistoryResult { +public struct SingleAddressInfoResult { /** - * All transactions, sorted: unconfirmed first, then by timestamp descending + * The queried address */ - public var transactions: [HistoryTransaction] + public var address: String /** - * Balance breakdown + * Total confirmed balance in satoshis */ - public var balance: WalletBalance + public var balance: UInt64 /** - * Total number of transactions + * UTXOs for this address */ - public var txCount: UInt32 + public var utxos: [AccountUtxo] /** - * Current blockchain tip height + * Number of transactions involving this address */ - public var blockHeight: UInt32 + public var transfers: UInt32 /** - * The detected or specified account type + * Current blockchain tip height */ - public var accountType: AccountType + public var blockHeight: UInt32 // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * All transactions, sorted: unconfirmed first, then by timestamp descending - */transactions: [HistoryTransaction], + * The queried address + */address: String, /** - * Balance breakdown - */balance: WalletBalance, + * Total confirmed balance in satoshis + */balance: UInt64, /** - * Total number of transactions - */txCount: UInt32, + * UTXOs for this address + */utxos: [AccountUtxo], /** - * Current blockchain tip height - */blockHeight: UInt32, + * Number of transactions involving this address + */transfers: UInt32, /** - * The detected or specified account type - */accountType: AccountType) { - self.transactions = transactions + * Current blockchain tip height + */blockHeight: UInt32) { + self.address = address self.balance = balance - self.txCount = txCount + self.utxos = utxos + self.transfers = transfers self.blockHeight = blockHeight - self.accountType = accountType } } #if compiler(>=6) -extension TransactionHistoryResult: Sendable {} +extension SingleAddressInfoResult: Sendable {} #endif -extension TransactionHistoryResult: Equatable, Hashable { - public static func ==(lhs: TransactionHistoryResult, rhs: TransactionHistoryResult) -> Bool { - if lhs.transactions != rhs.transactions { +extension SingleAddressInfoResult: Equatable, Hashable { + public static func ==(lhs: SingleAddressInfoResult, rhs: SingleAddressInfoResult) -> Bool { + if lhs.address != rhs.address { return false } if lhs.balance != rhs.balance { return false } - if lhs.txCount != rhs.txCount { + if lhs.utxos != rhs.utxos { return false } - if lhs.blockHeight != rhs.blockHeight { + if lhs.transfers != rhs.transfers { return false } - if lhs.accountType != rhs.accountType { + if lhs.blockHeight != rhs.blockHeight { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(transactions) + hasher.combine(address) hasher.combine(balance) - hasher.combine(txCount) + hasher.combine(utxos) + hasher.combine(transfers) hasher.combine(blockHeight) - hasher.combine(accountType) } } -extension TransactionHistoryResult: Codable {} +extension SingleAddressInfoResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTransactionHistoryResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionHistoryResult { +public struct FfiConverterTypeSingleAddressInfoResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SingleAddressInfoResult { return - try TransactionHistoryResult( - transactions: FfiConverterSequenceTypeHistoryTransaction.read(from: &buf), - balance: FfiConverterTypeWalletBalance.read(from: &buf), - txCount: FfiConverterUInt32.read(from: &buf), - blockHeight: FfiConverterUInt32.read(from: &buf), - accountType: FfiConverterTypeAccountType.read(from: &buf) + try SingleAddressInfoResult( + address: FfiConverterString.read(from: &buf), + balance: FfiConverterUInt64.read(from: &buf), + utxos: FfiConverterSequenceTypeAccountUtxo.read(from: &buf), + transfers: FfiConverterUInt32.read(from: &buf), + blockHeight: FfiConverterUInt32.read(from: &buf) ) } - public static func write(_ value: TransactionHistoryResult, into buf: inout [UInt8]) { - FfiConverterSequenceTypeHistoryTransaction.write(value.transactions, into: &buf) - FfiConverterTypeWalletBalance.write(value.balance, into: &buf) - FfiConverterUInt32.write(value.txCount, into: &buf) + public static func write(_ value: SingleAddressInfoResult, into buf: inout [UInt8]) { + FfiConverterString.write(value.address, into: &buf) + FfiConverterUInt64.write(value.balance, into: &buf) + FfiConverterSequenceTypeAccountUtxo.write(value.utxos, into: &buf) + FfiConverterUInt32.write(value.transfers, into: &buf) FfiConverterUInt32.write(value.blockHeight, into: &buf) - FfiConverterTypeAccountType.write(value.accountType, into: &buf) } } @@ -11308,86 +11385,139 @@ public struct FfiConverterTypeTransactionHistoryResult: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionHistoryResult_lift(_ buf: RustBuffer) throws -> TransactionHistoryResult { - return try FfiConverterTypeTransactionHistoryResult.lift(buf) +public func FfiConverterTypeSingleAddressInfoResult_lift(_ buf: RustBuffer) throws -> SingleAddressInfoResult { + return try FfiConverterTypeSingleAddressInfoResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionHistoryResult_lower(_ value: TransactionHistoryResult) -> RustBuffer { - return FfiConverterTypeTransactionHistoryResult.lower(value) +public func FfiConverterTypeSingleAddressInfoResult_lower(_ value: SingleAddressInfoResult) -> RustBuffer { + return FfiConverterTypeSingleAddressInfoResult.lower(value) } /** - * Address response from device. + * Result of creating a submarine swap (onchain -> Lightning). + * + * The caller funds `address` with `expected_amount_sat` from its onchain + * wallet; Boltz then pays the Lightning invoice supplied at creation. */ -public struct TrezorAddressResponse { +public struct SubmarineSwapResponse { + public var id: String /** - * The Bitcoin address + * Onchain lockup address to send funds to. */ public var address: String /** - * The serialized path (e.g., "m/84'/0'/0'/0/0") + * BIP21 URI for the lockup payment. */ - public var path: String + public var bip21: String + /** + * Exact amount in satoshis the caller must send to `address`. + */ + public var expectedAmountSat: UInt64 + /** + * Whether Boltz will accept a zero-conf lockup. + */ + public var acceptZeroConf: Bool + /** + * Onchain timeout height after which a refund is possible. + */ + public var timeoutBlockHeight: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. - public init( + public init(id: String, /** - * The Bitcoin address + * Onchain lockup address to send funds to. */address: String, /** - * The serialized path (e.g., "m/84'/0'/0'/0/0") - */path: String) { + * BIP21 URI for the lockup payment. + */bip21: String, + /** + * Exact amount in satoshis the caller must send to `address`. + */expectedAmountSat: UInt64, + /** + * Whether Boltz will accept a zero-conf lockup. + */acceptZeroConf: Bool, + /** + * Onchain timeout height after which a refund is possible. + */timeoutBlockHeight: UInt64) { + self.id = id self.address = address - self.path = path + self.bip21 = bip21 + self.expectedAmountSat = expectedAmountSat + self.acceptZeroConf = acceptZeroConf + self.timeoutBlockHeight = timeoutBlockHeight } } #if compiler(>=6) -extension TrezorAddressResponse: Sendable {} +extension SubmarineSwapResponse: Sendable {} #endif -extension TrezorAddressResponse: Equatable, Hashable { - public static func ==(lhs: TrezorAddressResponse, rhs: TrezorAddressResponse) -> Bool { +extension SubmarineSwapResponse: Equatable, Hashable { + public static func ==(lhs: SubmarineSwapResponse, rhs: SubmarineSwapResponse) -> Bool { + if lhs.id != rhs.id { + return false + } if lhs.address != rhs.address { return false } - if lhs.path != rhs.path { + if lhs.bip21 != rhs.bip21 { return false } - return true - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(address) - hasher.combine(path) + if lhs.expectedAmountSat != rhs.expectedAmountSat { + return false + } + if lhs.acceptZeroConf != rhs.acceptZeroConf { + return false + } + if lhs.timeoutBlockHeight != rhs.timeoutBlockHeight { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(id) + hasher.combine(address) + hasher.combine(bip21) + hasher.combine(expectedAmountSat) + hasher.combine(acceptZeroConf) + hasher.combine(timeoutBlockHeight) } } -extension TrezorAddressResponse: Codable {} +extension SubmarineSwapResponse: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorAddressResponse: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorAddressResponse { +public struct FfiConverterTypeSubmarineSwapResponse: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SubmarineSwapResponse { return - try TrezorAddressResponse( + try SubmarineSwapResponse( + id: FfiConverterString.read(from: &buf), address: FfiConverterString.read(from: &buf), - path: FfiConverterString.read(from: &buf) + bip21: FfiConverterString.read(from: &buf), + expectedAmountSat: FfiConverterUInt64.read(from: &buf), + acceptZeroConf: FfiConverterBool.read(from: &buf), + timeoutBlockHeight: FfiConverterUInt64.read(from: &buf) ) } - public static func write(_ value: TrezorAddressResponse, into buf: inout [UInt8]) { + public static func write(_ value: SubmarineSwapResponse, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) FfiConverterString.write(value.address, into: &buf) - FfiConverterString.write(value.path, into: &buf) + FfiConverterString.write(value.bip21, into: &buf) + FfiConverterUInt64.write(value.expectedAmountSat, into: &buf) + FfiConverterBool.write(value.acceptZeroConf, into: &buf) + FfiConverterUInt64.write(value.timeoutBlockHeight, into: &buf) } } @@ -11395,128 +11525,122 @@ public struct FfiConverterTypeTrezorAddressResponse: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorAddressResponse_lift(_ buf: RustBuffer) throws -> TrezorAddressResponse { - return try FfiConverterTypeTrezorAddressResponse.lift(buf) +public func FfiConverterTypeSubmarineSwapResponse_lift(_ buf: RustBuffer) throws -> SubmarineSwapResponse { + return try FfiConverterTypeSubmarineSwapResponse.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorAddressResponse_lower(_ value: TrezorAddressResponse) -> RustBuffer { - return FfiConverterTypeTrezorAddressResponse.lower(value) +public func FfiConverterTypeSubmarineSwapResponse_lower(_ value: SubmarineSwapResponse) -> RustBuffer { + return FfiConverterTypeSubmarineSwapResponse.lower(value) } /** - * Result from a high-level message call (for BLE/THP devices) + * A hardware-wallet model Bitkit supports. */ -public struct TrezorCallMessageResult { - /** - * Whether the call succeeded - */ - public var success: Bool +public struct SupportedHardwareWallet { + public var vendor: HardwareWalletVendor /** - * Response message type + * Human-readable manufacturer name, e.g. "Foundation". */ - public var messageType: UInt16 + public var vendorName: String /** - * Response protobuf data + * Stable model identifier that applications can map to bundled assets. */ - public var data: Data + public var model: String /** - * Error message (empty on success) + * Full user-facing name. */ - public var error: String + public var displayName: String /** - * Structured error code (None on success or when the native error is generic) + * Transports over which the application can interact with this model. */ - public var errorCode: TrezorTransportErrorCode? + public var transports: [HardwareWalletTransport] // Default memberwise initializers are never public by default, so we // declare one manually. - public init( - /** - * Whether the call succeeded - */success: Bool, + public init(vendor: HardwareWalletVendor, /** - * Response message type - */messageType: UInt16, + * Human-readable manufacturer name, e.g. "Foundation". + */vendorName: String, /** - * Response protobuf data - */data: Data, + * Stable model identifier that applications can map to bundled assets. + */model: String, /** - * Error message (empty on success) - */error: String, + * Full user-facing name. + */displayName: String, /** - * Structured error code (None on success or when the native error is generic) - */errorCode: TrezorTransportErrorCode?) { - self.success = success - self.messageType = messageType - self.data = data - self.error = error - self.errorCode = errorCode + * Transports over which the application can interact with this model. + */transports: [HardwareWalletTransport]) { + self.vendor = vendor + self.vendorName = vendorName + self.model = model + self.displayName = displayName + self.transports = transports } } #if compiler(>=6) -extension TrezorCallMessageResult: Sendable {} +extension SupportedHardwareWallet: Sendable {} #endif -extension TrezorCallMessageResult: Equatable, Hashable { - public static func ==(lhs: TrezorCallMessageResult, rhs: TrezorCallMessageResult) -> Bool { - if lhs.success != rhs.success { +extension SupportedHardwareWallet: Equatable, Hashable { + public static func ==(lhs: SupportedHardwareWallet, rhs: SupportedHardwareWallet) -> Bool { + if lhs.vendor != rhs.vendor { return false } - if lhs.messageType != rhs.messageType { + if lhs.vendorName != rhs.vendorName { return false } - if lhs.data != rhs.data { + if lhs.model != rhs.model { return false } - if lhs.error != rhs.error { + if lhs.displayName != rhs.displayName { return false } - if lhs.errorCode != rhs.errorCode { + if lhs.transports != rhs.transports { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(success) - hasher.combine(messageType) - hasher.combine(data) - hasher.combine(error) - hasher.combine(errorCode) + hasher.combine(vendor) + hasher.combine(vendorName) + hasher.combine(model) + hasher.combine(displayName) + hasher.combine(transports) } } -extension TrezorCallMessageResult: Codable {} +extension SupportedHardwareWallet: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorCallMessageResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorCallMessageResult { +public struct FfiConverterTypeSupportedHardwareWallet: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SupportedHardwareWallet { return - try TrezorCallMessageResult( - success: FfiConverterBool.read(from: &buf), - messageType: FfiConverterUInt16.read(from: &buf), - data: FfiConverterData.read(from: &buf), - error: FfiConverterString.read(from: &buf), - errorCode: FfiConverterOptionTypeTrezorTransportErrorCode.read(from: &buf) + try SupportedHardwareWallet( + vendor: FfiConverterTypeHardwareWalletVendor.read(from: &buf), + vendorName: FfiConverterString.read(from: &buf), + model: FfiConverterString.read(from: &buf), + displayName: FfiConverterString.read(from: &buf), + transports: FfiConverterSequenceTypeHardwareWalletTransport.read(from: &buf) ) } - public static func write(_ value: TrezorCallMessageResult, into buf: inout [UInt8]) { - FfiConverterBool.write(value.success, into: &buf) - FfiConverterUInt16.write(value.messageType, into: &buf) - FfiConverterData.write(value.data, into: &buf) - FfiConverterString.write(value.error, into: &buf) - FfiConverterOptionTypeTrezorTransportErrorCode.write(value.errorCode, into: &buf) + public static func write(_ value: SupportedHardwareWallet, into buf: inout [UInt8]) { + FfiConverterTypeHardwareWalletVendor.write(value.vendor, into: &buf) + FfiConverterString.write(value.vendorName, into: &buf) + FfiConverterString.write(value.model, into: &buf) + FfiConverterString.write(value.displayName, into: &buf) + FfiConverterSequenceTypeHardwareWalletTransport.write(value.transports, into: &buf) } } @@ -11524,156 +11648,111 @@ public struct FfiConverterTypeTrezorCallMessageResult: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorCallMessageResult_lift(_ buf: RustBuffer) throws -> TrezorCallMessageResult { - return try FfiConverterTypeTrezorCallMessageResult.lift(buf) +public func FfiConverterTypeSupportedHardwareWallet_lift(_ buf: RustBuffer) throws -> SupportedHardwareWallet { + return try FfiConverterTypeSupportedHardwareWallet.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorCallMessageResult_lower(_ value: TrezorCallMessageResult) -> RustBuffer { - return FfiConverterTypeTrezorCallMessageResult.lower(value) +public func FfiConverterTypeSupportedHardwareWallet_lower(_ value: SupportedHardwareWallet) -> RustBuffer { + return FfiConverterTypeSupportedHardwareWallet.lower(value) } -/** - * Device information exposed to FFI. - */ -public struct TrezorDeviceInfo { - /** - * Unique identifier for the device - */ - public var id: String - /** - * Transport type (USB or Bluetooth) - */ - public var transportType: TrezorTransportType - /** - * Device name (from BLE advertisement or USB descriptor) - */ - public var name: String? +public struct SweepResult { /** - * Transport-specific path (used internally for connection) + * The transaction ID of the sweep transaction */ - public var path: String + public var txid: String /** - * Device label (set by user during device setup) + * The total amount swept (in satoshis) */ - public var label: String? + public var amountSwept: UInt64 /** - * Device model (e.g., "T2", "Safe 5", "Safe 7") + * The fee paid (in satoshis) */ - public var model: String? + public var feePaid: UInt64 /** - * Whether the device is in bootloader mode + * The number of UTXOs swept */ - public var isBootloader: Bool + public var utxosSwept: UInt32 // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Unique identifier for the device - */id: String, - /** - * Transport type (USB or Bluetooth) - */transportType: TrezorTransportType, - /** - * Device name (from BLE advertisement or USB descriptor) - */name: String?, - /** - * Transport-specific path (used internally for connection) - */path: String, + * The transaction ID of the sweep transaction + */txid: String, /** - * Device label (set by user during device setup) - */label: String?, + * The total amount swept (in satoshis) + */amountSwept: UInt64, /** - * Device model (e.g., "T2", "Safe 5", "Safe 7") - */model: String?, + * The fee paid (in satoshis) + */feePaid: UInt64, /** - * Whether the device is in bootloader mode - */isBootloader: Bool) { - self.id = id - self.transportType = transportType - self.name = name - self.path = path - self.label = label - self.model = model - self.isBootloader = isBootloader + * The number of UTXOs swept + */utxosSwept: UInt32) { + self.txid = txid + self.amountSwept = amountSwept + self.feePaid = feePaid + self.utxosSwept = utxosSwept } } #if compiler(>=6) -extension TrezorDeviceInfo: Sendable {} +extension SweepResult: Sendable {} #endif -extension TrezorDeviceInfo: Equatable, Hashable { - public static func ==(lhs: TrezorDeviceInfo, rhs: TrezorDeviceInfo) -> Bool { - if lhs.id != rhs.id { - return false - } - if lhs.transportType != rhs.transportType { +extension SweepResult: Equatable, Hashable { + public static func ==(lhs: SweepResult, rhs: SweepResult) -> Bool { + if lhs.txid != rhs.txid { return false } - if lhs.name != rhs.name { + if lhs.amountSwept != rhs.amountSwept { return false } - if lhs.path != rhs.path { + if lhs.feePaid != rhs.feePaid { return false } - if lhs.label != rhs.label { - return false - } - if lhs.model != rhs.model { - return false - } - if lhs.isBootloader != rhs.isBootloader { + if lhs.utxosSwept != rhs.utxosSwept { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(id) - hasher.combine(transportType) - hasher.combine(name) - hasher.combine(path) - hasher.combine(label) - hasher.combine(model) - hasher.combine(isBootloader) + hasher.combine(txid) + hasher.combine(amountSwept) + hasher.combine(feePaid) + hasher.combine(utxosSwept) } } -extension TrezorDeviceInfo: Codable {} +extension SweepResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorDeviceInfo: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorDeviceInfo { +public struct FfiConverterTypeSweepResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SweepResult { return - try TrezorDeviceInfo( - id: FfiConverterString.read(from: &buf), - transportType: FfiConverterTypeTrezorTransportType.read(from: &buf), - name: FfiConverterOptionString.read(from: &buf), - path: FfiConverterString.read(from: &buf), - label: FfiConverterOptionString.read(from: &buf), - model: FfiConverterOptionString.read(from: &buf), - isBootloader: FfiConverterBool.read(from: &buf) + try SweepResult( + txid: FfiConverterString.read(from: &buf), + amountSwept: FfiConverterUInt64.read(from: &buf), + feePaid: FfiConverterUInt64.read(from: &buf), + utxosSwept: FfiConverterUInt32.read(from: &buf) ) } - public static func write(_ value: TrezorDeviceInfo, into buf: inout [UInt8]) { - FfiConverterString.write(value.id, into: &buf) - FfiConverterTypeTrezorTransportType.write(value.transportType, into: &buf) - FfiConverterOptionString.write(value.name, into: &buf) - FfiConverterString.write(value.path, into: &buf) - FfiConverterOptionString.write(value.label, into: &buf) - FfiConverterOptionString.write(value.model, into: &buf) - FfiConverterBool.write(value.isBootloader, into: &buf) + public static func write(_ value: SweepResult, into buf: inout [UInt8]) { + FfiConverterString.write(value.txid, into: &buf) + FfiConverterUInt64.write(value.amountSwept, into: &buf) + FfiConverterUInt64.write(value.feePaid, into: &buf) + FfiConverterUInt32.write(value.utxosSwept, into: &buf) } } @@ -11681,246 +11760,153 @@ public struct FfiConverterTypeTrezorDeviceInfo: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorDeviceInfo_lift(_ buf: RustBuffer) throws -> TrezorDeviceInfo { - return try FfiConverterTypeTrezorDeviceInfo.lift(buf) +public func FfiConverterTypeSweepResult_lift(_ buf: RustBuffer) throws -> SweepResult { + return try FfiConverterTypeSweepResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorDeviceInfo_lower(_ value: TrezorDeviceInfo) -> RustBuffer { - return FfiConverterTypeTrezorDeviceInfo.lower(value) +public func FfiConverterTypeSweepResult_lower(_ value: SweepResult) -> RustBuffer { + return FfiConverterTypeSweepResult.lower(value) } -/** - * Device features after initialization. - */ -public struct TrezorFeatures { - /** - * Vendor string - */ - public var vendor: String? - /** - * Device model - */ - public var model: String? - /** - * Device label (set by user during device setup) - */ - public var label: String? - /** - * Device ID (unique per device) - */ - public var deviceId: String? - /** - * Major firmware version - */ - public var majorVersion: UInt32? - /** - * Minor firmware version - */ - public var minorVersion: UInt32? +public struct SweepTransactionPreview { /** - * Patch firmware version + * The PSBT (Partially Signed Bitcoin Transaction) in base64 format */ - public var patchVersion: UInt32? + public var psbt: String /** - * Whether PIN protection is enabled + * The total amount available to sweep (in satoshis) */ - public var pinProtection: Bool? + public var totalAmount: UInt64 /** - * Whether the device is currently unlocked. When PIN protection is enabled - * and this is `Some(false)`, mobile callers should back off and ask the - * user to unlock the Trezor instead of repeatedly reconnecting. + * The estimated fee for the transaction (in satoshis) */ - public var unlocked: Bool? + public var estimatedFee: UInt64 /** - * Whether passphrase protection is enabled + * The estimated virtual size of the transaction (in vbytes) */ - public var passphraseProtection: Bool? + public var estimatedVsize: UInt64 /** - * Whether the device is initialized with a seed + * The number of UTXOs that will be swept */ - public var initialized: Bool? + public var utxosCount: UInt32 /** - * Whether the device needs backup + * The destination address */ - public var needsBackup: Bool? + public var destinationAddress: String /** - * Whether the device can accept passphrase entry on the device itself - * (`Capability_PassphraseEntry`). When false/None, use host entry only. + * The amount that will be sent to destination after fees (in satoshis) */ - public var passphraseEntryCapable: Bool? + public var amountAfterFees: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Vendor string - */vendor: String?, - /** - * Device model - */model: String?, - /** - * Device label (set by user during device setup) - */label: String?, - /** - * Device ID (unique per device) - */deviceId: String?, - /** - * Major firmware version - */majorVersion: UInt32?, - /** - * Minor firmware version - */minorVersion: UInt32?, - /** - * Patch firmware version - */patchVersion: UInt32?, + * The PSBT (Partially Signed Bitcoin Transaction) in base64 format + */psbt: String, /** - * Whether PIN protection is enabled - */pinProtection: Bool?, + * The total amount available to sweep (in satoshis) + */totalAmount: UInt64, /** - * Whether the device is currently unlocked. When PIN protection is enabled - * and this is `Some(false)`, mobile callers should back off and ask the - * user to unlock the Trezor instead of repeatedly reconnecting. - */unlocked: Bool?, + * The estimated fee for the transaction (in satoshis) + */estimatedFee: UInt64, /** - * Whether passphrase protection is enabled - */passphraseProtection: Bool?, + * The estimated virtual size of the transaction (in vbytes) + */estimatedVsize: UInt64, /** - * Whether the device is initialized with a seed - */initialized: Bool?, + * The number of UTXOs that will be swept + */utxosCount: UInt32, /** - * Whether the device needs backup - */needsBackup: Bool?, + * The destination address + */destinationAddress: String, /** - * Whether the device can accept passphrase entry on the device itself - * (`Capability_PassphraseEntry`). When false/None, use host entry only. - */passphraseEntryCapable: Bool?) { - self.vendor = vendor - self.model = model - self.label = label - self.deviceId = deviceId - self.majorVersion = majorVersion - self.minorVersion = minorVersion - self.patchVersion = patchVersion - self.pinProtection = pinProtection - self.unlocked = unlocked - self.passphraseProtection = passphraseProtection - self.initialized = initialized - self.needsBackup = needsBackup - self.passphraseEntryCapable = passphraseEntryCapable + * The amount that will be sent to destination after fees (in satoshis) + */amountAfterFees: UInt64) { + self.psbt = psbt + self.totalAmount = totalAmount + self.estimatedFee = estimatedFee + self.estimatedVsize = estimatedVsize + self.utxosCount = utxosCount + self.destinationAddress = destinationAddress + self.amountAfterFees = amountAfterFees } } #if compiler(>=6) -extension TrezorFeatures: Sendable {} +extension SweepTransactionPreview: Sendable {} #endif -extension TrezorFeatures: Equatable, Hashable { - public static func ==(lhs: TrezorFeatures, rhs: TrezorFeatures) -> Bool { - if lhs.vendor != rhs.vendor { - return false - } - if lhs.model != rhs.model { - return false - } - if lhs.label != rhs.label { - return false - } - if lhs.deviceId != rhs.deviceId { - return false - } - if lhs.majorVersion != rhs.majorVersion { - return false - } - if lhs.minorVersion != rhs.minorVersion { - return false - } - if lhs.patchVersion != rhs.patchVersion { +extension SweepTransactionPreview: Equatable, Hashable { + public static func ==(lhs: SweepTransactionPreview, rhs: SweepTransactionPreview) -> Bool { + if lhs.psbt != rhs.psbt { return false } - if lhs.pinProtection != rhs.pinProtection { + if lhs.totalAmount != rhs.totalAmount { return false } - if lhs.unlocked != rhs.unlocked { + if lhs.estimatedFee != rhs.estimatedFee { return false } - if lhs.passphraseProtection != rhs.passphraseProtection { + if lhs.estimatedVsize != rhs.estimatedVsize { return false } - if lhs.initialized != rhs.initialized { + if lhs.utxosCount != rhs.utxosCount { return false } - if lhs.needsBackup != rhs.needsBackup { + if lhs.destinationAddress != rhs.destinationAddress { return false } - if lhs.passphraseEntryCapable != rhs.passphraseEntryCapable { + if lhs.amountAfterFees != rhs.amountAfterFees { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(vendor) - hasher.combine(model) - hasher.combine(label) - hasher.combine(deviceId) - hasher.combine(majorVersion) - hasher.combine(minorVersion) - hasher.combine(patchVersion) - hasher.combine(pinProtection) - hasher.combine(unlocked) - hasher.combine(passphraseProtection) - hasher.combine(initialized) - hasher.combine(needsBackup) - hasher.combine(passphraseEntryCapable) + hasher.combine(psbt) + hasher.combine(totalAmount) + hasher.combine(estimatedFee) + hasher.combine(estimatedVsize) + hasher.combine(utxosCount) + hasher.combine(destinationAddress) + hasher.combine(amountAfterFees) } } -extension TrezorFeatures: Codable {} +extension SweepTransactionPreview: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorFeatures: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorFeatures { +public struct FfiConverterTypeSweepTransactionPreview: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SweepTransactionPreview { return - try TrezorFeatures( - vendor: FfiConverterOptionString.read(from: &buf), - model: FfiConverterOptionString.read(from: &buf), - label: FfiConverterOptionString.read(from: &buf), - deviceId: FfiConverterOptionString.read(from: &buf), - majorVersion: FfiConverterOptionUInt32.read(from: &buf), - minorVersion: FfiConverterOptionUInt32.read(from: &buf), - patchVersion: FfiConverterOptionUInt32.read(from: &buf), - pinProtection: FfiConverterOptionBool.read(from: &buf), - unlocked: FfiConverterOptionBool.read(from: &buf), - passphraseProtection: FfiConverterOptionBool.read(from: &buf), - initialized: FfiConverterOptionBool.read(from: &buf), - needsBackup: FfiConverterOptionBool.read(from: &buf), - passphraseEntryCapable: FfiConverterOptionBool.read(from: &buf) + try SweepTransactionPreview( + psbt: FfiConverterString.read(from: &buf), + totalAmount: FfiConverterUInt64.read(from: &buf), + estimatedFee: FfiConverterUInt64.read(from: &buf), + estimatedVsize: FfiConverterUInt64.read(from: &buf), + utxosCount: FfiConverterUInt32.read(from: &buf), + destinationAddress: FfiConverterString.read(from: &buf), + amountAfterFees: FfiConverterUInt64.read(from: &buf) ) } - public static func write(_ value: TrezorFeatures, into buf: inout [UInt8]) { - FfiConverterOptionString.write(value.vendor, into: &buf) - FfiConverterOptionString.write(value.model, into: &buf) - FfiConverterOptionString.write(value.label, into: &buf) - FfiConverterOptionString.write(value.deviceId, into: &buf) - FfiConverterOptionUInt32.write(value.majorVersion, into: &buf) - FfiConverterOptionUInt32.write(value.minorVersion, into: &buf) - FfiConverterOptionUInt32.write(value.patchVersion, into: &buf) - FfiConverterOptionBool.write(value.pinProtection, into: &buf) - FfiConverterOptionBool.write(value.unlocked, into: &buf) - FfiConverterOptionBool.write(value.passphraseProtection, into: &buf) - FfiConverterOptionBool.write(value.initialized, into: &buf) - FfiConverterOptionBool.write(value.needsBackup, into: &buf) - FfiConverterOptionBool.write(value.passphraseEntryCapable, into: &buf) + public static func write(_ value: SweepTransactionPreview, into buf: inout [UInt8]) { + FfiConverterString.write(value.psbt, into: &buf) + FfiConverterUInt64.write(value.totalAmount, into: &buf) + FfiConverterUInt64.write(value.estimatedFee, into: &buf) + FfiConverterUInt64.write(value.estimatedVsize, into: &buf) + FfiConverterUInt32.write(value.utxosCount, into: &buf) + FfiConverterString.write(value.destinationAddress, into: &buf) + FfiConverterUInt64.write(value.amountAfterFees, into: &buf) } } @@ -11928,114 +11914,167 @@ public struct FfiConverterTypeTrezorFeatures: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorFeatures_lift(_ buf: RustBuffer) throws -> TrezorFeatures { - return try FfiConverterTypeTrezorFeatures.lift(buf) +public func FfiConverterTypeSweepTransactionPreview_lift(_ buf: RustBuffer) throws -> SweepTransactionPreview { + return try FfiConverterTypeSweepTransactionPreview.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorFeatures_lower(_ value: TrezorFeatures) -> RustBuffer { - return FfiConverterTypeTrezorFeatures.lower(value) +public func FfiConverterTypeSweepTransactionPreview_lower(_ value: SweepTransactionPreview) -> RustBuffer { + return FfiConverterTypeSweepTransactionPreview.lower(value) } -/** - * Parameters for getting an address from the device. - */ -public struct TrezorGetAddressParams { +public struct SweepableBalances { /** - * BIP32 path (e.g., "m/84'/0'/0'/0/0") + * Balance in legacy (P2PKH) addresses (in satoshis) */ - public var path: String + public var legacyBalance: UInt64 /** - * Coin network (default: Bitcoin) + * Balance in P2SH-SegWit (P2SH-P2WPKH) addresses (in satoshis) */ - public var coin: TrezorCoinType? + public var p2shBalance: UInt64 /** - * Whether to display the address on the device for confirmation + * Balance in Taproot (P2TR) addresses (in satoshis) */ - public var showOnTrezor: Bool + public var taprootBalance: UInt64 /** - * Script type (auto-detected from path if not specified) + * Total balance across all wallet types (in satoshis) */ - public var scriptType: TrezorScriptType? + public var totalBalance: UInt64 + /** + * Number of UTXOs in legacy wallet + */ + public var legacyUtxosCount: UInt32 + /** + * Number of UTXOs in P2SH-SegWit wallet + */ + public var p2shUtxosCount: UInt32 + /** + * Number of UTXOs in Taproot wallet + */ + public var taprootUtxosCount: UInt32 + /** + * Total number of UTXOs across all wallet types + */ + public var totalUtxosCount: UInt32 // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * BIP32 path (e.g., "m/84'/0'/0'/0/0") - */path: String, + * Balance in legacy (P2PKH) addresses (in satoshis) + */legacyBalance: UInt64, /** - * Coin network (default: Bitcoin) - */coin: TrezorCoinType?, + * Balance in P2SH-SegWit (P2SH-P2WPKH) addresses (in satoshis) + */p2shBalance: UInt64, /** - * Whether to display the address on the device for confirmation - */showOnTrezor: Bool, + * Balance in Taproot (P2TR) addresses (in satoshis) + */taprootBalance: UInt64, /** - * Script type (auto-detected from path if not specified) - */scriptType: TrezorScriptType?) { - self.path = path - self.coin = coin - self.showOnTrezor = showOnTrezor - self.scriptType = scriptType + * Total balance across all wallet types (in satoshis) + */totalBalance: UInt64, + /** + * Number of UTXOs in legacy wallet + */legacyUtxosCount: UInt32, + /** + * Number of UTXOs in P2SH-SegWit wallet + */p2shUtxosCount: UInt32, + /** + * Number of UTXOs in Taproot wallet + */taprootUtxosCount: UInt32, + /** + * Total number of UTXOs across all wallet types + */totalUtxosCount: UInt32) { + self.legacyBalance = legacyBalance + self.p2shBalance = p2shBalance + self.taprootBalance = taprootBalance + self.totalBalance = totalBalance + self.legacyUtxosCount = legacyUtxosCount + self.p2shUtxosCount = p2shUtxosCount + self.taprootUtxosCount = taprootUtxosCount + self.totalUtxosCount = totalUtxosCount } } #if compiler(>=6) -extension TrezorGetAddressParams: Sendable {} +extension SweepableBalances: Sendable {} #endif -extension TrezorGetAddressParams: Equatable, Hashable { - public static func ==(lhs: TrezorGetAddressParams, rhs: TrezorGetAddressParams) -> Bool { - if lhs.path != rhs.path { +extension SweepableBalances: Equatable, Hashable { + public static func ==(lhs: SweepableBalances, rhs: SweepableBalances) -> Bool { + if lhs.legacyBalance != rhs.legacyBalance { return false } - if lhs.coin != rhs.coin { + if lhs.p2shBalance != rhs.p2shBalance { return false } - if lhs.showOnTrezor != rhs.showOnTrezor { + if lhs.taprootBalance != rhs.taprootBalance { return false } - if lhs.scriptType != rhs.scriptType { + if lhs.totalBalance != rhs.totalBalance { + return false + } + if lhs.legacyUtxosCount != rhs.legacyUtxosCount { + return false + } + if lhs.p2shUtxosCount != rhs.p2shUtxosCount { + return false + } + if lhs.taprootUtxosCount != rhs.taprootUtxosCount { + return false + } + if lhs.totalUtxosCount != rhs.totalUtxosCount { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(path) - hasher.combine(coin) - hasher.combine(showOnTrezor) - hasher.combine(scriptType) + hasher.combine(legacyBalance) + hasher.combine(p2shBalance) + hasher.combine(taprootBalance) + hasher.combine(totalBalance) + hasher.combine(legacyUtxosCount) + hasher.combine(p2shUtxosCount) + hasher.combine(taprootUtxosCount) + hasher.combine(totalUtxosCount) } } -extension TrezorGetAddressParams: Codable {} +extension SweepableBalances: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorGetAddressParams: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorGetAddressParams { +public struct FfiConverterTypeSweepableBalances: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SweepableBalances { return - try TrezorGetAddressParams( - path: FfiConverterString.read(from: &buf), - coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf), - showOnTrezor: FfiConverterBool.read(from: &buf), - scriptType: FfiConverterOptionTypeTrezorScriptType.read(from: &buf) + try SweepableBalances( + legacyBalance: FfiConverterUInt64.read(from: &buf), + p2shBalance: FfiConverterUInt64.read(from: &buf), + taprootBalance: FfiConverterUInt64.read(from: &buf), + totalBalance: FfiConverterUInt64.read(from: &buf), + legacyUtxosCount: FfiConverterUInt32.read(from: &buf), + p2shUtxosCount: FfiConverterUInt32.read(from: &buf), + taprootUtxosCount: FfiConverterUInt32.read(from: &buf), + totalUtxosCount: FfiConverterUInt32.read(from: &buf) ) } - public static func write(_ value: TrezorGetAddressParams, into buf: inout [UInt8]) { - FfiConverterString.write(value.path, into: &buf) - FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) - FfiConverterBool.write(value.showOnTrezor, into: &buf) - FfiConverterOptionTypeTrezorScriptType.write(value.scriptType, into: &buf) + public static func write(_ value: SweepableBalances, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.legacyBalance, into: &buf) + FfiConverterUInt64.write(value.p2shBalance, into: &buf) + FfiConverterUInt64.write(value.taprootBalance, into: &buf) + FfiConverterUInt64.write(value.totalBalance, into: &buf) + FfiConverterUInt32.write(value.legacyUtxosCount, into: &buf) + FfiConverterUInt32.write(value.p2shUtxosCount, into: &buf) + FfiConverterUInt32.write(value.taprootUtxosCount, into: &buf) + FfiConverterUInt32.write(value.totalUtxosCount, into: &buf) } } @@ -12043,184 +12082,192 @@ public struct FfiConverterTypeTrezorGetAddressParams: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorGetAddressParams_lift(_ buf: RustBuffer) throws -> TrezorGetAddressParams { - return try FfiConverterTypeTrezorGetAddressParams.lift(buf) +public func FfiConverterTypeSweepableBalances_lift(_ buf: RustBuffer) throws -> SweepableBalances { + return try FfiConverterTypeSweepableBalances.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorGetAddressParams_lower(_ value: TrezorGetAddressParams) -> RustBuffer { - return FfiConverterTypeTrezorGetAddressParams.lower(value) +public func FfiConverterTypeSweepableBalances_lower(_ value: SweepableBalances) -> RustBuffer { + return FfiConverterTypeSweepableBalances.lower(value) } /** - * Parameters for getting a public key from the device. + * Full details for a single transaction, including raw inputs/outputs and size metrics. */ -public struct TrezorGetPublicKeyParams { +public struct TransactionDetail { /** - * BIP32 path (e.g., "m/84'/0'/0'") + * Transaction ID (hex) */ - public var path: String + public var txid: String /** - * Coin network (default: Bitcoin) + * Amount received by the wallet (sats) */ - public var coin: TrezorCoinType? + public var received: UInt64 /** - * Whether to display on device for confirmation + * Amount sent by the wallet (sats) — includes change sent back to self */ - public var showOnTrezor: Bool - - // Default memberwise initializers are never public by default, so we - // declare one manually. - public init( - /** - * BIP32 path (e.g., "m/84'/0'/0'") - */path: String, - /** - * Coin network (default: Bitcoin) - */coin: TrezorCoinType?, - /** - * Whether to display on device for confirmation - */showOnTrezor: Bool) { - self.path = path - self.coin = coin - self.showOnTrezor = showOnTrezor - } -} - -#if compiler(>=6) -extension TrezorGetPublicKeyParams: Sendable {} -#endif - - -extension TrezorGetPublicKeyParams: Equatable, Hashable { - public static func ==(lhs: TrezorGetPublicKeyParams, rhs: TrezorGetPublicKeyParams) -> Bool { - if lhs.path != rhs.path { - return false - } - if lhs.coin != rhs.coin { - return false - } - if lhs.showOnTrezor != rhs.showOnTrezor { - return false - } - return true - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(path) - hasher.combine(coin) - hasher.combine(showOnTrezor) - } -} - -extension TrezorGetPublicKeyParams: Codable {} - - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public struct FfiConverterTypeTrezorGetPublicKeyParams: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorGetPublicKeyParams { - return - try TrezorGetPublicKeyParams( - path: FfiConverterString.read(from: &buf), - coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf), - showOnTrezor: FfiConverterBool.read(from: &buf) - ) - } - - public static func write(_ value: TrezorGetPublicKeyParams, into buf: inout [UInt8]) { - FfiConverterString.write(value.path, into: &buf) - FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) - FfiConverterBool.write(value.showOnTrezor, into: &buf) - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeTrezorGetPublicKeyParams_lift(_ buf: RustBuffer) throws -> TrezorGetPublicKeyParams { - return try FfiConverterTypeTrezorGetPublicKeyParams.lift(buf) -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeTrezorGetPublicKeyParams_lower(_ value: TrezorGetPublicKeyParams) -> RustBuffer { - return FfiConverterTypeTrezorGetPublicKeyParams.lower(value) -} - - -/** - * Previous transaction data (for non-SegWit input verification). - */ -public struct TrezorPrevTx { + public var sent: UInt64 /** - * Transaction hash (hex encoded) + * Net value from wallet's perspective: received - sent (positive = inflow, negative = outflow) */ - public var hash: String + public var net: Int64 /** - * Transaction version + * Display amount in sats (same semantics as HistoryTransaction.amount) */ - public var version: UInt32 + public var amount: UInt64 /** - * Lock time + * Transaction fee in sats (None if not available) */ - public var lockTime: UInt32 + public var fee: UInt64? + /** + * Transaction direction + */ + public var direction: TxDirection + /** + * Block height (None if unconfirmed/mempool) + */ + public var blockHeight: UInt32? + /** + * Block timestamp as unix epoch seconds (None if unconfirmed) + */ + public var timestamp: UInt64? + /** + * Number of confirmations (0 if unconfirmed) + */ + public var confirmations: UInt32 /** * Transaction inputs */ - public var inputs: [TrezorPrevTxInput] + public var inputs: [TxDetailInput] /** * Transaction outputs */ - public var outputs: [TrezorPrevTxOutput] + public var outputs: [TxDetailOutput] + /** + * Serialized transaction size in bytes + */ + public var size: UInt32 + /** + * Virtual size in vbytes (ceil(weight / 4)) + */ + public var vsize: UInt32 + /** + * Transaction weight in weight units + */ + public var weight: UInt32 + /** + * Fee rate in sat/vB (fee / vsize), None if fee is unavailable or vsize is zero + */ + public var feeRate: Double? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Transaction hash (hex encoded) - */hash: String, + * Transaction ID (hex) + */txid: String, /** - * Transaction version - */version: UInt32, + * Amount received by the wallet (sats) + */received: UInt64, /** - * Lock time - */lockTime: UInt32, + * Amount sent by the wallet (sats) — includes change sent back to self + */sent: UInt64, + /** + * Net value from wallet's perspective: received - sent (positive = inflow, negative = outflow) + */net: Int64, + /** + * Display amount in sats (same semantics as HistoryTransaction.amount) + */amount: UInt64, + /** + * Transaction fee in sats (None if not available) + */fee: UInt64?, + /** + * Transaction direction + */direction: TxDirection, + /** + * Block height (None if unconfirmed/mempool) + */blockHeight: UInt32?, + /** + * Block timestamp as unix epoch seconds (None if unconfirmed) + */timestamp: UInt64?, + /** + * Number of confirmations (0 if unconfirmed) + */confirmations: UInt32, /** * Transaction inputs - */inputs: [TrezorPrevTxInput], + */inputs: [TxDetailInput], /** * Transaction outputs - */outputs: [TrezorPrevTxOutput]) { - self.hash = hash - self.version = version - self.lockTime = lockTime + */outputs: [TxDetailOutput], + /** + * Serialized transaction size in bytes + */size: UInt32, + /** + * Virtual size in vbytes (ceil(weight / 4)) + */vsize: UInt32, + /** + * Transaction weight in weight units + */weight: UInt32, + /** + * Fee rate in sat/vB (fee / vsize), None if fee is unavailable or vsize is zero + */feeRate: Double?) { + self.txid = txid + self.received = received + self.sent = sent + self.net = net + self.amount = amount + self.fee = fee + self.direction = direction + self.blockHeight = blockHeight + self.timestamp = timestamp + self.confirmations = confirmations self.inputs = inputs self.outputs = outputs + self.size = size + self.vsize = vsize + self.weight = weight + self.feeRate = feeRate } } #if compiler(>=6) -extension TrezorPrevTx: Sendable {} +extension TransactionDetail: Sendable {} #endif -extension TrezorPrevTx: Equatable, Hashable { - public static func ==(lhs: TrezorPrevTx, rhs: TrezorPrevTx) -> Bool { - if lhs.hash != rhs.hash { +extension TransactionDetail: Equatable, Hashable { + public static func ==(lhs: TransactionDetail, rhs: TransactionDetail) -> Bool { + if lhs.txid != rhs.txid { return false } - if lhs.version != rhs.version { + if lhs.received != rhs.received { return false } - if lhs.lockTime != rhs.lockTime { + if lhs.sent != rhs.sent { + return false + } + if lhs.net != rhs.net { + return false + } + if lhs.amount != rhs.amount { + return false + } + if lhs.fee != rhs.fee { + return false + } + if lhs.direction != rhs.direction { + return false + } + if lhs.blockHeight != rhs.blockHeight { + return false + } + if lhs.timestamp != rhs.timestamp { + return false + } + if lhs.confirmations != rhs.confirmations { return false } if lhs.inputs != rhs.inputs { @@ -12229,158 +12276,221 @@ extension TrezorPrevTx: Equatable, Hashable { if lhs.outputs != rhs.outputs { return false } + if lhs.size != rhs.size { + return false + } + if lhs.vsize != rhs.vsize { + return false + } + if lhs.weight != rhs.weight { + return false + } + if lhs.feeRate != rhs.feeRate { + return false + } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(hash) - hasher.combine(version) - hasher.combine(lockTime) + hasher.combine(txid) + hasher.combine(received) + hasher.combine(sent) + hasher.combine(net) + hasher.combine(amount) + hasher.combine(fee) + hasher.combine(direction) + hasher.combine(blockHeight) + hasher.combine(timestamp) + hasher.combine(confirmations) hasher.combine(inputs) hasher.combine(outputs) + hasher.combine(size) + hasher.combine(vsize) + hasher.combine(weight) + hasher.combine(feeRate) } } -extension TrezorPrevTx: Codable {} +extension TransactionDetail: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorPrevTx: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPrevTx { +public struct FfiConverterTypeTransactionDetail: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionDetail { return - try TrezorPrevTx( - hash: FfiConverterString.read(from: &buf), - version: FfiConverterUInt32.read(from: &buf), - lockTime: FfiConverterUInt32.read(from: &buf), - inputs: FfiConverterSequenceTypeTrezorPrevTxInput.read(from: &buf), - outputs: FfiConverterSequenceTypeTrezorPrevTxOutput.read(from: &buf) - ) - } - - public static func write(_ value: TrezorPrevTx, into buf: inout [UInt8]) { - FfiConverterString.write(value.hash, into: &buf) - FfiConverterUInt32.write(value.version, into: &buf) - FfiConverterUInt32.write(value.lockTime, into: &buf) - FfiConverterSequenceTypeTrezorPrevTxInput.write(value.inputs, into: &buf) - FfiConverterSequenceTypeTrezorPrevTxOutput.write(value.outputs, into: &buf) - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeTrezorPrevTx_lift(_ buf: RustBuffer) throws -> TrezorPrevTx { - return try FfiConverterTypeTrezorPrevTx.lift(buf) + try TransactionDetail( + txid: FfiConverterString.read(from: &buf), + received: FfiConverterUInt64.read(from: &buf), + sent: FfiConverterUInt64.read(from: &buf), + net: FfiConverterInt64.read(from: &buf), + amount: FfiConverterUInt64.read(from: &buf), + fee: FfiConverterOptionUInt64.read(from: &buf), + direction: FfiConverterTypeTxDirection.read(from: &buf), + blockHeight: FfiConverterOptionUInt32.read(from: &buf), + timestamp: FfiConverterOptionUInt64.read(from: &buf), + confirmations: FfiConverterUInt32.read(from: &buf), + inputs: FfiConverterSequenceTypeTxDetailInput.read(from: &buf), + outputs: FfiConverterSequenceTypeTxDetailOutput.read(from: &buf), + size: FfiConverterUInt32.read(from: &buf), + vsize: FfiConverterUInt32.read(from: &buf), + weight: FfiConverterUInt32.read(from: &buf), + feeRate: FfiConverterOptionDouble.read(from: &buf) + ) + } + + public static func write(_ value: TransactionDetail, into buf: inout [UInt8]) { + FfiConverterString.write(value.txid, into: &buf) + FfiConverterUInt64.write(value.received, into: &buf) + FfiConverterUInt64.write(value.sent, into: &buf) + FfiConverterInt64.write(value.net, into: &buf) + FfiConverterUInt64.write(value.amount, into: &buf) + FfiConverterOptionUInt64.write(value.fee, into: &buf) + FfiConverterTypeTxDirection.write(value.direction, into: &buf) + FfiConverterOptionUInt32.write(value.blockHeight, into: &buf) + FfiConverterOptionUInt64.write(value.timestamp, into: &buf) + FfiConverterUInt32.write(value.confirmations, into: &buf) + FfiConverterSequenceTypeTxDetailInput.write(value.inputs, into: &buf) + FfiConverterSequenceTypeTxDetailOutput.write(value.outputs, into: &buf) + FfiConverterUInt32.write(value.size, into: &buf) + FfiConverterUInt32.write(value.vsize, into: &buf) + FfiConverterUInt32.write(value.weight, into: &buf) + FfiConverterOptionDouble.write(value.feeRate, into: &buf) + } } + #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorPrevTx_lower(_ value: TrezorPrevTx) -> RustBuffer { - return FfiConverterTypeTrezorPrevTx.lower(value) +public func FfiConverterTypeTransactionDetail_lift(_ buf: RustBuffer) throws -> TransactionDetail { + return try FfiConverterTypeTransactionDetail.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionDetail_lower(_ value: TransactionDetail) -> RustBuffer { + return FfiConverterTypeTransactionDetail.lower(value) } /** - * Input of a previous transaction. + * Details about an onchain transaction. */ -public struct TrezorPrevTxInput { +public struct TransactionDetails { + public var walletId: String /** - * Previous transaction hash (hex encoded) + * The transaction ID. */ - public var prevHash: String + public var txId: String /** - * Previous output index + * The net amount in this transaction (in satoshis). + * + * This is calculated as: (received - sent). For incoming payments, + * this will be positive. For outgoing payments, this will be negative. + * + * Note: This amount does NOT include transaction fees. */ - public var prevIndex: UInt32 + public var amountSats: Int64 /** - * Script signature (hex encoded) + * The transaction inputs with full details. */ - public var scriptSig: String + public var inputs: [TxInput] /** - * Sequence number + * The transaction outputs with full details. */ - public var sequence: UInt32 + public var outputs: [TxOutput] // Default memberwise initializers are never public by default, so we // declare one manually. - public init( + public init(walletId: String, /** - * Previous transaction hash (hex encoded) - */prevHash: String, + * The transaction ID. + */txId: String, /** - * Previous output index - */prevIndex: UInt32, + * The net amount in this transaction (in satoshis). + * + * This is calculated as: (received - sent). For incoming payments, + * this will be positive. For outgoing payments, this will be negative. + * + * Note: This amount does NOT include transaction fees. + */amountSats: Int64, /** - * Script signature (hex encoded) - */scriptSig: String, + * The transaction inputs with full details. + */inputs: [TxInput], /** - * Sequence number - */sequence: UInt32) { - self.prevHash = prevHash - self.prevIndex = prevIndex - self.scriptSig = scriptSig - self.sequence = sequence + * The transaction outputs with full details. + */outputs: [TxOutput]) { + self.walletId = walletId + self.txId = txId + self.amountSats = amountSats + self.inputs = inputs + self.outputs = outputs } } #if compiler(>=6) -extension TrezorPrevTxInput: Sendable {} +extension TransactionDetails: Sendable {} #endif -extension TrezorPrevTxInput: Equatable, Hashable { - public static func ==(lhs: TrezorPrevTxInput, rhs: TrezorPrevTxInput) -> Bool { - if lhs.prevHash != rhs.prevHash { +extension TransactionDetails: Equatable, Hashable { + public static func ==(lhs: TransactionDetails, rhs: TransactionDetails) -> Bool { + if lhs.walletId != rhs.walletId { return false } - if lhs.prevIndex != rhs.prevIndex { + if lhs.txId != rhs.txId { return false } - if lhs.scriptSig != rhs.scriptSig { + if lhs.amountSats != rhs.amountSats { return false } - if lhs.sequence != rhs.sequence { + if lhs.inputs != rhs.inputs { + return false + } + if lhs.outputs != rhs.outputs { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(prevHash) - hasher.combine(prevIndex) - hasher.combine(scriptSig) - hasher.combine(sequence) + hasher.combine(walletId) + hasher.combine(txId) + hasher.combine(amountSats) + hasher.combine(inputs) + hasher.combine(outputs) } } -extension TrezorPrevTxInput: Codable {} +extension TransactionDetails: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorPrevTxInput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPrevTxInput { +public struct FfiConverterTypeTransactionDetails: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionDetails { return - try TrezorPrevTxInput( - prevHash: FfiConverterString.read(from: &buf), - prevIndex: FfiConverterUInt32.read(from: &buf), - scriptSig: FfiConverterString.read(from: &buf), - sequence: FfiConverterUInt32.read(from: &buf) + try TransactionDetails( + walletId: FfiConverterString.read(from: &buf), + txId: FfiConverterString.read(from: &buf), + amountSats: FfiConverterInt64.read(from: &buf), + inputs: FfiConverterSequenceTypeTxInput.read(from: &buf), + outputs: FfiConverterSequenceTypeTxOutput.read(from: &buf) ) } - public static func write(_ value: TrezorPrevTxInput, into buf: inout [UInt8]) { - FfiConverterString.write(value.prevHash, into: &buf) - FfiConverterUInt32.write(value.prevIndex, into: &buf) - FfiConverterString.write(value.scriptSig, into: &buf) - FfiConverterUInt32.write(value.sequence, into: &buf) + public static func write(_ value: TransactionDetails, into buf: inout [UInt8]) { + FfiConverterString.write(value.walletId, into: &buf) + FfiConverterString.write(value.txId, into: &buf) + FfiConverterInt64.write(value.amountSats, into: &buf) + FfiConverterSequenceTypeTxInput.write(value.inputs, into: &buf) + FfiConverterSequenceTypeTxOutput.write(value.outputs, into: &buf) } } @@ -12388,86 +12498,128 @@ public struct FfiConverterTypeTrezorPrevTxInput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorPrevTxInput_lift(_ buf: RustBuffer) throws -> TrezorPrevTxInput { - return try FfiConverterTypeTrezorPrevTxInput.lift(buf) +public func FfiConverterTypeTransactionDetails_lift(_ buf: RustBuffer) throws -> TransactionDetails { + return try FfiConverterTypeTransactionDetails.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorPrevTxInput_lower(_ value: TrezorPrevTxInput) -> RustBuffer { - return FfiConverterTypeTrezorPrevTxInput.lower(value) +public func FfiConverterTypeTransactionDetails_lower(_ value: TransactionDetails) -> RustBuffer { + return FfiConverterTypeTransactionDetails.lower(value) } /** - * Output of a previous transaction. + * Result from querying transaction history for an xpub. */ -public struct TrezorPrevTxOutput { +public struct TransactionHistoryResult { /** - * Amount in satoshis + * All transactions, sorted: unconfirmed first, then by timestamp descending */ - public var amount: UInt64 + public var transactions: [HistoryTransaction] /** - * Script pubkey (hex encoded) + * Balance breakdown */ - public var scriptPubkey: String + public var balance: WalletBalance + /** + * Total number of transactions + */ + public var txCount: UInt32 + /** + * Current blockchain tip height + */ + public var blockHeight: UInt32 + /** + * The detected or specified account type + */ + public var accountType: AccountType // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Amount in satoshis - */amount: UInt64, + * All transactions, sorted: unconfirmed first, then by timestamp descending + */transactions: [HistoryTransaction], /** - * Script pubkey (hex encoded) - */scriptPubkey: String) { - self.amount = amount - self.scriptPubkey = scriptPubkey + * Balance breakdown + */balance: WalletBalance, + /** + * Total number of transactions + */txCount: UInt32, + /** + * Current blockchain tip height + */blockHeight: UInt32, + /** + * The detected or specified account type + */accountType: AccountType) { + self.transactions = transactions + self.balance = balance + self.txCount = txCount + self.blockHeight = blockHeight + self.accountType = accountType } } #if compiler(>=6) -extension TrezorPrevTxOutput: Sendable {} +extension TransactionHistoryResult: Sendable {} #endif -extension TrezorPrevTxOutput: Equatable, Hashable { - public static func ==(lhs: TrezorPrevTxOutput, rhs: TrezorPrevTxOutput) -> Bool { - if lhs.amount != rhs.amount { +extension TransactionHistoryResult: Equatable, Hashable { + public static func ==(lhs: TransactionHistoryResult, rhs: TransactionHistoryResult) -> Bool { + if lhs.transactions != rhs.transactions { return false } - if lhs.scriptPubkey != rhs.scriptPubkey { + if lhs.balance != rhs.balance { + return false + } + if lhs.txCount != rhs.txCount { + return false + } + if lhs.blockHeight != rhs.blockHeight { + return false + } + if lhs.accountType != rhs.accountType { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(amount) - hasher.combine(scriptPubkey) + hasher.combine(transactions) + hasher.combine(balance) + hasher.combine(txCount) + hasher.combine(blockHeight) + hasher.combine(accountType) } } -extension TrezorPrevTxOutput: Codable {} +extension TransactionHistoryResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorPrevTxOutput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPrevTxOutput { +public struct FfiConverterTypeTransactionHistoryResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionHistoryResult { return - try TrezorPrevTxOutput( - amount: FfiConverterUInt64.read(from: &buf), - scriptPubkey: FfiConverterString.read(from: &buf) - ) + try TransactionHistoryResult( + transactions: FfiConverterSequenceTypeHistoryTransaction.read(from: &buf), + balance: FfiConverterTypeWalletBalance.read(from: &buf), + txCount: FfiConverterUInt32.read(from: &buf), + blockHeight: FfiConverterUInt32.read(from: &buf), + accountType: FfiConverterTypeAccountType.read(from: &buf) + ) } - public static func write(_ value: TrezorPrevTxOutput, into buf: inout [UInt8]) { - FfiConverterUInt64.write(value.amount, into: &buf) - FfiConverterString.write(value.scriptPubkey, into: &buf) + public static func write(_ value: TransactionHistoryResult, into buf: inout [UInt8]) { + FfiConverterSequenceTypeHistoryTransaction.write(value.transactions, into: &buf) + FfiConverterTypeWalletBalance.write(value.balance, into: &buf) + FfiConverterUInt32.write(value.txCount, into: &buf) + FfiConverterUInt32.write(value.blockHeight, into: &buf) + FfiConverterTypeAccountType.write(value.accountType, into: &buf) } } @@ -12475,156 +12627,86 @@ public struct FfiConverterTypeTrezorPrevTxOutput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorPrevTxOutput_lift(_ buf: RustBuffer) throws -> TrezorPrevTxOutput { - return try FfiConverterTypeTrezorPrevTxOutput.lift(buf) +public func FfiConverterTypeTransactionHistoryResult_lift(_ buf: RustBuffer) throws -> TransactionHistoryResult { + return try FfiConverterTypeTransactionHistoryResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorPrevTxOutput_lower(_ value: TrezorPrevTxOutput) -> RustBuffer { - return FfiConverterTypeTrezorPrevTxOutput.lower(value) +public func FfiConverterTypeTransactionHistoryResult_lower(_ value: TransactionHistoryResult) -> RustBuffer { + return FfiConverterTypeTransactionHistoryResult.lower(value) } /** - * Public key response from device. + * Address response from device. */ -public struct TrezorPublicKeyResponse { +public struct TrezorAddressResponse { /** - * Extended public key (xpub) + * The Bitcoin address */ - public var xpub: String + public var address: String /** - * The serialized path (e.g., "m/84'/0'/0'") + * The serialized path (e.g., "m/84'/0'/0'/0/0") */ public var path: String - /** - * Compressed public key (hex encoded) - */ - public var publicKey: String - /** - * Chain code (hex encoded) - */ - public var chainCode: String - /** - * Parent key fingerprint - */ - public var fingerprint: UInt32 - /** - * Derivation depth - */ - public var depth: UInt32 - /** - * Master root fingerprint (from the device's master seed) - */ - public var rootFingerprint: UInt32? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Extended public key (xpub) - */xpub: String, - /** - * The serialized path (e.g., "m/84'/0'/0'") - */path: String, - /** - * Compressed public key (hex encoded) - */publicKey: String, - /** - * Chain code (hex encoded) - */chainCode: String, - /** - * Parent key fingerprint - */fingerprint: UInt32, - /** - * Derivation depth - */depth: UInt32, + * The Bitcoin address + */address: String, /** - * Master root fingerprint (from the device's master seed) - */rootFingerprint: UInt32?) { - self.xpub = xpub + * The serialized path (e.g., "m/84'/0'/0'/0/0") + */path: String) { + self.address = address self.path = path - self.publicKey = publicKey - self.chainCode = chainCode - self.fingerprint = fingerprint - self.depth = depth - self.rootFingerprint = rootFingerprint } } #if compiler(>=6) -extension TrezorPublicKeyResponse: Sendable {} +extension TrezorAddressResponse: Sendable {} #endif -extension TrezorPublicKeyResponse: Equatable, Hashable { - public static func ==(lhs: TrezorPublicKeyResponse, rhs: TrezorPublicKeyResponse) -> Bool { - if lhs.xpub != rhs.xpub { +extension TrezorAddressResponse: Equatable, Hashable { + public static func ==(lhs: TrezorAddressResponse, rhs: TrezorAddressResponse) -> Bool { + if lhs.address != rhs.address { return false } if lhs.path != rhs.path { return false } - if lhs.publicKey != rhs.publicKey { - return false - } - if lhs.chainCode != rhs.chainCode { - return false - } - if lhs.fingerprint != rhs.fingerprint { - return false - } - if lhs.depth != rhs.depth { - return false - } - if lhs.rootFingerprint != rhs.rootFingerprint { - return false - } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(xpub) + hasher.combine(address) hasher.combine(path) - hasher.combine(publicKey) - hasher.combine(chainCode) - hasher.combine(fingerprint) - hasher.combine(depth) - hasher.combine(rootFingerprint) } } -extension TrezorPublicKeyResponse: Codable {} +extension TrezorAddressResponse: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorPublicKeyResponse: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPublicKeyResponse { +public struct FfiConverterTypeTrezorAddressResponse: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorAddressResponse { return - try TrezorPublicKeyResponse( - xpub: FfiConverterString.read(from: &buf), - path: FfiConverterString.read(from: &buf), - publicKey: FfiConverterString.read(from: &buf), - chainCode: FfiConverterString.read(from: &buf), - fingerprint: FfiConverterUInt32.read(from: &buf), - depth: FfiConverterUInt32.read(from: &buf), - rootFingerprint: FfiConverterOptionUInt32.read(from: &buf) + try TrezorAddressResponse( + address: FfiConverterString.read(from: &buf), + path: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: TrezorPublicKeyResponse, into buf: inout [UInt8]) { - FfiConverterString.write(value.xpub, into: &buf) + public static func write(_ value: TrezorAddressResponse, into buf: inout [UInt8]) { + FfiConverterString.write(value.address, into: &buf) FfiConverterString.write(value.path, into: &buf) - FfiConverterString.write(value.publicKey, into: &buf) - FfiConverterString.write(value.chainCode, into: &buf) - FfiConverterUInt32.write(value.fingerprint, into: &buf) - FfiConverterUInt32.write(value.depth, into: &buf) - FfiConverterOptionUInt32.write(value.rootFingerprint, into: &buf) } } @@ -12632,100 +12714,128 @@ public struct FfiConverterTypeTrezorPublicKeyResponse: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorPublicKeyResponse_lift(_ buf: RustBuffer) throws -> TrezorPublicKeyResponse { - return try FfiConverterTypeTrezorPublicKeyResponse.lift(buf) +public func FfiConverterTypeTrezorAddressResponse_lift(_ buf: RustBuffer) throws -> TrezorAddressResponse { + return try FfiConverterTypeTrezorAddressResponse.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorPublicKeyResponse_lower(_ value: TrezorPublicKeyResponse) -> RustBuffer { - return FfiConverterTypeTrezorPublicKeyResponse.lower(value) +public func FfiConverterTypeTrezorAddressResponse_lower(_ value: TrezorAddressResponse) -> RustBuffer { + return FfiConverterTypeTrezorAddressResponse.lower(value) } /** - * Parameters for signing a message. + * Result from a high-level message call (for BLE/THP devices) */ -public struct TrezorSignMessageParams { +public struct TrezorCallMessageResult { /** - * BIP32 path for the signing key (e.g., "m/84'/0'/0'/0/0") + * Whether the call succeeded */ - public var path: String + public var success: Bool /** - * Message to sign + * Response message type */ - public var message: String + public var messageType: UInt16 /** - * Coin network (default: Bitcoin) + * Response protobuf data */ - public var coin: TrezorCoinType? + public var data: Data + /** + * Error message (empty on success) + */ + public var error: String + /** + * Structured error code (None on success or when the native error is generic) + */ + public var errorCode: TrezorTransportErrorCode? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * BIP32 path for the signing key (e.g., "m/84'/0'/0'/0/0") - */path: String, + * Whether the call succeeded + */success: Bool, /** - * Message to sign - */message: String, + * Response message type + */messageType: UInt16, /** - * Coin network (default: Bitcoin) - */coin: TrezorCoinType?) { - self.path = path - self.message = message - self.coin = coin + * Response protobuf data + */data: Data, + /** + * Error message (empty on success) + */error: String, + /** + * Structured error code (None on success or when the native error is generic) + */errorCode: TrezorTransportErrorCode?) { + self.success = success + self.messageType = messageType + self.data = data + self.error = error + self.errorCode = errorCode } } #if compiler(>=6) -extension TrezorSignMessageParams: Sendable {} +extension TrezorCallMessageResult: Sendable {} #endif -extension TrezorSignMessageParams: Equatable, Hashable { - public static func ==(lhs: TrezorSignMessageParams, rhs: TrezorSignMessageParams) -> Bool { - if lhs.path != rhs.path { +extension TrezorCallMessageResult: Equatable, Hashable { + public static func ==(lhs: TrezorCallMessageResult, rhs: TrezorCallMessageResult) -> Bool { + if lhs.success != rhs.success { return false } - if lhs.message != rhs.message { + if lhs.messageType != rhs.messageType { return false } - if lhs.coin != rhs.coin { + if lhs.data != rhs.data { + return false + } + if lhs.error != rhs.error { + return false + } + if lhs.errorCode != rhs.errorCode { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(path) - hasher.combine(message) - hasher.combine(coin) + hasher.combine(success) + hasher.combine(messageType) + hasher.combine(data) + hasher.combine(error) + hasher.combine(errorCode) } } -extension TrezorSignMessageParams: Codable {} +extension TrezorCallMessageResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorSignMessageParams: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignMessageParams { +public struct FfiConverterTypeTrezorCallMessageResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorCallMessageResult { return - try TrezorSignMessageParams( - path: FfiConverterString.read(from: &buf), - message: FfiConverterString.read(from: &buf), - coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf) + try TrezorCallMessageResult( + success: FfiConverterBool.read(from: &buf), + messageType: FfiConverterUInt16.read(from: &buf), + data: FfiConverterData.read(from: &buf), + error: FfiConverterString.read(from: &buf), + errorCode: FfiConverterOptionTypeTrezorTransportErrorCode.read(from: &buf) ) } - public static func write(_ value: TrezorSignMessageParams, into buf: inout [UInt8]) { - FfiConverterString.write(value.path, into: &buf) - FfiConverterString.write(value.message, into: &buf) - FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) + public static func write(_ value: TrezorCallMessageResult, into buf: inout [UInt8]) { + FfiConverterBool.write(value.success, into: &buf) + FfiConverterUInt16.write(value.messageType, into: &buf) + FfiConverterData.write(value.data, into: &buf) + FfiConverterString.write(value.error, into: &buf) + FfiConverterOptionTypeTrezorTransportErrorCode.write(value.errorCode, into: &buf) } } @@ -12733,142 +12843,156 @@ public struct FfiConverterTypeTrezorSignMessageParams: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorSignMessageParams_lift(_ buf: RustBuffer) throws -> TrezorSignMessageParams { - return try FfiConverterTypeTrezorSignMessageParams.lift(buf) +public func FfiConverterTypeTrezorCallMessageResult_lift(_ buf: RustBuffer) throws -> TrezorCallMessageResult { + return try FfiConverterTypeTrezorCallMessageResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorSignMessageParams_lower(_ value: TrezorSignMessageParams) -> RustBuffer { - return FfiConverterTypeTrezorSignMessageParams.lower(value) +public func FfiConverterTypeTrezorCallMessageResult_lower(_ value: TrezorCallMessageResult) -> RustBuffer { + return FfiConverterTypeTrezorCallMessageResult.lower(value) } /** - * Parameters for signing a transaction. + * Device information exposed to FFI. */ -public struct TrezorSignTxParams { +public struct TrezorDeviceInfo { /** - * Transaction inputs + * Unique identifier for the device */ - public var inputs: [TrezorTxInput] + public var id: String /** - * Transaction outputs + * Transport type (USB or Bluetooth) */ - public var outputs: [TrezorTxOutput] + public var transportType: TrezorTransportType /** - * Coin network (default: Bitcoin) + * Device name (from BLE advertisement or USB descriptor) */ - public var coin: TrezorCoinType? + public var name: String? /** - * Lock time (default: 0) + * Transport-specific path (used internally for connection) */ - public var lockTime: UInt32? + public var path: String /** - * Version (default: 2) + * Device label (set by user during device setup) */ - public var version: UInt32? + public var label: String? /** - * Previous transactions (for non-SegWit input verification) + * Device model (e.g., "T2", "Safe 5", "Safe 7") */ - public var prevTxs: [TrezorPrevTx] + public var model: String? + /** + * Whether the device is in bootloader mode + */ + public var isBootloader: Bool // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Transaction inputs - */inputs: [TrezorTxInput], + * Unique identifier for the device + */id: String, /** - * Transaction outputs - */outputs: [TrezorTxOutput], + * Transport type (USB or Bluetooth) + */transportType: TrezorTransportType, /** - * Coin network (default: Bitcoin) - */coin: TrezorCoinType?, + * Device name (from BLE advertisement or USB descriptor) + */name: String?, /** - * Lock time (default: 0) - */lockTime: UInt32?, + * Transport-specific path (used internally for connection) + */path: String, /** - * Version (default: 2) - */version: UInt32?, + * Device label (set by user during device setup) + */label: String?, /** - * Previous transactions (for non-SegWit input verification) - */prevTxs: [TrezorPrevTx]) { - self.inputs = inputs - self.outputs = outputs - self.coin = coin - self.lockTime = lockTime - self.version = version - self.prevTxs = prevTxs + * Device model (e.g., "T2", "Safe 5", "Safe 7") + */model: String?, + /** + * Whether the device is in bootloader mode + */isBootloader: Bool) { + self.id = id + self.transportType = transportType + self.name = name + self.path = path + self.label = label + self.model = model + self.isBootloader = isBootloader } } #if compiler(>=6) -extension TrezorSignTxParams: Sendable {} +extension TrezorDeviceInfo: Sendable {} #endif -extension TrezorSignTxParams: Equatable, Hashable { - public static func ==(lhs: TrezorSignTxParams, rhs: TrezorSignTxParams) -> Bool { - if lhs.inputs != rhs.inputs { +extension TrezorDeviceInfo: Equatable, Hashable { + public static func ==(lhs: TrezorDeviceInfo, rhs: TrezorDeviceInfo) -> Bool { + if lhs.id != rhs.id { return false } - if lhs.outputs != rhs.outputs { + if lhs.transportType != rhs.transportType { return false } - if lhs.coin != rhs.coin { + if lhs.name != rhs.name { return false } - if lhs.lockTime != rhs.lockTime { + if lhs.path != rhs.path { return false } - if lhs.version != rhs.version { + if lhs.label != rhs.label { return false } - if lhs.prevTxs != rhs.prevTxs { + if lhs.model != rhs.model { + return false + } + if lhs.isBootloader != rhs.isBootloader { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(inputs) - hasher.combine(outputs) - hasher.combine(coin) - hasher.combine(lockTime) - hasher.combine(version) - hasher.combine(prevTxs) + hasher.combine(id) + hasher.combine(transportType) + hasher.combine(name) + hasher.combine(path) + hasher.combine(label) + hasher.combine(model) + hasher.combine(isBootloader) } } -extension TrezorSignTxParams: Codable {} +extension TrezorDeviceInfo: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorSignTxParams: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignTxParams { +public struct FfiConverterTypeTrezorDeviceInfo: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorDeviceInfo { return - try TrezorSignTxParams( - inputs: FfiConverterSequenceTypeTrezorTxInput.read(from: &buf), - outputs: FfiConverterSequenceTypeTrezorTxOutput.read(from: &buf), - coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf), - lockTime: FfiConverterOptionUInt32.read(from: &buf), - version: FfiConverterOptionUInt32.read(from: &buf), - prevTxs: FfiConverterSequenceTypeTrezorPrevTx.read(from: &buf) + try TrezorDeviceInfo( + id: FfiConverterString.read(from: &buf), + transportType: FfiConverterTypeTrezorTransportType.read(from: &buf), + name: FfiConverterOptionString.read(from: &buf), + path: FfiConverterString.read(from: &buf), + label: FfiConverterOptionString.read(from: &buf), + model: FfiConverterOptionString.read(from: &buf), + isBootloader: FfiConverterBool.read(from: &buf) ) } - public static func write(_ value: TrezorSignTxParams, into buf: inout [UInt8]) { - FfiConverterSequenceTypeTrezorTxInput.write(value.inputs, into: &buf) - FfiConverterSequenceTypeTrezorTxOutput.write(value.outputs, into: &buf) - FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) - FfiConverterOptionUInt32.write(value.lockTime, into: &buf) - FfiConverterOptionUInt32.write(value.version, into: &buf) - FfiConverterSequenceTypeTrezorPrevTx.write(value.prevTxs, into: &buf) + public static func write(_ value: TrezorDeviceInfo, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterTypeTrezorTransportType.write(value.transportType, into: &buf) + FfiConverterOptionString.write(value.name, into: &buf) + FfiConverterString.write(value.path, into: &buf) + FfiConverterOptionString.write(value.label, into: &buf) + FfiConverterOptionString.write(value.model, into: &buf) + FfiConverterBool.write(value.isBootloader, into: &buf) } } @@ -12876,187 +13000,246 @@ public struct FfiConverterTypeTrezorSignTxParams: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorSignTxParams_lift(_ buf: RustBuffer) throws -> TrezorSignTxParams { - return try FfiConverterTypeTrezorSignTxParams.lift(buf) +public func FfiConverterTypeTrezorDeviceInfo_lift(_ buf: RustBuffer) throws -> TrezorDeviceInfo { + return try FfiConverterTypeTrezorDeviceInfo.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorSignTxParams_lower(_ value: TrezorSignTxParams) -> RustBuffer { - return FfiConverterTypeTrezorSignTxParams.lower(value) +public func FfiConverterTypeTrezorDeviceInfo_lower(_ value: TrezorDeviceInfo) -> RustBuffer { + return FfiConverterTypeTrezorDeviceInfo.lower(value) } /** - * Response from signing a message. + * Device features after initialization. */ -public struct TrezorSignedMessageResponse { +public struct TrezorFeatures { /** - * Bitcoin address that signed the message + * Vendor string */ - public var address: String + public var vendor: String? /** - * Signature (base64 encoded) + * Device model */ - public var signature: String - - // Default memberwise initializers are never public by default, so we - // declare one manually. - public init( - /** - * Bitcoin address that signed the message - */address: String, - /** - * Signature (base64 encoded) - */signature: String) { - self.address = address - self.signature = signature - } -} - -#if compiler(>=6) -extension TrezorSignedMessageResponse: Sendable {} -#endif - - -extension TrezorSignedMessageResponse: Equatable, Hashable { - public static func ==(lhs: TrezorSignedMessageResponse, rhs: TrezorSignedMessageResponse) -> Bool { - if lhs.address != rhs.address { - return false - } - if lhs.signature != rhs.signature { - return false - } - return true - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(address) - hasher.combine(signature) - } -} - -extension TrezorSignedMessageResponse: Codable {} - - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public struct FfiConverterTypeTrezorSignedMessageResponse: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignedMessageResponse { - return - try TrezorSignedMessageResponse( - address: FfiConverterString.read(from: &buf), - signature: FfiConverterString.read(from: &buf) - ) - } - - public static func write(_ value: TrezorSignedMessageResponse, into buf: inout [UInt8]) { - FfiConverterString.write(value.address, into: &buf) - FfiConverterString.write(value.signature, into: &buf) - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeTrezorSignedMessageResponse_lift(_ buf: RustBuffer) throws -> TrezorSignedMessageResponse { - return try FfiConverterTypeTrezorSignedMessageResponse.lift(buf) -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeTrezorSignedMessageResponse_lower(_ value: TrezorSignedMessageResponse) -> RustBuffer { - return FfiConverterTypeTrezorSignedMessageResponse.lower(value) -} - - -/** - * Signed transaction result. - */ -public struct TrezorSignedTx { + public var model: String? /** - * Signatures for each input (hex encoded) + * Device label (set by user during device setup) */ - public var signatures: [String] + public var label: String? /** - * Serialized transaction (hex) + * Device ID (unique per device) */ - public var serializedTx: String + public var deviceId: String? /** - * Broadcast transaction ID (populated when push=true) + * Major firmware version */ - public var txid: String? - - // Default memberwise initializers are never public by default, so we + public var majorVersion: UInt32? + /** + * Minor firmware version + */ + public var minorVersion: UInt32? + /** + * Patch firmware version + */ + public var patchVersion: UInt32? + /** + * Whether PIN protection is enabled + */ + public var pinProtection: Bool? + /** + * Whether the device is currently unlocked. When PIN protection is enabled + * and this is `Some(false)`, mobile callers should back off and ask the + * user to unlock the Trezor instead of repeatedly reconnecting. + */ + public var unlocked: Bool? + /** + * Whether passphrase protection is enabled + */ + public var passphraseProtection: Bool? + /** + * Whether the device is initialized with a seed + */ + public var initialized: Bool? + /** + * Whether the device needs backup + */ + public var needsBackup: Bool? + /** + * Whether the device can accept passphrase entry on the device itself + * (`Capability_PassphraseEntry`). When false/None, use host entry only. + */ + public var passphraseEntryCapable: Bool? + + // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Signatures for each input (hex encoded) - */signatures: [String], + * Vendor string + */vendor: String?, /** - * Serialized transaction (hex) - */serializedTx: String, + * Device model + */model: String?, /** - * Broadcast transaction ID (populated when push=true) - */txid: String?) { - self.signatures = signatures - self.serializedTx = serializedTx - self.txid = txid + * Device label (set by user during device setup) + */label: String?, + /** + * Device ID (unique per device) + */deviceId: String?, + /** + * Major firmware version + */majorVersion: UInt32?, + /** + * Minor firmware version + */minorVersion: UInt32?, + /** + * Patch firmware version + */patchVersion: UInt32?, + /** + * Whether PIN protection is enabled + */pinProtection: Bool?, + /** + * Whether the device is currently unlocked. When PIN protection is enabled + * and this is `Some(false)`, mobile callers should back off and ask the + * user to unlock the Trezor instead of repeatedly reconnecting. + */unlocked: Bool?, + /** + * Whether passphrase protection is enabled + */passphraseProtection: Bool?, + /** + * Whether the device is initialized with a seed + */initialized: Bool?, + /** + * Whether the device needs backup + */needsBackup: Bool?, + /** + * Whether the device can accept passphrase entry on the device itself + * (`Capability_PassphraseEntry`). When false/None, use host entry only. + */passphraseEntryCapable: Bool?) { + self.vendor = vendor + self.model = model + self.label = label + self.deviceId = deviceId + self.majorVersion = majorVersion + self.minorVersion = minorVersion + self.patchVersion = patchVersion + self.pinProtection = pinProtection + self.unlocked = unlocked + self.passphraseProtection = passphraseProtection + self.initialized = initialized + self.needsBackup = needsBackup + self.passphraseEntryCapable = passphraseEntryCapable } } #if compiler(>=6) -extension TrezorSignedTx: Sendable {} +extension TrezorFeatures: Sendable {} #endif -extension TrezorSignedTx: Equatable, Hashable { - public static func ==(lhs: TrezorSignedTx, rhs: TrezorSignedTx) -> Bool { - if lhs.signatures != rhs.signatures { +extension TrezorFeatures: Equatable, Hashable { + public static func ==(lhs: TrezorFeatures, rhs: TrezorFeatures) -> Bool { + if lhs.vendor != rhs.vendor { return false } - if lhs.serializedTx != rhs.serializedTx { + if lhs.model != rhs.model { return false } - if lhs.txid != rhs.txid { + if lhs.label != rhs.label { + return false + } + if lhs.deviceId != rhs.deviceId { + return false + } + if lhs.majorVersion != rhs.majorVersion { + return false + } + if lhs.minorVersion != rhs.minorVersion { + return false + } + if lhs.patchVersion != rhs.patchVersion { + return false + } + if lhs.pinProtection != rhs.pinProtection { + return false + } + if lhs.unlocked != rhs.unlocked { + return false + } + if lhs.passphraseProtection != rhs.passphraseProtection { + return false + } + if lhs.initialized != rhs.initialized { + return false + } + if lhs.needsBackup != rhs.needsBackup { + return false + } + if lhs.passphraseEntryCapable != rhs.passphraseEntryCapable { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(signatures) - hasher.combine(serializedTx) - hasher.combine(txid) + hasher.combine(vendor) + hasher.combine(model) + hasher.combine(label) + hasher.combine(deviceId) + hasher.combine(majorVersion) + hasher.combine(minorVersion) + hasher.combine(patchVersion) + hasher.combine(pinProtection) + hasher.combine(unlocked) + hasher.combine(passphraseProtection) + hasher.combine(initialized) + hasher.combine(needsBackup) + hasher.combine(passphraseEntryCapable) } } -extension TrezorSignedTx: Codable {} +extension TrezorFeatures: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorSignedTx: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignedTx { +public struct FfiConverterTypeTrezorFeatures: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorFeatures { return - try TrezorSignedTx( - signatures: FfiConverterSequenceString.read(from: &buf), - serializedTx: FfiConverterString.read(from: &buf), - txid: FfiConverterOptionString.read(from: &buf) + try TrezorFeatures( + vendor: FfiConverterOptionString.read(from: &buf), + model: FfiConverterOptionString.read(from: &buf), + label: FfiConverterOptionString.read(from: &buf), + deviceId: FfiConverterOptionString.read(from: &buf), + majorVersion: FfiConverterOptionUInt32.read(from: &buf), + minorVersion: FfiConverterOptionUInt32.read(from: &buf), + patchVersion: FfiConverterOptionUInt32.read(from: &buf), + pinProtection: FfiConverterOptionBool.read(from: &buf), + unlocked: FfiConverterOptionBool.read(from: &buf), + passphraseProtection: FfiConverterOptionBool.read(from: &buf), + initialized: FfiConverterOptionBool.read(from: &buf), + needsBackup: FfiConverterOptionBool.read(from: &buf), + passphraseEntryCapable: FfiConverterOptionBool.read(from: &buf) ) } - public static func write(_ value: TrezorSignedTx, into buf: inout [UInt8]) { - FfiConverterSequenceString.write(value.signatures, into: &buf) - FfiConverterString.write(value.serializedTx, into: &buf) - FfiConverterOptionString.write(value.txid, into: &buf) + public static func write(_ value: TrezorFeatures, into buf: inout [UInt8]) { + FfiConverterOptionString.write(value.vendor, into: &buf) + FfiConverterOptionString.write(value.model, into: &buf) + FfiConverterOptionString.write(value.label, into: &buf) + FfiConverterOptionString.write(value.deviceId, into: &buf) + FfiConverterOptionUInt32.write(value.majorVersion, into: &buf) + FfiConverterOptionUInt32.write(value.minorVersion, into: &buf) + FfiConverterOptionUInt32.write(value.patchVersion, into: &buf) + FfiConverterOptionBool.write(value.pinProtection, into: &buf) + FfiConverterOptionBool.write(value.unlocked, into: &buf) + FfiConverterOptionBool.write(value.passphraseProtection, into: &buf) + FfiConverterOptionBool.write(value.initialized, into: &buf) + FfiConverterOptionBool.write(value.needsBackup, into: &buf) + FfiConverterOptionBool.write(value.passphraseEntryCapable, into: &buf) } } @@ -13064,114 +13247,114 @@ public struct FfiConverterTypeTrezorSignedTx: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorSignedTx_lift(_ buf: RustBuffer) throws -> TrezorSignedTx { - return try FfiConverterTypeTrezorSignedTx.lift(buf) +public func FfiConverterTypeTrezorFeatures_lift(_ buf: RustBuffer) throws -> TrezorFeatures { + return try FfiConverterTypeTrezorFeatures.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorSignedTx_lower(_ value: TrezorSignedTx) -> RustBuffer { - return FfiConverterTypeTrezorSignedTx.lower(value) +public func FfiConverterTypeTrezorFeatures_lower(_ value: TrezorFeatures) -> RustBuffer { + return FfiConverterTypeTrezorFeatures.lower(value) } /** - * Result from a transport read operation + * Parameters for getting an address from the device. */ -public struct TrezorTransportReadResult { +public struct TrezorGetAddressParams { /** - * Whether the read succeeded + * BIP32 path (e.g., "m/84'/0'/0'/0/0") */ - public var success: Bool + public var path: String /** - * Data read (empty on failure) + * Coin network (default: Bitcoin) */ - public var data: Data + public var coin: TrezorCoinType? /** - * Error message (empty on success) + * Whether to display the address on the device for confirmation */ - public var error: String + public var showOnTrezor: Bool /** - * Structured error code (None on success or when the native error is generic) + * Script type (auto-detected from path if not specified) */ - public var errorCode: TrezorTransportErrorCode? + public var scriptType: TrezorScriptType? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Whether the read succeeded - */success: Bool, + * BIP32 path (e.g., "m/84'/0'/0'/0/0") + */path: String, /** - * Data read (empty on failure) - */data: Data, + * Coin network (default: Bitcoin) + */coin: TrezorCoinType?, /** - * Error message (empty on success) - */error: String, + * Whether to display the address on the device for confirmation + */showOnTrezor: Bool, /** - * Structured error code (None on success or when the native error is generic) - */errorCode: TrezorTransportErrorCode?) { - self.success = success - self.data = data - self.error = error - self.errorCode = errorCode + * Script type (auto-detected from path if not specified) + */scriptType: TrezorScriptType?) { + self.path = path + self.coin = coin + self.showOnTrezor = showOnTrezor + self.scriptType = scriptType } } #if compiler(>=6) -extension TrezorTransportReadResult: Sendable {} +extension TrezorGetAddressParams: Sendable {} #endif -extension TrezorTransportReadResult: Equatable, Hashable { - public static func ==(lhs: TrezorTransportReadResult, rhs: TrezorTransportReadResult) -> Bool { - if lhs.success != rhs.success { +extension TrezorGetAddressParams: Equatable, Hashable { + public static func ==(lhs: TrezorGetAddressParams, rhs: TrezorGetAddressParams) -> Bool { + if lhs.path != rhs.path { return false } - if lhs.data != rhs.data { + if lhs.coin != rhs.coin { return false } - if lhs.error != rhs.error { + if lhs.showOnTrezor != rhs.showOnTrezor { return false } - if lhs.errorCode != rhs.errorCode { + if lhs.scriptType != rhs.scriptType { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(success) - hasher.combine(data) - hasher.combine(error) - hasher.combine(errorCode) + hasher.combine(path) + hasher.combine(coin) + hasher.combine(showOnTrezor) + hasher.combine(scriptType) } } -extension TrezorTransportReadResult: Codable {} +extension TrezorGetAddressParams: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorTransportReadResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTransportReadResult { +public struct FfiConverterTypeTrezorGetAddressParams: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorGetAddressParams { return - try TrezorTransportReadResult( - success: FfiConverterBool.read(from: &buf), - data: FfiConverterData.read(from: &buf), - error: FfiConverterString.read(from: &buf), - errorCode: FfiConverterOptionTypeTrezorTransportErrorCode.read(from: &buf) + try TrezorGetAddressParams( + path: FfiConverterString.read(from: &buf), + coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf), + showOnTrezor: FfiConverterBool.read(from: &buf), + scriptType: FfiConverterOptionTypeTrezorScriptType.read(from: &buf) ) } - public static func write(_ value: TrezorTransportReadResult, into buf: inout [UInt8]) { - FfiConverterBool.write(value.success, into: &buf) - FfiConverterData.write(value.data, into: &buf) - FfiConverterString.write(value.error, into: &buf) - FfiConverterOptionTypeTrezorTransportErrorCode.write(value.errorCode, into: &buf) + public static func write(_ value: TrezorGetAddressParams, into buf: inout [UInt8]) { + FfiConverterString.write(value.path, into: &buf) + FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) + FfiConverterBool.write(value.showOnTrezor, into: &buf) + FfiConverterOptionTypeTrezorScriptType.write(value.scriptType, into: &buf) } } @@ -13179,100 +13362,100 @@ public struct FfiConverterTypeTrezorTransportReadResult: FfiConverterRustBuffer #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTransportReadResult_lift(_ buf: RustBuffer) throws -> TrezorTransportReadResult { - return try FfiConverterTypeTrezorTransportReadResult.lift(buf) +public func FfiConverterTypeTrezorGetAddressParams_lift(_ buf: RustBuffer) throws -> TrezorGetAddressParams { + return try FfiConverterTypeTrezorGetAddressParams.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTransportReadResult_lower(_ value: TrezorTransportReadResult) -> RustBuffer { - return FfiConverterTypeTrezorTransportReadResult.lower(value) +public func FfiConverterTypeTrezorGetAddressParams_lower(_ value: TrezorGetAddressParams) -> RustBuffer { + return FfiConverterTypeTrezorGetAddressParams.lower(value) } /** - * Result from a transport write or open operation + * Parameters for getting a public key from the device. */ -public struct TrezorTransportWriteResult { +public struct TrezorGetPublicKeyParams { /** - * Whether the operation succeeded + * BIP32 path (e.g., "m/84'/0'/0'") */ - public var success: Bool + public var path: String /** - * Error message (empty on success) + * Coin network (default: Bitcoin) */ - public var error: String + public var coin: TrezorCoinType? /** - * Structured error code (None on success or when the native error is generic) + * Whether to display on device for confirmation */ - public var errorCode: TrezorTransportErrorCode? + public var showOnTrezor: Bool // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Whether the operation succeeded - */success: Bool, + * BIP32 path (e.g., "m/84'/0'/0'") + */path: String, /** - * Error message (empty on success) - */error: String, + * Coin network (default: Bitcoin) + */coin: TrezorCoinType?, /** - * Structured error code (None on success or when the native error is generic) - */errorCode: TrezorTransportErrorCode?) { - self.success = success - self.error = error - self.errorCode = errorCode + * Whether to display on device for confirmation + */showOnTrezor: Bool) { + self.path = path + self.coin = coin + self.showOnTrezor = showOnTrezor } } #if compiler(>=6) -extension TrezorTransportWriteResult: Sendable {} +extension TrezorGetPublicKeyParams: Sendable {} #endif -extension TrezorTransportWriteResult: Equatable, Hashable { - public static func ==(lhs: TrezorTransportWriteResult, rhs: TrezorTransportWriteResult) -> Bool { - if lhs.success != rhs.success { +extension TrezorGetPublicKeyParams: Equatable, Hashable { + public static func ==(lhs: TrezorGetPublicKeyParams, rhs: TrezorGetPublicKeyParams) -> Bool { + if lhs.path != rhs.path { return false } - if lhs.error != rhs.error { + if lhs.coin != rhs.coin { return false } - if lhs.errorCode != rhs.errorCode { + if lhs.showOnTrezor != rhs.showOnTrezor { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(success) - hasher.combine(error) - hasher.combine(errorCode) + hasher.combine(path) + hasher.combine(coin) + hasher.combine(showOnTrezor) } } -extension TrezorTransportWriteResult: Codable {} +extension TrezorGetPublicKeyParams: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorTransportWriteResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTransportWriteResult { +public struct FfiConverterTypeTrezorGetPublicKeyParams: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorGetPublicKeyParams { return - try TrezorTransportWriteResult( - success: FfiConverterBool.read(from: &buf), - error: FfiConverterString.read(from: &buf), - errorCode: FfiConverterOptionTypeTrezorTransportErrorCode.read(from: &buf) + try TrezorGetPublicKeyParams( + path: FfiConverterString.read(from: &buf), + coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf), + showOnTrezor: FfiConverterBool.read(from: &buf) ) } - public static func write(_ value: TrezorTransportWriteResult, into buf: inout [UInt8]) { - FfiConverterBool.write(value.success, into: &buf) - FfiConverterString.write(value.error, into: &buf) - FfiConverterOptionTypeTrezorTransportErrorCode.write(value.errorCode, into: &buf) + public static func write(_ value: TrezorGetPublicKeyParams, into buf: inout [UInt8]) { + FfiConverterString.write(value.path, into: &buf) + FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) + FfiConverterBool.write(value.showOnTrezor, into: &buf) } } @@ -13280,170 +13463,128 @@ public struct FfiConverterTypeTrezorTransportWriteResult: FfiConverterRustBuffer #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTransportWriteResult_lift(_ buf: RustBuffer) throws -> TrezorTransportWriteResult { - return try FfiConverterTypeTrezorTransportWriteResult.lift(buf) +public func FfiConverterTypeTrezorGetPublicKeyParams_lift(_ buf: RustBuffer) throws -> TrezorGetPublicKeyParams { + return try FfiConverterTypeTrezorGetPublicKeyParams.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTransportWriteResult_lower(_ value: TrezorTransportWriteResult) -> RustBuffer { - return FfiConverterTypeTrezorTransportWriteResult.lower(value) +public func FfiConverterTypeTrezorGetPublicKeyParams_lower(_ value: TrezorGetPublicKeyParams) -> RustBuffer { + return FfiConverterTypeTrezorGetPublicKeyParams.lower(value) } /** - * Transaction input for signing. + * Previous transaction data (for non-SegWit input verification). */ -public struct TrezorTxInput { - /** - * Previous transaction hash (hex, 32 bytes) - */ - public var prevHash: String - /** - * Previous output index - */ - public var prevIndex: UInt32 - /** - * BIP32 derivation path (e.g., "m/84'/0'/0'/0/0") - */ - public var path: String +public struct TrezorPrevTx { /** - * Amount in satoshis + * Transaction hash (hex encoded) */ - public var amount: UInt64 + public var hash: String /** - * Script type + * Transaction version */ - public var scriptType: TrezorScriptType + public var version: UInt32 /** - * Sequence number (default: 0xFFFFFFFD for RBF) + * Lock time */ - public var sequence: UInt32? + public var lockTime: UInt32 /** - * Original transaction hash for RBF replacement (hex encoded) + * Transaction inputs */ - public var origHash: String? + public var inputs: [TrezorPrevTxInput] /** - * Original input index for RBF replacement + * Transaction outputs */ - public var origIndex: UInt32? + public var outputs: [TrezorPrevTxOutput] // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Previous transaction hash (hex, 32 bytes) - */prevHash: String, - /** - * Previous output index - */prevIndex: UInt32, - /** - * BIP32 derivation path (e.g., "m/84'/0'/0'/0/0") - */path: String, - /** - * Amount in satoshis - */amount: UInt64, + * Transaction hash (hex encoded) + */hash: String, /** - * Script type - */scriptType: TrezorScriptType, + * Transaction version + */version: UInt32, /** - * Sequence number (default: 0xFFFFFFFD for RBF) - */sequence: UInt32?, + * Lock time + */lockTime: UInt32, /** - * Original transaction hash for RBF replacement (hex encoded) - */origHash: String?, + * Transaction inputs + */inputs: [TrezorPrevTxInput], /** - * Original input index for RBF replacement - */origIndex: UInt32?) { - self.prevHash = prevHash - self.prevIndex = prevIndex - self.path = path - self.amount = amount - self.scriptType = scriptType - self.sequence = sequence - self.origHash = origHash - self.origIndex = origIndex + * Transaction outputs + */outputs: [TrezorPrevTxOutput]) { + self.hash = hash + self.version = version + self.lockTime = lockTime + self.inputs = inputs + self.outputs = outputs } } #if compiler(>=6) -extension TrezorTxInput: Sendable {} +extension TrezorPrevTx: Sendable {} #endif -extension TrezorTxInput: Equatable, Hashable { - public static func ==(lhs: TrezorTxInput, rhs: TrezorTxInput) -> Bool { - if lhs.prevHash != rhs.prevHash { - return false - } - if lhs.prevIndex != rhs.prevIndex { - return false - } - if lhs.path != rhs.path { - return false - } - if lhs.amount != rhs.amount { +extension TrezorPrevTx: Equatable, Hashable { + public static func ==(lhs: TrezorPrevTx, rhs: TrezorPrevTx) -> Bool { + if lhs.hash != rhs.hash { return false } - if lhs.scriptType != rhs.scriptType { + if lhs.version != rhs.version { return false } - if lhs.sequence != rhs.sequence { + if lhs.lockTime != rhs.lockTime { return false } - if lhs.origHash != rhs.origHash { + if lhs.inputs != rhs.inputs { return false } - if lhs.origIndex != rhs.origIndex { + if lhs.outputs != rhs.outputs { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(prevHash) - hasher.combine(prevIndex) - hasher.combine(path) - hasher.combine(amount) - hasher.combine(scriptType) - hasher.combine(sequence) - hasher.combine(origHash) - hasher.combine(origIndex) + hasher.combine(hash) + hasher.combine(version) + hasher.combine(lockTime) + hasher.combine(inputs) + hasher.combine(outputs) } } -extension TrezorTxInput: Codable {} +extension TrezorPrevTx: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorTxInput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTxInput { +public struct FfiConverterTypeTrezorPrevTx: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPrevTx { return - try TrezorTxInput( - prevHash: FfiConverterString.read(from: &buf), - prevIndex: FfiConverterUInt32.read(from: &buf), - path: FfiConverterString.read(from: &buf), - amount: FfiConverterUInt64.read(from: &buf), - scriptType: FfiConverterTypeTrezorScriptType.read(from: &buf), - sequence: FfiConverterOptionUInt32.read(from: &buf), - origHash: FfiConverterOptionString.read(from: &buf), - origIndex: FfiConverterOptionUInt32.read(from: &buf) + try TrezorPrevTx( + hash: FfiConverterString.read(from: &buf), + version: FfiConverterUInt32.read(from: &buf), + lockTime: FfiConverterUInt32.read(from: &buf), + inputs: FfiConverterSequenceTypeTrezorPrevTxInput.read(from: &buf), + outputs: FfiConverterSequenceTypeTrezorPrevTxOutput.read(from: &buf) ) } - public static func write(_ value: TrezorTxInput, into buf: inout [UInt8]) { - FfiConverterString.write(value.prevHash, into: &buf) - FfiConverterUInt32.write(value.prevIndex, into: &buf) - FfiConverterString.write(value.path, into: &buf) - FfiConverterUInt64.write(value.amount, into: &buf) - FfiConverterTypeTrezorScriptType.write(value.scriptType, into: &buf) - FfiConverterOptionUInt32.write(value.sequence, into: &buf) - FfiConverterOptionString.write(value.origHash, into: &buf) - FfiConverterOptionUInt32.write(value.origIndex, into: &buf) + public static func write(_ value: TrezorPrevTx, into buf: inout [UInt8]) { + FfiConverterString.write(value.hash, into: &buf) + FfiConverterUInt32.write(value.version, into: &buf) + FfiConverterUInt32.write(value.lockTime, into: &buf) + FfiConverterSequenceTypeTrezorPrevTxInput.write(value.inputs, into: &buf) + FfiConverterSequenceTypeTrezorPrevTxOutput.write(value.outputs, into: &buf) } } @@ -13451,156 +13592,114 @@ public struct FfiConverterTypeTrezorTxInput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTxInput_lift(_ buf: RustBuffer) throws -> TrezorTxInput { - return try FfiConverterTypeTrezorTxInput.lift(buf) +public func FfiConverterTypeTrezorPrevTx_lift(_ buf: RustBuffer) throws -> TrezorPrevTx { + return try FfiConverterTypeTrezorPrevTx.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTxInput_lower(_ value: TrezorTxInput) -> RustBuffer { - return FfiConverterTypeTrezorTxInput.lower(value) +public func FfiConverterTypeTrezorPrevTx_lower(_ value: TrezorPrevTx) -> RustBuffer { + return FfiConverterTypeTrezorPrevTx.lower(value) } /** - * Transaction output for signing. + * Input of a previous transaction. */ -public struct TrezorTxOutput { - /** - * Destination address (for external outputs) - */ - public var address: String? - /** - * BIP32 path (for change outputs) - */ - public var path: String? - /** - * Amount in satoshis - */ - public var amount: UInt64 +public struct TrezorPrevTxInput { /** - * Script type (for change outputs) + * Previous transaction hash (hex encoded) */ - public var scriptType: TrezorScriptType? + public var prevHash: String /** - * OP_RETURN data (hex encoded, for data outputs) + * Previous output index */ - public var opReturnData: String? + public var prevIndex: UInt32 /** - * Original transaction hash for RBF replacement (hex encoded) + * Script signature (hex encoded) */ - public var origHash: String? + public var scriptSig: String /** - * Original output index for RBF replacement + * Sequence number */ - public var origIndex: UInt32? + public var sequence: UInt32 // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Destination address (for external outputs) - */address: String?, - /** - * BIP32 path (for change outputs) - */path: String?, - /** - * Amount in satoshis - */amount: UInt64, - /** - * Script type (for change outputs) - */scriptType: TrezorScriptType?, + * Previous transaction hash (hex encoded) + */prevHash: String, /** - * OP_RETURN data (hex encoded, for data outputs) - */opReturnData: String?, + * Previous output index + */prevIndex: UInt32, /** - * Original transaction hash for RBF replacement (hex encoded) - */origHash: String?, + * Script signature (hex encoded) + */scriptSig: String, /** - * Original output index for RBF replacement - */origIndex: UInt32?) { - self.address = address - self.path = path - self.amount = amount - self.scriptType = scriptType - self.opReturnData = opReturnData - self.origHash = origHash - self.origIndex = origIndex + * Sequence number + */sequence: UInt32) { + self.prevHash = prevHash + self.prevIndex = prevIndex + self.scriptSig = scriptSig + self.sequence = sequence } } #if compiler(>=6) -extension TrezorTxOutput: Sendable {} +extension TrezorPrevTxInput: Sendable {} #endif -extension TrezorTxOutput: Equatable, Hashable { - public static func ==(lhs: TrezorTxOutput, rhs: TrezorTxOutput) -> Bool { - if lhs.address != rhs.address { - return false - } - if lhs.path != rhs.path { - return false - } - if lhs.amount != rhs.amount { - return false - } - if lhs.scriptType != rhs.scriptType { +extension TrezorPrevTxInput: Equatable, Hashable { + public static func ==(lhs: TrezorPrevTxInput, rhs: TrezorPrevTxInput) -> Bool { + if lhs.prevHash != rhs.prevHash { return false } - if lhs.opReturnData != rhs.opReturnData { + if lhs.prevIndex != rhs.prevIndex { return false } - if lhs.origHash != rhs.origHash { + if lhs.scriptSig != rhs.scriptSig { return false } - if lhs.origIndex != rhs.origIndex { + if lhs.sequence != rhs.sequence { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(address) - hasher.combine(path) - hasher.combine(amount) - hasher.combine(scriptType) - hasher.combine(opReturnData) - hasher.combine(origHash) - hasher.combine(origIndex) + hasher.combine(prevHash) + hasher.combine(prevIndex) + hasher.combine(scriptSig) + hasher.combine(sequence) } } -extension TrezorTxOutput: Codable {} +extension TrezorPrevTxInput: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorTxOutput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTxOutput { +public struct FfiConverterTypeTrezorPrevTxInput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPrevTxInput { return - try TrezorTxOutput( - address: FfiConverterOptionString.read(from: &buf), - path: FfiConverterOptionString.read(from: &buf), - amount: FfiConverterUInt64.read(from: &buf), - scriptType: FfiConverterOptionTypeTrezorScriptType.read(from: &buf), - opReturnData: FfiConverterOptionString.read(from: &buf), - origHash: FfiConverterOptionString.read(from: &buf), - origIndex: FfiConverterOptionUInt32.read(from: &buf) + try TrezorPrevTxInput( + prevHash: FfiConverterString.read(from: &buf), + prevIndex: FfiConverterUInt32.read(from: &buf), + scriptSig: FfiConverterString.read(from: &buf), + sequence: FfiConverterUInt32.read(from: &buf) ) } - public static func write(_ value: TrezorTxOutput, into buf: inout [UInt8]) { - FfiConverterOptionString.write(value.address, into: &buf) - FfiConverterOptionString.write(value.path, into: &buf) - FfiConverterUInt64.write(value.amount, into: &buf) - FfiConverterOptionTypeTrezorScriptType.write(value.scriptType, into: &buf) - FfiConverterOptionString.write(value.opReturnData, into: &buf) - FfiConverterOptionString.write(value.origHash, into: &buf) - FfiConverterOptionUInt32.write(value.origIndex, into: &buf) + public static func write(_ value: TrezorPrevTxInput, into buf: inout [UInt8]) { + FfiConverterString.write(value.prevHash, into: &buf) + FfiConverterUInt32.write(value.prevIndex, into: &buf) + FfiConverterString.write(value.scriptSig, into: &buf) + FfiConverterUInt32.write(value.sequence, into: &buf) } } @@ -13608,114 +13707,86 @@ public struct FfiConverterTypeTrezorTxOutput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTxOutput_lift(_ buf: RustBuffer) throws -> TrezorTxOutput { - return try FfiConverterTypeTrezorTxOutput.lift(buf) +public func FfiConverterTypeTrezorPrevTxInput_lift(_ buf: RustBuffer) throws -> TrezorPrevTxInput { + return try FfiConverterTypeTrezorPrevTxInput.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorTxOutput_lower(_ value: TrezorTxOutput) -> RustBuffer { - return FfiConverterTypeTrezorTxOutput.lower(value) +public func FfiConverterTypeTrezorPrevTxInput_lower(_ value: TrezorPrevTxInput) -> RustBuffer { + return FfiConverterTypeTrezorPrevTxInput.lower(value) } /** - * Parameters for verifying a message signature. + * Output of a previous transaction. */ -public struct TrezorVerifyMessageParams { - /** - * Bitcoin address that signed the message - */ - public var address: String - /** - * Signature (base64 encoded) - */ - public var signature: String +public struct TrezorPrevTxOutput { /** - * Original message + * Amount in satoshis */ - public var message: String + public var amount: UInt64 /** - * Coin network (default: Bitcoin) + * Script pubkey (hex encoded) */ - public var coin: TrezorCoinType? + public var scriptPubkey: String // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Bitcoin address that signed the message - */address: String, - /** - * Signature (base64 encoded) - */signature: String, - /** - * Original message - */message: String, + * Amount in satoshis + */amount: UInt64, /** - * Coin network (default: Bitcoin) - */coin: TrezorCoinType?) { - self.address = address - self.signature = signature - self.message = message - self.coin = coin + * Script pubkey (hex encoded) + */scriptPubkey: String) { + self.amount = amount + self.scriptPubkey = scriptPubkey } } #if compiler(>=6) -extension TrezorVerifyMessageParams: Sendable {} +extension TrezorPrevTxOutput: Sendable {} #endif -extension TrezorVerifyMessageParams: Equatable, Hashable { - public static func ==(lhs: TrezorVerifyMessageParams, rhs: TrezorVerifyMessageParams) -> Bool { - if lhs.address != rhs.address { - return false - } - if lhs.signature != rhs.signature { - return false - } - if lhs.message != rhs.message { +extension TrezorPrevTxOutput: Equatable, Hashable { + public static func ==(lhs: TrezorPrevTxOutput, rhs: TrezorPrevTxOutput) -> Bool { + if lhs.amount != rhs.amount { return false } - if lhs.coin != rhs.coin { + if lhs.scriptPubkey != rhs.scriptPubkey { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(address) - hasher.combine(signature) - hasher.combine(message) - hasher.combine(coin) + hasher.combine(amount) + hasher.combine(scriptPubkey) } } -extension TrezorVerifyMessageParams: Codable {} +extension TrezorPrevTxOutput: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTrezorVerifyMessageParams: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorVerifyMessageParams { +public struct FfiConverterTypeTrezorPrevTxOutput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPrevTxOutput { return - try TrezorVerifyMessageParams( - address: FfiConverterString.read(from: &buf), - signature: FfiConverterString.read(from: &buf), - message: FfiConverterString.read(from: &buf), - coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf) + try TrezorPrevTxOutput( + amount: FfiConverterUInt64.read(from: &buf), + scriptPubkey: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: TrezorVerifyMessageParams, into buf: inout [UInt8]) { - FfiConverterString.write(value.address, into: &buf) - FfiConverterString.write(value.signature, into: &buf) - FfiConverterString.write(value.message, into: &buf) - FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) + public static func write(_ value: TrezorPrevTxOutput, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.amount, into: &buf) + FfiConverterString.write(value.scriptPubkey, into: &buf) } } @@ -13723,128 +13794,156 @@ public struct FfiConverterTypeTrezorVerifyMessageParams: FfiConverterRustBuffer #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorVerifyMessageParams_lift(_ buf: RustBuffer) throws -> TrezorVerifyMessageParams { - return try FfiConverterTypeTrezorVerifyMessageParams.lift(buf) +public func FfiConverterTypeTrezorPrevTxOutput_lift(_ buf: RustBuffer) throws -> TrezorPrevTxOutput { + return try FfiConverterTypeTrezorPrevTxOutput.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTrezorVerifyMessageParams_lower(_ value: TrezorVerifyMessageParams) -> RustBuffer { - return FfiConverterTypeTrezorVerifyMessageParams.lower(value) +public func FfiConverterTypeTrezorPrevTxOutput_lower(_ value: TrezorPrevTxOutput) -> RustBuffer { + return FfiConverterTypeTrezorPrevTxOutput.lower(value) } /** - * A transaction input with full details. + * Public key response from device. */ -public struct TxDetailInput { +public struct TrezorPublicKeyResponse { /** - * Previous output transaction ID (hex) + * Extended public key (xpub) */ - public var txid: String + public var xpub: String /** - * Previous output index + * The serialized path (e.g., "m/84'/0'/0'") */ - public var vout: UInt32 + public var path: String /** - * Sequence number + * Compressed public key (hex encoded) */ - public var sequence: UInt32 + public var publicKey: String /** - * Script signature (hex-encoded) + * Chain code (hex encoded) */ - public var scriptSig: String + public var chainCode: String /** - * Witness stack (each element hex-encoded) + * Parent key fingerprint */ - public var witness: [String] + public var fingerprint: UInt32 + /** + * Derivation depth + */ + public var depth: UInt32 + /** + * Master root fingerprint (from the device's master seed) + */ + public var rootFingerprint: UInt32? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Previous output transaction ID (hex) - */txid: String, + * Extended public key (xpub) + */xpub: String, /** - * Previous output index - */vout: UInt32, + * The serialized path (e.g., "m/84'/0'/0'") + */path: String, /** - * Sequence number - */sequence: UInt32, + * Compressed public key (hex encoded) + */publicKey: String, /** - * Script signature (hex-encoded) - */scriptSig: String, + * Chain code (hex encoded) + */chainCode: String, /** - * Witness stack (each element hex-encoded) - */witness: [String]) { - self.txid = txid - self.vout = vout - self.sequence = sequence - self.scriptSig = scriptSig - self.witness = witness + * Parent key fingerprint + */fingerprint: UInt32, + /** + * Derivation depth + */depth: UInt32, + /** + * Master root fingerprint (from the device's master seed) + */rootFingerprint: UInt32?) { + self.xpub = xpub + self.path = path + self.publicKey = publicKey + self.chainCode = chainCode + self.fingerprint = fingerprint + self.depth = depth + self.rootFingerprint = rootFingerprint } } #if compiler(>=6) -extension TxDetailInput: Sendable {} +extension TrezorPublicKeyResponse: Sendable {} #endif -extension TxDetailInput: Equatable, Hashable { - public static func ==(lhs: TxDetailInput, rhs: TxDetailInput) -> Bool { - if lhs.txid != rhs.txid { +extension TrezorPublicKeyResponse: Equatable, Hashable { + public static func ==(lhs: TrezorPublicKeyResponse, rhs: TrezorPublicKeyResponse) -> Bool { + if lhs.xpub != rhs.xpub { return false } - if lhs.vout != rhs.vout { + if lhs.path != rhs.path { return false } - if lhs.sequence != rhs.sequence { + if lhs.publicKey != rhs.publicKey { return false } - if lhs.scriptSig != rhs.scriptSig { + if lhs.chainCode != rhs.chainCode { return false } - if lhs.witness != rhs.witness { + if lhs.fingerprint != rhs.fingerprint { + return false + } + if lhs.depth != rhs.depth { + return false + } + if lhs.rootFingerprint != rhs.rootFingerprint { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(txid) - hasher.combine(vout) - hasher.combine(sequence) - hasher.combine(scriptSig) - hasher.combine(witness) + hasher.combine(xpub) + hasher.combine(path) + hasher.combine(publicKey) + hasher.combine(chainCode) + hasher.combine(fingerprint) + hasher.combine(depth) + hasher.combine(rootFingerprint) } } -extension TxDetailInput: Codable {} +extension TrezorPublicKeyResponse: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTxDetailInput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxDetailInput { +public struct FfiConverterTypeTrezorPublicKeyResponse: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorPublicKeyResponse { return - try TxDetailInput( - txid: FfiConverterString.read(from: &buf), - vout: FfiConverterUInt32.read(from: &buf), - sequence: FfiConverterUInt32.read(from: &buf), - scriptSig: FfiConverterString.read(from: &buf), - witness: FfiConverterSequenceString.read(from: &buf) + try TrezorPublicKeyResponse( + xpub: FfiConverterString.read(from: &buf), + path: FfiConverterString.read(from: &buf), + publicKey: FfiConverterString.read(from: &buf), + chainCode: FfiConverterString.read(from: &buf), + fingerprint: FfiConverterUInt32.read(from: &buf), + depth: FfiConverterUInt32.read(from: &buf), + rootFingerprint: FfiConverterOptionUInt32.read(from: &buf) ) } - public static func write(_ value: TxDetailInput, into buf: inout [UInt8]) { - FfiConverterString.write(value.txid, into: &buf) - FfiConverterUInt32.write(value.vout, into: &buf) - FfiConverterUInt32.write(value.sequence, into: &buf) - FfiConverterString.write(value.scriptSig, into: &buf) - FfiConverterSequenceString.write(value.witness, into: &buf) + public static func write(_ value: TrezorPublicKeyResponse, into buf: inout [UInt8]) { + FfiConverterString.write(value.xpub, into: &buf) + FfiConverterString.write(value.path, into: &buf) + FfiConverterString.write(value.publicKey, into: &buf) + FfiConverterString.write(value.chainCode, into: &buf) + FfiConverterUInt32.write(value.fingerprint, into: &buf) + FfiConverterUInt32.write(value.depth, into: &buf) + FfiConverterOptionUInt32.write(value.rootFingerprint, into: &buf) } } @@ -13852,114 +13951,100 @@ public struct FfiConverterTypeTxDetailInput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxDetailInput_lift(_ buf: RustBuffer) throws -> TxDetailInput { - return try FfiConverterTypeTxDetailInput.lift(buf) +public func FfiConverterTypeTrezorPublicKeyResponse_lift(_ buf: RustBuffer) throws -> TrezorPublicKeyResponse { + return try FfiConverterTypeTrezorPublicKeyResponse.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxDetailInput_lower(_ value: TxDetailInput) -> RustBuffer { - return FfiConverterTypeTxDetailInput.lower(value) +public func FfiConverterTypeTrezorPublicKeyResponse_lower(_ value: TrezorPublicKeyResponse) -> RustBuffer { + return FfiConverterTypeTrezorPublicKeyResponse.lower(value) } /** - * A transaction output with full details. + * Parameters for signing a message. */ -public struct TxDetailOutput { - /** - * Output value in sats - */ - public var value: UInt64 +public struct TrezorSignMessageParams { /** - * Script public key (hex-encoded) + * BIP32 path for the signing key (e.g., "m/84'/0'/0'/0/0") */ - public var scriptPubkey: String + public var path: String /** - * Decoded address (None if script is not decodable to an address) + * Message to sign */ - public var address: String? + public var message: String /** - * Whether this output belongs to the queried wallet + * Coin network (default: Bitcoin) */ - public var isMine: Bool + public var coin: TrezorCoinType? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Output value in sats - */value: UInt64, - /** - * Script public key (hex-encoded) - */scriptPubkey: String, + * BIP32 path for the signing key (e.g., "m/84'/0'/0'/0/0") + */path: String, /** - * Decoded address (None if script is not decodable to an address) - */address: String?, + * Message to sign + */message: String, /** - * Whether this output belongs to the queried wallet - */isMine: Bool) { - self.value = value - self.scriptPubkey = scriptPubkey - self.address = address - self.isMine = isMine + * Coin network (default: Bitcoin) + */coin: TrezorCoinType?) { + self.path = path + self.message = message + self.coin = coin } } #if compiler(>=6) -extension TxDetailOutput: Sendable {} +extension TrezorSignMessageParams: Sendable {} #endif -extension TxDetailOutput: Equatable, Hashable { - public static func ==(lhs: TxDetailOutput, rhs: TxDetailOutput) -> Bool { - if lhs.value != rhs.value { - return false - } - if lhs.scriptPubkey != rhs.scriptPubkey { +extension TrezorSignMessageParams: Equatable, Hashable { + public static func ==(lhs: TrezorSignMessageParams, rhs: TrezorSignMessageParams) -> Bool { + if lhs.path != rhs.path { return false } - if lhs.address != rhs.address { + if lhs.message != rhs.message { return false } - if lhs.isMine != rhs.isMine { + if lhs.coin != rhs.coin { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(value) - hasher.combine(scriptPubkey) - hasher.combine(address) - hasher.combine(isMine) + hasher.combine(path) + hasher.combine(message) + hasher.combine(coin) } } -extension TxDetailOutput: Codable {} +extension TrezorSignMessageParams: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTxDetailOutput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxDetailOutput { +public struct FfiConverterTypeTrezorSignMessageParams: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignMessageParams { return - try TxDetailOutput( - value: FfiConverterUInt64.read(from: &buf), - scriptPubkey: FfiConverterString.read(from: &buf), - address: FfiConverterOptionString.read(from: &buf), - isMine: FfiConverterBool.read(from: &buf) + try TrezorSignMessageParams( + path: FfiConverterString.read(from: &buf), + message: FfiConverterString.read(from: &buf), + coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf) ) } - public static func write(_ value: TxDetailOutput, into buf: inout [UInt8]) { - FfiConverterUInt64.write(value.value, into: &buf) - FfiConverterString.write(value.scriptPubkey, into: &buf) - FfiConverterOptionString.write(value.address, into: &buf) - FfiConverterBool.write(value.isMine, into: &buf) + public static func write(_ value: TrezorSignMessageParams, into buf: inout [UInt8]) { + FfiConverterString.write(value.path, into: &buf) + FfiConverterString.write(value.message, into: &buf) + FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) } } @@ -13967,128 +14052,142 @@ public struct FfiConverterTypeTxDetailOutput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxDetailOutput_lift(_ buf: RustBuffer) throws -> TxDetailOutput { - return try FfiConverterTypeTxDetailOutput.lift(buf) +public func FfiConverterTypeTrezorSignMessageParams_lift(_ buf: RustBuffer) throws -> TrezorSignMessageParams { + return try FfiConverterTypeTrezorSignMessageParams.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxDetailOutput_lower(_ value: TxDetailOutput) -> RustBuffer { - return FfiConverterTypeTxDetailOutput.lower(value) -} +public func FfiConverterTypeTrezorSignMessageParams_lower(_ value: TrezorSignMessageParams) -> RustBuffer { + return FfiConverterTypeTrezorSignMessageParams.lower(value) +} /** - * Details about a transaction input. + * Parameters for signing a transaction. */ -public struct TxInput { +public struct TrezorSignTxParams { /** - * The transaction ID of the previous output being spent. + * Transaction inputs */ - public var txid: String + public var inputs: [TrezorTxInput] /** - * The output index of the previous output being spent. + * Transaction outputs */ - public var vout: UInt32 + public var outputs: [TrezorTxOutput] /** - * The script signature (hex-encoded). + * Coin network (default: Bitcoin) */ - public var scriptsig: String + public var coin: TrezorCoinType? /** - * The witness stack (hex-encoded strings). + * Lock time (default: 0) */ - public var witness: [String] + public var lockTime: UInt32? /** - * The sequence number. + * Version (default: 2) */ - public var sequence: UInt32 + public var version: UInt32? + /** + * Previous transactions (for non-SegWit input verification) + */ + public var prevTxs: [TrezorPrevTx] // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * The transaction ID of the previous output being spent. - */txid: String, + * Transaction inputs + */inputs: [TrezorTxInput], /** - * The output index of the previous output being spent. - */vout: UInt32, + * Transaction outputs + */outputs: [TrezorTxOutput], /** - * The script signature (hex-encoded). - */scriptsig: String, + * Coin network (default: Bitcoin) + */coin: TrezorCoinType?, /** - * The witness stack (hex-encoded strings). - */witness: [String], + * Lock time (default: 0) + */lockTime: UInt32?, /** - * The sequence number. - */sequence: UInt32) { - self.txid = txid - self.vout = vout - self.scriptsig = scriptsig - self.witness = witness - self.sequence = sequence + * Version (default: 2) + */version: UInt32?, + /** + * Previous transactions (for non-SegWit input verification) + */prevTxs: [TrezorPrevTx]) { + self.inputs = inputs + self.outputs = outputs + self.coin = coin + self.lockTime = lockTime + self.version = version + self.prevTxs = prevTxs } } #if compiler(>=6) -extension TxInput: Sendable {} +extension TrezorSignTxParams: Sendable {} #endif -extension TxInput: Equatable, Hashable { - public static func ==(lhs: TxInput, rhs: TxInput) -> Bool { - if lhs.txid != rhs.txid { +extension TrezorSignTxParams: Equatable, Hashable { + public static func ==(lhs: TrezorSignTxParams, rhs: TrezorSignTxParams) -> Bool { + if lhs.inputs != rhs.inputs { return false } - if lhs.vout != rhs.vout { + if lhs.outputs != rhs.outputs { return false } - if lhs.scriptsig != rhs.scriptsig { + if lhs.coin != rhs.coin { return false } - if lhs.witness != rhs.witness { + if lhs.lockTime != rhs.lockTime { return false } - if lhs.sequence != rhs.sequence { + if lhs.version != rhs.version { + return false + } + if lhs.prevTxs != rhs.prevTxs { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(txid) - hasher.combine(vout) - hasher.combine(scriptsig) - hasher.combine(witness) - hasher.combine(sequence) + hasher.combine(inputs) + hasher.combine(outputs) + hasher.combine(coin) + hasher.combine(lockTime) + hasher.combine(version) + hasher.combine(prevTxs) } } -extension TxInput: Codable {} +extension TrezorSignTxParams: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTxInput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxInput { +public struct FfiConverterTypeTrezorSignTxParams: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignTxParams { return - try TxInput( - txid: FfiConverterString.read(from: &buf), - vout: FfiConverterUInt32.read(from: &buf), - scriptsig: FfiConverterString.read(from: &buf), - witness: FfiConverterSequenceString.read(from: &buf), - sequence: FfiConverterUInt32.read(from: &buf) + try TrezorSignTxParams( + inputs: FfiConverterSequenceTypeTrezorTxInput.read(from: &buf), + outputs: FfiConverterSequenceTypeTrezorTxOutput.read(from: &buf), + coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf), + lockTime: FfiConverterOptionUInt32.read(from: &buf), + version: FfiConverterOptionUInt32.read(from: &buf), + prevTxs: FfiConverterSequenceTypeTrezorPrevTx.read(from: &buf) ) } - public static func write(_ value: TxInput, into buf: inout [UInt8]) { - FfiConverterString.write(value.txid, into: &buf) - FfiConverterUInt32.write(value.vout, into: &buf) - FfiConverterString.write(value.scriptsig, into: &buf) - FfiConverterSequenceString.write(value.witness, into: &buf) - FfiConverterUInt32.write(value.sequence, into: &buf) + public static func write(_ value: TrezorSignTxParams, into buf: inout [UInt8]) { + FfiConverterSequenceTypeTrezorTxInput.write(value.inputs, into: &buf) + FfiConverterSequenceTypeTrezorTxOutput.write(value.outputs, into: &buf) + FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) + FfiConverterOptionUInt32.write(value.lockTime, into: &buf) + FfiConverterOptionUInt32.write(value.version, into: &buf) + FfiConverterSequenceTypeTrezorPrevTx.write(value.prevTxs, into: &buf) } } @@ -14096,128 +14195,86 @@ public struct FfiConverterTypeTxInput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxInput_lift(_ buf: RustBuffer) throws -> TxInput { - return try FfiConverterTypeTxInput.lift(buf) +public func FfiConverterTypeTrezorSignTxParams_lift(_ buf: RustBuffer) throws -> TrezorSignTxParams { + return try FfiConverterTypeTrezorSignTxParams.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxInput_lower(_ value: TxInput) -> RustBuffer { - return FfiConverterTypeTxInput.lower(value) +public func FfiConverterTypeTrezorSignTxParams_lower(_ value: TrezorSignTxParams) -> RustBuffer { + return FfiConverterTypeTrezorSignTxParams.lower(value) } /** - * Details about a transaction output. + * Response from signing a message. */ -public struct TxOutput { - /** - * The script public key (hex-encoded). - */ - public var scriptpubkey: String - /** - * The script public key type (e.g., "p2pkh", "p2sh", "p2wpkh", "p2wsh", "p2tr"). - */ - public var scriptpubkeyType: String? - /** - * The address corresponding to this script (if decodable). - */ - public var scriptpubkeyAddress: String? +public struct TrezorSignedMessageResponse { /** - * The value in satoshis. + * Bitcoin address that signed the message */ - public var value: Int64 + public var address: String /** - * The output index in the transaction. + * Signature (base64 encoded) */ - public var n: UInt32 + public var signature: String // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * The script public key (hex-encoded). - */scriptpubkey: String, - /** - * The script public key type (e.g., "p2pkh", "p2sh", "p2wpkh", "p2wsh", "p2tr"). - */scriptpubkeyType: String?, - /** - * The address corresponding to this script (if decodable). - */scriptpubkeyAddress: String?, - /** - * The value in satoshis. - */value: Int64, + * Bitcoin address that signed the message + */address: String, /** - * The output index in the transaction. - */n: UInt32) { - self.scriptpubkey = scriptpubkey - self.scriptpubkeyType = scriptpubkeyType - self.scriptpubkeyAddress = scriptpubkeyAddress - self.value = value - self.n = n + * Signature (base64 encoded) + */signature: String) { + self.address = address + self.signature = signature } } #if compiler(>=6) -extension TxOutput: Sendable {} +extension TrezorSignedMessageResponse: Sendable {} #endif -extension TxOutput: Equatable, Hashable { - public static func ==(lhs: TxOutput, rhs: TxOutput) -> Bool { - if lhs.scriptpubkey != rhs.scriptpubkey { - return false - } - if lhs.scriptpubkeyType != rhs.scriptpubkeyType { - return false - } - if lhs.scriptpubkeyAddress != rhs.scriptpubkeyAddress { - return false - } - if lhs.value != rhs.value { +extension TrezorSignedMessageResponse: Equatable, Hashable { + public static func ==(lhs: TrezorSignedMessageResponse, rhs: TrezorSignedMessageResponse) -> Bool { + if lhs.address != rhs.address { return false } - if lhs.n != rhs.n { + if lhs.signature != rhs.signature { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(scriptpubkey) - hasher.combine(scriptpubkeyType) - hasher.combine(scriptpubkeyAddress) - hasher.combine(value) - hasher.combine(n) + hasher.combine(address) + hasher.combine(signature) } } -extension TxOutput: Codable {} +extension TrezorSignedMessageResponse: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTxOutput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxOutput { +public struct FfiConverterTypeTrezorSignedMessageResponse: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignedMessageResponse { return - try TxOutput( - scriptpubkey: FfiConverterString.read(from: &buf), - scriptpubkeyType: FfiConverterOptionString.read(from: &buf), - scriptpubkeyAddress: FfiConverterOptionString.read(from: &buf), - value: FfiConverterInt64.read(from: &buf), - n: FfiConverterUInt32.read(from: &buf) + try TrezorSignedMessageResponse( + address: FfiConverterString.read(from: &buf), + signature: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: TxOutput, into buf: inout [UInt8]) { - FfiConverterString.write(value.scriptpubkey, into: &buf) - FfiConverterOptionString.write(value.scriptpubkeyType, into: &buf) - FfiConverterOptionString.write(value.scriptpubkeyAddress, into: &buf) - FfiConverterInt64.write(value.value, into: &buf) - FfiConverterUInt32.write(value.n, into: &buf) + public static func write(_ value: TrezorSignedMessageResponse, into buf: inout [UInt8]) { + FfiConverterString.write(value.address, into: &buf) + FfiConverterString.write(value.signature, into: &buf) } } @@ -14225,100 +14282,100 @@ public struct FfiConverterTypeTxOutput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxOutput_lift(_ buf: RustBuffer) throws -> TxOutput { - return try FfiConverterTypeTxOutput.lift(buf) +public func FfiConverterTypeTrezorSignedMessageResponse_lift(_ buf: RustBuffer) throws -> TrezorSignedMessageResponse { + return try FfiConverterTypeTrezorSignedMessageResponse.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTxOutput_lower(_ value: TxOutput) -> RustBuffer { - return FfiConverterTypeTxOutput.lower(value) +public func FfiConverterTypeTrezorSignedMessageResponse_lower(_ value: TrezorSignedMessageResponse) -> RustBuffer { + return FfiConverterTypeTrezorSignedMessageResponse.lower(value) } /** - * Current state after accepting a scanned UR frame. + * Signed transaction result. */ -public struct UrDecoderStatus { +public struct TrezorSignedTx { /** - * Estimated completion from 0.0 through 1.0. + * Signatures for each input (hex encoded) */ - public var progress: Double + public var signatures: [String] /** - * Fountain source-fragment count, or 1 for a single-part UR. + * Serialized transaction (hex) */ - public var fragmentCount: UInt32 + public var serializedTx: String /** - * Present once the complete message has been decoded. + * Broadcast transaction ID (populated when push=true) */ - public var payload: UrPayload? + public var txid: String? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Estimated completion from 0.0 through 1.0. - */progress: Double, + * Signatures for each input (hex encoded) + */signatures: [String], /** - * Fountain source-fragment count, or 1 for a single-part UR. - */fragmentCount: UInt32, + * Serialized transaction (hex) + */serializedTx: String, /** - * Present once the complete message has been decoded. - */payload: UrPayload?) { - self.progress = progress - self.fragmentCount = fragmentCount - self.payload = payload + * Broadcast transaction ID (populated when push=true) + */txid: String?) { + self.signatures = signatures + self.serializedTx = serializedTx + self.txid = txid } } #if compiler(>=6) -extension UrDecoderStatus: Sendable {} +extension TrezorSignedTx: Sendable {} #endif -extension UrDecoderStatus: Equatable, Hashable { - public static func ==(lhs: UrDecoderStatus, rhs: UrDecoderStatus) -> Bool { - if lhs.progress != rhs.progress { +extension TrezorSignedTx: Equatable, Hashable { + public static func ==(lhs: TrezorSignedTx, rhs: TrezorSignedTx) -> Bool { + if lhs.signatures != rhs.signatures { return false } - if lhs.fragmentCount != rhs.fragmentCount { + if lhs.serializedTx != rhs.serializedTx { return false } - if lhs.payload != rhs.payload { + if lhs.txid != rhs.txid { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(progress) - hasher.combine(fragmentCount) - hasher.combine(payload) + hasher.combine(signatures) + hasher.combine(serializedTx) + hasher.combine(txid) } } -extension UrDecoderStatus: Codable {} +extension TrezorSignedTx: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeUrDecoderStatus: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UrDecoderStatus { +public struct FfiConverterTypeTrezorSignedTx: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorSignedTx { return - try UrDecoderStatus( - progress: FfiConverterDouble.read(from: &buf), - fragmentCount: FfiConverterUInt32.read(from: &buf), - payload: FfiConverterOptionTypeUrPayload.read(from: &buf) + try TrezorSignedTx( + signatures: FfiConverterSequenceString.read(from: &buf), + serializedTx: FfiConverterString.read(from: &buf), + txid: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: UrDecoderStatus, into buf: inout [UInt8]) { - FfiConverterDouble.write(value.progress, into: &buf) - FfiConverterUInt32.write(value.fragmentCount, into: &buf) - FfiConverterOptionTypeUrPayload.write(value.payload, into: &buf) + public static func write(_ value: TrezorSignedTx, into buf: inout [UInt8]) { + FfiConverterSequenceString.write(value.signatures, into: &buf) + FfiConverterString.write(value.serializedTx, into: &buf) + FfiConverterOptionString.write(value.txid, into: &buf) } } @@ -14326,79 +14383,114 @@ public struct FfiConverterTypeUrDecoderStatus: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeUrDecoderStatus_lift(_ buf: RustBuffer) throws -> UrDecoderStatus { - return try FfiConverterTypeUrDecoderStatus.lift(buf) +public func FfiConverterTypeTrezorSignedTx_lift(_ buf: RustBuffer) throws -> TrezorSignedTx { + return try FfiConverterTypeTrezorSignedTx.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeUrDecoderStatus_lower(_ value: UrDecoderStatus) -> RustBuffer { - return FfiConverterTypeUrDecoderStatus.lower(value) +public func FfiConverterTypeTrezorSignedTx_lower(_ value: TrezorSignedTx) -> RustBuffer { + return FfiConverterTypeTrezorSignedTx.lower(value) } -public struct ValidationResult { - public var address: String - public var network: NetworkType - public var addressType: AddressType +/** + * Result from a transport read operation + */ +public struct TrezorTransportReadResult { + /** + * Whether the read succeeded + */ + public var success: Bool + /** + * Data read (empty on failure) + */ + public var data: Data + /** + * Error message (empty on success) + */ + public var error: String + /** + * Structured error code (None on success or when the native error is generic) + */ + public var errorCode: TrezorTransportErrorCode? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(address: String, network: NetworkType, addressType: AddressType) { - self.address = address - self.network = network - self.addressType = addressType + public init( + /** + * Whether the read succeeded + */success: Bool, + /** + * Data read (empty on failure) + */data: Data, + /** + * Error message (empty on success) + */error: String, + /** + * Structured error code (None on success or when the native error is generic) + */errorCode: TrezorTransportErrorCode?) { + self.success = success + self.data = data + self.error = error + self.errorCode = errorCode } } #if compiler(>=6) -extension ValidationResult: Sendable {} +extension TrezorTransportReadResult: Sendable {} #endif -extension ValidationResult: Equatable, Hashable { - public static func ==(lhs: ValidationResult, rhs: ValidationResult) -> Bool { - if lhs.address != rhs.address { +extension TrezorTransportReadResult: Equatable, Hashable { + public static func ==(lhs: TrezorTransportReadResult, rhs: TrezorTransportReadResult) -> Bool { + if lhs.success != rhs.success { return false } - if lhs.network != rhs.network { + if lhs.data != rhs.data { return false } - if lhs.addressType != rhs.addressType { + if lhs.error != rhs.error { + return false + } + if lhs.errorCode != rhs.errorCode { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(address) - hasher.combine(network) - hasher.combine(addressType) + hasher.combine(success) + hasher.combine(data) + hasher.combine(error) + hasher.combine(errorCode) } } -extension ValidationResult: Codable {} +extension TrezorTransportReadResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeValidationResult: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ValidationResult { +public struct FfiConverterTypeTrezorTransportReadResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTransportReadResult { return - try ValidationResult( - address: FfiConverterString.read(from: &buf), - network: FfiConverterTypeNetworkType.read(from: &buf), - addressType: FfiConverterTypeAddressType.read(from: &buf) + try TrezorTransportReadResult( + success: FfiConverterBool.read(from: &buf), + data: FfiConverterData.read(from: &buf), + error: FfiConverterString.read(from: &buf), + errorCode: FfiConverterOptionTypeTrezorTransportErrorCode.read(from: &buf) ) } - public static func write(_ value: ValidationResult, into buf: inout [UInt8]) { - FfiConverterString.write(value.address, into: &buf) - FfiConverterTypeNetworkType.write(value.network, into: &buf) - FfiConverterTypeAddressType.write(value.addressType, into: &buf) + public static func write(_ value: TrezorTransportReadResult, into buf: inout [UInt8]) { + FfiConverterBool.write(value.success, into: &buf) + FfiConverterData.write(value.data, into: &buf) + FfiConverterString.write(value.error, into: &buf) + FfiConverterOptionTypeTrezorTransportErrorCode.write(value.errorCode, into: &buf) } } @@ -14406,142 +14498,100 @@ public struct FfiConverterTypeValidationResult: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeValidationResult_lift(_ buf: RustBuffer) throws -> ValidationResult { - return try FfiConverterTypeValidationResult.lift(buf) +public func FfiConverterTypeTrezorTransportReadResult_lift(_ buf: RustBuffer) throws -> TrezorTransportReadResult { + return try FfiConverterTypeTrezorTransportReadResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeValidationResult_lower(_ value: ValidationResult) -> RustBuffer { - return FfiConverterTypeValidationResult.lower(value) +public func FfiConverterTypeTrezorTransportReadResult_lower(_ value: TrezorTransportReadResult) -> RustBuffer { + return FfiConverterTypeTrezorTransportReadResult.lower(value) } /** - * Balance breakdown from BDK. + * Result from a transport write or open operation */ -public struct WalletBalance { - /** - * Confirmed and spendable balance (sats) - */ - public var confirmed: UInt64 - /** - * Immature coinbase outputs (sats) - */ - public var immature: UInt64 - /** - * Unconfirmed UTXOs from trusted sources (own change) (sats) - */ - public var trustedPending: UInt64 +public struct TrezorTransportWriteResult { /** - * Unconfirmed UTXOs from external sources (sats) + * Whether the operation succeeded */ - public var untrustedPending: UInt64 + public var success: Bool /** - * Total spendable: confirmed + trusted_pending (sats) + * Error message (empty on success) */ - public var spendable: UInt64 + public var error: String /** - * Grand total: all categories (sats) + * Structured error code (None on success or when the native error is generic) */ - public var total: UInt64 + public var errorCode: TrezorTransportErrorCode? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Confirmed and spendable balance (sats) - */confirmed: UInt64, - /** - * Immature coinbase outputs (sats) - */immature: UInt64, - /** - * Unconfirmed UTXOs from trusted sources (own change) (sats) - */trustedPending: UInt64, - /** - * Unconfirmed UTXOs from external sources (sats) - */untrustedPending: UInt64, + * Whether the operation succeeded + */success: Bool, /** - * Total spendable: confirmed + trusted_pending (sats) - */spendable: UInt64, + * Error message (empty on success) + */error: String, /** - * Grand total: all categories (sats) - */total: UInt64) { - self.confirmed = confirmed - self.immature = immature - self.trustedPending = trustedPending - self.untrustedPending = untrustedPending - self.spendable = spendable - self.total = total + * Structured error code (None on success or when the native error is generic) + */errorCode: TrezorTransportErrorCode?) { + self.success = success + self.error = error + self.errorCode = errorCode } } #if compiler(>=6) -extension WalletBalance: Sendable {} +extension TrezorTransportWriteResult: Sendable {} #endif -extension WalletBalance: Equatable, Hashable { - public static func ==(lhs: WalletBalance, rhs: WalletBalance) -> Bool { - if lhs.confirmed != rhs.confirmed { - return false - } - if lhs.immature != rhs.immature { - return false - } - if lhs.trustedPending != rhs.trustedPending { - return false - } - if lhs.untrustedPending != rhs.untrustedPending { +extension TrezorTransportWriteResult: Equatable, Hashable { + public static func ==(lhs: TrezorTransportWriteResult, rhs: TrezorTransportWriteResult) -> Bool { + if lhs.success != rhs.success { return false } - if lhs.spendable != rhs.spendable { + if lhs.error != rhs.error { return false } - if lhs.total != rhs.total { + if lhs.errorCode != rhs.errorCode { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(confirmed) - hasher.combine(immature) - hasher.combine(trustedPending) - hasher.combine(untrustedPending) - hasher.combine(spendable) - hasher.combine(total) + hasher.combine(success) + hasher.combine(error) + hasher.combine(errorCode) } } -extension WalletBalance: Codable {} +extension TrezorTransportWriteResult: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeWalletBalance: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> WalletBalance { +public struct FfiConverterTypeTrezorTransportWriteResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTransportWriteResult { return - try WalletBalance( - confirmed: FfiConverterUInt64.read(from: &buf), - immature: FfiConverterUInt64.read(from: &buf), - trustedPending: FfiConverterUInt64.read(from: &buf), - untrustedPending: FfiConverterUInt64.read(from: &buf), - spendable: FfiConverterUInt64.read(from: &buf), - total: FfiConverterUInt64.read(from: &buf) + try TrezorTransportWriteResult( + success: FfiConverterBool.read(from: &buf), + error: FfiConverterString.read(from: &buf), + errorCode: FfiConverterOptionTypeTrezorTransportErrorCode.read(from: &buf) ) } - public static func write(_ value: WalletBalance, into buf: inout [UInt8]) { - FfiConverterUInt64.write(value.confirmed, into: &buf) - FfiConverterUInt64.write(value.immature, into: &buf) - FfiConverterUInt64.write(value.trustedPending, into: &buf) - FfiConverterUInt64.write(value.untrustedPending, into: &buf) - FfiConverterUInt64.write(value.spendable, into: &buf) - FfiConverterUInt64.write(value.total, into: &buf) + public static func write(_ value: TrezorTransportWriteResult, into buf: inout [UInt8]) { + FfiConverterBool.write(value.success, into: &buf) + FfiConverterString.write(value.error, into: &buf) + FfiConverterOptionTypeTrezorTransportErrorCode.write(value.errorCode, into: &buf) } } @@ -14549,128 +14599,170 @@ public struct FfiConverterTypeWalletBalance: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeWalletBalance_lift(_ buf: RustBuffer) throws -> WalletBalance { - return try FfiConverterTypeWalletBalance.lift(buf) +public func FfiConverterTypeTrezorTransportWriteResult_lift(_ buf: RustBuffer) throws -> TrezorTransportWriteResult { + return try FfiConverterTypeTrezorTransportWriteResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeWalletBalance_lower(_ value: WalletBalance) -> RustBuffer { - return FfiConverterTypeWalletBalance.lower(value) +public func FfiConverterTypeTrezorTransportWriteResult_lower(_ value: TrezorTransportWriteResult) -> RustBuffer { + return FfiConverterTypeTrezorTransportWriteResult.lower(value) } /** - * Common parameters for creating and syncing a watch-only BDK wallet. + * Transaction input for signing. */ -public struct WalletParams { +public struct TrezorTxInput { /** - * Extended public key (xpub/ypub/zpub/tpub/upub/vpub) + * Previous transaction hash (hex, 32 bytes) */ - public var extendedKey: String + public var prevHash: String /** - * Electrum server URL for wallet sync + * Previous output index */ - public var electrumUrl: String + public var prevIndex: UInt32 /** - * Root fingerprint hex (e.g. "73c5da0a"). Required for hardware wallet signing. + * BIP32 derivation path (e.g., "m/84'/0'/0'/0/0") */ - public var fingerprint: String? + public var path: String /** - * Bitcoin network (auto-detected from key prefix if not specified) + * Amount in satoshis */ - public var network: Network? + public var amount: UInt64 /** - * Override account type for ambiguous key prefixes (xpub/tpub) + * Script type */ - public var accountType: AccountType? + public var scriptType: TrezorScriptType + /** + * Sequence number (default: 0xFFFFFFFD for RBF) + */ + public var sequence: UInt32? + /** + * Original transaction hash for RBF replacement (hex encoded) + */ + public var origHash: String? + /** + * Original input index for RBF replacement + */ + public var origIndex: UInt32? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Extended public key (xpub/ypub/zpub/tpub/upub/vpub) - */extendedKey: String, + * Previous transaction hash (hex, 32 bytes) + */prevHash: String, /** - * Electrum server URL for wallet sync - */electrumUrl: String, + * Previous output index + */prevIndex: UInt32, /** - * Root fingerprint hex (e.g. "73c5da0a"). Required for hardware wallet signing. - */fingerprint: String?, + * BIP32 derivation path (e.g., "m/84'/0'/0'/0/0") + */path: String, /** - * Bitcoin network (auto-detected from key prefix if not specified) - */network: Network?, + * Amount in satoshis + */amount: UInt64, /** - * Override account type for ambiguous key prefixes (xpub/tpub) - */accountType: AccountType?) { - self.extendedKey = extendedKey - self.electrumUrl = electrumUrl - self.fingerprint = fingerprint - self.network = network - self.accountType = accountType + * Script type + */scriptType: TrezorScriptType, + /** + * Sequence number (default: 0xFFFFFFFD for RBF) + */sequence: UInt32?, + /** + * Original transaction hash for RBF replacement (hex encoded) + */origHash: String?, + /** + * Original input index for RBF replacement + */origIndex: UInt32?) { + self.prevHash = prevHash + self.prevIndex = prevIndex + self.path = path + self.amount = amount + self.scriptType = scriptType + self.sequence = sequence + self.origHash = origHash + self.origIndex = origIndex } } #if compiler(>=6) -extension WalletParams: Sendable {} +extension TrezorTxInput: Sendable {} #endif -extension WalletParams: Equatable, Hashable { - public static func ==(lhs: WalletParams, rhs: WalletParams) -> Bool { - if lhs.extendedKey != rhs.extendedKey { +extension TrezorTxInput: Equatable, Hashable { + public static func ==(lhs: TrezorTxInput, rhs: TrezorTxInput) -> Bool { + if lhs.prevHash != rhs.prevHash { return false } - if lhs.electrumUrl != rhs.electrumUrl { + if lhs.prevIndex != rhs.prevIndex { return false } - if lhs.fingerprint != rhs.fingerprint { + if lhs.path != rhs.path { return false } - if lhs.network != rhs.network { + if lhs.amount != rhs.amount { return false } - if lhs.accountType != rhs.accountType { + if lhs.scriptType != rhs.scriptType { + return false + } + if lhs.sequence != rhs.sequence { + return false + } + if lhs.origHash != rhs.origHash { + return false + } + if lhs.origIndex != rhs.origIndex { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(extendedKey) - hasher.combine(electrumUrl) - hasher.combine(fingerprint) - hasher.combine(network) - hasher.combine(accountType) + hasher.combine(prevHash) + hasher.combine(prevIndex) + hasher.combine(path) + hasher.combine(amount) + hasher.combine(scriptType) + hasher.combine(sequence) + hasher.combine(origHash) + hasher.combine(origIndex) } } -extension WalletParams: Codable {} +extension TrezorTxInput: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeWalletParams: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> WalletParams { +public struct FfiConverterTypeTrezorTxInput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTxInput { return - try WalletParams( - extendedKey: FfiConverterString.read(from: &buf), - electrumUrl: FfiConverterString.read(from: &buf), - fingerprint: FfiConverterOptionString.read(from: &buf), - network: FfiConverterOptionTypeNetwork.read(from: &buf), - accountType: FfiConverterOptionTypeAccountType.read(from: &buf) + try TrezorTxInput( + prevHash: FfiConverterString.read(from: &buf), + prevIndex: FfiConverterUInt32.read(from: &buf), + path: FfiConverterString.read(from: &buf), + amount: FfiConverterUInt64.read(from: &buf), + scriptType: FfiConverterTypeTrezorScriptType.read(from: &buf), + sequence: FfiConverterOptionUInt32.read(from: &buf), + origHash: FfiConverterOptionString.read(from: &buf), + origIndex: FfiConverterOptionUInt32.read(from: &buf) ) } - public static func write(_ value: WalletParams, into buf: inout [UInt8]) { - FfiConverterString.write(value.extendedKey, into: &buf) - FfiConverterString.write(value.electrumUrl, into: &buf) - FfiConverterOptionString.write(value.fingerprint, into: &buf) - FfiConverterOptionTypeNetwork.write(value.network, into: &buf) - FfiConverterOptionTypeAccountType.write(value.accountType, into: &buf) + public static func write(_ value: TrezorTxInput, into buf: inout [UInt8]) { + FfiConverterString.write(value.prevHash, into: &buf) + FfiConverterUInt32.write(value.prevIndex, into: &buf) + FfiConverterString.write(value.path, into: &buf) + FfiConverterUInt64.write(value.amount, into: &buf) + FfiConverterTypeTrezorScriptType.write(value.scriptType, into: &buf) + FfiConverterOptionUInt32.write(value.sequence, into: &buf) + FfiConverterOptionString.write(value.origHash, into: &buf) + FfiConverterOptionUInt32.write(value.origIndex, into: &buf) } } @@ -14678,160 +14770,2145 @@ public struct FfiConverterTypeWalletParams: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeWalletParams_lift(_ buf: RustBuffer) throws -> WalletParams { - return try FfiConverterTypeWalletParams.lift(buf) +public func FfiConverterTypeTrezorTxInput_lift(_ buf: RustBuffer) throws -> TrezorTxInput { + return try FfiConverterTypeTrezorTxInput.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeWalletParams_lower(_ value: WalletParams) -> RustBuffer { - return FfiConverterTypeWalletParams.lower(value) +public func FfiConverterTypeTrezorTxInput_lower(_ value: TrezorTxInput) -> RustBuffer { + return FfiConverterTypeTrezorTxInput.lower(value) } /** - * Parameters for starting an xpub transaction watcher. + * Transaction output for signing. */ -public struct WatcherParams { +public struct TrezorTxOutput { /** - * Caller-supplied identifier for this watcher. + * Destination address (for external outputs) */ - public var watcherId: String + public var address: String? /** - * Wallet id that scopes the activities this watcher emits. Apps may use - * one wallet id for several account watchers and merge their snapshots. + * BIP32 path (for change outputs) */ - public var walletId: String + public var path: String? /** - * Extended public key (xpub/ypub/zpub/tpub/upub/vpub). + * Amount in satoshis */ - public var extendedKey: String + public var amount: UInt64 /** - * Electrum server URL (e.g. "ssl://electrum.example.com:50002"). + * Script type (for change outputs) */ - public var electrumUrl: String + public var scriptType: TrezorScriptType? /** - * Bitcoin network override (auto-detected from key prefix if None). + * OP_RETURN data (hex encoded, for data outputs) */ - public var network: Network? + public var opReturnData: String? /** - * Account type override (auto-detected from key prefix if None). + * Original transaction hash for RBF replacement (hex encoded) */ - public var accountType: AccountType? + public var origHash: String? /** - * Number of unused addresses to monitor beyond the last used - * (defaults to `DEFAULT_GAP_LIMIT` when None). + * Original output index for RBF replacement */ - public var gapLimit: UInt32? + public var origIndex: UInt32? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Caller-supplied identifier for this watcher. - */watcherId: String, + * Destination address (for external outputs) + */address: String?, /** - * Wallet id that scopes the activities this watcher emits. Apps may use - * one wallet id for several account watchers and merge their snapshots. - */walletId: String, + * BIP32 path (for change outputs) + */path: String?, /** - * Extended public key (xpub/ypub/zpub/tpub/upub/vpub). - */extendedKey: String, + * Amount in satoshis + */amount: UInt64, /** - * Electrum server URL (e.g. "ssl://electrum.example.com:50002"). - */electrumUrl: String, + * Script type (for change outputs) + */scriptType: TrezorScriptType?, /** - * Bitcoin network override (auto-detected from key prefix if None). - */network: Network?, + * OP_RETURN data (hex encoded, for data outputs) + */opReturnData: String?, /** - * Account type override (auto-detected from key prefix if None). - */accountType: AccountType?, + * Original transaction hash for RBF replacement (hex encoded) + */origHash: String?, /** - * Number of unused addresses to monitor beyond the last used - * (defaults to `DEFAULT_GAP_LIMIT` when None). - */gapLimit: UInt32?) { - self.watcherId = watcherId - self.walletId = walletId - self.extendedKey = extendedKey - self.electrumUrl = electrumUrl - self.network = network - self.accountType = accountType - self.gapLimit = gapLimit + * Original output index for RBF replacement + */origIndex: UInt32?) { + self.address = address + self.path = path + self.amount = amount + self.scriptType = scriptType + self.opReturnData = opReturnData + self.origHash = origHash + self.origIndex = origIndex } } #if compiler(>=6) -extension WatcherParams: Sendable {} +extension TrezorTxOutput: Sendable {} #endif -extension WatcherParams: Equatable, Hashable { - public static func ==(lhs: WatcherParams, rhs: WatcherParams) -> Bool { - if lhs.watcherId != rhs.watcherId { +extension TrezorTxOutput: Equatable, Hashable { + public static func ==(lhs: TrezorTxOutput, rhs: TrezorTxOutput) -> Bool { + if lhs.address != rhs.address { return false } - if lhs.walletId != rhs.walletId { + if lhs.path != rhs.path { return false } - if lhs.extendedKey != rhs.extendedKey { + if lhs.amount != rhs.amount { return false } - if lhs.electrumUrl != rhs.electrumUrl { + if lhs.scriptType != rhs.scriptType { return false } - if lhs.network != rhs.network { + if lhs.opReturnData != rhs.opReturnData { return false } - if lhs.accountType != rhs.accountType { + if lhs.origHash != rhs.origHash { return false } - if lhs.gapLimit != rhs.gapLimit { + if lhs.origIndex != rhs.origIndex { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(watcherId) - hasher.combine(walletId) - hasher.combine(extendedKey) - hasher.combine(electrumUrl) - hasher.combine(network) - hasher.combine(accountType) - hasher.combine(gapLimit) + hasher.combine(address) + hasher.combine(path) + hasher.combine(amount) + hasher.combine(scriptType) + hasher.combine(opReturnData) + hasher.combine(origHash) + hasher.combine(origIndex) } } -extension WatcherParams: Codable {} +extension TrezorTxOutput: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeWatcherParams: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> WatcherParams { +public struct FfiConverterTypeTrezorTxOutput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorTxOutput { return - try WatcherParams( - watcherId: FfiConverterString.read(from: &buf), - walletId: FfiConverterString.read(from: &buf), - extendedKey: FfiConverterString.read(from: &buf), - electrumUrl: FfiConverterString.read(from: &buf), - network: FfiConverterOptionTypeNetwork.read(from: &buf), - accountType: FfiConverterOptionTypeAccountType.read(from: &buf), - gapLimit: FfiConverterOptionUInt32.read(from: &buf) + try TrezorTxOutput( + address: FfiConverterOptionString.read(from: &buf), + path: FfiConverterOptionString.read(from: &buf), + amount: FfiConverterUInt64.read(from: &buf), + scriptType: FfiConverterOptionTypeTrezorScriptType.read(from: &buf), + opReturnData: FfiConverterOptionString.read(from: &buf), + origHash: FfiConverterOptionString.read(from: &buf), + origIndex: FfiConverterOptionUInt32.read(from: &buf) ) } - public static func write(_ value: WatcherParams, into buf: inout [UInt8]) { - FfiConverterString.write(value.watcherId, into: &buf) - FfiConverterString.write(value.walletId, into: &buf) - FfiConverterString.write(value.extendedKey, into: &buf) - FfiConverterString.write(value.electrumUrl, into: &buf) - FfiConverterOptionTypeNetwork.write(value.network, into: &buf) - FfiConverterOptionTypeAccountType.write(value.accountType, into: &buf) - FfiConverterOptionUInt32.write(value.gapLimit, into: &buf) + public static func write(_ value: TrezorTxOutput, into buf: inout [UInt8]) { + FfiConverterOptionString.write(value.address, into: &buf) + FfiConverterOptionString.write(value.path, into: &buf) + FfiConverterUInt64.write(value.amount, into: &buf) + FfiConverterOptionTypeTrezorScriptType.write(value.scriptType, into: &buf) + FfiConverterOptionString.write(value.opReturnData, into: &buf) + FfiConverterOptionString.write(value.origHash, into: &buf) + FfiConverterOptionUInt32.write(value.origIndex, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTrezorTxOutput_lift(_ buf: RustBuffer) throws -> TrezorTxOutput { + return try FfiConverterTypeTrezorTxOutput.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTrezorTxOutput_lower(_ value: TrezorTxOutput) -> RustBuffer { + return FfiConverterTypeTrezorTxOutput.lower(value) +} + + +/** + * Parameters for verifying a message signature. + */ +public struct TrezorVerifyMessageParams { + /** + * Bitcoin address that signed the message + */ + public var address: String + /** + * Signature (base64 encoded) + */ + public var signature: String + /** + * Original message + */ + public var message: String + /** + * Coin network (default: Bitcoin) + */ + public var coin: TrezorCoinType? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Bitcoin address that signed the message + */address: String, + /** + * Signature (base64 encoded) + */signature: String, + /** + * Original message + */message: String, + /** + * Coin network (default: Bitcoin) + */coin: TrezorCoinType?) { + self.address = address + self.signature = signature + self.message = message + self.coin = coin + } +} + +#if compiler(>=6) +extension TrezorVerifyMessageParams: Sendable {} +#endif + + +extension TrezorVerifyMessageParams: Equatable, Hashable { + public static func ==(lhs: TrezorVerifyMessageParams, rhs: TrezorVerifyMessageParams) -> Bool { + if lhs.address != rhs.address { + return false + } + if lhs.signature != rhs.signature { + return false + } + if lhs.message != rhs.message { + return false + } + if lhs.coin != rhs.coin { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(address) + hasher.combine(signature) + hasher.combine(message) + hasher.combine(coin) + } +} + +extension TrezorVerifyMessageParams: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTrezorVerifyMessageParams: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TrezorVerifyMessageParams { + return + try TrezorVerifyMessageParams( + address: FfiConverterString.read(from: &buf), + signature: FfiConverterString.read(from: &buf), + message: FfiConverterString.read(from: &buf), + coin: FfiConverterOptionTypeTrezorCoinType.read(from: &buf) + ) + } + + public static func write(_ value: TrezorVerifyMessageParams, into buf: inout [UInt8]) { + FfiConverterString.write(value.address, into: &buf) + FfiConverterString.write(value.signature, into: &buf) + FfiConverterString.write(value.message, into: &buf) + FfiConverterOptionTypeTrezorCoinType.write(value.coin, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTrezorVerifyMessageParams_lift(_ buf: RustBuffer) throws -> TrezorVerifyMessageParams { + return try FfiConverterTypeTrezorVerifyMessageParams.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTrezorVerifyMessageParams_lower(_ value: TrezorVerifyMessageParams) -> RustBuffer { + return FfiConverterTypeTrezorVerifyMessageParams.lower(value) +} + + +/** + * A transaction input with full details. + */ +public struct TxDetailInput { + /** + * Previous output transaction ID (hex) + */ + public var txid: String + /** + * Previous output index + */ + public var vout: UInt32 + /** + * Sequence number + */ + public var sequence: UInt32 + /** + * Script signature (hex-encoded) + */ + public var scriptSig: String + /** + * Witness stack (each element hex-encoded) + */ + public var witness: [String] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Previous output transaction ID (hex) + */txid: String, + /** + * Previous output index + */vout: UInt32, + /** + * Sequence number + */sequence: UInt32, + /** + * Script signature (hex-encoded) + */scriptSig: String, + /** + * Witness stack (each element hex-encoded) + */witness: [String]) { + self.txid = txid + self.vout = vout + self.sequence = sequence + self.scriptSig = scriptSig + self.witness = witness + } +} + +#if compiler(>=6) +extension TxDetailInput: Sendable {} +#endif + + +extension TxDetailInput: Equatable, Hashable { + public static func ==(lhs: TxDetailInput, rhs: TxDetailInput) -> Bool { + if lhs.txid != rhs.txid { + return false + } + if lhs.vout != rhs.vout { + return false + } + if lhs.sequence != rhs.sequence { + return false + } + if lhs.scriptSig != rhs.scriptSig { + return false + } + if lhs.witness != rhs.witness { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(txid) + hasher.combine(vout) + hasher.combine(sequence) + hasher.combine(scriptSig) + hasher.combine(witness) + } +} + +extension TxDetailInput: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTxDetailInput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxDetailInput { + return + try TxDetailInput( + txid: FfiConverterString.read(from: &buf), + vout: FfiConverterUInt32.read(from: &buf), + sequence: FfiConverterUInt32.read(from: &buf), + scriptSig: FfiConverterString.read(from: &buf), + witness: FfiConverterSequenceString.read(from: &buf) + ) + } + + public static func write(_ value: TxDetailInput, into buf: inout [UInt8]) { + FfiConverterString.write(value.txid, into: &buf) + FfiConverterUInt32.write(value.vout, into: &buf) + FfiConverterUInt32.write(value.sequence, into: &buf) + FfiConverterString.write(value.scriptSig, into: &buf) + FfiConverterSequenceString.write(value.witness, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxDetailInput_lift(_ buf: RustBuffer) throws -> TxDetailInput { + return try FfiConverterTypeTxDetailInput.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxDetailInput_lower(_ value: TxDetailInput) -> RustBuffer { + return FfiConverterTypeTxDetailInput.lower(value) +} + + +/** + * A transaction output with full details. + */ +public struct TxDetailOutput { + /** + * Output value in sats + */ + public var value: UInt64 + /** + * Script public key (hex-encoded) + */ + public var scriptPubkey: String + /** + * Decoded address (None if script is not decodable to an address) + */ + public var address: String? + /** + * Whether this output belongs to the queried wallet + */ + public var isMine: Bool + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Output value in sats + */value: UInt64, + /** + * Script public key (hex-encoded) + */scriptPubkey: String, + /** + * Decoded address (None if script is not decodable to an address) + */address: String?, + /** + * Whether this output belongs to the queried wallet + */isMine: Bool) { + self.value = value + self.scriptPubkey = scriptPubkey + self.address = address + self.isMine = isMine + } +} + +#if compiler(>=6) +extension TxDetailOutput: Sendable {} +#endif + + +extension TxDetailOutput: Equatable, Hashable { + public static func ==(lhs: TxDetailOutput, rhs: TxDetailOutput) -> Bool { + if lhs.value != rhs.value { + return false + } + if lhs.scriptPubkey != rhs.scriptPubkey { + return false + } + if lhs.address != rhs.address { + return false + } + if lhs.isMine != rhs.isMine { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + hasher.combine(scriptPubkey) + hasher.combine(address) + hasher.combine(isMine) + } +} + +extension TxDetailOutput: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTxDetailOutput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxDetailOutput { + return + try TxDetailOutput( + value: FfiConverterUInt64.read(from: &buf), + scriptPubkey: FfiConverterString.read(from: &buf), + address: FfiConverterOptionString.read(from: &buf), + isMine: FfiConverterBool.read(from: &buf) + ) + } + + public static func write(_ value: TxDetailOutput, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.value, into: &buf) + FfiConverterString.write(value.scriptPubkey, into: &buf) + FfiConverterOptionString.write(value.address, into: &buf) + FfiConverterBool.write(value.isMine, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxDetailOutput_lift(_ buf: RustBuffer) throws -> TxDetailOutput { + return try FfiConverterTypeTxDetailOutput.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxDetailOutput_lower(_ value: TxDetailOutput) -> RustBuffer { + return FfiConverterTypeTxDetailOutput.lower(value) +} + + +/** + * Details about a transaction input. + */ +public struct TxInput { + /** + * The transaction ID of the previous output being spent. + */ + public var txid: String + /** + * The output index of the previous output being spent. + */ + public var vout: UInt32 + /** + * The script signature (hex-encoded). + */ + public var scriptsig: String + /** + * The witness stack (hex-encoded strings). + */ + public var witness: [String] + /** + * The sequence number. + */ + public var sequence: UInt32 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * The transaction ID of the previous output being spent. + */txid: String, + /** + * The output index of the previous output being spent. + */vout: UInt32, + /** + * The script signature (hex-encoded). + */scriptsig: String, + /** + * The witness stack (hex-encoded strings). + */witness: [String], + /** + * The sequence number. + */sequence: UInt32) { + self.txid = txid + self.vout = vout + self.scriptsig = scriptsig + self.witness = witness + self.sequence = sequence + } +} + +#if compiler(>=6) +extension TxInput: Sendable {} +#endif + + +extension TxInput: Equatable, Hashable { + public static func ==(lhs: TxInput, rhs: TxInput) -> Bool { + if lhs.txid != rhs.txid { + return false + } + if lhs.vout != rhs.vout { + return false + } + if lhs.scriptsig != rhs.scriptsig { + return false + } + if lhs.witness != rhs.witness { + return false + } + if lhs.sequence != rhs.sequence { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(txid) + hasher.combine(vout) + hasher.combine(scriptsig) + hasher.combine(witness) + hasher.combine(sequence) + } +} + +extension TxInput: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTxInput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxInput { + return + try TxInput( + txid: FfiConverterString.read(from: &buf), + vout: FfiConverterUInt32.read(from: &buf), + scriptsig: FfiConverterString.read(from: &buf), + witness: FfiConverterSequenceString.read(from: &buf), + sequence: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: TxInput, into buf: inout [UInt8]) { + FfiConverterString.write(value.txid, into: &buf) + FfiConverterUInt32.write(value.vout, into: &buf) + FfiConverterString.write(value.scriptsig, into: &buf) + FfiConverterSequenceString.write(value.witness, into: &buf) + FfiConverterUInt32.write(value.sequence, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxInput_lift(_ buf: RustBuffer) throws -> TxInput { + return try FfiConverterTypeTxInput.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxInput_lower(_ value: TxInput) -> RustBuffer { + return FfiConverterTypeTxInput.lower(value) +} + + +/** + * Details about a transaction output. + */ +public struct TxOutput { + /** + * The script public key (hex-encoded). + */ + public var scriptpubkey: String + /** + * The script public key type (e.g., "p2pkh", "p2sh", "p2wpkh", "p2wsh", "p2tr"). + */ + public var scriptpubkeyType: String? + /** + * The address corresponding to this script (if decodable). + */ + public var scriptpubkeyAddress: String? + /** + * The value in satoshis. + */ + public var value: Int64 + /** + * The output index in the transaction. + */ + public var n: UInt32 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * The script public key (hex-encoded). + */scriptpubkey: String, + /** + * The script public key type (e.g., "p2pkh", "p2sh", "p2wpkh", "p2wsh", "p2tr"). + */scriptpubkeyType: String?, + /** + * The address corresponding to this script (if decodable). + */scriptpubkeyAddress: String?, + /** + * The value in satoshis. + */value: Int64, + /** + * The output index in the transaction. + */n: UInt32) { + self.scriptpubkey = scriptpubkey + self.scriptpubkeyType = scriptpubkeyType + self.scriptpubkeyAddress = scriptpubkeyAddress + self.value = value + self.n = n + } +} + +#if compiler(>=6) +extension TxOutput: Sendable {} +#endif + + +extension TxOutput: Equatable, Hashable { + public static func ==(lhs: TxOutput, rhs: TxOutput) -> Bool { + if lhs.scriptpubkey != rhs.scriptpubkey { + return false + } + if lhs.scriptpubkeyType != rhs.scriptpubkeyType { + return false + } + if lhs.scriptpubkeyAddress != rhs.scriptpubkeyAddress { + return false + } + if lhs.value != rhs.value { + return false + } + if lhs.n != rhs.n { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(scriptpubkey) + hasher.combine(scriptpubkeyType) + hasher.combine(scriptpubkeyAddress) + hasher.combine(value) + hasher.combine(n) + } +} + +extension TxOutput: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTxOutput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TxOutput { + return + try TxOutput( + scriptpubkey: FfiConverterString.read(from: &buf), + scriptpubkeyType: FfiConverterOptionString.read(from: &buf), + scriptpubkeyAddress: FfiConverterOptionString.read(from: &buf), + value: FfiConverterInt64.read(from: &buf), + n: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: TxOutput, into buf: inout [UInt8]) { + FfiConverterString.write(value.scriptpubkey, into: &buf) + FfiConverterOptionString.write(value.scriptpubkeyType, into: &buf) + FfiConverterOptionString.write(value.scriptpubkeyAddress, into: &buf) + FfiConverterInt64.write(value.value, into: &buf) + FfiConverterUInt32.write(value.n, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxOutput_lift(_ buf: RustBuffer) throws -> TxOutput { + return try FfiConverterTypeTxOutput.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTxOutput_lower(_ value: TxOutput) -> RustBuffer { + return FfiConverterTypeTxOutput.lower(value) +} + + +/** + * Current state after accepting a scanned UR frame. + */ +public struct UrDecoderStatus { + /** + * Estimated completion from 0.0 through 1.0. + */ + public var progress: Double + /** + * Fountain source-fragment count, or 1 for a single-part UR. + */ + public var fragmentCount: UInt32 + /** + * Present once the complete message has been decoded. + */ + public var payload: UrPayload? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Estimated completion from 0.0 through 1.0. + */progress: Double, + /** + * Fountain source-fragment count, or 1 for a single-part UR. + */fragmentCount: UInt32, + /** + * Present once the complete message has been decoded. + */payload: UrPayload?) { + self.progress = progress + self.fragmentCount = fragmentCount + self.payload = payload + } +} + +#if compiler(>=6) +extension UrDecoderStatus: Sendable {} +#endif + + +extension UrDecoderStatus: Equatable, Hashable { + public static func ==(lhs: UrDecoderStatus, rhs: UrDecoderStatus) -> Bool { + if lhs.progress != rhs.progress { + return false + } + if lhs.fragmentCount != rhs.fragmentCount { + return false + } + if lhs.payload != rhs.payload { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(progress) + hasher.combine(fragmentCount) + hasher.combine(payload) + } +} + +extension UrDecoderStatus: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeUrDecoderStatus: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UrDecoderStatus { + return + try UrDecoderStatus( + progress: FfiConverterDouble.read(from: &buf), + fragmentCount: FfiConverterUInt32.read(from: &buf), + payload: FfiConverterOptionTypeUrPayload.read(from: &buf) + ) + } + + public static func write(_ value: UrDecoderStatus, into buf: inout [UInt8]) { + FfiConverterDouble.write(value.progress, into: &buf) + FfiConverterUInt32.write(value.fragmentCount, into: &buf) + FfiConverterOptionTypeUrPayload.write(value.payload, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeUrDecoderStatus_lift(_ buf: RustBuffer) throws -> UrDecoderStatus { + return try FfiConverterTypeUrDecoderStatus.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeUrDecoderStatus_lower(_ value: UrDecoderStatus) -> RustBuffer { + return FfiConverterTypeUrDecoderStatus.lower(value) +} + + +public struct ValidationResult { + public var address: String + public var network: NetworkType + public var addressType: AddressType + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(address: String, network: NetworkType, addressType: AddressType) { + self.address = address + self.network = network + self.addressType = addressType + } +} + +#if compiler(>=6) +extension ValidationResult: Sendable {} +#endif + + +extension ValidationResult: Equatable, Hashable { + public static func ==(lhs: ValidationResult, rhs: ValidationResult) -> Bool { + if lhs.address != rhs.address { + return false + } + if lhs.network != rhs.network { + return false + } + if lhs.addressType != rhs.addressType { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(address) + hasher.combine(network) + hasher.combine(addressType) + } +} + +extension ValidationResult: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeValidationResult: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ValidationResult { + return + try ValidationResult( + address: FfiConverterString.read(from: &buf), + network: FfiConverterTypeNetworkType.read(from: &buf), + addressType: FfiConverterTypeAddressType.read(from: &buf) + ) + } + + public static func write(_ value: ValidationResult, into buf: inout [UInt8]) { + FfiConverterString.write(value.address, into: &buf) + FfiConverterTypeNetworkType.write(value.network, into: &buf) + FfiConverterTypeAddressType.write(value.addressType, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeValidationResult_lift(_ buf: RustBuffer) throws -> ValidationResult { + return try FfiConverterTypeValidationResult.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeValidationResult_lower(_ value: ValidationResult) -> RustBuffer { + return FfiConverterTypeValidationResult.lower(value) +} + + +/** + * Balance breakdown from BDK. + */ +public struct WalletBalance { + /** + * Confirmed and spendable balance (sats) + */ + public var confirmed: UInt64 + /** + * Immature coinbase outputs (sats) + */ + public var immature: UInt64 + /** + * Unconfirmed UTXOs from trusted sources (own change) (sats) + */ + public var trustedPending: UInt64 + /** + * Unconfirmed UTXOs from external sources (sats) + */ + public var untrustedPending: UInt64 + /** + * Total spendable: confirmed + trusted_pending (sats) + */ + public var spendable: UInt64 + /** + * Grand total: all categories (sats) + */ + public var total: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Confirmed and spendable balance (sats) + */confirmed: UInt64, + /** + * Immature coinbase outputs (sats) + */immature: UInt64, + /** + * Unconfirmed UTXOs from trusted sources (own change) (sats) + */trustedPending: UInt64, + /** + * Unconfirmed UTXOs from external sources (sats) + */untrustedPending: UInt64, + /** + * Total spendable: confirmed + trusted_pending (sats) + */spendable: UInt64, + /** + * Grand total: all categories (sats) + */total: UInt64) { + self.confirmed = confirmed + self.immature = immature + self.trustedPending = trustedPending + self.untrustedPending = untrustedPending + self.spendable = spendable + self.total = total + } +} + +#if compiler(>=6) +extension WalletBalance: Sendable {} +#endif + + +extension WalletBalance: Equatable, Hashable { + public static func ==(lhs: WalletBalance, rhs: WalletBalance) -> Bool { + if lhs.confirmed != rhs.confirmed { + return false + } + if lhs.immature != rhs.immature { + return false + } + if lhs.trustedPending != rhs.trustedPending { + return false + } + if lhs.untrustedPending != rhs.untrustedPending { + return false + } + if lhs.spendable != rhs.spendable { + return false + } + if lhs.total != rhs.total { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(confirmed) + hasher.combine(immature) + hasher.combine(trustedPending) + hasher.combine(untrustedPending) + hasher.combine(spendable) + hasher.combine(total) + } +} + +extension WalletBalance: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeWalletBalance: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> WalletBalance { + return + try WalletBalance( + confirmed: FfiConverterUInt64.read(from: &buf), + immature: FfiConverterUInt64.read(from: &buf), + trustedPending: FfiConverterUInt64.read(from: &buf), + untrustedPending: FfiConverterUInt64.read(from: &buf), + spendable: FfiConverterUInt64.read(from: &buf), + total: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: WalletBalance, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.confirmed, into: &buf) + FfiConverterUInt64.write(value.immature, into: &buf) + FfiConverterUInt64.write(value.trustedPending, into: &buf) + FfiConverterUInt64.write(value.untrustedPending, into: &buf) + FfiConverterUInt64.write(value.spendable, into: &buf) + FfiConverterUInt64.write(value.total, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWalletBalance_lift(_ buf: RustBuffer) throws -> WalletBalance { + return try FfiConverterTypeWalletBalance.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWalletBalance_lower(_ value: WalletBalance) -> RustBuffer { + return FfiConverterTypeWalletBalance.lower(value) +} + + +/** + * Common parameters for creating and syncing a watch-only BDK wallet. + */ +public struct WalletParams { + /** + * Extended public key (xpub/ypub/zpub/tpub/upub/vpub) + */ + public var extendedKey: String + /** + * Electrum server URL for wallet sync + */ + public var electrumUrl: String + /** + * Root fingerprint hex (e.g. "73c5da0a"). Required for hardware wallet signing. + */ + public var fingerprint: String? + /** + * Bitcoin network (auto-detected from key prefix if not specified) + */ + public var network: Network? + /** + * Override account type for ambiguous key prefixes (xpub/tpub) + */ + public var accountType: AccountType? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Extended public key (xpub/ypub/zpub/tpub/upub/vpub) + */extendedKey: String, + /** + * Electrum server URL for wallet sync + */electrumUrl: String, + /** + * Root fingerprint hex (e.g. "73c5da0a"). Required for hardware wallet signing. + */fingerprint: String?, + /** + * Bitcoin network (auto-detected from key prefix if not specified) + */network: Network?, + /** + * Override account type for ambiguous key prefixes (xpub/tpub) + */accountType: AccountType?) { + self.extendedKey = extendedKey + self.electrumUrl = electrumUrl + self.fingerprint = fingerprint + self.network = network + self.accountType = accountType + } +} + +#if compiler(>=6) +extension WalletParams: Sendable {} +#endif + + +extension WalletParams: Equatable, Hashable { + public static func ==(lhs: WalletParams, rhs: WalletParams) -> Bool { + if lhs.extendedKey != rhs.extendedKey { + return false + } + if lhs.electrumUrl != rhs.electrumUrl { + return false + } + if lhs.fingerprint != rhs.fingerprint { + return false + } + if lhs.network != rhs.network { + return false + } + if lhs.accountType != rhs.accountType { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(extendedKey) + hasher.combine(electrumUrl) + hasher.combine(fingerprint) + hasher.combine(network) + hasher.combine(accountType) + } +} + +extension WalletParams: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeWalletParams: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> WalletParams { + return + try WalletParams( + extendedKey: FfiConverterString.read(from: &buf), + electrumUrl: FfiConverterString.read(from: &buf), + fingerprint: FfiConverterOptionString.read(from: &buf), + network: FfiConverterOptionTypeNetwork.read(from: &buf), + accountType: FfiConverterOptionTypeAccountType.read(from: &buf) + ) + } + + public static func write(_ value: WalletParams, into buf: inout [UInt8]) { + FfiConverterString.write(value.extendedKey, into: &buf) + FfiConverterString.write(value.electrumUrl, into: &buf) + FfiConverterOptionString.write(value.fingerprint, into: &buf) + FfiConverterOptionTypeNetwork.write(value.network, into: &buf) + FfiConverterOptionTypeAccountType.write(value.accountType, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWalletParams_lift(_ buf: RustBuffer) throws -> WalletParams { + return try FfiConverterTypeWalletParams.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWalletParams_lower(_ value: WalletParams) -> RustBuffer { + return FfiConverterTypeWalletParams.lower(value) +} + + +/** + * Parameters for starting an xpub transaction watcher. + */ +public struct WatcherParams { + /** + * Caller-supplied identifier for this watcher. + */ + public var watcherId: String + /** + * Wallet id that scopes the activities this watcher emits. Apps may use + * one wallet id for several account watchers and merge their snapshots. + */ + public var walletId: String + /** + * Extended public key (xpub/ypub/zpub/tpub/upub/vpub). + */ + public var extendedKey: String + /** + * Electrum server URL (e.g. "ssl://electrum.example.com:50002"). + */ + public var electrumUrl: String + /** + * Bitcoin network override (auto-detected from key prefix if None). + */ + public var network: Network? + /** + * Account type override (auto-detected from key prefix if None). + */ + public var accountType: AccountType? + /** + * Number of unused addresses to monitor beyond the last used + * (defaults to `DEFAULT_GAP_LIMIT` when None). + */ + public var gapLimit: UInt32? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Caller-supplied identifier for this watcher. + */watcherId: String, + /** + * Wallet id that scopes the activities this watcher emits. Apps may use + * one wallet id for several account watchers and merge their snapshots. + */walletId: String, + /** + * Extended public key (xpub/ypub/zpub/tpub/upub/vpub). + */extendedKey: String, + /** + * Electrum server URL (e.g. "ssl://electrum.example.com:50002"). + */electrumUrl: String, + /** + * Bitcoin network override (auto-detected from key prefix if None). + */network: Network?, + /** + * Account type override (auto-detected from key prefix if None). + */accountType: AccountType?, + /** + * Number of unused addresses to monitor beyond the last used + * (defaults to `DEFAULT_GAP_LIMIT` when None). + */gapLimit: UInt32?) { + self.watcherId = watcherId + self.walletId = walletId + self.extendedKey = extendedKey + self.electrumUrl = electrumUrl + self.network = network + self.accountType = accountType + self.gapLimit = gapLimit + } +} + +#if compiler(>=6) +extension WatcherParams: Sendable {} +#endif + + +extension WatcherParams: Equatable, Hashable { + public static func ==(lhs: WatcherParams, rhs: WatcherParams) -> Bool { + if lhs.watcherId != rhs.watcherId { + return false + } + if lhs.walletId != rhs.walletId { + return false + } + if lhs.extendedKey != rhs.extendedKey { + return false + } + if lhs.electrumUrl != rhs.electrumUrl { + return false + } + if lhs.network != rhs.network { + return false + } + if lhs.accountType != rhs.accountType { + return false + } + if lhs.gapLimit != rhs.gapLimit { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(watcherId) + hasher.combine(walletId) + hasher.combine(extendedKey) + hasher.combine(electrumUrl) + hasher.combine(network) + hasher.combine(accountType) + hasher.combine(gapLimit) + } +} + +extension WatcherParams: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeWatcherParams: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> WatcherParams { + return + try WatcherParams( + watcherId: FfiConverterString.read(from: &buf), + walletId: FfiConverterString.read(from: &buf), + extendedKey: FfiConverterString.read(from: &buf), + electrumUrl: FfiConverterString.read(from: &buf), + network: FfiConverterOptionTypeNetwork.read(from: &buf), + accountType: FfiConverterOptionTypeAccountType.read(from: &buf), + gapLimit: FfiConverterOptionUInt32.read(from: &buf) + ) + } + + public static func write(_ value: WatcherParams, into buf: inout [UInt8]) { + FfiConverterString.write(value.watcherId, into: &buf) + FfiConverterString.write(value.walletId, into: &buf) + FfiConverterString.write(value.extendedKey, into: &buf) + FfiConverterString.write(value.electrumUrl, into: &buf) + FfiConverterOptionTypeNetwork.write(value.network, into: &buf) + FfiConverterOptionTypeAccountType.write(value.accountType, into: &buf) + FfiConverterOptionUInt32.write(value.gapLimit, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWatcherParams_lift(_ buf: RustBuffer) throws -> WatcherParams { + return try FfiConverterTypeWatcherParams.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWatcherParams_lower(_ value: WatcherParams) -> RustBuffer { + return FfiConverterTypeWatcherParams.lower(value) +} + + +/** + * Errors specific to account info operations (BDK/Electrum-based). + */ +public enum AccountInfoError: Swift.Error { + + + + /** + * The provided extended public key is invalid or cannot be parsed + */ + case InvalidExtendedKey(errorDetails: String + ) + /** + * The provided address is invalid + */ + case InvalidAddress(errorDetails: String + ) + /** + * Electrum connection or query failed + */ + case ElectrumError(errorDetails: String + ) + /** + * BDK wallet creation or operation error + */ + case WalletError(errorDetails: String + ) + /** + * Wallet sync with Electrum failed + */ + case SyncError(errorDetails: String + ) + /** + * The key type/prefix is not recognized + */ + case UnsupportedKeyType(errorDetails: String + ) + /** + * Network mismatch between key prefix and specified network + */ + case NetworkMismatch(errorDetails: String + ) + /** + * Invalid transaction ID provided + */ + case InvalidTxid(errorDetails: String + ) + /** + * A valid transaction ID was not found in the wallet + */ + case TransactionNotFound(errorDetails: String + ) + /** + * Watcher lifecycle or subscription error + */ + case WatcherError(errorDetails: String + ) +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAccountInfoError: FfiConverterRustBuffer { + typealias SwiftType = AccountInfoError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AccountInfoError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .InvalidExtendedKey( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 2: return .InvalidAddress( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 3: return .ElectrumError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 4: return .WalletError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 5: return .SyncError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 6: return .UnsupportedKeyType( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 7: return .NetworkMismatch( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 8: return .InvalidTxid( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 9: return .TransactionNotFound( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 10: return .WatcherError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: AccountInfoError, into buf: inout [UInt8]) { + switch value { + + + + + + case let .InvalidExtendedKey(errorDetails): + writeInt(&buf, Int32(1)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InvalidAddress(errorDetails): + writeInt(&buf, Int32(2)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .ElectrumError(errorDetails): + writeInt(&buf, Int32(3)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .WalletError(errorDetails): + writeInt(&buf, Int32(4)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .SyncError(errorDetails): + writeInt(&buf, Int32(5)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .UnsupportedKeyType(errorDetails): + writeInt(&buf, Int32(6)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .NetworkMismatch(errorDetails): + writeInt(&buf, Int32(7)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InvalidTxid(errorDetails): + writeInt(&buf, Int32(8)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .TransactionNotFound(errorDetails): + writeInt(&buf, Int32(9)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .WatcherError(errorDetails): + writeInt(&buf, Int32(10)) + FfiConverterString.write(errorDetails, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAccountInfoError_lift(_ buf: RustBuffer) throws -> AccountInfoError { + return try FfiConverterTypeAccountInfoError.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAccountInfoError_lower(_ value: AccountInfoError) -> RustBuffer { + return FfiConverterTypeAccountInfoError.lower(value) +} + + +extension AccountInfoError: Equatable, Hashable {} + +extension AccountInfoError: Codable {} + + + + +extension AccountInfoError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} + + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * Account type classification for extended public keys. + * + * Determines the BIP standard, derivation path purpose, and script type. + */ + +public enum AccountType { + + /** + * BIP44 legacy (P2PKH) — xpub/tpub prefix + */ + case legacy + /** + * BIP49 wrapped segwit (P2SH-P2WPKH) — ypub/upub prefix + */ + case wrappedSegwit + /** + * BIP84 native segwit (P2WPKH) — zpub/vpub prefix + */ + case nativeSegwit + /** + * BIP86 taproot (P2TR) + */ + case taproot +} + + +#if compiler(>=6) +extension AccountType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAccountType: FfiConverterRustBuffer { + typealias SwiftType = AccountType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AccountType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .legacy + + case 2: return .wrappedSegwit + + case 3: return .nativeSegwit + + case 4: return .taproot + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: AccountType, into buf: inout [UInt8]) { + switch value { + + + case .legacy: + writeInt(&buf, Int32(1)) + + + case .wrappedSegwit: + writeInt(&buf, Int32(2)) + + + case .nativeSegwit: + writeInt(&buf, Int32(3)) + + + case .taproot: + writeInt(&buf, Int32(4)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAccountType_lift(_ buf: RustBuffer) throws -> AccountType { + return try FfiConverterTypeAccountType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAccountType_lower(_ value: AccountType) -> RustBuffer { + return FfiConverterTypeAccountType.lower(value) +} + + +extension AccountType: Equatable, Hashable {} + +extension AccountType: Codable {} + + + + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum Activity { + + case onchain(OnchainActivity + ) + case lightning(LightningActivity + ) +} + + +#if compiler(>=6) +extension Activity: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeActivity: FfiConverterRustBuffer { + typealias SwiftType = Activity + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Activity { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .onchain(try FfiConverterTypeOnchainActivity.read(from: &buf) + ) + + case 2: return .lightning(try FfiConverterTypeLightningActivity.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Activity, into buf: inout [UInt8]) { + switch value { + + + case let .onchain(v1): + writeInt(&buf, Int32(1)) + FfiConverterTypeOnchainActivity.write(v1, into: &buf) + + + case let .lightning(v1): + writeInt(&buf, Int32(2)) + FfiConverterTypeLightningActivity.write(v1, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivity_lift(_ buf: RustBuffer) throws -> Activity { + return try FfiConverterTypeActivity.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivity_lower(_ value: Activity) -> RustBuffer { + return FfiConverterTypeActivity.lower(value) +} + + +extension Activity: Equatable, Hashable {} + +extension Activity: Codable {} + + + + + + + +public enum ActivityError: Swift.Error { + + + + case InvalidActivity(errorDetails: String + ) + case InitializationError(errorDetails: String + ) + case InsertError(errorDetails: String + ) + case RetrievalError(errorDetails: String + ) + case DataError(errorDetails: String + ) + case ConnectionError(errorDetails: String + ) + case SerializationError(errorDetails: String + ) +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeActivityError: FfiConverterRustBuffer { + typealias SwiftType = ActivityError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActivityError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .InvalidActivity( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 2: return .InitializationError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 3: return .InsertError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 4: return .RetrievalError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 5: return .DataError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 6: return .ConnectionError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 7: return .SerializationError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ActivityError, into buf: inout [UInt8]) { + switch value { + + + + + + case let .InvalidActivity(errorDetails): + writeInt(&buf, Int32(1)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InitializationError(errorDetails): + writeInt(&buf, Int32(2)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InsertError(errorDetails): + writeInt(&buf, Int32(3)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .RetrievalError(errorDetails): + writeInt(&buf, Int32(4)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .DataError(errorDetails): + writeInt(&buf, Int32(5)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .ConnectionError(errorDetails): + writeInt(&buf, Int32(6)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .SerializationError(errorDetails): + writeInt(&buf, Int32(7)) + FfiConverterString.write(errorDetails, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityError_lift(_ buf: RustBuffer) throws -> ActivityError { + return try FfiConverterTypeActivityError.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityError_lower(_ value: ActivityError) -> RustBuffer { + return FfiConverterTypeActivityError.lower(value) +} + + +extension ActivityError: Equatable, Hashable {} + +extension ActivityError: Codable {} + + + + +extension ActivityError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} + + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ActivityFilter { + + case all + case lightning + case onchain +} + + +#if compiler(>=6) +extension ActivityFilter: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeActivityFilter: FfiConverterRustBuffer { + typealias SwiftType = ActivityFilter + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActivityFilter { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .all + + case 2: return .lightning + + case 3: return .onchain + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ActivityFilter, into buf: inout [UInt8]) { + switch value { + + + case .all: + writeInt(&buf, Int32(1)) + + + case .lightning: + writeInt(&buf, Int32(2)) + + + case .onchain: + writeInt(&buf, Int32(3)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityFilter_lift(_ buf: RustBuffer) throws -> ActivityFilter { + return try FfiConverterTypeActivityFilter.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityFilter_lower(_ value: ActivityFilter) -> RustBuffer { + return FfiConverterTypeActivityFilter.lower(value) +} + + +extension ActivityFilter: Equatable, Hashable {} + +extension ActivityFilter: Codable {} + + + + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ActivityType { + + case onchain + case lightning +} + + +#if compiler(>=6) +extension ActivityType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeActivityType: FfiConverterRustBuffer { + typealias SwiftType = ActivityType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActivityType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .onchain + + case 2: return .lightning + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ActivityType, into buf: inout [UInt8]) { + switch value { + + + case .onchain: + writeInt(&buf, Int32(1)) + + + case .lightning: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityType_lift(_ buf: RustBuffer) throws -> ActivityType { + return try FfiConverterTypeActivityType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityType_lower(_ value: ActivityType) -> RustBuffer { + return FfiConverterTypeActivityType.lower(value) +} + + +extension ActivityType: Equatable, Hashable {} + +extension ActivityType: Codable {} + + + + + + + +public enum AddressError: Swift.Error { + + + + case InvalidAddress + case InvalidNetwork + case MnemonicGenerationFailed + case InvalidMnemonic + case InvalidEntropy + case AddressDerivationFailed +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAddressError: FfiConverterRustBuffer { + typealias SwiftType = AddressError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AddressError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .InvalidAddress + case 2: return .InvalidNetwork + case 3: return .MnemonicGenerationFailed + case 4: return .InvalidMnemonic + case 5: return .InvalidEntropy + case 6: return .AddressDerivationFailed + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: AddressError, into buf: inout [UInt8]) { + switch value { + + + + + + case .InvalidAddress: + writeInt(&buf, Int32(1)) + + + case .InvalidNetwork: + writeInt(&buf, Int32(2)) + + + case .MnemonicGenerationFailed: + writeInt(&buf, Int32(3)) + + + case .InvalidMnemonic: + writeInt(&buf, Int32(4)) + + + case .InvalidEntropy: + writeInt(&buf, Int32(5)) + + + case .AddressDerivationFailed: + writeInt(&buf, Int32(6)) + + } } } @@ -14839,182 +16916,105 @@ public struct FfiConverterTypeWatcherParams: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeWatcherParams_lift(_ buf: RustBuffer) throws -> WatcherParams { - return try FfiConverterTypeWatcherParams.lift(buf) +public func FfiConverterTypeAddressError_lift(_ buf: RustBuffer) throws -> AddressError { + return try FfiConverterTypeAddressError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeWatcherParams_lower(_ value: WatcherParams) -> RustBuffer { - return FfiConverterTypeWatcherParams.lower(value) +public func FfiConverterTypeAddressError_lower(_ value: AddressError) -> RustBuffer { + return FfiConverterTypeAddressError.lower(value) } -/** - * Errors specific to account info operations (BDK/Electrum-based). - */ -public enum AccountInfoError: Swift.Error { +extension AddressError: Equatable, Hashable {} +extension AddressError: Codable {} + + + + +extension AddressError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} + + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum AddressType { - - /** - * The provided extended public key is invalid or cannot be parsed - */ - case InvalidExtendedKey(errorDetails: String - ) - /** - * The provided address is invalid - */ - case InvalidAddress(errorDetails: String - ) - /** - * Electrum connection or query failed - */ - case ElectrumError(errorDetails: String - ) - /** - * BDK wallet creation or operation error - */ - case WalletError(errorDetails: String - ) - /** - * Wallet sync with Electrum failed - */ - case SyncError(errorDetails: String - ) - /** - * The key type/prefix is not recognized - */ - case UnsupportedKeyType(errorDetails: String - ) - /** - * Network mismatch between key prefix and specified network - */ - case NetworkMismatch(errorDetails: String - ) - /** - * Invalid transaction ID provided - */ - case InvalidTxid(errorDetails: String - ) - /** - * A valid transaction ID was not found in the wallet - */ - case TransactionNotFound(errorDetails: String - ) - /** - * Watcher lifecycle or subscription error - */ - case WatcherError(errorDetails: String - ) + case p2pkh + case p2sh + case p2wpkh + case p2wsh + case p2tr + case unknown } +#if compiler(>=6) +extension AddressType: Sendable {} +#endif + #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeAccountInfoError: FfiConverterRustBuffer { - typealias SwiftType = AccountInfoError +public struct FfiConverterTypeAddressType: FfiConverterRustBuffer { + typealias SwiftType = AddressType - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AccountInfoError { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AddressType { let variant: Int32 = try readInt(&buf) switch variant { - - + case 1: return .p2pkh - case 1: return .InvalidExtendedKey( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 2: return .InvalidAddress( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 3: return .ElectrumError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 4: return .WalletError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 5: return .SyncError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 6: return .UnsupportedKeyType( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 7: return .NetworkMismatch( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 8: return .InvalidTxid( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 9: return .TransactionNotFound( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 10: return .WatcherError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - - default: throw UniffiInternalError.unexpectedEnumCase + case 2: return .p2sh + + case 3: return .p2wpkh + + case 4: return .p2wsh + + case 5: return .p2tr + + case 6: return .unknown + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: AccountInfoError, into buf: inout [UInt8]) { + public static func write(_ value: AddressType, into buf: inout [UInt8]) { switch value { - - - - case let .InvalidExtendedKey(errorDetails): + case .p2pkh: writeInt(&buf, Int32(1)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .InvalidAddress(errorDetails): + + case .p2sh: writeInt(&buf, Int32(2)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .ElectrumError(errorDetails): + + case .p2wpkh: writeInt(&buf, Int32(3)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .WalletError(errorDetails): - writeInt(&buf, Int32(4)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .SyncError(errorDetails): - writeInt(&buf, Int32(5)) - FfiConverterString.write(errorDetails, into: &buf) - + case .p2wsh: + writeInt(&buf, Int32(4)) - case let .UnsupportedKeyType(errorDetails): - writeInt(&buf, Int32(6)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .NetworkMismatch(errorDetails): - writeInt(&buf, Int32(7)) - FfiConverterString.write(errorDetails, into: &buf) - + case .p2tr: + writeInt(&buf, Int32(5)) - case let .InvalidTxid(errorDetails): - writeInt(&buf, Int32(8)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .TransactionNotFound(errorDetails): - writeInt(&buf, Int32(9)) - FfiConverterString.write(errorDetails, into: &buf) - + case .unknown: + writeInt(&buf, Int32(6)) - case let .WatcherError(errorDetails): - writeInt(&buf, Int32(10)) - FfiConverterString.write(errorDetails, into: &buf) - } } } @@ -15023,106 +17023,82 @@ public struct FfiConverterTypeAccountInfoError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAccountInfoError_lift(_ buf: RustBuffer) throws -> AccountInfoError { - return try FfiConverterTypeAccountInfoError.lift(buf) +public func FfiConverterTypeAddressType_lift(_ buf: RustBuffer) throws -> AddressType { + return try FfiConverterTypeAddressType.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAccountInfoError_lower(_ value: AccountInfoError) -> RustBuffer { - return FfiConverterTypeAccountInfoError.lower(value) +public func FfiConverterTypeAddressType_lower(_ value: AddressType) -> RustBuffer { + return FfiConverterTypeAddressType.lower(value) } -extension AccountInfoError: Equatable, Hashable {} - -extension AccountInfoError: Codable {} - +extension AddressType: Equatable, Hashable {} +extension AddressType: Codable {} -extension AccountInfoError: Foundation.LocalizedError { - public var errorDescription: String? { - String(reflecting: self) - } -} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * Account type classification for extended public keys. - * - * Determines the BIP standard, derivation path purpose, and script type. - */ -public enum AccountType { +public enum BitcoinNetworkEnum { - /** - * BIP44 legacy (P2PKH) — xpub/tpub prefix - */ - case legacy - /** - * BIP49 wrapped segwit (P2SH-P2WPKH) — ypub/upub prefix - */ - case wrappedSegwit - /** - * BIP84 native segwit (P2WPKH) — zpub/vpub prefix - */ - case nativeSegwit - /** - * BIP86 taproot (P2TR) - */ - case taproot + case mainnet + case testnet + case signet + case regtest } #if compiler(>=6) -extension AccountType: Sendable {} +extension BitcoinNetworkEnum: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeAccountType: FfiConverterRustBuffer { - typealias SwiftType = AccountType +public struct FfiConverterTypeBitcoinNetworkEnum: FfiConverterRustBuffer { + typealias SwiftType = BitcoinNetworkEnum - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AccountType { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BitcoinNetworkEnum { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .legacy + case 1: return .mainnet - case 2: return .wrappedSegwit + case 2: return .testnet - case 3: return .nativeSegwit + case 3: return .signet - case 4: return .taproot + case 4: return .regtest default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: AccountType, into buf: inout [UInt8]) { + public static func write(_ value: BitcoinNetworkEnum, into buf: inout [UInt8]) { switch value { - case .legacy: + case .mainnet: writeInt(&buf, Int32(1)) - case .wrappedSegwit: + case .testnet: writeInt(&buf, Int32(2)) - case .nativeSegwit: + case .signet: writeInt(&buf, Int32(3)) - case .taproot: + case .regtest: writeInt(&buf, Int32(4)) } @@ -15133,75 +17109,190 @@ public struct FfiConverterTypeAccountType: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAccountType_lift(_ buf: RustBuffer) throws -> AccountType { - return try FfiConverterTypeAccountType.lift(buf) +public func FfiConverterTypeBitcoinNetworkEnum_lift(_ buf: RustBuffer) throws -> BitcoinNetworkEnum { + return try FfiConverterTypeBitcoinNetworkEnum.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAccountType_lower(_ value: AccountType) -> RustBuffer { - return FfiConverterTypeAccountType.lower(value) +public func FfiConverterTypeBitcoinNetworkEnum_lower(_ value: BitcoinNetworkEnum) -> RustBuffer { + return FfiConverterTypeBitcoinNetworkEnum.lower(value) } -extension AccountType: Equatable, Hashable {} +extension BitcoinNetworkEnum: Equatable, Hashable {} -extension AccountType: Codable {} +extension BitcoinNetworkEnum: Codable {} -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -public enum Activity { +public enum BlocktankError: Swift.Error { + - case onchain(OnchainActivity + + case HttpClient(errorDetails: String ) - case lightning(LightningActivity + case BlocktankClient(errorDetails: String + ) + case InvalidBlocktank(errorDetails: String + ) + case InitializationError(errorDetails: String + ) + case InsertError(errorDetails: String + ) + case RetrievalError(errorDetails: String + ) + case DataError(errorDetails: String + ) + case ConnectionError(errorDetails: String + ) + case SerializationError(errorDetails: String + ) + case ChannelOpen(errorType: BtChannelOrderErrorType, errorDetails: String + ) + case OrderState(errorDetails: String + ) + case InvalidParameter(errorDetails: String + ) + case DatabaseError(errorDetails: String ) } -#if compiler(>=6) -extension Activity: Sendable {} -#endif - #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeActivity: FfiConverterRustBuffer { - typealias SwiftType = Activity +public struct FfiConverterTypeBlocktankError: FfiConverterRustBuffer { + typealias SwiftType = BlocktankError - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Activity { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BlocktankError { let variant: Int32 = try readInt(&buf) switch variant { + - case 1: return .onchain(try FfiConverterTypeOnchainActivity.read(from: &buf) - ) - - case 2: return .lightning(try FfiConverterTypeLightningActivity.read(from: &buf) - ) + - default: throw UniffiInternalError.unexpectedEnumCase + case 1: return .HttpClient( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 2: return .BlocktankClient( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 3: return .InvalidBlocktank( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 4: return .InitializationError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 5: return .InsertError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 6: return .RetrievalError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 7: return .DataError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 8: return .ConnectionError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 9: return .SerializationError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 10: return .ChannelOpen( + errorType: try FfiConverterTypeBtChannelOrderErrorType.read(from: &buf), + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 11: return .OrderState( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 12: return .InvalidParameter( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 13: return .DatabaseError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: Activity, into buf: inout [UInt8]) { + public static func write(_ value: BlocktankError, into buf: inout [UInt8]) { switch value { + + + - case let .onchain(v1): + case let .HttpClient(errorDetails): writeInt(&buf, Int32(1)) - FfiConverterTypeOnchainActivity.write(v1, into: &buf) + FfiConverterString.write(errorDetails, into: &buf) - case let .lightning(v1): + case let .BlocktankClient(errorDetails): writeInt(&buf, Int32(2)) - FfiConverterTypeLightningActivity.write(v1, into: &buf) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InvalidBlocktank(errorDetails): + writeInt(&buf, Int32(3)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InitializationError(errorDetails): + writeInt(&buf, Int32(4)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InsertError(errorDetails): + writeInt(&buf, Int32(5)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .RetrievalError(errorDetails): + writeInt(&buf, Int32(6)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .DataError(errorDetails): + writeInt(&buf, Int32(7)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .ConnectionError(errorDetails): + writeInt(&buf, Int32(8)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .SerializationError(errorDetails): + writeInt(&buf, Int32(9)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .ChannelOpen(errorType,errorDetails): + writeInt(&buf, Int32(10)) + FfiConverterTypeBtChannelOrderErrorType.write(errorType, into: &buf) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .OrderState(errorDetails): + writeInt(&buf, Int32(11)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .InvalidParameter(errorDetails): + writeInt(&buf, Int32(12)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .DatabaseError(errorDetails): + writeInt(&buf, Int32(13)) + FfiConverterString.write(errorDetails, into: &buf) } } @@ -15211,81 +17302,101 @@ public struct FfiConverterTypeActivity: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeActivity_lift(_ buf: RustBuffer) throws -> Activity { - return try FfiConverterTypeActivity.lift(buf) +public func FfiConverterTypeBlocktankError_lift(_ buf: RustBuffer) throws -> BlocktankError { + return try FfiConverterTypeBlocktankError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeActivity_lower(_ value: Activity) -> RustBuffer { - return FfiConverterTypeActivity.lower(value) +public func FfiConverterTypeBlocktankError_lower(_ value: BlocktankError) -> RustBuffer { + return FfiConverterTypeBlocktankError.lower(value) } -extension Activity: Equatable, Hashable {} +extension BlocktankError: Equatable, Hashable {} + +extension BlocktankError: Codable {} -extension Activity: Codable {} +extension BlocktankError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} -public enum ActivityError: Swift.Error { + +/** + * Errors surfaced by the Boltz swaps module. + */ +public enum BoltzError: Swift.Error { - case InvalidActivity(errorDetails: String - ) case InitializationError(errorDetails: String ) - case InsertError(errorDetails: String + case ConnectionError(errorDetails: String ) - case RetrievalError(errorDetails: String + case DatabaseError(errorDetails: String ) - case DataError(errorDetails: String + case ApiError(errorDetails: String ) - case ConnectionError(errorDetails: String + case SwapError(errorDetails: String + ) + case BroadcastError(errorDetails: String + ) + case InvalidInput(errorDetails: String ) case SerializationError(errorDetails: String ) + case NotFound(errorDetails: String + ) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeActivityError: FfiConverterRustBuffer { - typealias SwiftType = ActivityError +public struct FfiConverterTypeBoltzError: FfiConverterRustBuffer { + typealias SwiftType = BoltzError - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActivityError { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzError { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .InvalidActivity( + case 1: return .InitializationError( errorDetails: try FfiConverterString.read(from: &buf) ) - case 2: return .InitializationError( + case 2: return .ConnectionError( errorDetails: try FfiConverterString.read(from: &buf) ) - case 3: return .InsertError( + case 3: return .DatabaseError( errorDetails: try FfiConverterString.read(from: &buf) ) - case 4: return .RetrievalError( + case 4: return .ApiError( errorDetails: try FfiConverterString.read(from: &buf) ) - case 5: return .DataError( + case 5: return .SwapError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 6: return .BroadcastError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 7: return .InvalidInput( errorDetails: try FfiConverterString.read(from: &buf) ) - case 6: return .ConnectionError( + case 8: return .SerializationError( errorDetails: try FfiConverterString.read(from: &buf) ) - case 7: return .SerializationError( + case 9: return .NotFound( errorDetails: try FfiConverterString.read(from: &buf) ) @@ -15293,47 +17404,57 @@ public struct FfiConverterTypeActivityError: FfiConverterRustBuffer { } } - public static func write(_ value: ActivityError, into buf: inout [UInt8]) { + public static func write(_ value: BoltzError, into buf: inout [UInt8]) { switch value { - case let .InvalidActivity(errorDetails): + case let .InitializationError(errorDetails): writeInt(&buf, Int32(1)) FfiConverterString.write(errorDetails, into: &buf) - case let .InitializationError(errorDetails): + case let .ConnectionError(errorDetails): writeInt(&buf, Int32(2)) FfiConverterString.write(errorDetails, into: &buf) - case let .InsertError(errorDetails): + case let .DatabaseError(errorDetails): writeInt(&buf, Int32(3)) FfiConverterString.write(errorDetails, into: &buf) - case let .RetrievalError(errorDetails): + case let .ApiError(errorDetails): writeInt(&buf, Int32(4)) FfiConverterString.write(errorDetails, into: &buf) - case let .DataError(errorDetails): + case let .SwapError(errorDetails): writeInt(&buf, Int32(5)) FfiConverterString.write(errorDetails, into: &buf) - case let .ConnectionError(errorDetails): + case let .BroadcastError(errorDetails): writeInt(&buf, Int32(6)) FfiConverterString.write(errorDetails, into: &buf) - case let .SerializationError(errorDetails): + case let .InvalidInput(errorDetails): writeInt(&buf, Int32(7)) FfiConverterString.write(errorDetails, into: &buf) + + case let .SerializationError(errorDetails): + writeInt(&buf, Int32(8)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .NotFound(errorDetails): + writeInt(&buf, Int32(9)) + FfiConverterString.write(errorDetails, into: &buf) + } } } @@ -15342,26 +17463,26 @@ public struct FfiConverterTypeActivityError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeActivityError_lift(_ buf: RustBuffer) throws -> ActivityError { - return try FfiConverterTypeActivityError.lift(buf) +public func FfiConverterTypeBoltzError_lift(_ buf: RustBuffer) throws -> BoltzError { + return try FfiConverterTypeBoltzError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeActivityError_lower(_ value: ActivityError) -> RustBuffer { - return FfiConverterTypeActivityError.lower(value) +public func FfiConverterTypeBoltzError_lower(_ value: BoltzError) -> RustBuffer { + return FfiConverterTypeBoltzError.lower(value) } -extension ActivityError: Equatable, Hashable {} +extension BoltzError: Equatable, Hashable {} -extension ActivityError: Codable {} +extension BoltzError: Codable {} -extension ActivityError: Foundation.LocalizedError { +extension BoltzError: Foundation.LocalizedError { public var errorDescription: String? { String(reflecting: self) } @@ -15372,223 +17493,58 @@ extension ActivityError: Foundation.LocalizedError { // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * Bitcoin network selection for Boltz swaps. Maps to the networks Boltz + * operates on (mainnet, testnet, regtest). + */ -public enum ActivityFilter { +public enum BoltzNetwork { - case all - case lightning - case onchain + case mainnet + case testnet + case regtest } #if compiler(>=6) -extension ActivityFilter: Sendable {} +extension BoltzNetwork: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeActivityFilter: FfiConverterRustBuffer { - typealias SwiftType = ActivityFilter +public struct FfiConverterTypeBoltzNetwork: FfiConverterRustBuffer { + typealias SwiftType = BoltzNetwork - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActivityFilter { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzNetwork { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .all - - case 2: return .lightning - - case 3: return .onchain - - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: ActivityFilter, into buf: inout [UInt8]) { - switch value { - - - case .all: - writeInt(&buf, Int32(1)) - - - case .lightning: - writeInt(&buf, Int32(2)) - - - case .onchain: - writeInt(&buf, Int32(3)) - - } - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeActivityFilter_lift(_ buf: RustBuffer) throws -> ActivityFilter { - return try FfiConverterTypeActivityFilter.lift(buf) -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeActivityFilter_lower(_ value: ActivityFilter) -> RustBuffer { - return FfiConverterTypeActivityFilter.lower(value) -} - - -extension ActivityFilter: Equatable, Hashable {} - -extension ActivityFilter: Codable {} - - - - - - -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum ActivityType { - - case onchain - case lightning -} - - -#if compiler(>=6) -extension ActivityType: Sendable {} -#endif - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public struct FfiConverterTypeActivityType: FfiConverterRustBuffer { - typealias SwiftType = ActivityType - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActivityType { - let variant: Int32 = try readInt(&buf) - switch variant { + case 1: return .mainnet - case 1: return .onchain + case 2: return .testnet - case 2: return .lightning + case 3: return .regtest default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: ActivityType, into buf: inout [UInt8]) { - switch value { - - - case .onchain: - writeInt(&buf, Int32(1)) - - - case .lightning: - writeInt(&buf, Int32(2)) - - } - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeActivityType_lift(_ buf: RustBuffer) throws -> ActivityType { - return try FfiConverterTypeActivityType.lift(buf) -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeActivityType_lower(_ value: ActivityType) -> RustBuffer { - return FfiConverterTypeActivityType.lower(value) -} - - -extension ActivityType: Equatable, Hashable {} - -extension ActivityType: Codable {} - - - - - - - -public enum AddressError: Swift.Error { - - - - case InvalidAddress - case InvalidNetwork - case MnemonicGenerationFailed - case InvalidMnemonic - case InvalidEntropy - case AddressDerivationFailed -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public struct FfiConverterTypeAddressError: FfiConverterRustBuffer { - typealias SwiftType = AddressError - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AddressError { - let variant: Int32 = try readInt(&buf) - switch variant { - - - - - case 1: return .InvalidAddress - case 2: return .InvalidNetwork - case 3: return .MnemonicGenerationFailed - case 4: return .InvalidMnemonic - case 5: return .InvalidEntropy - case 6: return .AddressDerivationFailed - - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: AddressError, into buf: inout [UInt8]) { + public static func write(_ value: BoltzNetwork, into buf: inout [UInt8]) { switch value { - - - - case .InvalidAddress: + case .mainnet: writeInt(&buf, Int32(1)) - case .InvalidNetwork: + case .testnet: writeInt(&buf, Int32(2)) - case .MnemonicGenerationFailed: + case .regtest: writeInt(&buf, Int32(3)) - - case .InvalidMnemonic: - writeInt(&buf, Int32(4)) - - - case .InvalidEntropy: - writeInt(&buf, Int32(5)) - - - case .AddressDerivationFailed: - writeInt(&buf, Int32(6)) - } } } @@ -15597,105 +17553,116 @@ public struct FfiConverterTypeAddressError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAddressError_lift(_ buf: RustBuffer) throws -> AddressError { - return try FfiConverterTypeAddressError.lift(buf) +public func FfiConverterTypeBoltzNetwork_lift(_ buf: RustBuffer) throws -> BoltzNetwork { + return try FfiConverterTypeBoltzNetwork.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAddressError_lower(_ value: AddressError) -> RustBuffer { - return FfiConverterTypeAddressError.lower(value) +public func FfiConverterTypeBoltzNetwork_lower(_ value: BoltzNetwork) -> RustBuffer { + return FfiConverterTypeBoltzNetwork.lower(value) } -extension AddressError: Equatable, Hashable {} - -extension AddressError: Codable {} - +extension BoltzNetwork: Equatable, Hashable {} +extension BoltzNetwork: Codable {} -extension AddressError: Foundation.LocalizedError { - public var errorDescription: String? { - String(reflecting: self) - } -} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * Events emitted to a registered [`crate::modules::boltz::BoltzEventListener`] + * as swaps progress through their lifecycle. + */ -public enum AddressType { +public enum BoltzSwapEvent { - case p2pkh - case p2sh - case p2wpkh - case p2wsh - case p2tr - case unknown + /** + * The swap transitioned to a new status. + */ + case statusUpdate(swapId: String, status: BoltzSwapStatus + ) + /** + * A reverse swap was claimed onchain. `txid` is the claim transaction. + */ + case claimed(swapId: String, txid: String + ) + /** + * A submarine swap was refunded onchain. `txid` is the refund transaction. + */ + case refunded(swapId: String, txid: String + ) + /** + * An error occurred while processing the swap (e.g. an auto-claim failed). + */ + case error(swapId: String, message: String + ) } #if compiler(>=6) -extension AddressType: Sendable {} +extension BoltzSwapEvent: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeAddressType: FfiConverterRustBuffer { - typealias SwiftType = AddressType +public struct FfiConverterTypeBoltzSwapEvent: FfiConverterRustBuffer { + typealias SwiftType = BoltzSwapEvent - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AddressType { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzSwapEvent { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .p2pkh - - case 2: return .p2sh - - case 3: return .p2wpkh + case 1: return .statusUpdate(swapId: try FfiConverterString.read(from: &buf), status: try FfiConverterTypeBoltzSwapStatus.read(from: &buf) + ) - case 4: return .p2wsh + case 2: return .claimed(swapId: try FfiConverterString.read(from: &buf), txid: try FfiConverterString.read(from: &buf) + ) - case 5: return .p2tr + case 3: return .refunded(swapId: try FfiConverterString.read(from: &buf), txid: try FfiConverterString.read(from: &buf) + ) - case 6: return .unknown + case 4: return .error(swapId: try FfiConverterString.read(from: &buf), message: try FfiConverterString.read(from: &buf) + ) default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: AddressType, into buf: inout [UInt8]) { + public static func write(_ value: BoltzSwapEvent, into buf: inout [UInt8]) { switch value { - case .p2pkh: + case let .statusUpdate(swapId,status): writeInt(&buf, Int32(1)) + FfiConverterString.write(swapId, into: &buf) + FfiConverterTypeBoltzSwapStatus.write(status, into: &buf) + - - case .p2sh: + case let .claimed(swapId,txid): writeInt(&buf, Int32(2)) + FfiConverterString.write(swapId, into: &buf) + FfiConverterString.write(txid, into: &buf) + - - case .p2wpkh: + case let .refunded(swapId,txid): writeInt(&buf, Int32(3)) + FfiConverterString.write(swapId, into: &buf) + FfiConverterString.write(txid, into: &buf) + - - case .p2wsh: + case let .error(swapId,message): writeInt(&buf, Int32(4)) - - - case .p2tr: - writeInt(&buf, Int32(5)) - - - case .unknown: - writeInt(&buf, Int32(6)) - + FfiConverterString.write(swapId, into: &buf) + FfiConverterString.write(message, into: &buf) + } } } @@ -15704,21 +17671,21 @@ public struct FfiConverterTypeAddressType: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAddressType_lift(_ buf: RustBuffer) throws -> AddressType { - return try FfiConverterTypeAddressType.lift(buf) +public func FfiConverterTypeBoltzSwapEvent_lift(_ buf: RustBuffer) throws -> BoltzSwapEvent { + return try FfiConverterTypeBoltzSwapEvent.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeAddressType_lower(_ value: AddressType) -> RustBuffer { - return FfiConverterTypeAddressType.lower(value) +public func FfiConverterTypeBoltzSwapEvent_lower(_ value: BoltzSwapEvent) -> RustBuffer { + return FfiConverterTypeBoltzSwapEvent.lower(value) } -extension AddressType: Equatable, Hashable {} +extension BoltzSwapEvent: Equatable, Hashable {} -extension AddressType: Codable {} +extension BoltzSwapEvent: Codable {} @@ -15727,61 +17694,202 @@ extension AddressType: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * Typed view of the Boltz swap lifecycle. `Unknown` carries the raw status so + * new server-side states don't break the bindings. + * + * See . + */ -public enum BitcoinNetworkEnum { +public enum BoltzSwapStatus { - case mainnet - case testnet - case signet - case regtest + /** + * `swap.created` — initial state. + */ + case swapCreated + /** + * `invoice.set` — invoice attached to a submarine swap. + */ + case invoiceSet + /** + * `transaction.mempool` — a lockup transaction is in the mempool. + */ + case transactionMempool + /** + * `transaction.confirmed` — a lockup transaction confirmed. + */ + case transactionConfirmed + /** + * `invoice.pending` — Boltz is paying the submarine swap invoice. + */ + case invoicePending + /** + * `invoice.paid` — submarine swap invoice paid by Boltz. + */ + case invoicePaid + /** + * `invoice.settled` — reverse swap invoice settled (preimage revealed). + */ + case invoiceSettled + /** + * `invoice.failedToPay` — submarine swap invoice could not be paid; refund. + */ + case invoiceFailedToPay + /** + * `invoice.expired` — reverse swap invoice expired before payment. + */ + case invoiceExpired + /** + * `transaction.claim.pending` — Boltz ready for a cooperative claim. + */ + case transactionClaimPending + /** + * `transaction.claimed` — onchain funds claimed. + */ + case transactionClaimed + /** + * `transaction.refunded` — onchain funds refunded. + */ + case transactionRefunded + /** + * `transaction.lockupFailed` — wrong amount locked; can refund. + */ + case transactionLockupFailed + /** + * `transaction.failed` — Boltz failed to lock the agreed funds. + */ + case transactionFailed + /** + * `swap.expired` — swap expired without completing. + */ + case swapExpired + /** + * Any status not yet modelled. `raw` holds the verbatim Boltz status. + */ + case unknown(raw: String + ) } #if compiler(>=6) -extension BitcoinNetworkEnum: Sendable {} +extension BoltzSwapStatus: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBitcoinNetworkEnum: FfiConverterRustBuffer { - typealias SwiftType = BitcoinNetworkEnum +public struct FfiConverterTypeBoltzSwapStatus: FfiConverterRustBuffer { + typealias SwiftType = BoltzSwapStatus - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BitcoinNetworkEnum { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzSwapStatus { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .mainnet + case 1: return .swapCreated + + case 2: return .invoiceSet + + case 3: return .transactionMempool + + case 4: return .transactionConfirmed + + case 5: return .invoicePending + + case 6: return .invoicePaid + + case 7: return .invoiceSettled + + case 8: return .invoiceFailedToPay + + case 9: return .invoiceExpired + + case 10: return .transactionClaimPending + + case 11: return .transactionClaimed + + case 12: return .transactionRefunded + + case 13: return .transactionLockupFailed + + case 14: return .transactionFailed + + case 15: return .swapExpired + + case 16: return .unknown(raw: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: BoltzSwapStatus, into buf: inout [UInt8]) { + switch value { + + + case .swapCreated: + writeInt(&buf, Int32(1)) + + + case .invoiceSet: + writeInt(&buf, Int32(2)) + + + case .transactionMempool: + writeInt(&buf, Int32(3)) + + + case .transactionConfirmed: + writeInt(&buf, Int32(4)) + + + case .invoicePending: + writeInt(&buf, Int32(5)) + - case 2: return .testnet + case .invoicePaid: + writeInt(&buf, Int32(6)) - case 3: return .signet - case 4: return .regtest + case .invoiceSettled: + writeInt(&buf, Int32(7)) - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: BitcoinNetworkEnum, into buf: inout [UInt8]) { - switch value { + case .invoiceFailedToPay: + writeInt(&buf, Int32(8)) - case .mainnet: - writeInt(&buf, Int32(1)) + case .invoiceExpired: + writeInt(&buf, Int32(9)) - case .testnet: - writeInt(&buf, Int32(2)) + case .transactionClaimPending: + writeInt(&buf, Int32(10)) - case .signet: - writeInt(&buf, Int32(3)) + case .transactionClaimed: + writeInt(&buf, Int32(11)) - case .regtest: - writeInt(&buf, Int32(4)) + case .transactionRefunded: + writeInt(&buf, Int32(12)) + + + case .transactionLockupFailed: + writeInt(&buf, Int32(13)) + + + case .transactionFailed: + writeInt(&buf, Int32(14)) + + + case .swapExpired: + writeInt(&buf, Int32(15)) + + + case let .unknown(raw): + writeInt(&buf, Int32(16)) + FfiConverterString.write(raw, into: &buf) + } } } @@ -15790,191 +17898,78 @@ public struct FfiConverterTypeBitcoinNetworkEnum: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBitcoinNetworkEnum_lift(_ buf: RustBuffer) throws -> BitcoinNetworkEnum { - return try FfiConverterTypeBitcoinNetworkEnum.lift(buf) +public func FfiConverterTypeBoltzSwapStatus_lift(_ buf: RustBuffer) throws -> BoltzSwapStatus { + return try FfiConverterTypeBoltzSwapStatus.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBitcoinNetworkEnum_lower(_ value: BitcoinNetworkEnum) -> RustBuffer { - return FfiConverterTypeBitcoinNetworkEnum.lower(value) +public func FfiConverterTypeBoltzSwapStatus_lower(_ value: BoltzSwapStatus) -> RustBuffer { + return FfiConverterTypeBoltzSwapStatus.lower(value) } -extension BitcoinNetworkEnum: Equatable, Hashable {} - -extension BitcoinNetworkEnum: Codable {} +extension BoltzSwapStatus: Equatable, Hashable {} +extension BoltzSwapStatus: Codable {} -public enum BlocktankError: Swift.Error { +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * The direction of a Boltz swap. + * + * - `Submarine`: onchain Bitcoin -> Lightning (the user locks onchain funds, + * Boltz pays a Lightning invoice). + * - `Reverse`: Lightning -> onchain Bitcoin (the user pays a Boltz hold + * invoice, Boltz locks onchain funds the user then claims). + */ +public enum BoltzSwapType { - - case HttpClient(errorDetails: String - ) - case BlocktankClient(errorDetails: String - ) - case InvalidBlocktank(errorDetails: String - ) - case InitializationError(errorDetails: String - ) - case InsertError(errorDetails: String - ) - case RetrievalError(errorDetails: String - ) - case DataError(errorDetails: String - ) - case ConnectionError(errorDetails: String - ) - case SerializationError(errorDetails: String - ) - case ChannelOpen(errorType: BtChannelOrderErrorType, errorDetails: String - ) - case OrderState(errorDetails: String - ) - case InvalidParameter(errorDetails: String - ) - case DatabaseError(errorDetails: String - ) + case submarine + case reverse } +#if compiler(>=6) +extension BoltzSwapType: Sendable {} +#endif + #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBlocktankError: FfiConverterRustBuffer { - typealias SwiftType = BlocktankError +public struct FfiConverterTypeBoltzSwapType: FfiConverterRustBuffer { + typealias SwiftType = BoltzSwapType - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BlocktankError { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzSwapType { let variant: Int32 = try readInt(&buf) switch variant { - - + case 1: return .submarine - case 1: return .HttpClient( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 2: return .BlocktankClient( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 3: return .InvalidBlocktank( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 4: return .InitializationError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 5: return .InsertError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 6: return .RetrievalError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 7: return .DataError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 8: return .ConnectionError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 9: return .SerializationError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 10: return .ChannelOpen( - errorType: try FfiConverterTypeBtChannelOrderErrorType.read(from: &buf), - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 11: return .OrderState( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 12: return .InvalidParameter( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 13: return .DatabaseError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - - default: throw UniffiInternalError.unexpectedEnumCase + case 2: return .reverse + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BlocktankError, into buf: inout [UInt8]) { + public static func write(_ value: BoltzSwapType, into buf: inout [UInt8]) { switch value { - - - - case let .HttpClient(errorDetails): + case .submarine: writeInt(&buf, Int32(1)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .BlocktankClient(errorDetails): - writeInt(&buf, Int32(2)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .InvalidBlocktank(errorDetails): - writeInt(&buf, Int32(3)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .InitializationError(errorDetails): - writeInt(&buf, Int32(4)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .InsertError(errorDetails): - writeInt(&buf, Int32(5)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .RetrievalError(errorDetails): - writeInt(&buf, Int32(6)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .DataError(errorDetails): - writeInt(&buf, Int32(7)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .ConnectionError(errorDetails): - writeInt(&buf, Int32(8)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .SerializationError(errorDetails): - writeInt(&buf, Int32(9)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .ChannelOpen(errorType,errorDetails): - writeInt(&buf, Int32(10)) - FfiConverterTypeBtChannelOrderErrorType.write(errorType, into: &buf) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .OrderState(errorDetails): - writeInt(&buf, Int32(11)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .InvalidParameter(errorDetails): - writeInt(&buf, Int32(12)) - FfiConverterString.write(errorDetails, into: &buf) - + case .reverse: + writeInt(&buf, Int32(2)) - case let .DatabaseError(errorDetails): - writeInt(&buf, Int32(13)) - FfiConverterString.write(errorDetails, into: &buf) - } } } @@ -15983,59 +17978,39 @@ public struct FfiConverterTypeBlocktankError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBlocktankError_lift(_ buf: RustBuffer) throws -> BlocktankError { - return try FfiConverterTypeBlocktankError.lift(buf) +public func FfiConverterTypeBoltzSwapType_lift(_ buf: RustBuffer) throws -> BoltzSwapType { + return try FfiConverterTypeBoltzSwapType.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBlocktankError_lower(_ value: BlocktankError) -> RustBuffer { - return FfiConverterTypeBlocktankError.lower(value) +public func FfiConverterTypeBoltzSwapType_lower(_ value: BoltzSwapType) -> RustBuffer { + return FfiConverterTypeBoltzSwapType.lower(value) } -extension BlocktankError: Equatable, Hashable {} - -extension BlocktankError: Codable {} - +extension BoltzSwapType: Equatable, Hashable {} +extension BoltzSwapType: Codable {} -extension BlocktankError: Foundation.LocalizedError { - public var errorDescription: String? { - String(reflecting: self) - } -} -/** - * Errors surfaced by the Boltz swaps module. - */ -public enum BoltzError: Swift.Error { +public enum BroadcastError: Swift.Error { - case InitializationError(errorDetails: String - ) - case ConnectionError(errorDetails: String - ) - case DatabaseError(errorDetails: String - ) - case ApiError(errorDetails: String - ) - case SwapError(errorDetails: String - ) - case BroadcastError(errorDetails: String + case InvalidHex(errorDetails: String ) - case InvalidInput(errorDetails: String + case InvalidTransaction(errorDetails: String ) - case SerializationError(errorDetails: String + case ElectrumError(errorDetails: String ) - case NotFound(errorDetails: String + case TaskError(errorDetails: String ) } @@ -16043,41 +18018,26 @@ public enum BoltzError: Swift.Error { #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBoltzError: FfiConverterRustBuffer { - typealias SwiftType = BoltzError +public struct FfiConverterTypeBroadcastError: FfiConverterRustBuffer { + typealias SwiftType = BroadcastError - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzError { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BroadcastError { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .InitializationError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 2: return .ConnectionError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 3: return .DatabaseError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 4: return .ApiError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 5: return .SwapError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 6: return .BroadcastError( + case 1: return .InvalidHex( errorDetails: try FfiConverterString.read(from: &buf) ) - case 7: return .InvalidInput( + case 2: return .InvalidTransaction( errorDetails: try FfiConverterString.read(from: &buf) ) - case 8: return .SerializationError( + case 3: return .ElectrumError( errorDetails: try FfiConverterString.read(from: &buf) ) - case 9: return .NotFound( + case 4: return .TaskError( errorDetails: try FfiConverterString.read(from: &buf) ) @@ -16085,57 +18045,32 @@ public struct FfiConverterTypeBoltzError: FfiConverterRustBuffer { } } - public static func write(_ value: BoltzError, into buf: inout [UInt8]) { + public static func write(_ value: BroadcastError, into buf: inout [UInt8]) { switch value { - case let .InitializationError(errorDetails): + case let .InvalidHex(errorDetails): writeInt(&buf, Int32(1)) FfiConverterString.write(errorDetails, into: &buf) - case let .ConnectionError(errorDetails): + case let .InvalidTransaction(errorDetails): writeInt(&buf, Int32(2)) FfiConverterString.write(errorDetails, into: &buf) - case let .DatabaseError(errorDetails): + case let .ElectrumError(errorDetails): writeInt(&buf, Int32(3)) FfiConverterString.write(errorDetails, into: &buf) - case let .ApiError(errorDetails): + case let .TaskError(errorDetails): writeInt(&buf, Int32(4)) FfiConverterString.write(errorDetails, into: &buf) - - case let .SwapError(errorDetails): - writeInt(&buf, Int32(5)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .BroadcastError(errorDetails): - writeInt(&buf, Int32(6)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .InvalidInput(errorDetails): - writeInt(&buf, Int32(7)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .SerializationError(errorDetails): - writeInt(&buf, Int32(8)) - FfiConverterString.write(errorDetails, into: &buf) - - - case let .NotFound(errorDetails): - writeInt(&buf, Int32(9)) - FfiConverterString.write(errorDetails, into: &buf) - } } } @@ -16144,26 +18079,26 @@ public struct FfiConverterTypeBoltzError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzError_lift(_ buf: RustBuffer) throws -> BoltzError { - return try FfiConverterTypeBoltzError.lift(buf) +public func FfiConverterTypeBroadcastError_lift(_ buf: RustBuffer) throws -> BroadcastError { + return try FfiConverterTypeBroadcastError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzError_lower(_ value: BoltzError) -> RustBuffer { - return FfiConverterTypeBoltzError.lower(value) +public func FfiConverterTypeBroadcastError_lower(_ value: BroadcastError) -> RustBuffer { + return FfiConverterTypeBroadcastError.lower(value) } -extension BoltzError: Equatable, Hashable {} +extension BroadcastError: Equatable, Hashable {} -extension BoltzError: Codable {} +extension BroadcastError: Codable {} -extension BoltzError: Foundation.LocalizedError { +extension BroadcastError: Foundation.LocalizedError { public var errorDescription: String? { String(reflecting: self) } @@ -16174,58 +18109,61 @@ extension BoltzError: Foundation.LocalizedError { // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * Bitcoin network selection for Boltz swaps. Maps to the networks Boltz - * operates on (mainnet, testnet, regtest). - */ -public enum BoltzNetwork { +public enum BtBolt11InvoiceState { - case mainnet - case testnet - case regtest + case pending + case holding + case paid + case canceled } #if compiler(>=6) -extension BoltzNetwork: Sendable {} +extension BtBolt11InvoiceState: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBoltzNetwork: FfiConverterRustBuffer { - typealias SwiftType = BoltzNetwork +public struct FfiConverterTypeBtBolt11InvoiceState: FfiConverterRustBuffer { + typealias SwiftType = BtBolt11InvoiceState - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzNetwork { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtBolt11InvoiceState { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .mainnet + case 1: return .pending - case 2: return .testnet + case 2: return .holding - case 3: return .regtest + case 3: return .paid + + case 4: return .canceled default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BoltzNetwork, into buf: inout [UInt8]) { + public static func write(_ value: BtBolt11InvoiceState, into buf: inout [UInt8]) { switch value { - case .mainnet: + case .pending: writeInt(&buf, Int32(1)) - case .testnet: + case .holding: writeInt(&buf, Int32(2)) - case .regtest: + case .paid: writeInt(&buf, Int32(3)) + + case .canceled: + writeInt(&buf, Int32(4)) + } } } @@ -16234,21 +18172,21 @@ public struct FfiConverterTypeBoltzNetwork: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzNetwork_lift(_ buf: RustBuffer) throws -> BoltzNetwork { - return try FfiConverterTypeBoltzNetwork.lift(buf) +public func FfiConverterTypeBtBolt11InvoiceState_lift(_ buf: RustBuffer) throws -> BtBolt11InvoiceState { + return try FfiConverterTypeBtBolt11InvoiceState.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzNetwork_lower(_ value: BoltzNetwork) -> RustBuffer { - return FfiConverterTypeBoltzNetwork.lower(value) +public func FfiConverterTypeBtBolt11InvoiceState_lower(_ value: BtBolt11InvoiceState) -> RustBuffer { + return FfiConverterTypeBtBolt11InvoiceState.lower(value) } -extension BoltzNetwork: Equatable, Hashable {} +extension BtBolt11InvoiceState: Equatable, Hashable {} -extension BoltzNetwork: Codable {} +extension BtBolt11InvoiceState: Codable {} @@ -16257,93 +18195,147 @@ extension BoltzNetwork: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * Events emitted to a registered [`crate::modules::boltz::BoltzEventListener`] - * as swaps progress through their lifecycle. - */ -public enum BoltzSwapEvent { +public enum BtChannelOrderErrorType { - /** - * The swap transitioned to a new status. - */ - case statusUpdate(swapId: String, status: BoltzSwapStatus - ) - /** - * A reverse swap was claimed onchain. `txid` is the claim transaction. - */ - case claimed(swapId: String, txid: String - ) - /** - * A submarine swap was refunded onchain. `txid` is the refund transaction. - */ - case refunded(swapId: String, txid: String - ) - /** - * An error occurred while processing the swap (e.g. an auto-claim failed). - */ - case error(swapId: String, message: String - ) + case wrongOrderState + case peerNotReachable + case channelRejectedByDestination + case channelRejectedByLsp + case blocktankNotReady +} + + +#if compiler(>=6) +extension BtChannelOrderErrorType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeBtChannelOrderErrorType: FfiConverterRustBuffer { + typealias SwiftType = BtChannelOrderErrorType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtChannelOrderErrorType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .wrongOrderState + + case 2: return .peerNotReachable + + case 3: return .channelRejectedByDestination + + case 4: return .channelRejectedByLsp + + case 5: return .blocktankNotReady + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: BtChannelOrderErrorType, into buf: inout [UInt8]) { + switch value { + + + case .wrongOrderState: + writeInt(&buf, Int32(1)) + + + case .peerNotReachable: + writeInt(&buf, Int32(2)) + + + case .channelRejectedByDestination: + writeInt(&buf, Int32(3)) + + + case .channelRejectedByLsp: + writeInt(&buf, Int32(4)) + + + case .blocktankNotReady: + writeInt(&buf, Int32(5)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeBtChannelOrderErrorType_lift(_ buf: RustBuffer) throws -> BtChannelOrderErrorType { + return try FfiConverterTypeBtChannelOrderErrorType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeBtChannelOrderErrorType_lower(_ value: BtChannelOrderErrorType) -> RustBuffer { + return FfiConverterTypeBtChannelOrderErrorType.lower(value) +} + + +extension BtChannelOrderErrorType: Equatable, Hashable {} + +extension BtChannelOrderErrorType: Codable {} + + + + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum BtOpenChannelState { + + case opening + case `open` + case closed } #if compiler(>=6) -extension BoltzSwapEvent: Sendable {} +extension BtOpenChannelState: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBoltzSwapEvent: FfiConverterRustBuffer { - typealias SwiftType = BoltzSwapEvent +public struct FfiConverterTypeBtOpenChannelState: FfiConverterRustBuffer { + typealias SwiftType = BtOpenChannelState - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzSwapEvent { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtOpenChannelState { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .statusUpdate(swapId: try FfiConverterString.read(from: &buf), status: try FfiConverterTypeBoltzSwapStatus.read(from: &buf) - ) - - case 2: return .claimed(swapId: try FfiConverterString.read(from: &buf), txid: try FfiConverterString.read(from: &buf) - ) + case 1: return .opening - case 3: return .refunded(swapId: try FfiConverterString.read(from: &buf), txid: try FfiConverterString.read(from: &buf) - ) + case 2: return .`open` - case 4: return .error(swapId: try FfiConverterString.read(from: &buf), message: try FfiConverterString.read(from: &buf) - ) + case 3: return .closed default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BoltzSwapEvent, into buf: inout [UInt8]) { + public static func write(_ value: BtOpenChannelState, into buf: inout [UInt8]) { switch value { - case let .statusUpdate(swapId,status): + case .opening: writeInt(&buf, Int32(1)) - FfiConverterString.write(swapId, into: &buf) - FfiConverterTypeBoltzSwapStatus.write(status, into: &buf) - - case let .claimed(swapId,txid): + + case .`open`: writeInt(&buf, Int32(2)) - FfiConverterString.write(swapId, into: &buf) - FfiConverterString.write(txid, into: &buf) - - case let .refunded(swapId,txid): + + case .closed: writeInt(&buf, Int32(3)) - FfiConverterString.write(swapId, into: &buf) - FfiConverterString.write(txid, into: &buf) - - case let .error(swapId,message): - writeInt(&buf, Int32(4)) - FfiConverterString.write(swapId, into: &buf) - FfiConverterString.write(message, into: &buf) - } } } @@ -16352,21 +18344,21 @@ public struct FfiConverterTypeBoltzSwapEvent: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzSwapEvent_lift(_ buf: RustBuffer) throws -> BoltzSwapEvent { - return try FfiConverterTypeBoltzSwapEvent.lift(buf) +public func FfiConverterTypeBtOpenChannelState_lift(_ buf: RustBuffer) throws -> BtOpenChannelState { + return try FfiConverterTypeBtOpenChannelState.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzSwapEvent_lower(_ value: BoltzSwapEvent) -> RustBuffer { - return FfiConverterTypeBoltzSwapEvent.lower(value) +public func FfiConverterTypeBtOpenChannelState_lower(_ value: BtOpenChannelState) -> RustBuffer { + return FfiConverterTypeBtOpenChannelState.lower(value) } -extension BoltzSwapEvent: Equatable, Hashable {} +extension BtOpenChannelState: Equatable, Hashable {} -extension BoltzSwapEvent: Codable {} +extension BtOpenChannelState: Codable {} @@ -16375,202 +18367,147 @@ extension BoltzSwapEvent: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * Typed view of the Boltz swap lifecycle. `Unknown` carries the raw status so - * new server-side states don't break the bindings. - * - * See . - */ -public enum BoltzSwapStatus { +public enum BtOrderState { - /** - * `swap.created` — initial state. - */ - case swapCreated - /** - * `invoice.set` — invoice attached to a submarine swap. - */ - case invoiceSet - /** - * `transaction.mempool` — a lockup transaction is in the mempool. - */ - case transactionMempool - /** - * `transaction.confirmed` — a lockup transaction confirmed. - */ - case transactionConfirmed - /** - * `invoice.pending` — Boltz is paying the submarine swap invoice. - */ - case invoicePending - /** - * `invoice.paid` — submarine swap invoice paid by Boltz. - */ - case invoicePaid - /** - * `invoice.settled` — reverse swap invoice settled (preimage revealed). - */ - case invoiceSettled - /** - * `invoice.failedToPay` — submarine swap invoice could not be paid; refund. - */ - case invoiceFailedToPay - /** - * `invoice.expired` — reverse swap invoice expired before payment. - */ - case invoiceExpired - /** - * `transaction.claim.pending` — Boltz ready for a cooperative claim. - */ - case transactionClaimPending - /** - * `transaction.claimed` — onchain funds claimed. - */ - case transactionClaimed - /** - * `transaction.refunded` — onchain funds refunded. - */ - case transactionRefunded - /** - * `transaction.lockupFailed` — wrong amount locked; can refund. - */ - case transactionLockupFailed - /** - * `transaction.failed` — Boltz failed to lock the agreed funds. - */ - case transactionFailed - /** - * `swap.expired` — swap expired without completing. - */ - case swapExpired - /** - * Any status not yet modelled. `raw` holds the verbatim Boltz status. - */ - case unknown(raw: String - ) + case created + case expired + case `open` + case closed } #if compiler(>=6) -extension BoltzSwapStatus: Sendable {} +extension BtOrderState: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBoltzSwapStatus: FfiConverterRustBuffer { - typealias SwiftType = BoltzSwapStatus +public struct FfiConverterTypeBtOrderState: FfiConverterRustBuffer { + typealias SwiftType = BtOrderState - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzSwapStatus { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtOrderState { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .swapCreated - - case 2: return .invoiceSet - - case 3: return .transactionMempool - - case 4: return .transactionConfirmed - - case 5: return .invoicePending - - case 6: return .invoicePaid - - case 7: return .invoiceSettled - - case 8: return .invoiceFailedToPay - - case 9: return .invoiceExpired - - case 10: return .transactionClaimPending - - case 11: return .transactionClaimed - - case 12: return .transactionRefunded - - case 13: return .transactionLockupFailed + case 1: return .created - case 14: return .transactionFailed + case 2: return .expired - case 15: return .swapExpired + case 3: return .`open` - case 16: return .unknown(raw: try FfiConverterString.read(from: &buf) - ) + case 4: return .closed default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BoltzSwapStatus, into buf: inout [UInt8]) { + public static func write(_ value: BtOrderState, into buf: inout [UInt8]) { switch value { - case .swapCreated: + case .created: writeInt(&buf, Int32(1)) - case .invoiceSet: + case .expired: writeInt(&buf, Int32(2)) - case .transactionMempool: + case .`open`: writeInt(&buf, Int32(3)) - case .transactionConfirmed: + case .closed: writeInt(&buf, Int32(4)) + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeBtOrderState_lift(_ buf: RustBuffer) throws -> BtOrderState { + return try FfiConverterTypeBtOrderState.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeBtOrderState_lower(_ value: BtOrderState) -> RustBuffer { + return FfiConverterTypeBtOrderState.lower(value) +} + + +extension BtOrderState: Equatable, Hashable {} + +extension BtOrderState: Codable {} + + + + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum BtOrderState2 { + + case created + case expired + case executed + case paid +} + + +#if compiler(>=6) +extension BtOrderState2: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeBtOrderState2: FfiConverterRustBuffer { + typealias SwiftType = BtOrderState2 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtOrderState2 { + let variant: Int32 = try readInt(&buf) + switch variant { - case .invoicePending: - writeInt(&buf, Int32(5)) - - - case .invoicePaid: - writeInt(&buf, Int32(6)) - - - case .invoiceSettled: - writeInt(&buf, Int32(7)) - - - case .invoiceFailedToPay: - writeInt(&buf, Int32(8)) - - - case .invoiceExpired: - writeInt(&buf, Int32(9)) - + case 1: return .created - case .transactionClaimPending: - writeInt(&buf, Int32(10)) + case 2: return .expired + case 3: return .executed - case .transactionClaimed: - writeInt(&buf, Int32(11)) + case 4: return .paid + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: BtOrderState2, into buf: inout [UInt8]) { + switch value { - case .transactionRefunded: - writeInt(&buf, Int32(12)) + case .created: + writeInt(&buf, Int32(1)) - case .transactionLockupFailed: - writeInt(&buf, Int32(13)) + case .expired: + writeInt(&buf, Int32(2)) - case .transactionFailed: - writeInt(&buf, Int32(14)) + case .executed: + writeInt(&buf, Int32(3)) - case .swapExpired: - writeInt(&buf, Int32(15)) + case .paid: + writeInt(&buf, Int32(4)) - case let .unknown(raw): - writeInt(&buf, Int32(16)) - FfiConverterString.write(raw, into: &buf) - } } } @@ -16579,21 +18516,21 @@ public struct FfiConverterTypeBoltzSwapStatus: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzSwapStatus_lift(_ buf: RustBuffer) throws -> BoltzSwapStatus { - return try FfiConverterTypeBoltzSwapStatus.lift(buf) +public func FfiConverterTypeBtOrderState2_lift(_ buf: RustBuffer) throws -> BtOrderState2 { + return try FfiConverterTypeBtOrderState2.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzSwapStatus_lower(_ value: BoltzSwapStatus) -> RustBuffer { - return FfiConverterTypeBoltzSwapStatus.lower(value) +public func FfiConverterTypeBtOrderState2_lower(_ value: BtOrderState2) -> RustBuffer { + return FfiConverterTypeBtOrderState2.lower(value) } -extension BoltzSwapStatus: Equatable, Hashable {} +extension BtOrderState2: Equatable, Hashable {} -extension BoltzSwapStatus: Codable {} +extension BtOrderState2: Codable {} @@ -16602,55 +18539,68 @@ extension BoltzSwapStatus: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * The direction of a Boltz swap. - * - * - `Submarine`: onchain Bitcoin -> Lightning (the user locks onchain funds, - * Boltz pays a Lightning invoice). - * - `Reverse`: Lightning -> onchain Bitcoin (the user pays a Boltz hold - * invoice, Boltz locks onchain funds the user then claims). - */ -public enum BoltzSwapType { +public enum BtPaymentState { - case submarine - case reverse + case created + case partiallyPaid + case paid + case refunded + case refundAvailable } #if compiler(>=6) -extension BoltzSwapType: Sendable {} +extension BtPaymentState: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBoltzSwapType: FfiConverterRustBuffer { - typealias SwiftType = BoltzSwapType +public struct FfiConverterTypeBtPaymentState: FfiConverterRustBuffer { + typealias SwiftType = BtPaymentState - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BoltzSwapType { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtPaymentState { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .submarine + case 1: return .created - case 2: return .reverse + case 2: return .partiallyPaid + + case 3: return .paid + + case 4: return .refunded + + case 5: return .refundAvailable default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BoltzSwapType, into buf: inout [UInt8]) { + public static func write(_ value: BtPaymentState, into buf: inout [UInt8]) { switch value { - case .submarine: + case .created: writeInt(&buf, Int32(1)) - case .reverse: + case .partiallyPaid: writeInt(&buf, Int32(2)) + + case .paid: + writeInt(&buf, Int32(3)) + + + case .refunded: + writeInt(&buf, Int32(4)) + + + case .refundAvailable: + writeInt(&buf, Int32(5)) + } } } @@ -16659,99 +18609,91 @@ public struct FfiConverterTypeBoltzSwapType: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzSwapType_lift(_ buf: RustBuffer) throws -> BoltzSwapType { - return try FfiConverterTypeBoltzSwapType.lift(buf) +public func FfiConverterTypeBtPaymentState_lift(_ buf: RustBuffer) throws -> BtPaymentState { + return try FfiConverterTypeBtPaymentState.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBoltzSwapType_lower(_ value: BoltzSwapType) -> RustBuffer { - return FfiConverterTypeBoltzSwapType.lower(value) +public func FfiConverterTypeBtPaymentState_lower(_ value: BtPaymentState) -> RustBuffer { + return FfiConverterTypeBtPaymentState.lower(value) } -extension BoltzSwapType: Equatable, Hashable {} - -extension BoltzSwapType: Codable {} +extension BtPaymentState: Equatable, Hashable {} +extension BtPaymentState: Codable {} -public enum BroadcastError: Swift.Error { +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +public enum BtPaymentState2 { - - case InvalidHex(errorDetails: String - ) - case InvalidTransaction(errorDetails: String - ) - case ElectrumError(errorDetails: String - ) - case TaskError(errorDetails: String - ) + case created + case paid + case refunded + case refundAvailable + case canceled } +#if compiler(>=6) +extension BtPaymentState2: Sendable {} +#endif + #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBroadcastError: FfiConverterRustBuffer { - typealias SwiftType = BroadcastError +public struct FfiConverterTypeBtPaymentState2: FfiConverterRustBuffer { + typealias SwiftType = BtPaymentState2 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BroadcastError { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtPaymentState2 { let variant: Int32 = try readInt(&buf) switch variant { - - + case 1: return .created - case 1: return .InvalidHex( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 2: return .InvalidTransaction( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 3: return .ElectrumError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - case 4: return .TaskError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - - default: throw UniffiInternalError.unexpectedEnumCase + case 2: return .paid + + case 3: return .refunded + + case 4: return .refundAvailable + + case 5: return .canceled + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BroadcastError, into buf: inout [UInt8]) { + public static func write(_ value: BtPaymentState2, into buf: inout [UInt8]) { switch value { - - - - case let .InvalidHex(errorDetails): + case .created: writeInt(&buf, Int32(1)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .InvalidTransaction(errorDetails): + + case .paid: writeInt(&buf, Int32(2)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .ElectrumError(errorDetails): + + case .refunded: writeInt(&buf, Int32(3)) - FfiConverterString.write(errorDetails, into: &buf) - - case let .TaskError(errorDetails): + + case .refundAvailable: writeInt(&buf, Int32(4)) - FfiConverterString.write(errorDetails, into: &buf) - + + + case .canceled: + writeInt(&buf, Int32(5)) + } } } @@ -16760,30 +18702,23 @@ public struct FfiConverterTypeBroadcastError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBroadcastError_lift(_ buf: RustBuffer) throws -> BroadcastError { - return try FfiConverterTypeBroadcastError.lift(buf) +public func FfiConverterTypeBtPaymentState2_lift(_ buf: RustBuffer) throws -> BtPaymentState2 { + return try FfiConverterTypeBtPaymentState2.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBroadcastError_lower(_ value: BroadcastError) -> RustBuffer { - return FfiConverterTypeBroadcastError.lower(value) +public func FfiConverterTypeBtPaymentState2_lower(_ value: BtPaymentState2) -> RustBuffer { + return FfiConverterTypeBtPaymentState2.lower(value) } -extension BroadcastError: Equatable, Hashable {} - -extension BroadcastError: Codable {} - +extension BtPaymentState2: Equatable, Hashable {} +extension BtPaymentState2: Codable {} -extension BroadcastError: Foundation.LocalizedError { - public var errorDescription: String? { - String(reflecting: self) - } -} @@ -16791,58 +18726,58 @@ extension BroadcastError: Foundation.LocalizedError { // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -public enum BtBolt11InvoiceState { +public enum CJitStateEnum { - case pending - case holding - case paid - case canceled + case created + case completed + case expired + case failed } #if compiler(>=6) -extension BtBolt11InvoiceState: Sendable {} +extension CJitStateEnum: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBtBolt11InvoiceState: FfiConverterRustBuffer { - typealias SwiftType = BtBolt11InvoiceState +public struct FfiConverterTypeCJitStateEnum: FfiConverterRustBuffer { + typealias SwiftType = CJitStateEnum - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtBolt11InvoiceState { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CJitStateEnum { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .pending + case 1: return .created - case 2: return .holding + case 2: return .completed - case 3: return .paid + case 3: return .expired - case 4: return .canceled + case 4: return .failed default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BtBolt11InvoiceState, into buf: inout [UInt8]) { + public static func write(_ value: CJitStateEnum, into buf: inout [UInt8]) { switch value { - case .pending: + case .created: writeInt(&buf, Int32(1)) - case .holding: + case .completed: writeInt(&buf, Int32(2)) - case .paid: + case .expired: writeInt(&buf, Int32(3)) - case .canceled: + case .failed: writeInt(&buf, Int32(4)) } @@ -16853,21 +18788,21 @@ public struct FfiConverterTypeBtBolt11InvoiceState: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtBolt11InvoiceState_lift(_ buf: RustBuffer) throws -> BtBolt11InvoiceState { - return try FfiConverterTypeBtBolt11InvoiceState.lift(buf) +public func FfiConverterTypeCJitStateEnum_lift(_ buf: RustBuffer) throws -> CJitStateEnum { + return try FfiConverterTypeCJitStateEnum.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtBolt11InvoiceState_lower(_ value: BtBolt11InvoiceState) -> RustBuffer { - return FfiConverterTypeBtBolt11InvoiceState.lower(value) +public func FfiConverterTypeCJitStateEnum_lower(_ value: CJitStateEnum) -> RustBuffer { + return FfiConverterTypeCJitStateEnum.lower(value) } -extension BtBolt11InvoiceState: Equatable, Hashable {} +extension CJitStateEnum: Equatable, Hashable {} -extension BtBolt11InvoiceState: Codable {} +extension CJitStateEnum: Codable {} @@ -16876,68 +18811,66 @@ extension BtBolt11InvoiceState: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * Coin selection strategy for transaction composition. + */ -public enum BtChannelOrderErrorType { +public enum CoinSelection { - case wrongOrderState - case peerNotReachable - case channelRejectedByDestination - case channelRejectedByLsp - case blocktankNotReady + /** + * Branch-and-bound (default). Minimizes change by searching for exact matches. + */ + case branchAndBound + /** + * Selects largest UTXOs first. Useful for UTXO consolidation. + */ + case largestFirst + /** + * Selects oldest UTXOs first. Maximizes coin-age spending. + */ + case oldestFirst } #if compiler(>=6) -extension BtChannelOrderErrorType: Sendable {} +extension CoinSelection: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBtChannelOrderErrorType: FfiConverterRustBuffer { - typealias SwiftType = BtChannelOrderErrorType +public struct FfiConverterTypeCoinSelection: FfiConverterRustBuffer { + typealias SwiftType = CoinSelection - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtChannelOrderErrorType { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CoinSelection { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .wrongOrderState - - case 2: return .peerNotReachable - - case 3: return .channelRejectedByDestination + case 1: return .branchAndBound - case 4: return .channelRejectedByLsp + case 2: return .largestFirst - case 5: return .blocktankNotReady + case 3: return .oldestFirst default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BtChannelOrderErrorType, into buf: inout [UInt8]) { + public static func write(_ value: CoinSelection, into buf: inout [UInt8]) { switch value { - case .wrongOrderState: + case .branchAndBound: writeInt(&buf, Int32(1)) - case .peerNotReachable: + case .largestFirst: writeInt(&buf, Int32(2)) - case .channelRejectedByDestination: + case .oldestFirst: writeInt(&buf, Int32(3)) - - case .channelRejectedByLsp: - writeInt(&buf, Int32(4)) - - - case .blocktankNotReady: - writeInt(&buf, Int32(5)) - } } } @@ -16946,21 +18879,21 @@ public struct FfiConverterTypeBtChannelOrderErrorType: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtChannelOrderErrorType_lift(_ buf: RustBuffer) throws -> BtChannelOrderErrorType { - return try FfiConverterTypeBtChannelOrderErrorType.lift(buf) +public func FfiConverterTypeCoinSelection_lift(_ buf: RustBuffer) throws -> CoinSelection { + return try FfiConverterTypeCoinSelection.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtChannelOrderErrorType_lower(_ value: BtChannelOrderErrorType) -> RustBuffer { - return FfiConverterTypeBtChannelOrderErrorType.lower(value) +public func FfiConverterTypeCoinSelection_lower(_ value: CoinSelection) -> RustBuffer { + return FfiConverterTypeCoinSelection.lower(value) } -extension BtChannelOrderErrorType: Equatable, Hashable {} +extension CoinSelection: Equatable, Hashable {} -extension BtChannelOrderErrorType: Codable {} +extension CoinSelection: Codable {} @@ -16969,54 +18902,76 @@ extension BtChannelOrderErrorType: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * Output specification for transaction composition. + */ -public enum BtOpenChannelState { +public enum ComposeOutput { - case opening - case `open` - case closed + /** + * Payment to a specific address with a fixed amount (satoshis) + */ + case payment(address: String, amountSats: UInt64 + ) + /** + * Send all remaining funds (after fees) to an address + */ + case sendMax(address: String + ) + /** + * OP_RETURN data output (hex-encoded payload) + */ + case opReturn(dataHex: String + ) } #if compiler(>=6) -extension BtOpenChannelState: Sendable {} +extension ComposeOutput: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBtOpenChannelState: FfiConverterRustBuffer { - typealias SwiftType = BtOpenChannelState +public struct FfiConverterTypeComposeOutput: FfiConverterRustBuffer { + typealias SwiftType = ComposeOutput - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtOpenChannelState { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ComposeOutput { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .opening + case 1: return .payment(address: try FfiConverterString.read(from: &buf), amountSats: try FfiConverterUInt64.read(from: &buf) + ) - case 2: return .`open` + case 2: return .sendMax(address: try FfiConverterString.read(from: &buf) + ) - case 3: return .closed + case 3: return .opReturn(dataHex: try FfiConverterString.read(from: &buf) + ) default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BtOpenChannelState, into buf: inout [UInt8]) { + public static func write(_ value: ComposeOutput, into buf: inout [UInt8]) { switch value { - case .opening: + case let .payment(address,amountSats): writeInt(&buf, Int32(1)) + FfiConverterString.write(address, into: &buf) + FfiConverterUInt64.write(amountSats, into: &buf) + - - case .`open`: + case let .sendMax(address): writeInt(&buf, Int32(2)) + FfiConverterString.write(address, into: &buf) + - - case .closed: + case let .opReturn(dataHex): writeInt(&buf, Int32(3)) - + FfiConverterString.write(dataHex, into: &buf) + } } } @@ -17025,21 +18980,21 @@ public struct FfiConverterTypeBtOpenChannelState: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtOpenChannelState_lift(_ buf: RustBuffer) throws -> BtOpenChannelState { - return try FfiConverterTypeBtOpenChannelState.lift(buf) +public func FfiConverterTypeComposeOutput_lift(_ buf: RustBuffer) throws -> ComposeOutput { + return try FfiConverterTypeComposeOutput.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtOpenChannelState_lower(_ value: BtOpenChannelState) -> RustBuffer { - return FfiConverterTypeBtOpenChannelState.lower(value) +public func FfiConverterTypeComposeOutput_lower(_ value: ComposeOutput) -> RustBuffer { + return FfiConverterTypeComposeOutput.lower(value) } -extension BtOpenChannelState: Equatable, Hashable {} +extension ComposeOutput: Equatable, Hashable {} -extension BtOpenChannelState: Codable {} +extension ComposeOutput: Codable {} @@ -17048,61 +19003,79 @@ extension BtOpenChannelState: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * Result of composing a transaction at a single fee rate. + */ -public enum BtOrderState { +public enum ComposeResult { - case created - case expired - case `open` - case closed + /** + * Successfully built a signable PSBT + */ + case success( + /** + * Base64-encoded PSBT ready for signing + */psbt: String, + /** + * Total fee in satoshis + */fee: UInt64, + /** + * Target fee rate in sat/vB (actual may differ slightly due to rounding) + */feeRate: Float, + /** + * Total value spent (payments + fee, excluding change). + * Uses BDK's `sent - received` semantics, which may undercount for + * self-transfers where the destination is also owned by the wallet. + */totalSpent: UInt64 + ) + /** + * Composition failed (e.g. insufficient funds) + */ + case error(error: String + ) } #if compiler(>=6) -extension BtOrderState: Sendable {} +extension ComposeResult: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBtOrderState: FfiConverterRustBuffer { - typealias SwiftType = BtOrderState +public struct FfiConverterTypeComposeResult: FfiConverterRustBuffer { + typealias SwiftType = ComposeResult - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtOrderState { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ComposeResult { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .created - - case 2: return .expired - - case 3: return .`open` + case 1: return .success(psbt: try FfiConverterString.read(from: &buf), fee: try FfiConverterUInt64.read(from: &buf), feeRate: try FfiConverterFloat.read(from: &buf), totalSpent: try FfiConverterUInt64.read(from: &buf) + ) - case 4: return .closed + case 2: return .error(error: try FfiConverterString.read(from: &buf) + ) default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BtOrderState, into buf: inout [UInt8]) { + public static func write(_ value: ComposeResult, into buf: inout [UInt8]) { switch value { - case .created: + case let .success(psbt,fee,feeRate,totalSpent): writeInt(&buf, Int32(1)) + FfiConverterString.write(psbt, into: &buf) + FfiConverterUInt64.write(fee, into: &buf) + FfiConverterFloat.write(feeRate, into: &buf) + FfiConverterUInt64.write(totalSpent, into: &buf) + - - case .expired: + case let .error(error): writeInt(&buf, Int32(2)) - - - case .`open`: - writeInt(&buf, Int32(3)) - - - case .closed: - writeInt(&buf, Int32(4)) - + FfiConverterString.write(error, into: &buf) + } } } @@ -17111,84 +19084,99 @@ public struct FfiConverterTypeBtOrderState: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtOrderState_lift(_ buf: RustBuffer) throws -> BtOrderState { - return try FfiConverterTypeBtOrderState.lift(buf) +public func FfiConverterTypeComposeResult_lift(_ buf: RustBuffer) throws -> ComposeResult { + return try FfiConverterTypeComposeResult.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtOrderState_lower(_ value: BtOrderState) -> RustBuffer { - return FfiConverterTypeBtOrderState.lower(value) +public func FfiConverterTypeComposeResult_lower(_ value: ComposeResult) -> RustBuffer { + return FfiConverterTypeComposeResult.lower(value) } -extension BtOrderState: Equatable, Hashable {} +extension ComposeResult: Equatable, Hashable {} -extension BtOrderState: Codable {} +extension ComposeResult: Codable {} -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -public enum BtOrderState2 { - - case created - case expired - case executed - case paid -} +public enum DbError: Swift.Error { + + + case DbActivityError(errorDetails: ActivityError + ) + case DbBlocktankError(errorDetails: BlocktankError + ) + case DbBoltzError(errorDetails: BoltzError + ) + case InitializationError(errorDetails: String + ) +} -#if compiler(>=6) -extension BtOrderState2: Sendable {} -#endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBtOrderState2: FfiConverterRustBuffer { - typealias SwiftType = BtOrderState2 +public struct FfiConverterTypeDbError: FfiConverterRustBuffer { + typealias SwiftType = DbError - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtOrderState2 { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DbError { let variant: Int32 = try readInt(&buf) switch variant { + - case 1: return .created - - case 2: return .expired - - case 3: return .executed - - case 4: return .paid + - default: throw UniffiInternalError.unexpectedEnumCase + case 1: return .DbActivityError( + errorDetails: try FfiConverterTypeActivityError.read(from: &buf) + ) + case 2: return .DbBlocktankError( + errorDetails: try FfiConverterTypeBlocktankError.read(from: &buf) + ) + case 3: return .DbBoltzError( + errorDetails: try FfiConverterTypeBoltzError.read(from: &buf) + ) + case 4: return .InitializationError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BtOrderState2, into buf: inout [UInt8]) { + public static func write(_ value: DbError, into buf: inout [UInt8]) { switch value { + + - case .created: - writeInt(&buf, Int32(1)) + case let .DbActivityError(errorDetails): + writeInt(&buf, Int32(1)) + FfiConverterTypeActivityError.write(errorDetails, into: &buf) + - case .expired: + case let .DbBlocktankError(errorDetails): writeInt(&buf, Int32(2)) + FfiConverterTypeBlocktankError.write(errorDetails, into: &buf) + - - case .executed: + case let .DbBoltzError(errorDetails): writeInt(&buf, Int32(3)) + FfiConverterTypeBoltzError.write(errorDetails, into: &buf) + - - case .paid: + case let .InitializationError(errorDetails): writeInt(&buf, Int32(4)) - + FfiConverterString.write(errorDetails, into: &buf) + } } } @@ -17197,91 +19185,150 @@ public struct FfiConverterTypeBtOrderState2: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtOrderState2_lift(_ buf: RustBuffer) throws -> BtOrderState2 { - return try FfiConverterTypeBtOrderState2.lift(buf) +public func FfiConverterTypeDbError_lift(_ buf: RustBuffer) throws -> DbError { + return try FfiConverterTypeDbError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtOrderState2_lower(_ value: BtOrderState2) -> RustBuffer { - return FfiConverterTypeBtOrderState2.lower(value) +public func FfiConverterTypeDbError_lower(_ value: DbError) -> RustBuffer { + return FfiConverterTypeDbError.lower(value) } -extension BtOrderState2: Equatable, Hashable {} +extension DbError: Equatable, Hashable {} -extension BtOrderState2: Codable {} +extension DbError: Codable {} +extension DbError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -public enum BtPaymentState { + + +public enum DecodingError: Swift.Error { + - case created - case partiallyPaid - case paid - case refunded - case refundAvailable + + case InvalidFormat + case InvalidNetwork + case InvalidAmount + case InvalidLnurlPayAmount(amountSatoshis: UInt64, min: UInt64, max: UInt64 + ) + case InvalidTimestamp + case InvalidChecksum + case InvalidResponse + case UnsupportedType + case InvalidAddress + case RequestFailed + case ClientCreationFailed + case InvoiceCreationFailed(errorMessage: String + ) } -#if compiler(>=6) -extension BtPaymentState: Sendable {} -#endif - #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBtPaymentState: FfiConverterRustBuffer { - typealias SwiftType = BtPaymentState +public struct FfiConverterTypeDecodingError: FfiConverterRustBuffer { + typealias SwiftType = DecodingError - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtPaymentState { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DecodingError { let variant: Int32 = try readInt(&buf) switch variant { + - case 1: return .created - - case 2: return .partiallyPaid - - case 3: return .paid - - case 4: return .refunded - - case 5: return .refundAvailable + - default: throw UniffiInternalError.unexpectedEnumCase + case 1: return .InvalidFormat + case 2: return .InvalidNetwork + case 3: return .InvalidAmount + case 4: return .InvalidLnurlPayAmount( + amountSatoshis: try FfiConverterUInt64.read(from: &buf), + min: try FfiConverterUInt64.read(from: &buf), + max: try FfiConverterUInt64.read(from: &buf) + ) + case 5: return .InvalidTimestamp + case 6: return .InvalidChecksum + case 7: return .InvalidResponse + case 8: return .UnsupportedType + case 9: return .InvalidAddress + case 10: return .RequestFailed + case 11: return .ClientCreationFailed + case 12: return .InvoiceCreationFailed( + errorMessage: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BtPaymentState, into buf: inout [UInt8]) { + public static func write(_ value: DecodingError, into buf: inout [UInt8]) { switch value { + + + - case .created: + case .InvalidFormat: writeInt(&buf, Int32(1)) - case .partiallyPaid: + case .InvalidNetwork: writeInt(&buf, Int32(2)) - case .paid: + case .InvalidAmount: writeInt(&buf, Int32(3)) - case .refunded: + case let .InvalidLnurlPayAmount(amountSatoshis,min,max): writeInt(&buf, Int32(4)) + FfiConverterUInt64.write(amountSatoshis, into: &buf) + FfiConverterUInt64.write(min, into: &buf) + FfiConverterUInt64.write(max, into: &buf) + - - case .refundAvailable: + case .InvalidTimestamp: writeInt(&buf, Int32(5)) + + case .InvalidChecksum: + writeInt(&buf, Int32(6)) + + + case .InvalidResponse: + writeInt(&buf, Int32(7)) + + + case .UnsupportedType: + writeInt(&buf, Int32(8)) + + + case .InvalidAddress: + writeInt(&buf, Int32(9)) + + + case .RequestFailed: + writeInt(&buf, Int32(10)) + + + case .ClientCreationFailed: + writeInt(&buf, Int32(11)) + + + case let .InvoiceCreationFailed(errorMessage): + writeInt(&buf, Int32(12)) + FfiConverterString.write(errorMessage, into: &buf) + } } } @@ -17290,91 +19337,87 @@ public struct FfiConverterTypeBtPaymentState: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtPaymentState_lift(_ buf: RustBuffer) throws -> BtPaymentState { - return try FfiConverterTypeBtPaymentState.lift(buf) +public func FfiConverterTypeDecodingError_lift(_ buf: RustBuffer) throws -> DecodingError { + return try FfiConverterTypeDecodingError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtPaymentState_lower(_ value: BtPaymentState) -> RustBuffer { - return FfiConverterTypeBtPaymentState.lower(value) +public func FfiConverterTypeDecodingError_lower(_ value: DecodingError) -> RustBuffer { + return FfiConverterTypeDecodingError.lower(value) } -extension BtPaymentState: Equatable, Hashable {} +extension DecodingError: Equatable, Hashable {} + +extension DecodingError: Codable {} -extension BtPaymentState: Codable {} +extension DecodingError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} + // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * How an application exchanges data with a hardware wallet. + */ -public enum BtPaymentState2 { +public enum HardwareWalletTransport { - case created - case paid - case refunded - case refundAvailable - case canceled + case usb + case bluetooth + case qr } #if compiler(>=6) -extension BtPaymentState2: Sendable {} +extension HardwareWalletTransport: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeBtPaymentState2: FfiConverterRustBuffer { - typealias SwiftType = BtPaymentState2 +public struct FfiConverterTypeHardwareWalletTransport: FfiConverterRustBuffer { + typealias SwiftType = HardwareWalletTransport - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BtPaymentState2 { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> HardwareWalletTransport { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .created - - case 2: return .paid - - case 3: return .refunded + case 1: return .usb - case 4: return .refundAvailable + case 2: return .bluetooth - case 5: return .canceled + case 3: return .qr default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: BtPaymentState2, into buf: inout [UInt8]) { + public static func write(_ value: HardwareWalletTransport, into buf: inout [UInt8]) { switch value { - case .created: + case .usb: writeInt(&buf, Int32(1)) - case .paid: + case .bluetooth: writeInt(&buf, Int32(2)) - case .refunded: + case .qr: writeInt(&buf, Int32(3)) - - case .refundAvailable: - writeInt(&buf, Int32(4)) - - - case .canceled: - writeInt(&buf, Int32(5)) - } } } @@ -17383,21 +19426,21 @@ public struct FfiConverterTypeBtPaymentState2: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtPaymentState2_lift(_ buf: RustBuffer) throws -> BtPaymentState2 { - return try FfiConverterTypeBtPaymentState2.lift(buf) +public func FfiConverterTypeHardwareWalletTransport_lift(_ buf: RustBuffer) throws -> HardwareWalletTransport { + return try FfiConverterTypeHardwareWalletTransport.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeBtPaymentState2_lower(_ value: BtPaymentState2) -> RustBuffer { - return FfiConverterTypeBtPaymentState2.lower(value) +public func FfiConverterTypeHardwareWalletTransport_lower(_ value: HardwareWalletTransport) -> RustBuffer { + return FfiConverterTypeHardwareWalletTransport.lower(value) } -extension BtPaymentState2: Equatable, Hashable {} +extension HardwareWalletTransport: Equatable, Hashable {} -extension BtPaymentState2: Codable {} +extension HardwareWalletTransport: Codable {} @@ -17406,61 +19449,57 @@ extension BtPaymentState2: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * A hardware-wallet vendor recognized by Bitkit. + */ -public enum CJitStateEnum { +public enum HardwareWalletVendor { - case created - case completed - case expired - case failed + case trezor + case foundation + case blockstream } #if compiler(>=6) -extension CJitStateEnum: Sendable {} +extension HardwareWalletVendor: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeCJitStateEnum: FfiConverterRustBuffer { - typealias SwiftType = CJitStateEnum +public struct FfiConverterTypeHardwareWalletVendor: FfiConverterRustBuffer { + typealias SwiftType = HardwareWalletVendor - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CJitStateEnum { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> HardwareWalletVendor { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .created - - case 2: return .completed + case 1: return .trezor - case 3: return .expired + case 2: return .foundation - case 4: return .failed + case 3: return .blockstream default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: CJitStateEnum, into buf: inout [UInt8]) { + public static func write(_ value: HardwareWalletVendor, into buf: inout [UInt8]) { switch value { - case .created: + case .trezor: writeInt(&buf, Int32(1)) - case .completed: + case .foundation: writeInt(&buf, Int32(2)) - case .expired: + case .blockstream: writeInt(&buf, Int32(3)) - - case .failed: - writeInt(&buf, Int32(4)) - } } } @@ -17469,21 +19508,21 @@ public struct FfiConverterTypeCJitStateEnum: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeCJitStateEnum_lift(_ buf: RustBuffer) throws -> CJitStateEnum { - return try FfiConverterTypeCJitStateEnum.lift(buf) +public func FfiConverterTypeHardwareWalletVendor_lift(_ buf: RustBuffer) throws -> HardwareWalletVendor { + return try FfiConverterTypeHardwareWalletVendor.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeCJitStateEnum_lower(_ value: CJitStateEnum) -> RustBuffer { - return FfiConverterTypeCJitStateEnum.lower(value) +public func FfiConverterTypeHardwareWalletVendor_lower(_ value: HardwareWalletVendor) -> RustBuffer { + return FfiConverterTypeHardwareWalletVendor.lower(value) } -extension CJitStateEnum: Equatable, Hashable {} +extension HardwareWalletVendor: Equatable, Hashable {} -extension CJitStateEnum: Codable {} +extension HardwareWalletVendor: Codable {} @@ -17492,66 +19531,61 @@ extension CJitStateEnum: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * Coin selection strategy for transaction composition. - */ -public enum CoinSelection { +public enum JadeAddressVariant { - /** - * Branch-and-bound (default). Minimizes change by searching for exact matches. - */ - case branchAndBound - /** - * Selects largest UTXOs first. Useful for UTXO consolidation. - */ - case largestFirst - /** - * Selects oldest UTXOs first. Maximizes coin-age spending. - */ - case oldestFirst + case pkh + case wpkh + case shWpkh + case tr } #if compiler(>=6) -extension CoinSelection: Sendable {} +extension JadeAddressVariant: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeCoinSelection: FfiConverterRustBuffer { - typealias SwiftType = CoinSelection +public struct FfiConverterTypeJadeAddressVariant: FfiConverterRustBuffer { + typealias SwiftType = JadeAddressVariant - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CoinSelection { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeAddressVariant { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .branchAndBound + case 1: return .pkh - case 2: return .largestFirst + case 2: return .wpkh - case 3: return .oldestFirst + case 3: return .shWpkh + + case 4: return .tr default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: CoinSelection, into buf: inout [UInt8]) { + public static func write(_ value: JadeAddressVariant, into buf: inout [UInt8]) { switch value { - case .branchAndBound: + case .pkh: writeInt(&buf, Int32(1)) - case .largestFirst: + case .wpkh: writeInt(&buf, Int32(2)) - case .oldestFirst: + case .shWpkh: writeInt(&buf, Int32(3)) + + case .tr: + writeInt(&buf, Int32(4)) + } } } @@ -17560,98 +19594,262 @@ public struct FfiConverterTypeCoinSelection: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeCoinSelection_lift(_ buf: RustBuffer) throws -> CoinSelection { - return try FfiConverterTypeCoinSelection.lift(buf) +public func FfiConverterTypeJadeAddressVariant_lift(_ buf: RustBuffer) throws -> JadeAddressVariant { + return try FfiConverterTypeJadeAddressVariant.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeCoinSelection_lower(_ value: CoinSelection) -> RustBuffer { - return FfiConverterTypeCoinSelection.lower(value) +public func FfiConverterTypeJadeAddressVariant_lower(_ value: JadeAddressVariant) -> RustBuffer { + return FfiConverterTypeJadeAddressVariant.lower(value) } -extension CoinSelection: Equatable, Hashable {} +extension JadeAddressVariant: Equatable, Hashable {} -extension CoinSelection: Codable {} +extension JadeAddressVariant: Codable {} -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * Output specification for transaction composition. - */ -public enum ComposeOutput { +public enum JadeError: Swift.Error { + - /** - * Payment to a specific address with a fixed amount (satoshis) - */ - case payment(address: String, amountSats: UInt64 + + case TransportError(errorDetails: String ) - /** - * Send all remaining funds (after fees) to an address - */ - case sendMax(address: String + case DeviceNotFound + case DeviceDisconnected + case DeviceBusy + case NotConnected + case NotInitialized + case ConnectionError(errorDetails: String ) - /** - * OP_RETURN data output (hex-encoded payload) - */ - case opReturn(dataHex: String + case ProtocolError(errorDetails: String + ) + case Timeout + case UserCancelled + case DeviceLocked + case DeviceUninitialized + case InvalidPin + case NetworkMismatch(errorDetails: String + ) + case UnsupportedFirmware(installed: String, required: String + ) + case InvalidPath(errorDetails: String + ) + case InvalidPsbt(errorDetails: String + ) + case PsbtTooLarge(size: UInt64, max: UInt64 + ) + case FingerprintMismatch(device: String, psbt: String + ) + case NothingSigned + case AddressMismatch(expected: String, returned: String + ) + case PinServerError(errorDetails: String + ) + case DeviceError(errorDetails: String + ) + case IoError(errorDetails: String ) } -#if compiler(>=6) -extension ComposeOutput: Sendable {} -#endif - #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeComposeOutput: FfiConverterRustBuffer { - typealias SwiftType = ComposeOutput +public struct FfiConverterTypeJadeError: FfiConverterRustBuffer { + typealias SwiftType = JadeError - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ComposeOutput { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeError { let variant: Int32 = try readInt(&buf) switch variant { + + + + + case 1: return .TransportError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 2: return .DeviceNotFound + case 3: return .DeviceDisconnected + case 4: return .DeviceBusy + case 5: return .NotConnected + case 6: return .NotInitialized + case 7: return .ConnectionError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 8: return .ProtocolError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 9: return .Timeout + case 10: return .UserCancelled + case 11: return .DeviceLocked + case 12: return .DeviceUninitialized + case 13: return .InvalidPin + case 14: return .NetworkMismatch( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 15: return .UnsupportedFirmware( + installed: try FfiConverterString.read(from: &buf), + required: try FfiConverterString.read(from: &buf) + ) + case 16: return .InvalidPath( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 17: return .InvalidPsbt( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 18: return .PsbtTooLarge( + size: try FfiConverterUInt64.read(from: &buf), + max: try FfiConverterUInt64.read(from: &buf) + ) + case 19: return .FingerprintMismatch( + device: try FfiConverterString.read(from: &buf), + psbt: try FfiConverterString.read(from: &buf) + ) + case 20: return .NothingSigned + case 21: return .AddressMismatch( + expected: try FfiConverterString.read(from: &buf), + returned: try FfiConverterString.read(from: &buf) + ) + case 22: return .PinServerError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 23: return .DeviceError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + case 24: return .IoError( + errorDetails: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: JadeError, into buf: inout [UInt8]) { + switch value { + + + + + + case let .TransportError(errorDetails): + writeInt(&buf, Int32(1)) + FfiConverterString.write(errorDetails, into: &buf) + + + case .DeviceNotFound: + writeInt(&buf, Int32(2)) + + + case .DeviceDisconnected: + writeInt(&buf, Int32(3)) + + + case .DeviceBusy: + writeInt(&buf, Int32(4)) + + + case .NotConnected: + writeInt(&buf, Int32(5)) + + + case .NotInitialized: + writeInt(&buf, Int32(6)) + + + case let .ConnectionError(errorDetails): + writeInt(&buf, Int32(7)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .ProtocolError(errorDetails): + writeInt(&buf, Int32(8)) + FfiConverterString.write(errorDetails, into: &buf) + + + case .Timeout: + writeInt(&buf, Int32(9)) + + + case .UserCancelled: + writeInt(&buf, Int32(10)) + + + case .DeviceLocked: + writeInt(&buf, Int32(11)) + + + case .DeviceUninitialized: + writeInt(&buf, Int32(12)) + - case 1: return .payment(address: try FfiConverterString.read(from: &buf), amountSats: try FfiConverterUInt64.read(from: &buf) - ) + case .InvalidPin: + writeInt(&buf, Int32(13)) - case 2: return .sendMax(address: try FfiConverterString.read(from: &buf) - ) - case 3: return .opReturn(dataHex: try FfiConverterString.read(from: &buf) - ) + case let .NetworkMismatch(errorDetails): + writeInt(&buf, Int32(14)) + FfiConverterString.write(errorDetails, into: &buf) + - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: ComposeOutput, into buf: inout [UInt8]) { - switch value { + case let .UnsupportedFirmware(installed,required): + writeInt(&buf, Int32(15)) + FfiConverterString.write(installed, into: &buf) + FfiConverterString.write(required, into: &buf) + + case let .InvalidPath(errorDetails): + writeInt(&buf, Int32(16)) + FfiConverterString.write(errorDetails, into: &buf) + - case let .payment(address,amountSats): - writeInt(&buf, Int32(1)) - FfiConverterString.write(address, into: &buf) - FfiConverterUInt64.write(amountSats, into: &buf) + case let .InvalidPsbt(errorDetails): + writeInt(&buf, Int32(17)) + FfiConverterString.write(errorDetails, into: &buf) - case let .sendMax(address): - writeInt(&buf, Int32(2)) - FfiConverterString.write(address, into: &buf) + case let .PsbtTooLarge(size,max): + writeInt(&buf, Int32(18)) + FfiConverterUInt64.write(size, into: &buf) + FfiConverterUInt64.write(max, into: &buf) - case let .opReturn(dataHex): - writeInt(&buf, Int32(3)) - FfiConverterString.write(dataHex, into: &buf) + case let .FingerprintMismatch(device,psbt): + writeInt(&buf, Int32(19)) + FfiConverterString.write(device, into: &buf) + FfiConverterString.write(psbt, into: &buf) + + + case .NothingSigned: + writeInt(&buf, Int32(20)) + + + case let .AddressMismatch(expected,returned): + writeInt(&buf, Int32(21)) + FfiConverterString.write(expected, into: &buf) + FfiConverterString.write(returned, into: &buf) + + + case let .PinServerError(errorDetails): + writeInt(&buf, Int32(22)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .DeviceError(errorDetails): + writeInt(&buf, Int32(23)) + FfiConverterString.write(errorDetails, into: &buf) + + + case let .IoError(errorDetails): + writeInt(&buf, Int32(24)) + FfiConverterString.write(errorDetails, into: &buf) } } @@ -17661,102 +19859,84 @@ public struct FfiConverterTypeComposeOutput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeComposeOutput_lift(_ buf: RustBuffer) throws -> ComposeOutput { - return try FfiConverterTypeComposeOutput.lift(buf) +public func FfiConverterTypeJadeError_lift(_ buf: RustBuffer) throws -> JadeError { + return try FfiConverterTypeJadeError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeComposeOutput_lower(_ value: ComposeOutput) -> RustBuffer { - return FfiConverterTypeComposeOutput.lower(value) +public func FfiConverterTypeJadeError_lower(_ value: JadeError) -> RustBuffer { + return FfiConverterTypeJadeError.lower(value) } -extension ComposeOutput: Equatable, Hashable {} +extension JadeError: Equatable, Hashable {} + +extension JadeError: Codable {} -extension ComposeOutput: Codable {} +extension JadeError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} + // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * Result of composing a transaction at a single fee rate. - */ -public enum ComposeResult { +public enum JadeNetwork { - /** - * Successfully built a signable PSBT - */ - case success( - /** - * Base64-encoded PSBT ready for signing - */psbt: String, - /** - * Total fee in satoshis - */fee: UInt64, - /** - * Target fee rate in sat/vB (actual may differ slightly due to rounding) - */feeRate: Float, - /** - * Total value spent (payments + fee, excluding change). - * Uses BDK's `sent - received` semantics, which may undercount for - * self-transfers where the destination is also owned by the wallet. - */totalSpent: UInt64 - ) - /** - * Composition failed (e.g. insufficient funds) - */ - case error(error: String - ) + case mainnet + case testnet + case regtest } #if compiler(>=6) -extension ComposeResult: Sendable {} +extension JadeNetwork: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeComposeResult: FfiConverterRustBuffer { - typealias SwiftType = ComposeResult +public struct FfiConverterTypeJadeNetwork: FfiConverterRustBuffer { + typealias SwiftType = JadeNetwork - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ComposeResult { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeNetwork { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .success(psbt: try FfiConverterString.read(from: &buf), fee: try FfiConverterUInt64.read(from: &buf), feeRate: try FfiConverterFloat.read(from: &buf), totalSpent: try FfiConverterUInt64.read(from: &buf) - ) + case 1: return .mainnet - case 2: return .error(error: try FfiConverterString.read(from: &buf) - ) + case 2: return .testnet + + case 3: return .regtest default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: ComposeResult, into buf: inout [UInt8]) { + public static func write(_ value: JadeNetwork, into buf: inout [UInt8]) { switch value { - case let .success(psbt,fee,feeRate,totalSpent): + case .mainnet: writeInt(&buf, Int32(1)) - FfiConverterString.write(psbt, into: &buf) - FfiConverterUInt64.write(fee, into: &buf) - FfiConverterFloat.write(feeRate, into: &buf) - FfiConverterUInt64.write(totalSpent, into: &buf) - - case let .error(error): + + case .testnet: writeInt(&buf, Int32(2)) - FfiConverterString.write(error, into: &buf) - + + + case .regtest: + writeInt(&buf, Int32(3)) + } } } @@ -17765,99 +19945,77 @@ public struct FfiConverterTypeComposeResult: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeComposeResult_lift(_ buf: RustBuffer) throws -> ComposeResult { - return try FfiConverterTypeComposeResult.lift(buf) +public func FfiConverterTypeJadeNetwork_lift(_ buf: RustBuffer) throws -> JadeNetwork { + return try FfiConverterTypeJadeNetwork.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeComposeResult_lower(_ value: ComposeResult) -> RustBuffer { - return FfiConverterTypeComposeResult.lower(value) +public func FfiConverterTypeJadeNetwork_lower(_ value: JadeNetwork) -> RustBuffer { + return FfiConverterTypeJadeNetwork.lower(value) } -extension ComposeResult: Equatable, Hashable {} - -extension ComposeResult: Codable {} +extension JadeNetwork: Equatable, Hashable {} +extension JadeNetwork: Codable {} -public enum DbError: Swift.Error { +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +public enum JadePingStatus { - - case DbActivityError(errorDetails: ActivityError - ) - case DbBlocktankError(errorDetails: BlocktankError - ) - case DbBoltzError(errorDetails: BoltzError - ) - case InitializationError(errorDetails: String - ) + case idle + case busy + case awaitingUserInput } +#if compiler(>=6) +extension JadePingStatus: Sendable {} +#endif + #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeDbError: FfiConverterRustBuffer { - typealias SwiftType = DbError +public struct FfiConverterTypeJadePingStatus: FfiConverterRustBuffer { + typealias SwiftType = JadePingStatus - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DbError { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadePingStatus { let variant: Int32 = try readInt(&buf) switch variant { - - + case 1: return .idle - case 1: return .DbActivityError( - errorDetails: try FfiConverterTypeActivityError.read(from: &buf) - ) - case 2: return .DbBlocktankError( - errorDetails: try FfiConverterTypeBlocktankError.read(from: &buf) - ) - case 3: return .DbBoltzError( - errorDetails: try FfiConverterTypeBoltzError.read(from: &buf) - ) - case 4: return .InitializationError( - errorDetails: try FfiConverterString.read(from: &buf) - ) - - default: throw UniffiInternalError.unexpectedEnumCase + case 2: return .busy + + case 3: return .awaitingUserInput + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: DbError, into buf: inout [UInt8]) { + public static func write(_ value: JadePingStatus, into buf: inout [UInt8]) { switch value { - - - - case let .DbActivityError(errorDetails): + case .idle: writeInt(&buf, Int32(1)) - FfiConverterTypeActivityError.write(errorDetails, into: &buf) - - case let .DbBlocktankError(errorDetails): + + case .busy: writeInt(&buf, Int32(2)) - FfiConverterTypeBlocktankError.write(errorDetails, into: &buf) - - case let .DbBoltzError(errorDetails): + + case .awaitingUserInput: writeInt(&buf, Int32(3)) - FfiConverterTypeBoltzError.write(errorDetails, into: &buf) - - case let .InitializationError(errorDetails): - writeInt(&buf, Int32(4)) - FfiConverterString.write(errorDetails, into: &buf) - } } } @@ -17866,150 +20024,98 @@ public struct FfiConverterTypeDbError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeDbError_lift(_ buf: RustBuffer) throws -> DbError { - return try FfiConverterTypeDbError.lift(buf) +public func FfiConverterTypeJadePingStatus_lift(_ buf: RustBuffer) throws -> JadePingStatus { + return try FfiConverterTypeJadePingStatus.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeDbError_lower(_ value: DbError) -> RustBuffer { - return FfiConverterTypeDbError.lower(value) +public func FfiConverterTypeJadePingStatus_lower(_ value: JadePingStatus) -> RustBuffer { + return FfiConverterTypeJadePingStatus.lower(value) } -extension DbError: Equatable, Hashable {} - -extension DbError: Codable {} - - +extension JadePingStatus: Equatable, Hashable {} +extension JadePingStatus: Codable {} -extension DbError: Foundation.LocalizedError { - public var errorDescription: String? { - String(reflecting: self) - } -} -public enum DecodingError: Swift.Error { +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +public enum JadeState { - - case InvalidFormat - case InvalidNetwork - case InvalidAmount - case InvalidLnurlPayAmount(amountSatoshis: UInt64, min: UInt64, max: UInt64 - ) - case InvalidTimestamp - case InvalidChecksum - case InvalidResponse - case UnsupportedType - case InvalidAddress - case RequestFailed - case ClientCreationFailed - case InvoiceCreationFailed(errorMessage: String - ) + case uninit + case unsaved + case locked + case ready + case temp + case unknown } +#if compiler(>=6) +extension JadeState: Sendable {} +#endif + #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeDecodingError: FfiConverterRustBuffer { - typealias SwiftType = DecodingError +public struct FfiConverterTypeJadeState: FfiConverterRustBuffer { + typealias SwiftType = JadeState - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DecodingError { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeState { let variant: Int32 = try readInt(&buf) switch variant { - - - - - case 1: return .InvalidFormat - case 2: return .InvalidNetwork - case 3: return .InvalidAmount - case 4: return .InvalidLnurlPayAmount( - amountSatoshis: try FfiConverterUInt64.read(from: &buf), - min: try FfiConverterUInt64.read(from: &buf), - max: try FfiConverterUInt64.read(from: &buf) - ) - case 5: return .InvalidTimestamp - case 6: return .InvalidChecksum - case 7: return .InvalidResponse - case 8: return .UnsupportedType - case 9: return .InvalidAddress - case 10: return .RequestFailed - case 11: return .ClientCreationFailed - case 12: return .InvoiceCreationFailed( - errorMessage: try FfiConverterString.read(from: &buf) - ) - - default: throw UniffiInternalError.unexpectedEnumCase + + case 1: return .uninit + + case 2: return .unsaved + + case 3: return .locked + + case 4: return .ready + + case 5: return .temp + + case 6: return .unknown + + default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: DecodingError, into buf: inout [UInt8]) { + public static func write(_ value: JadeState, into buf: inout [UInt8]) { switch value { - - - - case .InvalidFormat: + case .uninit: writeInt(&buf, Int32(1)) - case .InvalidNetwork: + case .unsaved: writeInt(&buf, Int32(2)) - case .InvalidAmount: + case .locked: writeInt(&buf, Int32(3)) - case let .InvalidLnurlPayAmount(amountSatoshis,min,max): + case .ready: writeInt(&buf, Int32(4)) - FfiConverterUInt64.write(amountSatoshis, into: &buf) - FfiConverterUInt64.write(min, into: &buf) - FfiConverterUInt64.write(max, into: &buf) - - case .InvalidTimestamp: + + case .temp: writeInt(&buf, Int32(5)) - case .InvalidChecksum: + case .unknown: writeInt(&buf, Int32(6)) - - case .InvalidResponse: - writeInt(&buf, Int32(7)) - - - case .UnsupportedType: - writeInt(&buf, Int32(8)) - - - case .InvalidAddress: - writeInt(&buf, Int32(9)) - - - case .RequestFailed: - writeInt(&buf, Int32(10)) - - - case .ClientCreationFailed: - writeInt(&buf, Int32(11)) - - - case let .InvoiceCreationFailed(errorMessage): - writeInt(&buf, Int32(12)) - FfiConverterString.write(errorMessage, into: &buf) - } } } @@ -18018,87 +20124,91 @@ public struct FfiConverterTypeDecodingError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeDecodingError_lift(_ buf: RustBuffer) throws -> DecodingError { - return try FfiConverterTypeDecodingError.lift(buf) +public func FfiConverterTypeJadeState_lift(_ buf: RustBuffer) throws -> JadeState { + return try FfiConverterTypeJadeState.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeDecodingError_lower(_ value: DecodingError) -> RustBuffer { - return FfiConverterTypeDecodingError.lower(value) +public func FfiConverterTypeJadeState_lower(_ value: JadeState) -> RustBuffer { + return FfiConverterTypeJadeState.lower(value) } -extension DecodingError: Equatable, Hashable {} - -extension DecodingError: Codable {} - +extension JadeState: Equatable, Hashable {} +extension JadeState: Codable {} -extension DecodingError: Foundation.LocalizedError { - public var errorDescription: String? { - String(reflecting: self) - } -} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * How an application exchanges data with a hardware wallet. - */ -public enum HardwareWalletTransport { +public enum JadeTransportErrorCode { - case usb - case bluetooth - case qr + case deviceBusy + case notConnected + case disconnected + case timeout + case permissionDenied } #if compiler(>=6) -extension HardwareWalletTransport: Sendable {} +extension JadeTransportErrorCode: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeHardwareWalletTransport: FfiConverterRustBuffer { - typealias SwiftType = HardwareWalletTransport +public struct FfiConverterTypeJadeTransportErrorCode: FfiConverterRustBuffer { + typealias SwiftType = JadeTransportErrorCode - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> HardwareWalletTransport { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeTransportErrorCode { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .usb + case 1: return .deviceBusy - case 2: return .bluetooth + case 2: return .notConnected - case 3: return .qr + case 3: return .disconnected + + case 4: return .timeout + + case 5: return .permissionDenied default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: HardwareWalletTransport, into buf: inout [UInt8]) { + public static func write(_ value: JadeTransportErrorCode, into buf: inout [UInt8]) { switch value { - case .usb: + case .deviceBusy: writeInt(&buf, Int32(1)) - case .bluetooth: + case .notConnected: writeInt(&buf, Int32(2)) - case .qr: + case .disconnected: writeInt(&buf, Int32(3)) + + case .timeout: + writeInt(&buf, Int32(4)) + + + case .permissionDenied: + writeInt(&buf, Int32(5)) + } } } @@ -18107,21 +20217,21 @@ public struct FfiConverterTypeHardwareWalletTransport: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeHardwareWalletTransport_lift(_ buf: RustBuffer) throws -> HardwareWalletTransport { - return try FfiConverterTypeHardwareWalletTransport.lift(buf) +public func FfiConverterTypeJadeTransportErrorCode_lift(_ buf: RustBuffer) throws -> JadeTransportErrorCode { + return try FfiConverterTypeJadeTransportErrorCode.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeHardwareWalletTransport_lower(_ value: HardwareWalletTransport) -> RustBuffer { - return FfiConverterTypeHardwareWalletTransport.lower(value) +public func FfiConverterTypeJadeTransportErrorCode_lower(_ value: JadeTransportErrorCode) -> RustBuffer { + return FfiConverterTypeJadeTransportErrorCode.lower(value) } -extension HardwareWalletTransport: Equatable, Hashable {} +extension JadeTransportErrorCode: Equatable, Hashable {} -extension HardwareWalletTransport: Codable {} +extension JadeTransportErrorCode: Codable {} @@ -18130,48 +20240,45 @@ extension HardwareWalletTransport: Codable {} // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. -/** - * A hardware-wallet vendor recognized by Bitkit. - */ -public enum HardwareWalletVendor { +public enum JadeTransportKind { - case trezor - case foundation + case bluetooth + case serial } #if compiler(>=6) -extension HardwareWalletVendor: Sendable {} +extension JadeTransportKind: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeHardwareWalletVendor: FfiConverterRustBuffer { - typealias SwiftType = HardwareWalletVendor +public struct FfiConverterTypeJadeTransportKind: FfiConverterRustBuffer { + typealias SwiftType = JadeTransportKind - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> HardwareWalletVendor { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> JadeTransportKind { let variant: Int32 = try readInt(&buf) switch variant { - case 1: return .trezor + case 1: return .bluetooth - case 2: return .foundation + case 2: return .serial default: throw UniffiInternalError.unexpectedEnumCase } } - public static func write(_ value: HardwareWalletVendor, into buf: inout [UInt8]) { + public static func write(_ value: JadeTransportKind, into buf: inout [UInt8]) { switch value { - case .trezor: + case .bluetooth: writeInt(&buf, Int32(1)) - case .foundation: + case .serial: writeInt(&buf, Int32(2)) } @@ -18182,21 +20289,21 @@ public struct FfiConverterTypeHardwareWalletVendor: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeHardwareWalletVendor_lift(_ buf: RustBuffer) throws -> HardwareWalletVendor { - return try FfiConverterTypeHardwareWalletVendor.lift(buf) +public func FfiConverterTypeJadeTransportKind_lift(_ buf: RustBuffer) throws -> JadeTransportKind { + return try FfiConverterTypeJadeTransportKind.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeHardwareWalletVendor_lower(_ value: HardwareWalletVendor) -> RustBuffer { - return FfiConverterTypeHardwareWalletVendor.lower(value) +public func FfiConverterTypeJadeTransportKind_lower(_ value: JadeTransportKind) -> RustBuffer { + return FfiConverterTypeJadeTransportKind.lower(value) } -extension HardwareWalletVendor: Equatable, Hashable {} +extension JadeTransportKind: Equatable, Hashable {} -extension HardwareWalletVendor: Codable {} +extension JadeTransportKind: Codable {} @@ -21520,6 +23627,54 @@ fileprivate struct FfiConverterOptionTypeILspNode: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeJadeDeviceInfo: FfiConverterRustBuffer { + typealias SwiftType = JadeDeviceInfo? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeJadeDeviceInfo.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeJadeDeviceInfo.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeJadeVersionInfo: FfiConverterRustBuffer { + typealias SwiftType = JadeVersionInfo? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeJadeVersionInfo.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeJadeVersionInfo.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -21832,6 +23987,30 @@ fileprivate struct FfiConverterOptionTypeCoinSelection: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeJadeTransportErrorCode: FfiConverterRustBuffer { + typealias SwiftType = JadeTransportErrorCode? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeJadeTransportErrorCode.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeJadeTransportErrorCode.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -22384,12 +24563,87 @@ fileprivate struct FfiConverterSequenceTypeIBtOrder: FfiConverterRustBuffer { } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [IBtOrder] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [IBtOrder] { + let len: Int32 = try readInt(&buf) + var seq = [IBtOrder]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeIBtOrder.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeICJitEntry: FfiConverterRustBuffer { + typealias SwiftType = [IcJitEntry] + + public static func write(_ value: [IcJitEntry], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeICJitEntry.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [IcJitEntry] { + let len: Int32 = try readInt(&buf) + var seq = [IcJitEntry]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeICJitEntry.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeILspNode: FfiConverterRustBuffer { + typealias SwiftType = [ILspNode] + + public static func write(_ value: [ILspNode], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeILspNode.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ILspNode] { + let len: Int32 = try readInt(&buf) + var seq = [ILspNode]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeILspNode.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeIManualRefund: FfiConverterRustBuffer { + typealias SwiftType = [IManualRefund] + + public static func write(_ value: [IManualRefund], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeIManualRefund.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [IManualRefund] { let len: Int32 = try readInt(&buf) - var seq = [IBtOrder]() + var seq = [IManualRefund]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeIBtOrder.read(from: &buf)) + seq.append(try FfiConverterTypeIManualRefund.read(from: &buf)) } return seq } @@ -22398,23 +24652,23 @@ fileprivate struct FfiConverterSequenceTypeIBtOrder: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeICJitEntry: FfiConverterRustBuffer { - typealias SwiftType = [IcJitEntry] +fileprivate struct FfiConverterSequenceTypeJadeAccount: FfiConverterRustBuffer { + typealias SwiftType = [JadeAccount] - public static func write(_ value: [IcJitEntry], into buf: inout [UInt8]) { + public static func write(_ value: [JadeAccount], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeICJitEntry.write(item, into: &buf) + FfiConverterTypeJadeAccount.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [IcJitEntry] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [JadeAccount] { let len: Int32 = try readInt(&buf) - var seq = [IcJitEntry]() + var seq = [JadeAccount]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeICJitEntry.read(from: &buf)) + seq.append(try FfiConverterTypeJadeAccount.read(from: &buf)) } return seq } @@ -22423,23 +24677,23 @@ fileprivate struct FfiConverterSequenceTypeICJitEntry: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeILspNode: FfiConverterRustBuffer { - typealias SwiftType = [ILspNode] +fileprivate struct FfiConverterSequenceTypeJadeDeviceInfo: FfiConverterRustBuffer { + typealias SwiftType = [JadeDeviceInfo] - public static func write(_ value: [ILspNode], into buf: inout [UInt8]) { + public static func write(_ value: [JadeDeviceInfo], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeILspNode.write(item, into: &buf) + FfiConverterTypeJadeDeviceInfo.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ILspNode] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [JadeDeviceInfo] { let len: Int32 = try readInt(&buf) - var seq = [ILspNode]() + var seq = [JadeDeviceInfo]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeILspNode.read(from: &buf)) + seq.append(try FfiConverterTypeJadeDeviceInfo.read(from: &buf)) } return seq } @@ -22448,23 +24702,23 @@ fileprivate struct FfiConverterSequenceTypeILspNode: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeIManualRefund: FfiConverterRustBuffer { - typealias SwiftType = [IManualRefund] +fileprivate struct FfiConverterSequenceTypeJadeNativeDevice: FfiConverterRustBuffer { + typealias SwiftType = [JadeNativeDevice] - public static func write(_ value: [IManualRefund], into buf: inout [UInt8]) { + public static func write(_ value: [JadeNativeDevice], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeIManualRefund.write(item, into: &buf) + FfiConverterTypeJadeNativeDevice.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [IManualRefund] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [JadeNativeDevice] { let len: Int32 = try readInt(&buf) - var seq = [IManualRefund]() + var seq = [JadeNativeDevice]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeIManualRefund.read(from: &buf)) + seq.append(try FfiConverterTypeJadeNativeDevice.read(from: &buf)) } return seq } @@ -22920,6 +25174,31 @@ fileprivate struct FfiConverterSequenceTypeTxOutput: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeAccountType: FfiConverterRustBuffer { + typealias SwiftType = [AccountType] + + public static func write(_ value: [AccountType], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeAccountType.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AccountType] { + let len: Int32 = try readInt(&buf) + var seq = [AccountType]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeAccountType.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -23160,975 +25439,1356 @@ public func addTags(walletId: String, activityId: String, tags: [String])throws ) } } -public func approvePubkyAuth(authUrl: String, secretKeyHex: String)async throws { +public func approvePubkyAuth(authUrl: String, secretKeyHex: String)async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_approve_pubky_auth(FfiConverterString.lower(authUrl),FfiConverterString.lower(secretKeyHex) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypePubkyError_lift + ) +} +public func blocktankRemoveAllCjitEntries()async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_blocktank_remove_all_cjit_entries( + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeBlocktankError_lift + ) +} +public func blocktankRemoveAllOrders()async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_blocktank_remove_all_orders( + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeBlocktankError_lift + ) +} +public func blocktankWipeAll()async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_blocktank_wipe_all( + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeBlocktankError_lift + ) +} +/** + * Claim a reverse swap's onchain funds to its claim address, returning the + * broadcast claim transaction id. Normally happens automatically via the + * updates stream; exposed for manual recovery. The claim key is re-derived from + * `mnemonic`. Claims are serialized per swap, so calling this while the updates + * stream is auto-claiming the same swap waits for that claim and returns its + * txid rather than broadcasting a second transaction. + */ +public func boltzClaimReverseSwap(swapId: String, mnemonic: String, bip39Passphrase: String?, feeRateSatPerVb: Double?)async throws -> String { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_claim_reverse_swap(FfiConverterString.lower(swapId),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterOptionDouble.lower(feeRateSatPerVb) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterString.lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * Create a reverse swap (Lightning -> onchain). + * + * The caller pays the returned hold invoice from its Lightning node; + * `claim_address` is the onchain address the received funds are claimed to. + * The claim key and preimage are derived deterministically from `mnemonic` + * (only the derivation index is persisted, never the secrets) so the claim can + * be made automatically once Boltz locks the funds. `bip39_passphrase` must + * match the wallet's, or claims will derive the wrong key. + */ +public func boltzCreateReverseSwap(network: BoltzNetwork, electrumUrl: String, amountSat: UInt64, claimAddress: String, mnemonic: String, bip39Passphrase: String?)async throws -> ReverseSwapResponse { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_create_reverse_swap(FfiConverterTypeBoltzNetwork_lower(network),FfiConverterString.lower(electrumUrl),FfiConverterUInt64.lower(amountSat),FfiConverterString.lower(claimAddress),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeReverseSwapResponse_lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * Create a submarine swap (onchain -> Lightning). + * + * `invoice` is a BOLT11 invoice the caller's Lightning node generated. The + * caller funds the returned lockup address from its onchain wallet. The refund + * key is derived deterministically from `mnemonic` (only the derivation index + * is persisted, never the key), and the swap is tracked if an updates stream is + * running. `bip39_passphrase` must match the wallet's, or refunds will derive + * the wrong key. + */ +public func boltzCreateSubmarineSwap(network: BoltzNetwork, electrumUrl: String, invoice: String, mnemonic: String, bip39Passphrase: String?)async throws -> SubmarineSwapResponse { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_create_submarine_swap(FfiConverterTypeBoltzNetwork_lower(network),FfiConverterString.lower(electrumUrl),FfiConverterString.lower(invoice),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeSubmarineSwapResponse_lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * Fetch fees and limits for reverse swaps (Lightning -> onchain). + */ +public func boltzGetReverseLimits(network: BoltzNetwork)async throws -> BoltzPairInfo { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_get_reverse_limits(FfiConverterTypeBoltzNetwork_lower(network) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeBoltzPairInfo_lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * Fetch fees and limits for submarine swaps (onchain -> Lightning). + */ +public func boltzGetSubmarineLimits(network: BoltzNetwork)async throws -> BoltzPairInfo { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_get_submarine_limits(FfiConverterTypeBoltzNetwork_lower(network) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeBoltzPairInfo_lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * Fetch a single swap by id. + */ +public func boltzGetSwap(swapId: String)async throws -> BoltzSwap? { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_get_swap(FfiConverterString.lower(swapId) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterOptionTypeBoltzSwap.lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * List swaps that have not reached a terminal state (for recovery/resume). + */ +public func boltzListPendingSwaps()async throws -> [BoltzSwap] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_list_pending_swaps( + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypeBoltzSwap.lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * List every persisted swap, newest first. + */ +public func boltzListSwaps()async throws -> [BoltzSwap] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_list_swaps( + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypeBoltzSwap.lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * Refund a submarine swap's locked funds to `refund_address`, returning the + * broadcast refund transaction id. Used when Boltz fails to pay the invoice or + * the swap expires. The refund key is re-derived from `mnemonic`. Refunds are + * serialized per swap, so two concurrent calls cannot both broadcast: the second + * waits for the first and returns its txid. + */ +public func boltzRefundSubmarineSwap(swapId: String, refundAddress: String, mnemonic: String, bip39Passphrase: String?, feeRateSatPerVb: Double?)async throws -> String { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_boltz_refund_submarine_swap(FfiConverterString.lower(swapId),FfiConverterString.lower(refundAddress),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterOptionDouble.lower(feeRateSatPerVb) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterString.lift, + errorHandler: FfiConverterTypeBoltzError_lift + ) +} +/** + * Open a Boltz WebSocket for `network`, subscribe to all pending swaps, and + * drive their lifecycle (auto-claiming reverse swaps) until stopped. Replaces + * any previously running updates stream (only one network is tracked at a + * time). `mnemonic` is held in memory for the lifetime of the stream so + * confirmed reverse swaps can be auto-claimed; it is never persisted. Events + * are delivered to `listener`. + * + * `fee_rate_sat_per_vb` is the fee rate used for automatic claim transactions. + * Bitkit owns fee estimation and should pass its current recommended rate; when + * `None`, a conservative built-in default is used. To auto-claim at an updated + * fee rate, call this again (it restarts the stream). + * + * `accept_zero_conf` claims reverse swaps as soon as Boltz's lockup enters the + * mempool instead of waiting for its confirmation. That reveals the preimage + * against an unconfirmed lockup: if the lockup were replaced before + * confirming, the user would be debited on Lightning without receiving + * onchain funds. Pass `false` to keep the confirmation-gated default. + */ +public func boltzStartSwapUpdates(network: BoltzNetwork, listener: BoltzEventListener, mnemonic: String, bip39Passphrase: String?, feeRateSatPerVb: Double?, acceptZeroConf: Bool)async throws { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_approve_pubky_auth(FfiConverterString.lower(authUrl),FfiConverterString.lower(secretKeyHex) + uniffi_bitkitcore_fn_func_boltz_start_swap_updates(FfiConverterTypeBoltzNetwork_lower(network),FfiConverterTypeBoltzEventListener_lower(listener),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterOptionDouble.lower(feeRateSatPerVb),FfiConverterBool.lower(acceptZeroConf) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_void, completeFunc: ffi_bitkitcore_rust_future_complete_void, freeFunc: ffi_bitkitcore_rust_future_free_void, liftFunc: { $0 }, - errorHandler: FfiConverterTypePubkyError_lift + errorHandler: FfiConverterTypeBoltzError_lift ) } -public func blocktankRemoveAllCjitEntries()async throws { +/** + * Stop the running Boltz updates stream, if any. + */ +public func boltzStopSwapUpdates()async { return - try await uniffiRustCallAsync( + try! await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_blocktank_remove_all_cjit_entries( + uniffi_bitkitcore_fn_func_boltz_stop_swap_updates( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_void, completeFunc: ffi_bitkitcore_rust_future_complete_void, freeFunc: ffi_bitkitcore_rust_future_free_void, liftFunc: { $0 }, - errorHandler: FfiConverterTypeBlocktankError_lift + errorHandler: nil + ) } -public func blocktankRemoveAllOrders()async throws { +public func broadcastSweepTransaction(psbt: String, mnemonicPhrase: String, network: Network?, bip39Passphrase: String?, electrumUrl: String)async throws -> SweepResult { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_blocktank_remove_all_orders( + uniffi_bitkitcore_fn_func_broadcast_sweep_transaction(FfiConverterString.lower(psbt),FfiConverterString.lower(mnemonicPhrase),FfiConverterOptionTypeNetwork.lower(network),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterString.lower(electrumUrl) ) }, - pollFunc: ffi_bitkitcore_rust_future_poll_void, - completeFunc: ffi_bitkitcore_rust_future_complete_void, - freeFunc: ffi_bitkitcore_rust_future_free_void, - liftFunc: { $0 }, - errorHandler: FfiConverterTypeBlocktankError_lift + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeSweepResult_lift, + errorHandler: FfiConverterTypeSweepError_lift ) } -public func blocktankWipeAll()async throws { +public func calculateChannelLiquidityOptions(params: ChannelLiquidityParams) -> ChannelLiquidityOptions { + return try! FfiConverterTypeChannelLiquidityOptions_lift(try! rustCall() { + uniffi_bitkitcore_fn_func_calculate_channel_liquidity_options( + FfiConverterTypeChannelLiquidityParams_lower(params),$0 + ) +}) +} +public func cancelPubkyAuth()async throws { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_blocktank_wipe_all( + uniffi_bitkitcore_fn_func_cancel_pubky_auth( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_void, completeFunc: ffi_bitkitcore_rust_future_complete_void, freeFunc: ffi_bitkitcore_rust_future_free_void, liftFunc: { $0 }, - errorHandler: FfiConverterTypeBlocktankError_lift + errorHandler: FfiConverterTypePubkyError_lift + ) +} +public func checkSweepableBalances(mnemonicPhrase: String, network: Network?, bip39Passphrase: String?, electrumUrl: String)async throws -> SweepableBalances { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_check_sweepable_balances(FfiConverterString.lower(mnemonicPhrase),FfiConverterOptionTypeNetwork.lower(network),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterString.lower(electrumUrl) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeSweepableBalances_lift, + errorHandler: FfiConverterTypeSweepError_lift ) } /** - * Claim a reverse swap's onchain funds to its claim address, returning the - * broadcast claim transaction id. Normally happens automatically via the - * updates stream; exposed for manual recovery. The claim key is re-derived from - * `mnemonic`. Claims are serialized per swap, so calling this while the updates - * stream is auto-claiming the same swap waits for that claim and returns its - * txid rather than broadcasting a second transaction. + * Decode closed channels from Core's canonical backup JSON. */ -public func boltzClaimReverseSwap(swapId: String, mnemonic: String, bip39Passphrase: String?, feeRateSatPerVb: Double?)async throws -> String { +public func closedChannelsFromJson(json: String)throws -> [ClosedChannelDetails] { + return try FfiConverterSequenceTypeClosedChannelDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_closed_channels_from_json( + FfiConverterString.lower(json),$0 + ) +}) +} +/** + * Serialize closed channels to Core's canonical backup JSON. Closed channels + * are not wallet-scoped, so no wallet-id normalization is applied. + */ +public func closedChannelsToJson(channels: [ClosedChannelDetails])throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_closed_channels_to_json( + FfiConverterSequenceTypeClosedChannelDetails.lower(channels),$0 + ) +}) +} +public func completePubkyAuth()async throws -> String { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_claim_reverse_swap(FfiConverterString.lower(swapId),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterOptionDouble.lower(feeRateSatPerVb) + uniffi_bitkitcore_fn_func_complete_pubky_auth( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, liftFunc: FfiConverterString.lift, - errorHandler: FfiConverterTypeBoltzError_lift + errorHandler: FfiConverterTypePubkyError_lift + ) +} +public func createChannelRequestUrl(k1: String, callback: String, localNodeId: String, isPrivate: Bool, cancel: Bool)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeLnurlError_lift) { + uniffi_bitkitcore_fn_func_create_channel_request_url( + FfiConverterString.lower(k1), + FfiConverterString.lower(callback), + FfiConverterString.lower(localNodeId), + FfiConverterBool.lower(isPrivate), + FfiConverterBool.lower(cancel),$0 + ) +}) +} +public func createCjitEntry(channelSizeSat: UInt64, invoiceSat: UInt64, invoiceDescription: String, nodeId: String, channelExpiryWeeks: UInt32, options: CreateCjitOptions?)async throws -> IcJitEntry { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_create_cjit_entry(FfiConverterUInt64.lower(channelSizeSat),FfiConverterUInt64.lower(invoiceSat),FfiConverterString.lower(invoiceDescription),FfiConverterString.lower(nodeId),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateCjitOptions.lower(options) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeICJitEntry_lift, + errorHandler: FfiConverterTypeBlocktankError_lift + ) +} +public func createOrder(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, options: CreateOrderOptions?)async throws -> IBtOrder { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_create_order(FfiConverterUInt64.lower(lspBalanceSat),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateOrderOptions.lower(options) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeIBtOrder_lift, + errorHandler: FfiConverterTypeBlocktankError_lift + ) +} +public func createWithdrawCallbackUrl(k1: String, callback: String, paymentRequest: String)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeLnurlError_lift) { + uniffi_bitkitcore_fn_func_create_withdraw_callback_url( + FfiConverterString.lower(k1), + FfiConverterString.lower(callback), + FfiConverterString.lower(paymentRequest),$0 + ) +}) +} +public func decode(invoice: String)async throws -> Scanner { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_decode(FfiConverterString.lower(invoice) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeScanner_lift, + errorHandler: FfiConverterTypeDecodingError_lift ) } -/** - * Create a reverse swap (Lightning -> onchain). - * - * The caller pays the returned hold invoice from its Lightning node; - * `claim_address` is the onchain address the received funds are claimed to. - * The claim key and preimage are derived deterministically from `mnemonic` - * (only the derivation index is persisted, never the secrets) so the claim can - * be made automatically once Boltz locks the funds. `bip39_passphrase` must - * match the wallet's, or claims will derive the wrong key. - */ -public func boltzCreateReverseSwap(network: BoltzNetwork, electrumUrl: String, amountSat: UInt64, claimAddress: String, mnemonic: String, bip39Passphrase: String?)async throws -> ReverseSwapResponse { - return - try await uniffiRustCallAsync( - rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_create_reverse_swap(FfiConverterTypeBoltzNetwork_lower(network),FfiConverterString.lower(electrumUrl),FfiConverterUInt64.lower(amountSat),FfiConverterString.lower(claimAddress),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase) - ) - }, - pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, - completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, - freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeReverseSwapResponse_lift, - errorHandler: FfiConverterTypeBoltzError_lift - ) +public func deleteActivitiesByWalletId(walletId: String)throws -> UInt32 { + return try FfiConverterUInt32.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_delete_activities_by_wallet_id( + FfiConverterString.lower(walletId),$0 + ) +}) +} +public func deleteActivityById(walletId: String, activityId: String)throws -> Bool { + return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_delete_activity_by_id( + FfiConverterString.lower(walletId), + FfiConverterString.lower(activityId),$0 + ) +}) +} +public func deletePreActivityMetadata(walletId: String, paymentId: String)throws {try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_delete_pre_activity_metadata( + FfiConverterString.lower(walletId), + FfiConverterString.lower(paymentId),$0 + ) +} +} +public func deleteTransactionDetails(walletId: String, txId: String)throws -> Bool { + return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_delete_transaction_details( + FfiConverterString.lower(walletId), + FfiConverterString.lower(txId),$0 + ) +}) +} +public func deriveBitcoinAddress(mnemonicPhrase: String, derivationPathStr: String?, network: Network?, bip39Passphrase: String?)throws -> GetAddressResponse { + return try FfiConverterTypeGetAddressResponse_lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { + uniffi_bitkitcore_fn_func_derive_bitcoin_address( + FfiConverterString.lower(mnemonicPhrase), + FfiConverterOptionString.lower(derivationPathStr), + FfiConverterOptionTypeNetwork.lower(network), + FfiConverterOptionString.lower(bip39Passphrase),$0 + ) +}) +} +public func deriveBitcoinAddresses(mnemonicPhrase: String, derivationPathStr: String?, network: Network?, bip39Passphrase: String?, isChange: Bool?, startIndex: UInt32?, count: UInt32?)throws -> GetAddressesResponse { + return try FfiConverterTypeGetAddressesResponse_lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { + uniffi_bitkitcore_fn_func_derive_bitcoin_addresses( + FfiConverterString.lower(mnemonicPhrase), + FfiConverterOptionString.lower(derivationPathStr), + FfiConverterOptionTypeNetwork.lower(network), + FfiConverterOptionString.lower(bip39Passphrase), + FfiConverterOptionBool.lower(isChange), + FfiConverterOptionUInt32.lower(startIndex), + FfiConverterOptionUInt32.lower(count),$0 + ) +}) +} +public func deriveOnchainDescriptor(mnemonicPhrase: String, network: Network, bip39Passphrase: String?, accountType: AccountType, accountIndex: UInt32)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { + uniffi_bitkitcore_fn_func_derive_onchain_descriptor( + FfiConverterString.lower(mnemonicPhrase), + FfiConverterTypeNetwork_lower(network), + FfiConverterOptionString.lower(bip39Passphrase), + FfiConverterTypeAccountType_lower(accountType), + FfiConverterUInt32.lower(accountIndex),$0 + ) +}) +} +public func derivePrivateKey(mnemonicPhrase: String, derivationPathStr: String?, network: Network?, bip39Passphrase: String?)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { + uniffi_bitkitcore_fn_func_derive_private_key( + FfiConverterString.lower(mnemonicPhrase), + FfiConverterOptionString.lower(derivationPathStr), + FfiConverterOptionTypeNetwork.lower(network), + FfiConverterOptionString.lower(bip39Passphrase),$0 + ) +}) +} +public func derivePubkySecretKey(seed: Data)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypePubkyError_lift) { + uniffi_bitkitcore_fn_func_derive_pubky_secret_key( + FfiConverterData.lower(seed),$0 + ) +}) } /** - * Create a submarine swap (onchain -> Lightning). - * - * `invoice` is a BOLT11 invoice the caller's Lightning node generated. The - * caller funds the returned lockup address from its onchain wallet. The refund - * key is derived deterministically from `mnemonic` (only the derivation index - * is persisted, never the key), and the swap is tracked if an updates stream is - * running. `bip39_passphrase` must match the wallet's, or refunds will derive - * the wrong key. + * Derive a stable, cross-platform `wallet_id` for a hardware (watch-only) wallet + * from its account extended public keys. See `derive_wallet_id` in the activity + * module for the exact derivation. Order of `xpubs` does not matter. Returns an + * error if `device_type` is blank or `xpubs` is empty / has a blank entry. */ -public func boltzCreateSubmarineSwap(network: BoltzNetwork, electrumUrl: String, invoice: String, mnemonic: String, bip39Passphrase: String?)async throws -> SubmarineSwapResponse { +public func deriveWalletId(deviceType: String, xpubs: [String])throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_derive_wallet_id( + FfiConverterString.lower(deviceType), + FfiConverterSequenceString.lower(xpubs),$0 + ) +}) +} +public func entropyToMnemonic(entropy: Data)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { + uniffi_bitkitcore_fn_func_entropy_to_mnemonic( + FfiConverterData.lower(entropy),$0 + ) +}) +} +public func estimateOrderFee(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, options: CreateOrderOptions?)async throws -> IBtEstimateFeeResponse { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_create_submarine_swap(FfiConverterTypeBoltzNetwork_lower(network),FfiConverterString.lower(electrumUrl),FfiConverterString.lower(invoice),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase) + uniffi_bitkitcore_fn_func_estimate_order_fee(FfiConverterUInt64.lower(lspBalanceSat),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateOrderOptions.lower(options) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeSubmarineSwapResponse_lift, - errorHandler: FfiConverterTypeBoltzError_lift + liftFunc: FfiConverterTypeIBtEstimateFeeResponse_lift, + errorHandler: FfiConverterTypeBlocktankError_lift ) } -/** - * Fetch fees and limits for reverse swaps (Lightning -> onchain). - */ -public func boltzGetReverseLimits(network: BoltzNetwork)async throws -> BoltzPairInfo { +public func estimateOrderFeeFull(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, options: CreateOrderOptions?)async throws -> IBtEstimateFeeResponse2 { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_get_reverse_limits(FfiConverterTypeBoltzNetwork_lower(network) + uniffi_bitkitcore_fn_func_estimate_order_fee_full(FfiConverterUInt64.lower(lspBalanceSat),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateOrderOptions.lower(options) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeBoltzPairInfo_lift, - errorHandler: FfiConverterTypeBoltzError_lift + liftFunc: FfiConverterTypeIBtEstimateFeeResponse2_lift, + errorHandler: FfiConverterTypeBlocktankError_lift ) } -/** - * Fetch fees and limits for submarine swaps (onchain -> Lightning). - */ -public func boltzGetSubmarineLimits(network: BoltzNetwork)async throws -> BoltzPairInfo { +public func fetchPubkyContacts(publicKey: String)async throws -> [String] { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_get_submarine_limits(FfiConverterTypeBoltzNetwork_lower(network) + uniffi_bitkitcore_fn_func_fetch_pubky_contacts(FfiConverterString.lower(publicKey) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeBoltzPairInfo_lift, - errorHandler: FfiConverterTypeBoltzError_lift + liftFunc: FfiConverterSequenceString.lift, + errorHandler: FfiConverterTypePubkyError_lift ) } -/** - * Fetch a single swap by id. - */ -public func boltzGetSwap(swapId: String)async throws -> BoltzSwap? { +public func fetchPubkyFile(uri: String)async throws -> Data { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_get_swap(FfiConverterString.lower(swapId) + uniffi_bitkitcore_fn_func_fetch_pubky_file(FfiConverterString.lower(uri) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterOptionTypeBoltzSwap.lift, - errorHandler: FfiConverterTypeBoltzError_lift + liftFunc: FfiConverterData.lift, + errorHandler: FfiConverterTypePubkyError_lift ) } -/** - * List swaps that have not reached a terminal state (for recovery/resume). - */ -public func boltzListPendingSwaps()async throws -> [BoltzSwap] { +public func fetchPubkyFileString(uri: String)async throws -> String { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_list_pending_swaps( + uniffi_bitkitcore_fn_func_fetch_pubky_file_string(FfiConverterString.lower(uri) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterSequenceTypeBoltzSwap.lift, - errorHandler: FfiConverterTypeBoltzError_lift + liftFunc: FfiConverterString.lift, + errorHandler: FfiConverterTypePubkyError_lift ) } -/** - * List every persisted swap, newest first. - */ -public func boltzListSwaps()async throws -> [BoltzSwap] { +public func fetchPubkyProfile(publicKey: String)async throws -> PubkyProfile { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_list_swaps( + uniffi_bitkitcore_fn_func_fetch_pubky_profile(FfiConverterString.lower(publicKey) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterSequenceTypeBoltzSwap.lift, - errorHandler: FfiConverterTypeBoltzError_lift + liftFunc: FfiConverterTypePubkyProfile_lift, + errorHandler: FfiConverterTypePubkyError_lift ) } /** - * Refund a submarine swap's locked funds to `refund_address`, returning the - * broadcast refund transaction id. Used when Boltz fails to pay the invoice or - * the swap expires. The refund key is re-derived from `mnemonic`. Refunds are - * serialized per swap, so two concurrent calls cannot both broadcast: the second - * waits for the first and returns its txid. + * Combine and finalize a signed PSBT, then extract its broadcastable transaction. */ -public func boltzRefundSubmarineSwap(swapId: String, refundAddress: String, mnemonic: String, bip39Passphrase: String?, feeRateSatPerVb: Double?)async throws -> String { - return - try await uniffiRustCallAsync( - rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_refund_submarine_swap(FfiConverterString.lower(swapId),FfiConverterString.lower(refundAddress),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterOptionDouble.lower(feeRateSatPerVb) - ) - }, - pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, - completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, - freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterString.lift, - errorHandler: FfiConverterTypeBoltzError_lift - ) +public func finalizePsbt(originalPsbt: String, signedPsbt: String)throws -> CompletedTransaction { + return try FfiConverterTypeCompletedTransaction_lift(try rustCallWithError(FfiConverterTypePsbtCompletionError_lift) { + uniffi_bitkitcore_fn_func_finalize_psbt( + FfiConverterString.lower(originalPsbt), + FfiConverterString.lower(signedPsbt),$0 + ) +}) +} +public func generateMnemonic(wordCount: WordCount?)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { + uniffi_bitkitcore_fn_func_generate_mnemonic( + FfiConverterOptionTypeWordCount.lower(wordCount),$0 + ) +}) +} +public func getActivities(walletId: String?, filter: ActivityFilter?, txType: PaymentType?, tags: [String]?, search: String?, minDate: UInt64?, maxDate: UInt64?, limit: UInt32?, sortDirection: SortDirection?)throws -> [Activity] { + return try FfiConverterSequenceTypeActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_activities( + FfiConverterOptionString.lower(walletId), + FfiConverterOptionTypeActivityFilter.lower(filter), + FfiConverterOptionTypePaymentType.lower(txType), + FfiConverterOptionSequenceString.lower(tags), + FfiConverterOptionString.lower(search), + FfiConverterOptionUInt64.lower(minDate), + FfiConverterOptionUInt64.lower(maxDate), + FfiConverterOptionUInt32.lower(limit), + FfiConverterOptionTypeSortDirection.lower(sortDirection),$0 + ) +}) +} +public func getActivitiesByTag(walletId: String?, tag: String, limit: UInt32?, sortDirection: SortDirection?)throws -> [Activity] { + return try FfiConverterSequenceTypeActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_activities_by_tag( + FfiConverterOptionString.lower(walletId), + FfiConverterString.lower(tag), + FfiConverterOptionUInt32.lower(limit), + FfiConverterOptionTypeSortDirection.lower(sortDirection),$0 + ) +}) } /** - * Open a Boltz WebSocket for `network`, subscribe to all pending swaps, and - * drive their lifecycle (auto-claiming reverse swaps) until stopped. Replaces - * any previously running updates stream (only one network is tracked at a - * time). `mnemonic` is held in memory for the lifetime of the stream so - * confirmed reverse swaps can be auto-claimed; it is never persisted. Events - * are delivered to `listener`. - * - * `fee_rate_sat_per_vb` is the fee rate used for automatic claim transactions. - * Bitkit owns fee estimation and should pass its current recommended rate; when - * `None`, a conservative built-in default is used. To auto-claim at an updated - * fee rate, call this again (it restarts the stream). - * - * `accept_zero_conf` claims reverse swaps as soon as Boltz's lockup enters the - * mempool instead of waiting for its confirmation. That reveals the preimage - * against an unconfirmed lockup: if the lockup were replaced before - * confirming, the user would be debited on Lightning without receiving - * onchain funds. Pass `false` to keep the confirmation-gated default. + * Activity tags for a single wallet scope, or every scope when `wallet_id` is `None`. */ -public func boltzStartSwapUpdates(network: BoltzNetwork, listener: BoltzEventListener, mnemonic: String, bip39Passphrase: String?, feeRateSatPerVb: Double?, acceptZeroConf: Bool)async throws { +public func getActivitiesTags(walletId: String?)throws -> [ActivityTags] { + return try FfiConverterSequenceTypeActivityTags.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_activities_tags( + FfiConverterOptionString.lower(walletId),$0 + ) +}) +} +public func getActivityById(walletId: String, activityId: String)throws -> Activity? { + return try FfiConverterOptionTypeActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_activity_by_id( + FfiConverterString.lower(walletId), + FfiConverterString.lower(activityId),$0 + ) +}) +} +public func getActivityByTxId(walletId: String, txId: String)throws -> OnchainActivity? { + return try FfiConverterOptionTypeOnchainActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_activity_by_tx_id( + FfiConverterString.lower(walletId), + FfiConverterString.lower(txId),$0 + ) +}) +} +public func getAllActivitiesTags()throws -> [ActivityTags] { + return try FfiConverterSequenceTypeActivityTags.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_all_activities_tags($0 + ) +}) +} +public func getAllClosedChannels(sortDirection: SortDirection?)throws -> [ClosedChannelDetails] { + return try FfiConverterSequenceTypeClosedChannelDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_all_closed_channels( + FfiConverterOptionTypeSortDirection.lower(sortDirection),$0 + ) +}) +} +public func getAllPreActivityMetadata()throws -> [PreActivityMetadata] { + return try FfiConverterSequenceTypePreActivityMetadata.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_all_pre_activity_metadata($0 + ) +}) +} +public func getAllTransactionDetails()throws -> [TransactionDetails] { + return try FfiConverterSequenceTypeTransactionDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_all_transaction_details($0 + ) +}) +} +public func getAllUniqueTags()throws -> [String] { + return try FfiConverterSequenceString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_all_unique_tags($0 + ) +}) +} +public func getBip39Suggestions(partialWord: String, limit: UInt32) -> [String] { + return try! FfiConverterSequenceString.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_get_bip39_suggestions( + FfiConverterString.lower(partialWord), + FfiConverterUInt32.lower(limit),$0 + ) +}) +} +public func getBip39Wordlist() -> [String] { + return try! FfiConverterSequenceString.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_get_bip39_wordlist($0 + ) +}) +} +public func getCjitEntries(entryIds: [String]?, filter: CJitStateEnum?, refresh: Bool)async throws -> [IcJitEntry] { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_start_swap_updates(FfiConverterTypeBoltzNetwork_lower(network),FfiConverterTypeBoltzEventListener_lower(listener),FfiConverterString.lower(mnemonic),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterOptionDouble.lower(feeRateSatPerVb),FfiConverterBool.lower(acceptZeroConf) + uniffi_bitkitcore_fn_func_get_cjit_entries(FfiConverterOptionSequenceString.lower(entryIds),FfiConverterOptionTypeCJitStateEnum.lower(filter),FfiConverterBool.lower(refresh) ) }, - pollFunc: ffi_bitkitcore_rust_future_poll_void, - completeFunc: ffi_bitkitcore_rust_future_complete_void, - freeFunc: ffi_bitkitcore_rust_future_free_void, - liftFunc: { $0 }, - errorHandler: FfiConverterTypeBoltzError_lift + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypeICJitEntry.lift, + errorHandler: FfiConverterTypeBlocktankError_lift ) } +public func getClosedChannelById(channelId: String)throws -> ClosedChannelDetails? { + return try FfiConverterOptionTypeClosedChannelDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_closed_channel_by_id( + FfiConverterString.lower(channelId),$0 + ) +}) +} /** - * Stop the running Boltz updates stream, if any. + * The default address gap limit used by account scanning and the xpub watcher. + * Exposed so platforms reference one source of truth instead of hardcoding 20. */ -public func boltzStopSwapUpdates()async { - return - try! await uniffiRustCallAsync( - rustFutureFunc: { - uniffi_bitkitcore_fn_func_boltz_stop_swap_updates( - ) - }, - pollFunc: ffi_bitkitcore_rust_future_poll_void, - completeFunc: ffi_bitkitcore_rust_future_complete_void, - freeFunc: ffi_bitkitcore_rust_future_free_void, - liftFunc: { $0 }, - errorHandler: nil - - ) +public func getDefaultGapLimit() -> UInt32 { + return try! FfiConverterUInt32.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_get_default_gap_limit($0 + ) +}) } -public func broadcastSweepTransaction(psbt: String, mnemonicPhrase: String, network: Network?, bip39Passphrase: String?, electrumUrl: String)async throws -> SweepResult { +public func getDefaultLspBalance(params: DefaultLspBalanceParams) -> UInt64 { + return try! FfiConverterUInt64.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_get_default_lsp_balance( + FfiConverterTypeDefaultLspBalanceParams_lower(params),$0 + ) +}) +} +public func getDefaultWalletId() -> String { + return try! FfiConverterString.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_get_default_wallet_id($0 + ) +}) +} +public func getGift(giftId: String)async throws -> IGift { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_broadcast_sweep_transaction(FfiConverterString.lower(psbt),FfiConverterString.lower(mnemonicPhrase),FfiConverterOptionTypeNetwork.lower(network),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterString.lower(electrumUrl) + uniffi_bitkitcore_fn_func_get_gift(FfiConverterString.lower(giftId) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeSweepResult_lift, - errorHandler: FfiConverterTypeSweepError_lift + liftFunc: FfiConverterTypeIGift_lift, + errorHandler: FfiConverterTypeBlocktankError_lift ) } -public func calculateChannelLiquidityOptions(params: ChannelLiquidityParams) -> ChannelLiquidityOptions { - return try! FfiConverterTypeChannelLiquidityOptions_lift(try! rustCall() { - uniffi_bitkitcore_fn_func_calculate_channel_liquidity_options( - FfiConverterTypeChannelLiquidityParams_lower(params),$0 - ) -}) -} -public func cancelPubkyAuth()async throws { +public func getInfo(refresh: Bool?)async throws -> IBtInfo? { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_cancel_pubky_auth( + uniffi_bitkitcore_fn_func_get_info(FfiConverterOptionBool.lower(refresh) ) }, - pollFunc: ffi_bitkitcore_rust_future_poll_void, - completeFunc: ffi_bitkitcore_rust_future_complete_void, - freeFunc: ffi_bitkitcore_rust_future_free_void, - liftFunc: { $0 }, - errorHandler: FfiConverterTypePubkyError_lift + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterOptionTypeIBtInfo.lift, + errorHandler: FfiConverterTypeBlocktankError_lift ) } -public func checkSweepableBalances(mnemonicPhrase: String, network: Network?, bip39Passphrase: String?, electrumUrl: String)async throws -> SweepableBalances { +public func getLnurlInvoice(address: String, amountSatoshis: UInt64)async throws -> String { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_check_sweepable_balances(FfiConverterString.lower(mnemonicPhrase),FfiConverterOptionTypeNetwork.lower(network),FfiConverterOptionString.lower(bip39Passphrase),FfiConverterString.lower(electrumUrl) + uniffi_bitkitcore_fn_func_get_lnurl_invoice(FfiConverterString.lower(address),FfiConverterUInt64.lower(amountSatoshis) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeSweepableBalances_lift, - errorHandler: FfiConverterTypeSweepError_lift + liftFunc: FfiConverterString.lift, + errorHandler: FfiConverterTypeLnurlError_lift ) } -/** - * Decode closed channels from Core's canonical backup JSON. - */ -public func closedChannelsFromJson(json: String)throws -> [ClosedChannelDetails] { - return try FfiConverterSequenceTypeClosedChannelDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_closed_channels_from_json( - FfiConverterString.lower(json),$0 - ) -}) -} -/** - * Serialize closed channels to Core's canonical backup JSON. Closed channels - * are not wallet-scoped, so no wallet-id normalization is applied. - */ -public func closedChannelsToJson(channels: [ClosedChannelDetails])throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_closed_channels_to_json( - FfiConverterSequenceTypeClosedChannelDetails.lower(channels),$0 - ) -}) -} -public func completePubkyAuth()async throws -> String { +public func getLnurlInvoiceForPayData(data: LnurlPayData, amountMsats: UInt64, comment: String?)async throws -> String { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_complete_pubky_auth( + uniffi_bitkitcore_fn_func_get_lnurl_invoice_for_pay_data(FfiConverterTypeLnurlPayData_lower(data),FfiConverterUInt64.lower(amountMsats),FfiConverterOptionString.lower(comment) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, liftFunc: FfiConverterString.lift, - errorHandler: FfiConverterTypePubkyError_lift + errorHandler: FfiConverterTypeLnurlError_lift ) } -public func createChannelRequestUrl(k1: String, callback: String, localNodeId: String, isPrivate: Bool, cancel: Bool)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeLnurlError_lift) { - uniffi_bitkitcore_fn_func_create_channel_request_url( - FfiConverterString.lower(k1), - FfiConverterString.lower(callback), - FfiConverterString.lower(localNodeId), - FfiConverterBool.lower(isPrivate), - FfiConverterBool.lower(cancel),$0 - ) -}) -} -public func createCjitEntry(channelSizeSat: UInt64, invoiceSat: UInt64, invoiceDescription: String, nodeId: String, channelExpiryWeeks: UInt32, options: CreateCjitOptions?)async throws -> IcJitEntry { +public func getMinZeroConfTxFee(orderId: String)async throws -> IBt0ConfMinTxFeeWindow { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_create_cjit_entry(FfiConverterUInt64.lower(channelSizeSat),FfiConverterUInt64.lower(invoiceSat),FfiConverterString.lower(invoiceDescription),FfiConverterString.lower(nodeId),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateCjitOptions.lower(options) + uniffi_bitkitcore_fn_func_get_min_zero_conf_tx_fee(FfiConverterString.lower(orderId) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeICJitEntry_lift, + liftFunc: FfiConverterTypeIBt0ConfMinTxFeeWindow_lift, errorHandler: FfiConverterTypeBlocktankError_lift ) } -public func createOrder(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, options: CreateOrderOptions?)async throws -> IBtOrder { +public func getOrders(orderIds: [String]?, filter: BtOrderState2?, refresh: Bool)async throws -> [IBtOrder] { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_create_order(FfiConverterUInt64.lower(lspBalanceSat),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateOrderOptions.lower(options) + uniffi_bitkitcore_fn_func_get_orders(FfiConverterOptionSequenceString.lower(orderIds),FfiConverterOptionTypeBtOrderState2.lower(filter),FfiConverterBool.lower(refresh) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIBtOrder_lift, + liftFunc: FfiConverterSequenceTypeIBtOrder.lift, errorHandler: FfiConverterTypeBlocktankError_lift ) } -public func createWithdrawCallbackUrl(k1: String, callback: String, paymentRequest: String)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeLnurlError_lift) { - uniffi_bitkitcore_fn_func_create_withdraw_callback_url( - FfiConverterString.lower(k1), - FfiConverterString.lower(callback), - FfiConverterString.lower(paymentRequest),$0 - ) -}) -} -public func decode(invoice: String)async throws -> Scanner { +public func getPayment(paymentId: String)async throws -> IBtBolt11Invoice { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_decode(FfiConverterString.lower(invoice) + uniffi_bitkitcore_fn_func_get_payment(FfiConverterString.lower(paymentId) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeScanner_lift, - errorHandler: FfiConverterTypeDecodingError_lift + liftFunc: FfiConverterTypeIBtBolt11Invoice_lift, + errorHandler: FfiConverterTypeBlocktankError_lift ) } -public func deleteActivitiesByWalletId(walletId: String)throws -> UInt32 { - return try FfiConverterUInt32.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_delete_activities_by_wallet_id( - FfiConverterString.lower(walletId),$0 - ) -}) -} -public func deleteActivityById(walletId: String, activityId: String)throws -> Bool { - return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_delete_activity_by_id( - FfiConverterString.lower(walletId), - FfiConverterString.lower(activityId),$0 - ) -}) -} -public func deletePreActivityMetadata(walletId: String, paymentId: String)throws {try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_delete_pre_activity_metadata( - FfiConverterString.lower(walletId), - FfiConverterString.lower(paymentId),$0 - ) -} -} -public func deleteTransactionDetails(walletId: String, txId: String)throws -> Bool { - return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_delete_transaction_details( +public func getPreActivityMetadata(walletId: String, searchKey: String, searchByAddress: Bool)throws -> PreActivityMetadata? { + return try FfiConverterOptionTypePreActivityMetadata.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_pre_activity_metadata( FfiConverterString.lower(walletId), - FfiConverterString.lower(txId),$0 - ) -}) -} -public func deriveBitcoinAddress(mnemonicPhrase: String, derivationPathStr: String?, network: Network?, bip39Passphrase: String?)throws -> GetAddressResponse { - return try FfiConverterTypeGetAddressResponse_lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { - uniffi_bitkitcore_fn_func_derive_bitcoin_address( - FfiConverterString.lower(mnemonicPhrase), - FfiConverterOptionString.lower(derivationPathStr), - FfiConverterOptionTypeNetwork.lower(network), - FfiConverterOptionString.lower(bip39Passphrase),$0 - ) -}) -} -public func deriveBitcoinAddresses(mnemonicPhrase: String, derivationPathStr: String?, network: Network?, bip39Passphrase: String?, isChange: Bool?, startIndex: UInt32?, count: UInt32?)throws -> GetAddressesResponse { - return try FfiConverterTypeGetAddressesResponse_lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { - uniffi_bitkitcore_fn_func_derive_bitcoin_addresses( - FfiConverterString.lower(mnemonicPhrase), - FfiConverterOptionString.lower(derivationPathStr), - FfiConverterOptionTypeNetwork.lower(network), - FfiConverterOptionString.lower(bip39Passphrase), - FfiConverterOptionBool.lower(isChange), - FfiConverterOptionUInt32.lower(startIndex), - FfiConverterOptionUInt32.lower(count),$0 - ) -}) -} -public func deriveOnchainDescriptor(mnemonicPhrase: String, network: Network, bip39Passphrase: String?, accountType: AccountType, accountIndex: UInt32)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { - uniffi_bitkitcore_fn_func_derive_onchain_descriptor( - FfiConverterString.lower(mnemonicPhrase), - FfiConverterTypeNetwork_lower(network), - FfiConverterOptionString.lower(bip39Passphrase), - FfiConverterTypeAccountType_lower(accountType), - FfiConverterUInt32.lower(accountIndex),$0 + FfiConverterString.lower(searchKey), + FfiConverterBool.lower(searchByAddress),$0 ) }) } -public func derivePrivateKey(mnemonicPhrase: String, derivationPathStr: String?, network: Network?, bip39Passphrase: String?)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { - uniffi_bitkitcore_fn_func_derive_private_key( - FfiConverterString.lower(mnemonicPhrase), - FfiConverterOptionString.lower(derivationPathStr), - FfiConverterOptionTypeNetwork.lower(network), - FfiConverterOptionString.lower(bip39Passphrase),$0 +/** + * Pre-activity metadata for a single wallet scope, or every scope when `wallet_id` is `None`. + */ +public func getPreActivityMetadataList(walletId: String?)throws -> [PreActivityMetadata] { + return try FfiConverterSequenceTypePreActivityMetadata.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_pre_activity_metadata_list( + FfiConverterOptionString.lower(walletId),$0 ) }) } -public func derivePubkySecretKey(seed: Data)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypePubkyError_lift) { - uniffi_bitkitcore_fn_func_derive_pubky_secret_key( - FfiConverterData.lower(seed),$0 +/** + * The hardware-wallet models supported by Bitkit and their available transports. + */ +public func getSupportedHardwareWallets() -> [SupportedHardwareWallet] { + return try! FfiConverterSequenceTypeSupportedHardwareWallet.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_get_supported_hardware_wallets($0 ) }) } -/** - * Derive a stable, cross-platform `wallet_id` for a hardware (watch-only) wallet - * from its account extended public keys. See `derive_wallet_id` in the activity - * module for the exact derivation. Order of `xpubs` does not matter. Returns an - * error if `device_type` is blank or `xpubs` is empty / has a blank entry. - */ -public func deriveWalletId(deviceType: String, xpubs: [String])throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_derive_wallet_id( - FfiConverterString.lower(deviceType), - FfiConverterSequenceString.lower(xpubs),$0 +public func getTags(walletId: String, activityId: String)throws -> [String] { + return try FfiConverterSequenceString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_tags( + FfiConverterString.lower(walletId), + FfiConverterString.lower(activityId),$0 ) }) } -public func entropyToMnemonic(entropy: Data)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { - uniffi_bitkitcore_fn_func_entropy_to_mnemonic( - FfiConverterData.lower(entropy),$0 +public func getTransactionDetails(walletId: String, txId: String)throws -> TransactionDetails? { + return try FfiConverterOptionTypeTransactionDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_get_transaction_details( + FfiConverterString.lower(walletId), + FfiConverterString.lower(txId),$0 ) }) } -public func estimateOrderFee(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, options: CreateOrderOptions?)async throws -> IBtEstimateFeeResponse { +public func giftOrder(clientNodeId: String, code: String)async throws -> IGift { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_estimate_order_fee(FfiConverterUInt64.lower(lspBalanceSat),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateOrderOptions.lower(options) + uniffi_bitkitcore_fn_func_gift_order(FfiConverterString.lower(clientNodeId),FfiConverterString.lower(code) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIBtEstimateFeeResponse_lift, + liftFunc: FfiConverterTypeIGift_lift, errorHandler: FfiConverterTypeBlocktankError_lift ) } -public func estimateOrderFeeFull(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, options: CreateOrderOptions?)async throws -> IBtEstimateFeeResponse2 { +public func giftPay(invoice: String)async throws -> IGift { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_estimate_order_fee_full(FfiConverterUInt64.lower(lspBalanceSat),FfiConverterUInt32.lower(channelExpiryWeeks),FfiConverterOptionTypeCreateOrderOptions.lower(options) + uniffi_bitkitcore_fn_func_gift_pay(FfiConverterString.lower(invoice) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIBtEstimateFeeResponse2_lift, + liftFunc: FfiConverterTypeIGift_lift, errorHandler: FfiConverterTypeBlocktankError_lift ) } -public func fetchPubkyContacts(publicKey: String)async throws -> [String] { +public func initDb(basePath: String)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeDbError_lift) { + uniffi_bitkitcore_fn_func_init_db( + FfiConverterString.lower(basePath),$0 + ) +}) +} +public func insertActivity(activity: Activity)throws {try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_insert_activity( + FfiConverterTypeActivity_lower(activity),$0 + ) +} +} +public func isAddressUsed(address: String)throws -> Bool { + return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { + uniffi_bitkitcore_fn_func_is_address_used( + FfiConverterString.lower(address),$0 + ) +}) +} +public func isValidBip39Word(word: String) -> Bool { + return try! FfiConverterBool.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_is_valid_bip39_word( + FfiConverterString.lower(word),$0 + ) +}) +} +/** + * Map a generic account type onto Jade's descriptor variant. + */ +public func jadeAccountTypeToVariant(accountType: AccountType) -> JadeAddressVariant { + return try! FfiConverterTypeJadeAddressVariant_lift(try! rustCall() { + uniffi_bitkitcore_fn_func_jade_account_type_to_variant( + FfiConverterTypeAccountType_lower(accountType),$0 + ) +}) +} +/** + * Abort the operation in flight. + * + * Jade has no cancel message, so this closes the link. The application should + * reconnect afterwards. This is what backs a cancel button on a signing screen. + * + * The aborted request returns `UserCancelled`, whether it notices the abort + * flag or the closed link first, so a cancel never surfaces as a disconnection. + */ +public func jadeCancel()async throws { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_fetch_pubky_contacts(FfiConverterString.lower(publicKey) + uniffi_bitkitcore_fn_func_jade_cancel( ) }, - pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, - completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, - freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterSequenceString.lift, - errorHandler: FfiConverterTypePubkyError_lift + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func fetchPubkyFile(uri: String)async throws -> Data { +/** + * Open a device and read its firmware and state summary. + * + * The path normally comes from the last `jade_scan`, but a known Bluetooth + * address or serial path can be passed directly to reconnect without a scan. + * Any previously open connection is closed first. The returned `jade_state` + * tells the application what to do next: `Locked` means call `jade_unlock`, + * `Ready` means the device is already usable, and `Uninit` means the user must + * create or restore a wallet on the device itself. + */ +public func jadeConnect(transport: JadeTransportKind, path: String)async throws -> JadeVersionInfo { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_fetch_pubky_file(FfiConverterString.lower(uri) + uniffi_bitkitcore_fn_func_jade_connect(FfiConverterTypeJadeTransportKind_lower(transport),FfiConverterString.lower(path) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterData.lift, - errorHandler: FfiConverterTypePubkyError_lift + liftFunc: FfiConverterTypeJadeVersionInfo_lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func fetchPubkyFileString(uri: String)async throws -> String { +/** + * Close the device and clear session state. + * + * Safe to call while an operation is waiting on a confirmation: the pending + * request returns `UserCancelled` promptly rather than running out its deadline. + */ +public func jadeDisconnect()async throws { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_fetch_pubky_file_string(FfiConverterString.lower(uri) + uniffi_bitkitcore_fn_func_jade_disconnect( + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeJadeError_lift + ) +} +/** + * Fetch the account keys an import needs in one call. + * + * Shaped like `passport_parse_account_export` so applications have a single + * import path across signers. Each key is fetched under one held connection, + * which matters over Bluetooth where every round trip is slow. + */ +public func jadeGetAccountExport(network: JadeNetwork, accountIndex: UInt32, accountTypes: [AccountType])async throws -> JadeAccountExport { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_jade_get_account_export(FfiConverterTypeJadeNetwork_lower(network),FfiConverterUInt32.lower(accountIndex),FfiConverterSequenceTypeAccountType.lower(accountTypes) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterString.lift, - errorHandler: FfiConverterTypePubkyError_lift + liftFunc: FfiConverterTypeJadeAccountExport_lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func fetchPubkyProfile(publicKey: String)async throws -> PubkyProfile { +public func jadeGetConnectedDevice()async -> JadeDeviceInfo? { return - try await uniffiRustCallAsync( + try! await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_fetch_pubky_profile(FfiConverterString.lower(publicKey) + uniffi_bitkitcore_fn_func_jade_get_connected_device( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypePubkyProfile_lift, - errorHandler: FfiConverterTypePubkyError_lift + liftFunc: FfiConverterOptionTypeJadeDeviceInfo.lift, + errorHandler: nil + ) } /** - * Combine and finalize a signed PSBT, then extract its broadcastable transaction. + * The device's master fingerprint, eight lowercase hex characters. + * + * This must be supplied as `WalletParams.fingerprint` when composing, or the + * resulting PSBT carries no BIP32 key origins and the device signs nothing. */ -public func finalizePsbt(originalPsbt: String, signedPsbt: String)throws -> CompletedTransaction { - return try FfiConverterTypeCompletedTransaction_lift(try rustCallWithError(FfiConverterTypePsbtCompletionError_lift) { - uniffi_bitkitcore_fn_func_finalize_psbt( - FfiConverterString.lower(originalPsbt), - FfiConverterString.lower(signedPsbt),$0 - ) -}) -} -public func generateMnemonic(wordCount: WordCount?)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { - uniffi_bitkitcore_fn_func_generate_mnemonic( - FfiConverterOptionTypeWordCount.lower(wordCount),$0 - ) -}) -} -public func getActivities(walletId: String?, filter: ActivityFilter?, txType: PaymentType?, tags: [String]?, search: String?, minDate: UInt64?, maxDate: UInt64?, limit: UInt32?, sortDirection: SortDirection?)throws -> [Activity] { - return try FfiConverterSequenceTypeActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_activities( - FfiConverterOptionString.lower(walletId), - FfiConverterOptionTypeActivityFilter.lower(filter), - FfiConverterOptionTypePaymentType.lower(txType), - FfiConverterOptionSequenceString.lower(tags), - FfiConverterOptionString.lower(search), - FfiConverterOptionUInt64.lower(minDate), - FfiConverterOptionUInt64.lower(maxDate), - FfiConverterOptionUInt32.lower(limit), - FfiConverterOptionTypeSortDirection.lower(sortDirection),$0 - ) -}) -} -public func getActivitiesByTag(walletId: String?, tag: String, limit: UInt32?, sortDirection: SortDirection?)throws -> [Activity] { - return try FfiConverterSequenceTypeActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_activities_by_tag( - FfiConverterOptionString.lower(walletId), - FfiConverterString.lower(tag), - FfiConverterOptionUInt32.lower(limit), - FfiConverterOptionTypeSortDirection.lower(sortDirection),$0 - ) -}) +public func jadeGetMasterFingerprint(network: JadeNetwork)async throws -> String { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_jade_get_master_fingerprint(FfiConverterTypeJadeNetwork_lower(network) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterString.lift, + errorHandler: FfiConverterTypeJadeError_lift + ) } /** - * Activity tags for a single wallet scope, or every scope when `wallet_id` is `None`. + * The version summary read at connect or by the last refresh. + * + * Neither touches the device nor waits for an operation in flight. */ -public func getActivitiesTags(walletId: String?)throws -> [ActivityTags] { - return try FfiConverterSequenceTypeActivityTags.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_activities_tags( - FfiConverterOptionString.lower(walletId),$0 - ) -}) -} -public func getActivityById(walletId: String, activityId: String)throws -> Activity? { - return try FfiConverterOptionTypeActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_activity_by_id( - FfiConverterString.lower(walletId), - FfiConverterString.lower(activityId),$0 - ) -}) -} -public func getActivityByTxId(walletId: String, txId: String)throws -> OnchainActivity? { - return try FfiConverterOptionTypeOnchainActivity.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_activity_by_tx_id( - FfiConverterString.lower(walletId), - FfiConverterString.lower(txId),$0 - ) -}) -} -public func getAllActivitiesTags()throws -> [ActivityTags] { - return try FfiConverterSequenceTypeActivityTags.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_all_activities_tags($0 - ) -}) -} -public func getAllClosedChannels(sortDirection: SortDirection?)throws -> [ClosedChannelDetails] { - return try FfiConverterSequenceTypeClosedChannelDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_all_closed_channels( - FfiConverterOptionTypeSortDirection.lower(sortDirection),$0 - ) -}) -} -public func getAllPreActivityMetadata()throws -> [PreActivityMetadata] { - return try FfiConverterSequenceTypePreActivityMetadata.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_all_pre_activity_metadata($0 - ) -}) -} -public func getAllTransactionDetails()throws -> [TransactionDetails] { - return try FfiConverterSequenceTypeTransactionDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_all_transaction_details($0 - ) -}) -} -public func getAllUniqueTags()throws -> [String] { - return try FfiConverterSequenceString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_all_unique_tags($0 - ) -}) -} -public func getBip39Suggestions(partialWord: String, limit: UInt32) -> [String] { - return try! FfiConverterSequenceString.lift(try! rustCall() { - uniffi_bitkitcore_fn_func_get_bip39_suggestions( - FfiConverterString.lower(partialWord), - FfiConverterUInt32.lower(limit),$0 - ) -}) -} -public func getBip39Wordlist() -> [String] { - return try! FfiConverterSequenceString.lift(try! rustCall() { - uniffi_bitkitcore_fn_func_get_bip39_wordlist($0 - ) -}) -} -public func getCjitEntries(entryIds: [String]?, filter: CJitStateEnum?, refresh: Bool)async throws -> [IcJitEntry] { +public func jadeGetVersionInfo()async -> JadeVersionInfo? { return - try await uniffiRustCallAsync( + try! await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_cjit_entries(FfiConverterOptionSequenceString.lower(entryIds),FfiConverterOptionTypeCJitStateEnum.lower(filter),FfiConverterBool.lower(refresh) + uniffi_bitkitcore_fn_func_jade_get_version_info( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterSequenceTypeICJitEntry.lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterOptionTypeJadeVersionInfo.lift, + errorHandler: nil + ) } -public func getClosedChannelById(channelId: String)throws -> ClosedChannelDetails? { - return try FfiConverterOptionTypeClosedChannelDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_closed_channel_by_id( - FfiConverterString.lower(channelId),$0 - ) -}) -} /** - * The default address gap limit used by account scanning and the xpub watcher. - * Exposed so platforms reference one source of truth instead of hardcoding 20. + * Fetch an extended public key, echoed back with the path and fingerprint. */ -public func getDefaultGapLimit() -> UInt32 { - return try! FfiConverterUInt32.lift(try! rustCall() { - uniffi_bitkitcore_fn_func_get_default_gap_limit($0 - ) -}) -} -public func getDefaultLspBalance(params: DefaultLspBalanceParams) -> UInt64 { - return try! FfiConverterUInt64.lift(try! rustCall() { - uniffi_bitkitcore_fn_func_get_default_lsp_balance( - FfiConverterTypeDefaultLspBalanceParams_lower(params),$0 - ) -}) -} -public func getDefaultWalletId() -> String { - return try! FfiConverterString.lift(try! rustCall() { - uniffi_bitkitcore_fn_func_get_default_wallet_id($0 - ) -}) -} -public func getGift(giftId: String)async throws -> IGift { +public func jadeGetXpub(network: JadeNetwork, derivationPath: String)async throws -> JadeXpubResponse { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_gift(FfiConverterString.lower(giftId) + uniffi_bitkitcore_fn_func_jade_get_xpub(FfiConverterTypeJadeNetwork_lower(network),FfiConverterString.lower(derivationPath) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIGift_lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterTypeJadeXpubResponse_lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func getInfo(refresh: Bool?)async throws -> IBtInfo? { +public func jadeIsConnected() -> Bool { + return try! FfiConverterBool.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_jade_is_connected($0 + ) +}) +} +/** + * The devices found by the last scan, without starting a new one. + */ +public func jadeListDevices()async -> [JadeDeviceInfo] { return - try await uniffiRustCallAsync( + try! await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_info(FfiConverterOptionBool.lower(refresh) + uniffi_bitkitcore_fn_func_jade_list_devices( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterOptionTypeIBtInfo.lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterSequenceTypeJadeDeviceInfo.lift, + errorHandler: nil + ) } -public func getLnurlInvoice(address: String, amountSatoshis: UInt64)async throws -> String { +/** + * Lock the device and zero its in-memory key material. + */ +public func jadeLogout()async throws { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_lnurl_invoice(FfiConverterString.lower(address),FfiConverterUInt64.lower(amountSatoshis) + uniffi_bitkitcore_fn_func_jade_logout( ) }, - pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, - completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, - freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterString.lift, - errorHandler: FfiConverterTypeLnurlError_lift + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func getLnurlInvoiceForPayData(data: LnurlPayData, amountMsats: UInt64, comment: String?)async throws -> String { +/** + * Tell the library that the native layer saw the device disconnect. + * + * Without this, an idle Bluetooth drop is invisible until the next request. + * Await it before reconnecting the same path: a notification that is still + * pending when a reconnect to that path completes closes the new connection. + */ +public func jadeNotifyDisconnected(path: String)async { return - try await uniffiRustCallAsync( + try! await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_lnurl_invoice_for_pay_data(FfiConverterTypeLnurlPayData_lower(data),FfiConverterUInt64.lower(amountMsats),FfiConverterOptionString.lower(comment) + uniffi_bitkitcore_fn_func_jade_notify_disconnected(FfiConverterString.lower(path) ) }, - pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, - completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, - freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterString.lift, - errorHandler: FfiConverterTypeLnurlError_lift + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: nil + ) } -public func getMinZeroConfTxFee(orderId: String)async throws -> IBt0ConfMinTxFeeWindow { +/** + * Check whether the device is idle, busy, or waiting on the user. + */ +public func jadePing()async throws -> JadePingStatus { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_min_zero_conf_tx_fee(FfiConverterString.lower(orderId) + uniffi_bitkitcore_fn_func_jade_ping( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIBt0ConfMinTxFeeWindow_lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterTypeJadePingStatus_lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func getOrders(orderIds: [String]?, filter: BtOrderState2?, refresh: Bool)async throws -> [IBtOrder] { +/** + * Re-read the version summary from the device. + */ +public func jadeRefreshVersionInfo()async throws -> JadeVersionInfo { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_orders(FfiConverterOptionSequenceString.lower(orderIds),FfiConverterOptionTypeBtOrderState2.lower(filter),FfiConverterBool.lower(refresh) + uniffi_bitkitcore_fn_func_jade_refresh_version_info( ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterSequenceTypeIBtOrder.lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterTypeJadeVersionInfo_lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func getPayment(paymentId: String)async throws -> IBtBolt11Invoice { +/** + * Discover Jade devices. + * + * Bluetooth discovery is performed by the registered transport callback; on + * desktop and Python builds, attached USB serial units are enumerated too. + * Returns `DeviceBusy` while a connection is open, because starting a + * Bluetooth scan during an active link drops it on Android. + */ +public func jadeScan(timeoutMs: UInt32)async throws -> [JadeDeviceInfo] { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_get_payment(FfiConverterString.lower(paymentId) + uniffi_bitkitcore_fn_func_jade_scan(FfiConverterUInt32.lower(timeoutMs) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIBtBolt11Invoice_lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterSequenceTypeJadeDeviceInfo.lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func getPreActivityMetadata(walletId: String, searchKey: String, searchByAddress: Bool)throws -> PreActivityMetadata? { - return try FfiConverterOptionTypePreActivityMetadata.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_pre_activity_metadata( - FfiConverterString.lower(walletId), - FfiConverterString.lower(searchKey), - FfiConverterBool.lower(searchByAddress),$0 - ) -}) -} /** - * Pre-activity metadata for a single wallet scope, or every scope when `wallet_id` is `None`. + * Register the native transport. + * + * Returns `true` when this replaced a previously registered callback, which + * lets the application tell a fresh registration from a re-registration. */ -public func getPreActivityMetadataList(walletId: String?)throws -> [PreActivityMetadata] { - return try FfiConverterSequenceTypePreActivityMetadata.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_pre_activity_metadata_list( - FfiConverterOptionString.lower(walletId),$0 +public func jadeSetTransportCallback(callback: JadeTransportCallback) -> Bool { + return try! FfiConverterBool.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_jade_set_transport_callback( + FfiConverterTypeJadeTransportCallback_lower(callback),$0 ) }) } /** - * The hardware-wallet models supported by Bitkit and their available transports. + * Sign a message, returning the signature with the address that verifies it. */ -public func getSupportedHardwareWallets() -> [SupportedHardwareWallet] { - return try! FfiConverterSequenceTypeSupportedHardwareWallet.lift(try! rustCall() { - uniffi_bitkitcore_fn_func_get_supported_hardware_wallets($0 - ) -}) -} -public func getTags(walletId: String, activityId: String)throws -> [String] { - return try FfiConverterSequenceString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_tags( - FfiConverterString.lower(walletId), - FfiConverterString.lower(activityId),$0 - ) -}) -} -public func getTransactionDetails(walletId: String, txId: String)throws -> TransactionDetails? { - return try FfiConverterOptionTypeTransactionDetails.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_get_transaction_details( - FfiConverterString.lower(walletId), - FfiConverterString.lower(txId),$0 - ) -}) -} -public func giftOrder(clientNodeId: String, code: String)async throws -> IGift { +public func jadeSignMessage(network: JadeNetwork, derivationPath: String, message: String)async throws -> JadeSignedMessage { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_gift_order(FfiConverterString.lower(clientNodeId),FfiConverterString.lower(code) + uniffi_bitkitcore_fn_func_jade_sign_message(FfiConverterTypeJadeNetwork_lower(network),FfiConverterString.lower(derivationPath),FfiConverterString.lower(message) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIGift_lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterTypeJadeSignedMessage_lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func giftPay(invoice: String)async throws -> IGift { +/** + * Sign a PSBT, returning the signed PSBT base64 encoded. + * + * The reply is checked against what was sent before it is returned. Feed the + * result to `finalize_psbt` with the original PSBT, then broadcast with + * `onchain_broadcast_raw_tx`. + */ +public func jadeSignPsbt(network: JadeNetwork, psbt: String)async throws -> String { return try await uniffiRustCallAsync( rustFutureFunc: { - uniffi_bitkitcore_fn_func_gift_pay(FfiConverterString.lower(invoice) + uniffi_bitkitcore_fn_func_jade_sign_psbt(FfiConverterTypeJadeNetwork_lower(network),FfiConverterString.lower(psbt) ) }, pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeIGift_lift, - errorHandler: FfiConverterTypeBlocktankError_lift + liftFunc: FfiConverterString.lift, + errorHandler: FfiConverterTypeJadeError_lift ) } -public func initDb(basePath: String)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeDbError_lift) { - uniffi_bitkitcore_fn_func_init_db( - FfiConverterString.lower(basePath),$0 - ) -}) -} -public func insertActivity(activity: Activity)throws {try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_insert_activity( - FfiConverterTypeActivity_lower(activity),$0 - ) -} -} -public func isAddressUsed(address: String)throws -> Bool { - return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { - uniffi_bitkitcore_fn_func_is_address_used( - FfiConverterString.lower(address),$0 - ) -}) +/** + * Unlock the device for a network. + * + * Runs the blind pinserver exchange when the device asks for it, which needs + * network access. The PIN is entered on the device and never reaches the host. + */ +public func jadeUnlock(network: JadeNetwork)async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_jade_unlock(FfiConverterTypeJadeNetwork_lower(network) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeJadeError_lift + ) } -public func isValidBip39Word(word: String) -> Bool { - return try! FfiConverterBool.lift(try! rustCall() { - uniffi_bitkitcore_fn_func_is_valid_bip39_word( - FfiConverterString.lower(word),$0 - ) -}) +/** + * Display an address on the device and check it against the expected one. + * + * This always prompts on the device screen, so it is a verification step + * rather than a way to fetch an address. Returns `AddressMismatch` when the + * device disagrees with `expected_address`. + */ +public func jadeVerifyAddress(network: JadeNetwork, variant: JadeAddressVariant, derivationPath: String, expectedAddress: String)async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_jade_verify_address(FfiConverterTypeJadeNetwork_lower(network),FfiConverterTypeJadeAddressVariant_lower(variant),FfiConverterString.lower(derivationPath),FfiConverterString.lower(expectedAddress) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypeJadeError_lift + ) } public func lnurlAuth(domain: String, k1: String, callback: String, bip32Mnemonic: String, network: Network?, bip39Passphrase: String?)async throws -> String { return @@ -25601,6 +28261,69 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_is_valid_bip39_word() != 31846) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_jade_account_type_to_variant() != 35222) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_cancel() != 64384) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_connect() != 62038) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_disconnect() != 22575) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_get_account_export() != 39143) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_get_connected_device() != 31749) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_get_master_fingerprint() != 29630) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_get_version_info() != 58697) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_get_xpub() != 51180) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_is_connected() != 16304) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_list_devices() != 31161) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_logout() != 2301) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_notify_disconnected() != 17140) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_ping() != 45620) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_refresh_version_info() != 52539) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_scan() != 445) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_set_transport_callback() != 61572) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_sign_message() != 257) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_sign_psbt() != 20865) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_unlock() != 35535) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_jade_verify_address() != 54249) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_lnurl_auth() != 58593) { return InitializationResult.apiChecksumMismatch } @@ -25883,6 +28606,24 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_method_eventlistener_on_event() != 35531) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_method_jadetransportcallback_scan_devices() != 38147) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_jadetransportcallback_open_device() != 21299) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_jadetransportcallback_close_device() != 16955) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_jadetransportcallback_write_chunk() != 12779) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_jadetransportcallback_read_chunk() != 21790) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_jadetransportcallback_get_chunk_size() != 29973) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_method_trezortransportcallback_enumerate_devices() != 18766) { return InitializationResult.apiChecksumMismatch } @@ -25934,6 +28675,7 @@ private let initializationResult: InitializationResult = { uniffiCallbackInitBoltzEventListener() uniffiCallbackInitEventListener() + uniffiCallbackInitJadeTransportCallback() uniffiCallbackInitTrezorTransportCallback() uniffiCallbackInitTrezorUiCallback() return InitializationResult.ok diff --git a/bindings/ios/bitkitcoreFFI.h b/bindings/ios/bitkitcoreFFI.h index 79b2fb2..b4dc45f 100644 --- a/bindings/ios/bitkitcoreFFI.h +++ b/bindings/ios/bitkitcoreFFI.h @@ -264,6 +264,48 @@ typedef void (*UniffiCallbackInterfaceEventListenerMethod0)(uint64_t, RustBuffer RustCallStatus *_Nonnull uniffiCallStatus ); +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD0 +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD0 +typedef void (*UniffiCallbackInterfaceJadeTransportCallbackMethod0)(uint64_t, uint32_t, RustBuffer* _Nonnull, + RustCallStatus *_Nonnull uniffiCallStatus + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD1 +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD1 +typedef void (*UniffiCallbackInterfaceJadeTransportCallbackMethod1)(uint64_t, RustBuffer, RustBuffer* _Nonnull, + RustCallStatus *_Nonnull uniffiCallStatus + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD2 +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD2 +typedef void (*UniffiCallbackInterfaceJadeTransportCallbackMethod2)(uint64_t, RustBuffer, RustBuffer* _Nonnull, + RustCallStatus *_Nonnull uniffiCallStatus + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD3 +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD3 +typedef void (*UniffiCallbackInterfaceJadeTransportCallbackMethod3)(uint64_t, RustBuffer, RustBuffer, RustBuffer* _Nonnull, + RustCallStatus *_Nonnull uniffiCallStatus + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD4 +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD4 +typedef void (*UniffiCallbackInterfaceJadeTransportCallbackMethod4)(uint64_t, RustBuffer, uint32_t, RustBuffer* _Nonnull, + RustCallStatus *_Nonnull uniffiCallStatus + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD5 +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK_METHOD5 +typedef void (*UniffiCallbackInterfaceJadeTransportCallbackMethod5)(uint64_t, RustBuffer, uint32_t* _Nonnull, + RustCallStatus *_Nonnull uniffiCallStatus + ); + #endif #ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_TREZOR_TRANSPORT_CALLBACK_METHOD0 #define UNIFFI_FFIDEF_CALLBACK_INTERFACE_TREZOR_TRANSPORT_CALLBACK_METHOD0 @@ -371,6 +413,19 @@ typedef struct UniffiVTableCallbackInterfaceEventListener { UniffiCallbackInterfaceFree _Nonnull uniffiFree; } UniffiVTableCallbackInterfaceEventListener; +#endif +#ifndef UNIFFI_FFIDEF_V_TABLE_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK +#define UNIFFI_FFIDEF_V_TABLE_CALLBACK_INTERFACE_JADE_TRANSPORT_CALLBACK +typedef struct UniffiVTableCallbackInterfaceJadeTransportCallback { + UniffiCallbackInterfaceJadeTransportCallbackMethod0 _Nonnull scanDevices; + UniffiCallbackInterfaceJadeTransportCallbackMethod1 _Nonnull openDevice; + UniffiCallbackInterfaceJadeTransportCallbackMethod2 _Nonnull closeDevice; + UniffiCallbackInterfaceJadeTransportCallbackMethod3 _Nonnull writeChunk; + UniffiCallbackInterfaceJadeTransportCallbackMethod4 _Nonnull readChunk; + UniffiCallbackInterfaceJadeTransportCallbackMethod5 _Nonnull getChunkSize; + UniffiCallbackInterfaceFree _Nonnull uniffiFree; +} UniffiVTableCallbackInterfaceJadeTransportCallback; + #endif #ifndef UNIFFI_FFIDEF_V_TABLE_CALLBACK_INTERFACE_TREZOR_TRANSPORT_CALLBACK #define UNIFFI_FFIDEF_V_TABLE_CALLBACK_INTERFACE_TREZOR_TRANSPORT_CALLBACK @@ -439,6 +494,51 @@ void uniffi_bitkitcore_fn_init_callback_vtable_eventlistener(const UniffiVTableC void uniffi_bitkitcore_fn_method_eventlistener_on_event(void*_Nonnull ptr, RustBuffer watcher_id, RustBuffer event, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_JADETRANSPORTCALLBACK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_JADETRANSPORTCALLBACK +void*_Nonnull uniffi_bitkitcore_fn_clone_jadetransportcallback(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_JADETRANSPORTCALLBACK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_JADETRANSPORTCALLBACK +void uniffi_bitkitcore_fn_free_jadetransportcallback(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_INIT_CALLBACK_VTABLE_JADETRANSPORTCALLBACK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_INIT_CALLBACK_VTABLE_JADETRANSPORTCALLBACK +void uniffi_bitkitcore_fn_init_callback_vtable_jadetransportcallback(const UniffiVTableCallbackInterfaceJadeTransportCallback* _Nonnull vtable +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_SCAN_DEVICES +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_SCAN_DEVICES +RustBuffer uniffi_bitkitcore_fn_method_jadetransportcallback_scan_devices(void*_Nonnull ptr, uint32_t timeout_ms, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_OPEN_DEVICE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_OPEN_DEVICE +RustBuffer uniffi_bitkitcore_fn_method_jadetransportcallback_open_device(void*_Nonnull ptr, RustBuffer path, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_CLOSE_DEVICE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_CLOSE_DEVICE +RustBuffer uniffi_bitkitcore_fn_method_jadetransportcallback_close_device(void*_Nonnull ptr, RustBuffer path, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_WRITE_CHUNK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_WRITE_CHUNK +RustBuffer uniffi_bitkitcore_fn_method_jadetransportcallback_write_chunk(void*_Nonnull ptr, RustBuffer path, RustBuffer data, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_READ_CHUNK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_READ_CHUNK +RustBuffer uniffi_bitkitcore_fn_method_jadetransportcallback_read_chunk(void*_Nonnull ptr, RustBuffer path, uint32_t timeout_ms, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_GET_CHUNK_SIZE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_JADETRANSPORTCALLBACK_GET_CHUNK_SIZE +uint32_t uniffi_bitkitcore_fn_method_jadetransportcallback_get_chunk_size(void*_Nonnull ptr, RustBuffer path, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_TREZORTRANSPORTCALLBACK #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_TREZORTRANSPORTCALLBACK void*_Nonnull uniffi_bitkitcore_fn_clone_trezortransportcallback(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status @@ -1022,6 +1122,120 @@ int8_t uniffi_bitkitcore_fn_func_is_address_used(RustBuffer address, RustCallSta int8_t uniffi_bitkitcore_fn_func_is_valid_bip39_word(RustBuffer word, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_ACCOUNT_TYPE_TO_VARIANT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_ACCOUNT_TYPE_TO_VARIANT +RustBuffer uniffi_bitkitcore_fn_func_jade_account_type_to_variant(RustBuffer account_type, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_CANCEL +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_CANCEL +uint64_t uniffi_bitkitcore_fn_func_jade_cancel(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_CONNECT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_CONNECT +uint64_t uniffi_bitkitcore_fn_func_jade_connect(RustBuffer transport, RustBuffer path +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_DISCONNECT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_DISCONNECT +uint64_t uniffi_bitkitcore_fn_func_jade_disconnect(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_ACCOUNT_EXPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_ACCOUNT_EXPORT +uint64_t uniffi_bitkitcore_fn_func_jade_get_account_export(RustBuffer network, uint32_t account_index, RustBuffer account_types +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_CONNECTED_DEVICE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_CONNECTED_DEVICE +uint64_t uniffi_bitkitcore_fn_func_jade_get_connected_device(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_MASTER_FINGERPRINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_MASTER_FINGERPRINT +uint64_t uniffi_bitkitcore_fn_func_jade_get_master_fingerprint(RustBuffer network +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_VERSION_INFO +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_VERSION_INFO +uint64_t uniffi_bitkitcore_fn_func_jade_get_version_info(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_XPUB +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_GET_XPUB +uint64_t uniffi_bitkitcore_fn_func_jade_get_xpub(RustBuffer network, RustBuffer derivation_path +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_IS_CONNECTED +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_IS_CONNECTED +int8_t uniffi_bitkitcore_fn_func_jade_is_connected(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_LIST_DEVICES +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_LIST_DEVICES +uint64_t uniffi_bitkitcore_fn_func_jade_list_devices(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_LOGOUT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_LOGOUT +uint64_t uniffi_bitkitcore_fn_func_jade_logout(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_NOTIFY_DISCONNECTED +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_NOTIFY_DISCONNECTED +uint64_t uniffi_bitkitcore_fn_func_jade_notify_disconnected(RustBuffer path +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_PING +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_PING +uint64_t uniffi_bitkitcore_fn_func_jade_ping(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_REFRESH_VERSION_INFO +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_REFRESH_VERSION_INFO +uint64_t uniffi_bitkitcore_fn_func_jade_refresh_version_info(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SCAN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SCAN +uint64_t uniffi_bitkitcore_fn_func_jade_scan(uint32_t timeout_ms +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SET_TRANSPORT_CALLBACK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SET_TRANSPORT_CALLBACK +int8_t uniffi_bitkitcore_fn_func_jade_set_transport_callback(void*_Nonnull callback, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SIGN_MESSAGE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SIGN_MESSAGE +uint64_t uniffi_bitkitcore_fn_func_jade_sign_message(RustBuffer network, RustBuffer derivation_path, RustBuffer message +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SIGN_PSBT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_SIGN_PSBT +uint64_t uniffi_bitkitcore_fn_func_jade_sign_psbt(RustBuffer network, RustBuffer psbt +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_UNLOCK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_UNLOCK +uint64_t uniffi_bitkitcore_fn_func_jade_unlock(RustBuffer network +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_VERIFY_ADDRESS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_JADE_VERIFY_ADDRESS +uint64_t uniffi_bitkitcore_fn_func_jade_verify_address(RustBuffer network, RustBuffer variant, RustBuffer derivation_path, RustBuffer expected_address +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_LNURL_AUTH #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_LNURL_AUTH uint64_t uniffi_bitkitcore_fn_func_lnurl_auth(RustBuffer domain, RustBuffer k1, RustBuffer callback, RustBuffer bip32_mnemonic, RustBuffer network, RustBuffer bip39_passphrase @@ -2310,6 +2524,132 @@ uint16_t uniffi_bitkitcore_checksum_func_is_address_used(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_IS_VALID_BIP39_WORD uint16_t uniffi_bitkitcore_checksum_func_is_valid_bip39_word(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_ACCOUNT_TYPE_TO_VARIANT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_ACCOUNT_TYPE_TO_VARIANT +uint16_t uniffi_bitkitcore_checksum_func_jade_account_type_to_variant(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_CANCEL +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_CANCEL +uint16_t uniffi_bitkitcore_checksum_func_jade_cancel(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_CONNECT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_CONNECT +uint16_t uniffi_bitkitcore_checksum_func_jade_connect(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_DISCONNECT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_DISCONNECT +uint16_t uniffi_bitkitcore_checksum_func_jade_disconnect(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_ACCOUNT_EXPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_ACCOUNT_EXPORT +uint16_t uniffi_bitkitcore_checksum_func_jade_get_account_export(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_CONNECTED_DEVICE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_CONNECTED_DEVICE +uint16_t uniffi_bitkitcore_checksum_func_jade_get_connected_device(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_MASTER_FINGERPRINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_MASTER_FINGERPRINT +uint16_t uniffi_bitkitcore_checksum_func_jade_get_master_fingerprint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_VERSION_INFO +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_VERSION_INFO +uint16_t uniffi_bitkitcore_checksum_func_jade_get_version_info(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_XPUB +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_GET_XPUB +uint16_t uniffi_bitkitcore_checksum_func_jade_get_xpub(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_IS_CONNECTED +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_IS_CONNECTED +uint16_t uniffi_bitkitcore_checksum_func_jade_is_connected(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_LIST_DEVICES +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_LIST_DEVICES +uint16_t uniffi_bitkitcore_checksum_func_jade_list_devices(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_LOGOUT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_LOGOUT +uint16_t uniffi_bitkitcore_checksum_func_jade_logout(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_NOTIFY_DISCONNECTED +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_NOTIFY_DISCONNECTED +uint16_t uniffi_bitkitcore_checksum_func_jade_notify_disconnected(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_PING +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_PING +uint16_t uniffi_bitkitcore_checksum_func_jade_ping(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_REFRESH_VERSION_INFO +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_REFRESH_VERSION_INFO +uint16_t uniffi_bitkitcore_checksum_func_jade_refresh_version_info(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SCAN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SCAN +uint16_t uniffi_bitkitcore_checksum_func_jade_scan(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SET_TRANSPORT_CALLBACK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SET_TRANSPORT_CALLBACK +uint16_t uniffi_bitkitcore_checksum_func_jade_set_transport_callback(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SIGN_MESSAGE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SIGN_MESSAGE +uint16_t uniffi_bitkitcore_checksum_func_jade_sign_message(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SIGN_PSBT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_SIGN_PSBT +uint16_t uniffi_bitkitcore_checksum_func_jade_sign_psbt(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_UNLOCK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_UNLOCK +uint16_t uniffi_bitkitcore_checksum_func_jade_unlock(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_VERIFY_ADDRESS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_JADE_VERIFY_ADDRESS +uint16_t uniffi_bitkitcore_checksum_func_jade_verify_address(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_LNURL_AUTH @@ -2874,6 +3214,42 @@ uint16_t uniffi_bitkitcore_checksum_method_boltzeventlistener_on_event(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_EVENTLISTENER_ON_EVENT uint16_t uniffi_bitkitcore_checksum_method_eventlistener_on_event(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_SCAN_DEVICES +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_SCAN_DEVICES +uint16_t uniffi_bitkitcore_checksum_method_jadetransportcallback_scan_devices(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_OPEN_DEVICE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_OPEN_DEVICE +uint16_t uniffi_bitkitcore_checksum_method_jadetransportcallback_open_device(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_CLOSE_DEVICE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_CLOSE_DEVICE +uint16_t uniffi_bitkitcore_checksum_method_jadetransportcallback_close_device(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_WRITE_CHUNK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_WRITE_CHUNK +uint16_t uniffi_bitkitcore_checksum_method_jadetransportcallback_write_chunk(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_READ_CHUNK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_READ_CHUNK +uint16_t uniffi_bitkitcore_checksum_method_jadetransportcallback_read_chunk(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_GET_CHUNK_SIZE +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_JADETRANSPORTCALLBACK_GET_CHUNK_SIZE +uint16_t uniffi_bitkitcore_checksum_method_jadetransportcallback_get_chunk_size(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_TREZORTRANSPORTCALLBACK_ENUMERATE_DEVICES diff --git a/src/lib.rs b/src/lib.rs index 0b4cfab..ae073d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,13 @@ pub use crate::modules::hardware_wallet::{ get_supported_hardware_wallets, HardwareWalletTransport, HardwareWalletVendor, SupportedHardwareWallet, }; +use crate::modules::jade::JadeManager; +pub use crate::modules::jade::{ + jade_set_transport_callback, JadeAccount, JadeAccountExport, JadeAddressVariant, + JadeDeviceInfo, JadeError, JadeNativeDevice, JadeNetwork, JadePingStatus, JadeSignedMessage, + JadeState, JadeTransportCallback, JadeTransportErrorCode, JadeTransportKind, + JadeTransportReadResult, JadeTransportResult, JadeVersionInfo, JadeXpubResponse, +}; use crate::modules::pubky::{PubkyAuthDetails, PubkyAuthKind, PubkyError, PubkyProfile}; use crate::modules::trezor::account_type_to_script_type; pub use crate::modules::trezor::{ @@ -104,6 +111,7 @@ static DB: OnceCell> = OnceCell::new(); static ASYNC_DB: OnceCell> = OnceCell::new(); static RUNTIME: OnceCell = OnceCell::new(); static TREZOR_MANAGER: OnceCell = OnceCell::new(); +static JADE_MANAGER: OnceCell = OnceCell::new(); fn ensure_runtime() -> &'static Runtime { RUNTIME.get_or_init(|| Runtime::new().expect("Failed to create Tokio runtime")) @@ -2598,8 +2606,321 @@ pub async fn trezor_clear_credentials(device_id: String) -> Result<(), TrezorErr }) } +// ============================================================================ +// Jade Hardware Wallet Functions +// ============================================================================ + +fn get_jade_manager() -> &'static JadeManager { + JADE_MANAGER.get_or_init(JadeManager::new) +} + +/// Discover Jade devices. +/// +/// Bluetooth discovery is performed by the registered transport callback; on +/// desktop and Python builds, attached USB serial units are enumerated too. +/// Returns `DeviceBusy` while a connection is open, because starting a +/// Bluetooth scan during an active link drops it on Android. +#[uniffi::export] +pub async fn jade_scan(timeout_ms: u32) -> Result, JadeError> { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().scan(timeout_ms).await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// The devices found by the last scan, without starting a new one. +#[uniffi::export] +pub async fn jade_list_devices() -> Vec { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().list_devices().await }) + .await + .unwrap_or_default() +} + +/// Open a device and read its firmware and state summary. +/// +/// The path normally comes from the last `jade_scan`, but a known Bluetooth +/// address or serial path can be passed directly to reconnect without a scan. +/// Any previously open connection is closed first. The returned `jade_state` +/// tells the application what to do next: `Locked` means call `jade_unlock`, +/// `Ready` means the device is already usable, and `Uninit` means the user must +/// create or restore a wallet on the device itself. +#[uniffi::export] +pub async fn jade_connect( + transport: JadeTransportKind, + path: String, +) -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().connect(transport, &path).await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Close the device and clear session state. +/// +/// Safe to call while an operation is waiting on a confirmation: the pending +/// request returns `UserCancelled` promptly rather than running out its deadline. +#[uniffi::export] +pub async fn jade_disconnect() -> Result<(), JadeError> { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().disconnect().await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Abort the operation in flight. +/// +/// Jade has no cancel message, so this closes the link. The application should +/// reconnect afterwards. This is what backs a cancel button on a signing screen. +/// +/// The aborted request returns `UserCancelled`, whether it notices the abort +/// flag or the closed link first, so a cancel never surfaces as a disconnection. +#[uniffi::export] +pub async fn jade_cancel() -> Result<(), JadeError> { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().cancel().await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Tell the library that the native layer saw the device disconnect. +/// +/// Without this, an idle Bluetooth drop is invisible until the next request. +/// Await it before reconnecting the same path: a notification that is still +/// pending when a reconnect to that path completes closes the new connection. +#[uniffi::export] +pub async fn jade_notify_disconnected(path: String) { + let rt = ensure_runtime(); + let _ = rt + .spawn(async move { get_jade_manager().notify_disconnected(&path).await }) + .await; +} + +#[uniffi::export] +pub fn jade_is_connected() -> bool { + get_jade_manager().is_connected() +} + +#[uniffi::export] +pub async fn jade_get_connected_device() -> Option { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().connected_device().await }) + .await + .unwrap_or(None) +} + +/// The version summary read at connect or by the last refresh. +/// +/// Neither touches the device nor waits for an operation in flight. +#[uniffi::export] +pub async fn jade_get_version_info() -> Option { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().version_info().await }) + .await + .unwrap_or(None) +} + +/// Re-read the version summary from the device. +#[uniffi::export] +pub async fn jade_refresh_version_info() -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().refresh_version_info().await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Check whether the device is idle, busy, or waiting on the user. +#[uniffi::export] +pub async fn jade_ping() -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().ping().await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Unlock the device for a network. +/// +/// Runs the blind pinserver exchange when the device asks for it, which needs +/// network access. The PIN is entered on the device and never reaches the host. +#[uniffi::export] +pub async fn jade_unlock(network: JadeNetwork) -> Result<(), JadeError> { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().unlock(network).await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Lock the device and zero its in-memory key material. +#[uniffi::export] +pub async fn jade_logout() -> Result<(), JadeError> { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().logout().await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Fetch an extended public key, echoed back with the path and fingerprint. +#[uniffi::export] +pub async fn jade_get_xpub( + network: JadeNetwork, + derivation_path: String, +) -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().get_xpub(network, derivation_path).await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// The device's master fingerprint, eight lowercase hex characters. +/// +/// This must be supplied as `WalletParams.fingerprint` when composing, or the +/// resulting PSBT carries no BIP32 key origins and the device signs nothing. +#[uniffi::export] +pub async fn jade_get_master_fingerprint(network: JadeNetwork) -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().master_fingerprint(network).await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Fetch the account keys an import needs in one call. +/// +/// Shaped like `passport_parse_account_export` so applications have a single +/// import path across signers. Each key is fetched under one held connection, +/// which matters over Bluetooth where every round trip is slow. +#[uniffi::export] +pub async fn jade_get_account_export( + network: JadeNetwork, + account_index: u32, + account_types: Vec, +) -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { + get_jade_manager() + .account_export(network, account_index, account_types) + .await + }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Display an address on the device and check it against the expected one. +/// +/// This always prompts on the device screen, so it is a verification step +/// rather than a way to fetch an address. Returns `AddressMismatch` when the +/// device disagrees with `expected_address`. +#[uniffi::export] +pub async fn jade_verify_address( + network: JadeNetwork, + variant: JadeAddressVariant, + derivation_path: String, + expected_address: String, +) -> Result<(), JadeError> { + let rt = ensure_runtime(); + rt.spawn(async move { + get_jade_manager() + .verify_address(network, variant, derivation_path, expected_address) + .await + }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Sign a message, returning the signature with the address that verifies it. +#[uniffi::export] +pub async fn jade_sign_message( + network: JadeNetwork, + derivation_path: String, + message: String, +) -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { + get_jade_manager() + .sign_message(network, derivation_path, message) + .await + }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Sign a PSBT, returning the signed PSBT base64 encoded. +/// +/// The reply is checked against what was sent before it is returned. Feed the +/// result to `finalize_psbt` with the original PSBT, then broadcast with +/// `onchain_broadcast_raw_tx`. +#[uniffi::export] +pub async fn jade_sign_psbt(network: JadeNetwork, psbt: String) -> Result { + let rt = ensure_runtime(); + rt.spawn(async move { get_jade_manager().sign_psbt(network, psbt).await }) + .await + .unwrap_or_else(|e| { + Err(JadeError::IoError { + error_details: format!("Runtime error: {}", e), + }) + }) +} + +/// Map a generic account type onto Jade's descriptor variant. +#[uniffi::export] +pub fn jade_account_type_to_variant(account_type: AccountType) -> JadeAddressVariant { + crate::modules::jade::account_type_to_variant(account_type) +} + // ============================================================================ // Account info FFI exports + // ============================================================================ /// Query account information for an extended public key via Electrum. diff --git a/src/modules/activity/backup_migration.rs b/src/modules/activity/backup_migration.rs index b5e1ba9..aa4df9c 100644 --- a/src/modules/activity/backup_migration.rs +++ b/src/modules/activity/backup_migration.rs @@ -341,11 +341,23 @@ mod tests { let migrated = migrate_backup_activities_json(backup).unwrap(); let value: Value = serde_json::from_str(&migrated).unwrap(); - assert_eq!(wallet_id_at(&value, "/0/v1/walletId"), Some(DEFAULT_WALLET_ID)); - assert_eq!(wallet_id_at(&value, "/1/v1/walletId"), Some(DEFAULT_WALLET_ID)); + assert_eq!( + wallet_id_at(&value, "/0/v1/walletId"), + Some(DEFAULT_WALLET_ID) + ); + assert_eq!( + wallet_id_at(&value, "/1/v1/walletId"), + Some(DEFAULT_WALLET_ID) + ); // Non-wallet fields are preserved untouched. - assert_eq!(value.pointer("/0/v1/txId").and_then(Value::as_str), Some("tx_1")); - assert_eq!(value.pointer("/1/v1/invoice").and_then(Value::as_str), Some("lnbc1")); + assert_eq!( + value.pointer("/0/v1/txId").and_then(Value::as_str), + Some("tx_1") + ); + assert_eq!( + value.pointer("/1/v1/invoice").and_then(Value::as_str), + Some("lnbc1") + ); } #[test] @@ -439,7 +451,10 @@ mod tests { let migrated = migrate_backup_activities_json(backup).unwrap(); let value: Value = serde_json::from_str(&migrated).unwrap(); - assert_eq!(wallet_id_at(&value, "/0/v1/walletId"), Some("trezor:abcd1234")); + assert_eq!( + wallet_id_at(&value, "/0/v1/walletId"), + Some("trezor:abcd1234") + ); } #[test] @@ -579,10 +594,9 @@ mod tests { #[test] fn tags_metadata_details_from_canonical_default_wallet_id() { - let tags = activity_tags_from_json( - json!([{ "activity_id": "a1", "tags": ["food"] }]).to_string(), - ) - .unwrap(); + let tags = + activity_tags_from_json(json!([{ "activity_id": "a1", "tags": ["food"] }]).to_string()) + .unwrap(); assert_eq!(tags[0].wallet_id, DEFAULT_WALLET_ID); assert_eq!(tags[0].activity_id, "a1"); diff --git a/src/modules/hardware_wallet/catalog.rs b/src/modules/hardware_wallet/catalog.rs index 6180ff1..a3ef820 100644 --- a/src/modules/hardware_wallet/catalog.rs +++ b/src/modules/hardware_wallet/catalog.rs @@ -13,6 +13,14 @@ pub fn get_supported_hardware_wallets() -> Vec { transports, }; + let jade = |model: &str, display_name: &str| SupportedHardwareWallet { + vendor: HardwareWalletVendor::Blockstream, + vendor_name: "Blockstream".to_string(), + model: model.to_string(), + display_name: display_name.to_string(), + transports: vec![Usb, Bluetooth], + }; + vec![ trezor("Model One", vec![Usb]), trezor("Model T", vec![Usb]), @@ -26,5 +34,9 @@ pub fn get_supported_hardware_wallets() -> Vec { display_name: "Foundation Passport".to_string(), transports: vec![Qr], }, + // Jade's USB link is CDC serial rather than HID, reported here as Usb + // because that is what a user plugs in. + jade("Jade", "Blockstream Jade"), + jade("Jade Plus", "Blockstream Jade Plus"), ] } diff --git a/src/modules/hardware_wallet/tests.rs b/src/modules/hardware_wallet/tests.rs index d13ca08..ace3d9c 100644 --- a/src/modules/hardware_wallet/tests.rs +++ b/src/modules/hardware_wallet/tests.rs @@ -4,7 +4,7 @@ use super::{get_supported_hardware_wallets, HardwareWalletTransport, HardwareWal fn catalog_lists_supported_models_and_transports() { let wallets = get_supported_hardware_wallets(); - assert_eq!(wallets.len(), 6); + assert_eq!(wallets.len(), 8); assert!(wallets .iter() .filter(|wallet| wallet.vendor == HardwareWalletVendor::Trezor) @@ -24,4 +24,17 @@ fn catalog_lists_supported_models_and_transports() { .unwrap(); assert_eq!(passport.vendor, HardwareWalletVendor::Foundation); assert_eq!(passport.transports, [HardwareWalletTransport::Qr]); + + let jades: Vec<_> = wallets + .iter() + .filter(|wallet| wallet.vendor == HardwareWalletVendor::Blockstream) + .collect(); + assert_eq!(jades.len(), 2); + assert!(jades.iter().all(|wallet| { + wallet.transports.contains(&HardwareWalletTransport::Usb) + && wallet + .transports + .contains(&HardwareWalletTransport::Bluetooth) + })); + assert!(jades.iter().any(|wallet| wallet.model == "Jade Plus")); } diff --git a/src/modules/hardware_wallet/types.rs b/src/modules/hardware_wallet/types.rs index f8ce601..325e69e 100644 --- a/src/modules/hardware_wallet/types.rs +++ b/src/modules/hardware_wallet/types.rs @@ -3,6 +3,7 @@ pub enum HardwareWalletVendor { Trezor, Foundation, + Blockstream, } /// How an application exchanges data with a hardware wallet. diff --git a/src/modules/jade/README.md b/src/modules/jade/README.md new file mode 100644 index 0000000..70a14e2 --- /dev/null +++ b/src/modules/jade/README.md @@ -0,0 +1,124 @@ +# Jade Module - Technical Overview + +Blockstream Jade support for bitkit-core, over Bluetooth (all platforms) and USB +CDC serial (desktop and Python). Bitcoin single signature only. + +The protocol itself lives in +[`jade-client-rs`](https://github.com/synonymdev/jade-client-rs). This module +is the FFI adapter. For the wire format, the pinserver exchange, PSBT checks and +the transport contract, read that crate's documentation; what follows is only +what is specific to bitkit-core. + +## Architecture + +``` +┌──────────────────────────────────────────────────────────────────────┐ +│ bitkit-android / bitkit-ios │ +│ implements JadeTransportCallback: BLE, and USB host on Android │ +└───────────────────────────────┬──────────────────────────────────────┘ + │ UniFFI +┌───────────────────────────────▼──────────────────────────────────────┐ +│ bitkit-core │ +│ lib.rs jade_* exports over a global JadeManager │ +│ implementation.rs session lock, device list, abort handle │ +│ callbacks.rs JadeTransportCallback + bridge to JadeTransport │ +│ types.rs #[uniffi::remote] scaffolding for crate types │ +└───────────────────────────────┬──────────────────────────────────────┘ + │ +┌───────────────────────────────▼──────────────────────────────────────┐ +│ jade-client-rs │ +│ CBOR protocol, pinserver, PSBT checks, serial transport │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +## Why the types are declared with `#[uniffi::remote]` + +The crate's types carry no binding framework. `types.rs` attaches UniFFI +scaffolding to them from here, which generates the same code a +`#[derive(uniffi::…)]` would without a mirrored set of structs. + +This is the main way this module differs from `trezor`, which predates the +technique: that module maintains roughly 900 lines of parallel types and +hand-written `From` conversions in both directions against +`trezor-connect-rs`. The declarations here have to match upstream field for +field, and the compiler enforces it. + +One consequence worth knowing: `#[uniffi::remote(Error)]` needs to match every +variant, so `jade_client_rs::JadeError` deliberately is not `#[non_exhaustive]`. + +## Session state + +`jade_client_rs::Jade` takes `&mut self` per operation, so the one request at a +time rule is a compile time property there. A free-function FFI surface needs a +process global, so `JadeManager` supplies the lock that implies. + +The abort handle is kept outside that lock on purpose. Sharing one lock would +make `jade_disconnect` and every status read queue behind a five minute +confirmation, and UniFFI async exports are detached onto the runtime, so a +cancelled Swift or Kotlin task does not cancel the Rust future by itself. +`jade_cancel` and `jade_disconnect` therefore close the transport through a +`CancelHandle` without taking the session lock. + +A separate lifecycle lock serializes scans, connection setup, and teardown. +Disconnect and cancellation invalidate queued connection attempts and interrupt an +active handshake. Native callbacks that have already started must finish before +another connection can reuse the path. If cancellation arrives during a native +open, teardown waits for that callback to return and closes its result. + +## Transport bridge + +`JadeTransportCallback` is the `#[uniffi::export(with_foreign)]` trait the +application implements; `CallbackTransport` adapts it onto the crate's +`JadeTransport`. Every callback invocation runs on the tokio blocking pool, so a +slow implementation costs a blocking thread rather than a runtime worker. + +The full Bluetooth contract, including the two second inter-chunk deadline and +the write-with-response requirement, is documented on the trait and in the +crate's README. Read it before writing a native implementation; each of those +rules fails only against real hardware. + +Errors cross the boundary as a typed `JadeTransportErrorCode` rather than an +error string. The trezor adapter has to encode its code into a sentinel string +and parse it back out, because its upstream crate offers no typed channel. + +## Signing + +Jade returns a signed PSBT, so it follows the Passport path: + +``` +onchain_compose_transaction -> psbt (base64) +jade_sign_psbt -> signed psbt (base64) +finalize_psbt(original, signed) -> CompletedTransaction +onchain_broadcast_raw_tx +``` + +`WalletParams.fingerprint` must be set to the value from +`jade_get_master_fingerprint`, or the composed PSBT carries no BIP32 key origins +and the device signs nothing. The crate rejects that case before the round trip +with `FingerprintMismatch`. + +## Constraints + +- No `#[uniffi::export]` item here may be `cfg` gated. All three build scripts + generate bindings from the host library, so a host only export would appear in + the generated Swift and Kotlin while being absent from the device library. +- No `u8` or `u16` in the FFI surface. `ping` returns `JadePingStatus` and + `battery_status` is `u32`, keeping this module clear of the narrow unsigned + return path that needed a binding generator fix for Android ARM32. +- Registering a transport callback twice replaces the first, so an Android + activity restart can re-register. The replacement is logged. + +## Dependency + +Pinned by git revision until the crate is published to crates.io, so bitkit-core +never depends on an unreleased version. Bumping it means updating both target +tables in `Cargo.toml`. + +## Testing + +```bash +cargo test modules::jade # adapter only +``` + +Protocol level tests live in the crate and run with `cargo test` there, against +a scripted mock device and a fake pinserver. diff --git a/src/modules/jade/callbacks.rs b/src/modules/jade/callbacks.rs new file mode 100644 index 0000000..0724095 --- /dev/null +++ b/src/modules/jade/callbacks.rs @@ -0,0 +1,264 @@ +//! The transport contract the native application implements, and the bridge +//! from it to the protocol crate's transport trait. +//! +//! Rust owns the Jade protocol; the application owns the bytes. On iOS that +//! means CoreBluetooth against the Nordic UART Service, and on Android the +//! Bluetooth API plus, optionally, the USB Host API for CDC serial. +//! +//! Methods are synchronous because that is the shape the trezor module already +//! established here. Every one of them is invoked on the blocking pool, so a +//! slow implementation costs a blocking thread rather than a runtime worker. + +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, RwLock}; +use std::time::Duration; + +use async_trait::async_trait; +use jade_client_rs::{JadeError, JadeTransport, JadeTransportErrorCode, MAX_CHUNK_BYTES}; + +use super::types::JadeTransportKind; + +/// A device the native layer discovered. +#[derive(Debug, Clone, uniffi::Record)] +pub struct JadeNativeDevice { + /// Transport specific address: a BLE identifier or a serial device path. + pub path: String, + pub transport: JadeTransportKind, + /// Advertised or descriptor name, for example "Jade C0FFEE". + pub name: Option, + pub serial_number: Option, +} + +/// Outcome of an operation that returns no data. +#[derive(Debug, Clone, uniffi::Record)] +pub struct JadeTransportResult { + pub success: bool, + /// Empty on success. + pub error: String, + pub error_code: Option, +} + +/// Outcome of a read. +#[derive(Debug, Clone, uniffi::Record)] +pub struct JadeTransportReadResult { + pub success: bool, + /// Bytes read. Success with an empty vector means nothing has arrived yet, + /// which is the normal case while the user is deciding on the device. + pub data: Vec, + /// Empty on success. + pub error: String, + pub error_code: Option, +} + +/// Native transport for Jade. +/// +/// # Bluetooth contract +/// +/// Jade advertises the Nordic UART Service: +/// +/// - service `6e400001-b5a3-f393-e0a9-e50e24dcca9e` +/// - write `6e400002-b5a3-f393-e0a9-e50e24dcca9e` (host to Jade) +/// - notify `6e400003-b5a3-f393-e0a9-e50e24dcca9e` (Jade to host) +/// +/// Devices advertise as "Jade" or "Jade ". +/// +/// Three requirements that are easy to miss and break signing on real hardware: +/// +/// 1. **Write with response.** Write-without-response silently drops chunks on +/// the ESP32 GATT stack. +/// 2. **Do not pause between chunks.** Firmware discards a partially received +/// message after two seconds of silence, three on Jade v1, and answers with +/// an unattributed error. A 30 KB PSBT is roughly 60 writes, so any UI thread +/// stall in the middle of a send breaks the operation. +/// 3. **`read_chunk` must return promptly.** Honour `timeout_ms`, which this +/// crate caps at 250ms. The long per-operation deadline is enforced in Rust +/// so the user can cancel. +/// +/// Once `close_device` has been called for a path, this crate issues no further +/// reads or writes for it and discards the result of one already in flight, so +/// a transport that keeps reporting empty reads after closing does not hold a +/// disconnect open until the handshake deadline. A `read_chunk` that has +/// already started cannot be interrupted, though, so requirement 3 is what +/// bounds a disconnect issued mid-handshake: an implementation that ignores +/// `timeout_ms` delays it for as long as that call takes to return. +#[uniffi::export(with_foreign)] +pub trait JadeTransportCallback: Send + Sync { + /// Discover devices, blocking up to `timeout_ms`. + fn scan_devices(&self, timeout_ms: u32) -> Vec; + + /// Open a connection and enable notifications. + fn open_device(&self, path: String) -> JadeTransportResult; + + /// Close the connection and release the device. + fn close_device(&self, path: String) -> JadeTransportResult; + + /// Write one chunk, no larger than `get_chunk_size`. + fn write_chunk(&self, path: String, data: Vec) -> JadeTransportResult; + + /// Read whatever has arrived, waiting at most `timeout_ms`. + /// + /// Returning success with an empty vector is normal and means "nothing yet". + fn read_chunk(&self, path: String, timeout_ms: u32) -> JadeTransportReadResult; + + /// Maximum bytes per write. + /// + /// For Bluetooth this is `min(negotiated_mtu - 3, 509)`. The value is + /// clamped into a usable range, so an unnegotiated `0` is not fatal. + fn get_chunk_size(&self, path: String) -> u32; +} + +/// The registered callback. +/// +/// A read-write cell rather than a write-once cell on purpose. An Android +/// activity restart rebuilds the Bluetooth manager and registers a fresh +/// implementation; silently keeping the first one would leave this crate calling +/// into a dead context with no recovery short of killing the process. +static TRANSPORT_CALLBACK: RwLock>> = RwLock::new(None); + +/// Register the native transport. +/// +/// Returns `true` when this replaced a previously registered callback, which +/// lets the application tell a fresh registration from a re-registration. +#[uniffi::export] +pub fn jade_set_transport_callback(callback: Arc) -> bool { + #[cfg(target_os = "android")] + crate::init_android_logger(); + + let mut guard = TRANSPORT_CALLBACK + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let replaced = guard.is_some(); + if replaced { + log::warn!("[jade] transport callback replaced"); + } + *guard = Some(callback); + replaced +} + +/// Fetch the registered transport, if any. +pub(crate) fn transport_callback() -> Option> { + TRANSPORT_CALLBACK + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .clone() +} + +fn to_error(code: Option, message: String) -> JadeError { + match code { + Some(code) => JadeError::from(code), + None => JadeError::TransportError { + error_details: message, + }, + } +} + +/// Bridges the foreign callback onto the protocol crate's transport trait. +/// +/// The error code travels as a typed value the whole way, so nothing has to be +/// encoded into an error string and parsed back out. The trezor adapter in this +/// repo does exactly that, because its upstream crate offers no typed channel. +pub(crate) struct CallbackTransport { + callback: Arc, + path: String, + chunk_size: usize, + /// Set by `close`, so reads and writes fail at once instead of waiting on a + /// native layer that may keep answering for a released path. + closed: Arc, +} + +impl CallbackTransport { + pub(crate) fn new(callback: Arc, path: String) -> Self { + // Clamp whatever the native layer reports. A zero would make the write + // loop fail to advance, and anything above the Bluetooth cap would be + // rejected by the link layer. + let reported = callback.get_chunk_size(path.clone()); + let chunk_size = reported.clamp(1, MAX_CHUNK_BYTES) as usize; + Self { + callback, + path, + chunk_size, + closed: Arc::new(AtomicBool::new(false)), + } + } + + fn ensure_open(&self) -> Result<(), JadeError> { + if self.closed.load(Ordering::SeqCst) { + return Err(JadeError::from(JadeTransportErrorCode::Disconnected)); + } + Ok(()) + } +} + +#[async_trait] +impl JadeTransport for CallbackTransport { + async fn write_all(&self, data: Vec) -> Result<(), JadeError> { + self.ensure_open()?; + let callback = Arc::clone(&self.callback); + let path = self.path.clone(); + let chunk_size = self.chunk_size; + let closed = Arc::clone(&self.closed); + + // Foreign callbacks are synchronous and can block. Running them on a + // worker thread would park it for the duration; the blocking pool is + // sized for exactly this. + tokio::task::spawn_blocking(move || { + for chunk in data.chunks(chunk_size) { + if closed.load(Ordering::SeqCst) { + return Err(JadeError::from(JadeTransportErrorCode::Disconnected)); + } + let result = callback.write_chunk(path.clone(), chunk.to_vec()); + if !result.success { + return Err(to_error(result.error_code, result.error)); + } + } + Ok(()) + }) + .await + .map_err(|error| JadeError::IoError { + error_details: format!("write task failed: {error}"), + })? + } + + async fn read_some(&self, timeout: Duration) -> Result, JadeError> { + self.ensure_open()?; + let callback = Arc::clone(&self.callback); + let path = self.path.clone(); + let timeout_ms = timeout.as_millis().min(u128::from(u32::MAX)) as u32; + let closed = Arc::clone(&self.closed); + + tokio::task::spawn_blocking(move || { + let result = callback.read_chunk(path, timeout_ms); + // `close` cannot interrupt a `read_chunk` that has already entered + // the native layer, so re-check afterwards. Bytes that arrive for a + // released path are dropped rather than fed back to the parser. + if closed.load(Ordering::SeqCst) { + return Err(JadeError::from(JadeTransportErrorCode::Disconnected)); + } + if !result.success { + return Err(to_error(result.error_code, result.error)); + } + Ok(result.data) + }) + .await + .map_err(|error| JadeError::IoError { + error_details: format!("read task failed: {error}"), + })? + } + + async fn close(&self) -> Result<(), JadeError> { + self.closed.store(true, Ordering::SeqCst); + let callback = Arc::clone(&self.callback); + let path = self.path.clone(); + tokio::task::spawn_blocking(move || { + let result = callback.close_device(path); + if !result.success { + return Err(to_error(result.error_code, result.error)); + } + Ok(()) + }) + .await + .map_err(|error| JadeError::IoError { + error_details: format!("close task failed: {error}"), + })? + } +} diff --git a/src/modules/jade/implementation.rs b/src/modules/jade/implementation.rs new file mode 100644 index 0000000..7ae8857 --- /dev/null +++ b/src/modules/jade/implementation.rs @@ -0,0 +1,439 @@ +//! Session state for the FFI surface. +//! +//! `jade_client_rs::Jade` takes `&mut self` for every operation, which makes the +//! one-request-at-a-time rule a compile time property. The FFI surface here is a +//! set of free functions over a process global, so this adds the lock that shape +//! implies, plus the device list and the abort handle. +//! +//! The abort handle is deliberately kept outside the session lock. Holding one +//! lock for both would make `jade_disconnect` and every status read queue behind +//! a five minute confirmation, and UniFFI async exports are detached onto the +//! runtime, so a cancelled Swift or Kotlin task does not cancel the Rust future +//! by itself. + +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + +use base64::{engine::general_purpose::STANDARD, Engine as _}; +use bitcoin::psbt::Psbt; +use jade_client_rs::{CancelHandle, Jade, JadeTransport}; +use tokio::sync::{watch, Mutex, RwLock}; + +use super::callbacks::{transport_callback, CallbackTransport}; +use super::types::*; +use crate::onchain::AccountType; + +/// A device seen by the last scan. +#[derive(Debug, Clone)] +struct CachedDevice { + info: JadeDeviceInfo, +} + +pub struct JadeManager { + device_list: Mutex>, + /// Serializes discovery, connection setup, and teardown. + lifecycle: Mutex<()>, + /// Invalidates active and queued connection attempts before teardown waits. + connection_changes: watch::Sender<()>, + /// Held for exactly one operation. + session: Mutex>, + /// Cloned out by the abort path, which must not wait on `session`. + cancel: RwLock>, + /// Cheap status reads that never touch a lock held across device I/O. + connected: AtomicBool, + connected_device: RwLock>, + version_info: RwLock>, +} + +impl Default for JadeManager { + fn default() -> Self { + Self::new() + } +} + +impl JadeManager { + pub fn new() -> Self { + Self { + device_list: Mutex::new(Vec::new()), + lifecycle: Mutex::new(()), + connection_changes: watch::channel(()).0, + session: Mutex::new(None), + cancel: RwLock::new(None), + connected: AtomicBool::new(false), + connected_device: RwLock::new(None), + version_info: RwLock::new(None), + } + } + + // ------------------------------------------------------------------ + // Discovery + // ------------------------------------------------------------------ + + /// Discover devices on every transport this build supports. + pub async fn scan(&self, timeout_ms: u32) -> Result, JadeError> { + let _lifecycle = self + .lifecycle + .try_lock() + .map_err(|_| JadeError::DeviceBusy)?; + // Starting a Bluetooth scan while a GATT link is up reliably drops it on + // Android, so refuse rather than silently breaking the open session. + if self.connected.load(Ordering::SeqCst) { + return Err(JadeError::DeviceBusy); + } + + let mut discovered: Vec = Vec::new(); + + // Mobile builds discover only through the native transport, so a missing + // registration is a wiring error rather than an empty scan. + #[cfg(any(target_os = "ios", target_os = "android"))] + let callback = Some(transport_callback().ok_or(JadeError::NotInitialized)?); + #[cfg(not(any(target_os = "ios", target_os = "android")))] + let callback = transport_callback(); + + if let Some(callback) = callback { + let found = tokio::task::spawn_blocking(move || callback.scan_devices(timeout_ms)) + .await + .map_err(|error| JadeError::IoError { + error_details: format!("scan task failed: {error}"), + })?; + discovered.extend(found.into_iter().map(|device| JadeDeviceInfo { + path: device.path, + transport: device.transport, + name: device.name, + serial_number: device.serial_number, + })); + } + + #[cfg(not(any(target_os = "ios", target_os = "android")))] + discovered.extend(jade_client_rs::serial::enumerate_devices()); + + *self.device_list.lock().await = discovered + .iter() + .cloned() + .map(|info| CachedDevice { info }) + .collect(); + Ok(discovered) + } + + /// The devices found by the last scan. + pub async fn list_devices(&self) -> Vec { + self.device_list + .lock() + .await + .iter() + .map(|device| device.info.clone()) + .collect() + } + + // ------------------------------------------------------------------ + // Connection lifecycle + // ------------------------------------------------------------------ + + /// Open a device and read its version summary. + /// + /// A path the last scan did not report is accepted as well: a Bluetooth + /// address stays valid across scans, and a device that just stopped + /// advertising, or was reconnected before the next scan, would otherwise be + /// unreachable until a scan happens to see it again. The native transport + /// reports an unreachable path when it opens it. + pub async fn connect( + &self, + transport_kind: JadeTransportKind, + path: &str, + ) -> Result { + let mut changes = self.connection_changes.subscribe(); + let _lifecycle = self.lifecycle.lock().await; + if changes.has_changed().unwrap_or(true) { + return Err(JadeError::UserCancelled); + } + let device = { + let devices = self.device_list.lock().await; + devices + .iter() + .find(|candidate| { + candidate.info.transport == transport_kind && candidate.info.path == path + }) + .map(|candidate| candidate.info.clone()) + .unwrap_or_else(|| JadeDeviceInfo { + path: path.to_string(), + transport: transport_kind, + name: None, + serial_number: None, + }) + }; + + // Close anything already open first. Overwriting the session would + // strand the native handle with no path left to close it. + self.disconnect_session().await?; + if changes.has_changed().unwrap_or(true) { + return Err(JadeError::UserCancelled); + } + + // A native open callback cannot be interrupted by dropping its future. + // Keep ownership until it returns, then close it if teardown was requested. + let transport = self.build_transport(transport_kind, path).await?; + if changes.has_changed().unwrap_or(true) { + transport.close().await?; + return Err(JadeError::UserCancelled); + } + let connecting = Jade::connect(Arc::clone(&transport)); + tokio::pin!(connecting); + let session = tokio::select! { + biased; + _ = changes.changed() => { + let closed = transport.close().await; + // Native callbacks already running on the blocking pool must finish + // before a replacement can reuse the same device path. + let _ = connecting.await; + closed?; + return Err(JadeError::UserCancelled); + } + result = &mut connecting => result?, + }; + let version = session.version_info().clone(); + + *self.cancel.write().await = Some(session.cancel_handle()); + *self.connected_device.write().await = Some(device); + *self.version_info.write().await = Some(version.clone()); + *self.session.lock().await = Some(session); + self.connected.store(true, Ordering::SeqCst); + + Ok(version) + } + + async fn build_transport( + &self, + transport_kind: JadeTransportKind, + path: &str, + ) -> Result, JadeError> { + // A serial device found by the crate's own enumeration is driven + // directly; anything the native layer reported goes back through it. + #[cfg(not(any(target_os = "ios", target_os = "android")))] + if transport_kind == JadeTransportKind::Serial + && jade_client_rs::serial::enumerate_devices() + .iter() + .any(|device| device.path == path) + { + return Ok(Arc::new(jade_client_rs::SerialTransport::open(path)?)); + } + + let callback = transport_callback().ok_or(JadeError::NotInitialized)?; + let open_path = path.to_string(); + let opener = Arc::clone(&callback); + let result = tokio::task::spawn_blocking(move || opener.open_device(open_path)) + .await + .map_err(|error| JadeError::IoError { + error_details: format!("open task failed: {error}"), + })?; + if !result.success { + return Err(JadeError::ConnectionError { + error_details: result.error, + }); + } + Ok(Arc::new(CallbackTransport::new(callback, path.to_string()))) + } + + /// Close the device and clear session state. + /// + /// Safe to call while an operation is in flight: the cancel handle closes + /// the transport without taking the session lock, so a blocked request + /// returns promptly instead of running out its deadline. + pub async fn disconnect(&self) -> Result<(), JadeError> { + self.connection_changes.send_replace(()); + let _lifecycle = self.lifecycle.lock().await; + self.disconnect_session().await + } + + async fn disconnect_session(&self) -> Result<(), JadeError> { + self.connected.store(false, Ordering::SeqCst); + + if let Some(cancel) = self.cancel.write().await.take() { + if let Err(error) = cancel.cancel().await { + log::debug!("[jade] error closing the transport: {error}"); + } + } + *self.connected_device.write().await = None; + *self.version_info.write().await = None; + *self.session.lock().await = None; + Ok(()) + } + + /// Abort the operation in flight without tearing down session state. + /// + /// Jade has no cancel message, so closing the link is the only way to stop a + /// pending confirmation. The application is expected to reconnect. + pub async fn cancel(&self) -> Result<(), JadeError> { + self.connection_changes.send_replace(()); + let _lifecycle = self.lifecycle.lock().await; + let handle = self.cancel.read().await.clone(); + if let Some(handle) = handle { + handle.cancel().await?; + } + Ok(()) + } + + /// Record a disconnect the native layer noticed while nothing was in flight. + /// + /// No connection attempt can be running while this holds `lifecycle`, so + /// unlike `disconnect` it does not invalidate queued attempts: a reconnect + /// issued alongside the notification should proceed, not fail as cancelled. + pub async fn notify_disconnected(&self, path: &str) { + let _lifecycle = self.lifecycle.lock().await; + let matches = self + .connected_device + .read() + .await + .as_ref() + .map(|device| device.path == path) + .unwrap_or(false); + if matches { + log::debug!("[jade] native layer reported a disconnect"); + let _ = self.disconnect_session().await; + } + } + + pub fn is_connected(&self) -> bool { + self.connected.load(Ordering::SeqCst) + } + + pub async fn connected_device(&self) -> Option { + self.connected_device.read().await.clone() + } + + /// The version summary read at connect, or refreshed since. + /// + /// Served from a copy so it never waits behind a device confirmation that + /// holds `session`. + pub async fn version_info(&self) -> Option { + self.version_info.read().await.clone() + } + + /// Re-read the version summary from the device. + pub async fn refresh_version_info(&self) -> Result { + let mut guard = self.session.lock().await; + let session = guard.as_mut().ok_or(JadeError::NotConnected)?; + let version = session.refresh_version_info().await?.clone(); + *self.version_info.write().await = Some(version.clone()); + Ok(version) + } + + // ------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------ + + pub async fn ping(&self) -> Result { + let mut guard = self.session.lock().await; + guard.as_mut().ok_or(JadeError::NotConnected)?.ping().await + } + + pub async fn unlock(&self, network: JadeNetwork) -> Result<(), JadeError> { + let mut guard = self.session.lock().await; + guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .unlock(network) + .await + } + + pub async fn logout(&self) -> Result<(), JadeError> { + let mut guard = self.session.lock().await; + guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .logout() + .await + } + + pub async fn master_fingerprint(&self, network: JadeNetwork) -> Result { + let mut guard = self.session.lock().await; + guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .master_fingerprint(network) + .await + } + + pub async fn get_xpub( + &self, + network: JadeNetwork, + derivation_path: String, + ) -> Result { + let mut guard = self.session.lock().await; + guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .get_xpub(network, &derivation_path) + .await + } + + pub async fn account_export( + &self, + network: JadeNetwork, + account_index: u32, + account_types: Vec, + ) -> Result { + let variants: Vec = account_types + .into_iter() + .map(account_type_to_variant) + .collect(); + let mut guard = self.session.lock().await; + guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .account_export(network, account_index, &variants) + .await + } + + pub async fn verify_address( + &self, + network: JadeNetwork, + variant: JadeAddressVariant, + derivation_path: String, + expected_address: String, + ) -> Result<(), JadeError> { + let mut guard = self.session.lock().await; + guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .verify_address(network, variant, &derivation_path, &expected_address) + .await + } + + pub async fn sign_message( + &self, + network: JadeNetwork, + derivation_path: String, + message: String, + ) -> Result { + let mut guard = self.session.lock().await; + guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .sign_message(network, &derivation_path, &message) + .await + } + + /// Sign a base64 PSBT and return the signed PSBT, base64 encoded. + /// + /// The FFI surface speaks base64 because that is what `compose_transaction` + /// emits and what `finalize_psbt` expects; the protocol crate works in typed + /// PSBTs, so the encoding boundary lives here. + pub async fn sign_psbt(&self, network: JadeNetwork, psbt: String) -> Result { + let bytes = STANDARD + .decode(psbt.trim()) + .map_err(|error| JadeError::InvalidPsbt { + error_details: format!("base64 decoding failed: {error}"), + })?; + let parsed = Psbt::deserialize(&bytes).map_err(|error| JadeError::InvalidPsbt { + error_details: format!("parsing failed: {error}"), + })?; + + let mut guard = self.session.lock().await; + let signed = guard + .as_mut() + .ok_or(JadeError::NotConnected)? + .sign_psbt(network, &parsed) + .await?; + Ok(STANDARD.encode(signed.serialize())) + } +} diff --git a/src/modules/jade/lifecycle_tests.rs b/src/modules/jade/lifecycle_tests.rs new file mode 100644 index 0000000..e5096d2 --- /dev/null +++ b/src/modules/jade/lifecycle_tests.rs @@ -0,0 +1,547 @@ +use std::collections::{HashMap, HashSet, VecDeque}; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::sync::{Arc, Condvar, Mutex}; +use std::time::Duration; + +use tokio::sync::Semaphore; + +use super::{ + jade_set_transport_callback, JadeError, JadeManager, JadeNativeDevice, JadeNetwork, + JadeTransportCallback, JadeTransportKind, JadeTransportReadResult, JadeTransportResult, +}; + +#[derive(Default)] +struct NativeState { + open: HashSet, + closed: Vec, + replies: HashMap>>, +} + +struct Callback { + state: Mutex, + hold_replies: AtomicBool, + hold_open: Mutex, + open_gate: Condvar, + hold_close: Mutex, + close_gate: Condvar, + fail_read: AtomicBool, + /// Makes `read_chunk` block for its timeout instead of answering at once, + /// which is where a real Bluetooth transport spends a confirmation. + slow_read: AtomicBool, + reads_after_close: AtomicBool, + only_first_close: AtomicBool, + close_count: AtomicUsize, + closes: Semaphore, + opens: Semaphore, + writes: Semaphore, +} + +impl Callback { + fn new() -> Arc { + let callback = Arc::new(Self { + state: Mutex::new(NativeState::default()), + hold_replies: AtomicBool::new(true), + hold_open: Mutex::new(false), + open_gate: Condvar::new(), + hold_close: Mutex::new(false), + close_gate: Condvar::new(), + fail_read: AtomicBool::new(false), + slow_read: AtomicBool::new(false), + reads_after_close: AtomicBool::new(false), + only_first_close: AtomicBool::new(false), + close_count: AtomicUsize::new(0), + closes: Semaphore::new(0), + opens: Semaphore::new(0), + writes: Semaphore::new(0), + }); + jade_set_transport_callback(callback.clone()); + callback + } + + fn release_open(&self) { + *self.hold_open.lock().unwrap() = false; + self.open_gate.notify_all(); + } + + fn release_close(&self) { + *self.hold_close.lock().unwrap() = false; + self.close_gate.notify_all(); + } + + fn release_replies(&self) { + self.hold_replies.store(false, Ordering::SeqCst); + } + + fn open_paths(&self) -> HashSet { + self.state.lock().unwrap().open.clone() + } +} + +fn success() -> JadeTransportResult { + JadeTransportResult { + success: true, + error: String::new(), + error_code: None, + } +} + +fn reply(data: &[u8]) -> Vec { + let mut decoder = minicbor::Decoder::new(data); + let fields = decoder.map().unwrap().unwrap(); + let mut id = ""; + let mut method = ""; + for _ in 0..fields { + match decoder.str().unwrap() { + "id" => id = decoder.str().unwrap(), + "method" => method = decoder.str().unwrap(), + _ => decoder.skip().unwrap(), + } + } + let mut encoder = minicbor::Encoder::new(Vec::new()); + encoder.map(2).unwrap().str("id").unwrap().str(id).unwrap(); + encoder.str("result").unwrap(); + if method == "get_version_info" { + encoder + .map(2) + .unwrap() + .str("JADE_VERSION") + .unwrap() + .str("1.0.41") + .unwrap() + .str("JADE_STATE") + .unwrap() + .str("READY") + .unwrap(); + } else { + encoder.bool(true).unwrap(); + } + encoder.into_writer() +} + +impl JadeTransportCallback for Callback { + fn scan_devices(&self, _timeout_ms: u32) -> Vec { + Vec::new() + } + + fn open_device(&self, path: String) -> JadeTransportResult { + self.opens.add_permits(1); + let mut hold = self.hold_open.lock().unwrap(); + while *hold { + hold = self.open_gate.wait(hold).unwrap(); + } + self.state.lock().unwrap().open.insert(path); + success() + } + + fn close_device(&self, path: String) -> JadeTransportResult { + let first_close = self.close_count.fetch_add(1, Ordering::SeqCst) == 0; + self.closes.add_permits(1); + let must_wait = first_close || !self.only_first_close.load(Ordering::SeqCst); + let mut hold = self.hold_close.lock().unwrap(); + while *hold && must_wait { + hold = self.close_gate.wait(hold).unwrap(); + } + let mut state = self.state.lock().unwrap(); + state.open.remove(&path); + state.closed.push(path); + success() + } + + fn write_chunk(&self, path: String, data: Vec) -> JadeTransportResult { + self.state + .lock() + .unwrap() + .replies + .entry(path) + .or_default() + .push_back(reply(&data)); + self.writes.add_permits(1); + success() + } + + fn read_chunk(&self, path: String, _timeout_ms: u32) -> JadeTransportReadResult { + if self.slow_read.load(Ordering::SeqCst) { + std::thread::sleep(Duration::from_millis(200)); + } + let released = !self.reads_after_close.load(Ordering::SeqCst) + && !self.state.lock().unwrap().open.contains(&path); + if self.fail_read.load(Ordering::SeqCst) || released { + return JadeTransportReadResult { + success: false, + data: Vec::new(), + error: String::new(), + error_code: Some(super::JadeTransportErrorCode::Disconnected), + }; + } + let data = if self.hold_replies.load(Ordering::SeqCst) { + Vec::new() + } else { + self.state + .lock() + .unwrap() + .replies + .entry(path) + .or_default() + .pop_front() + .unwrap_or_default() + }; + JadeTransportReadResult { + success: true, + data, + error: String::new(), + error_code: None, + } + } + + fn get_chunk_size(&self, _path: String) -> u32 { + 509 + } +} + +async fn wait_for(signal: &Semaphore) { + tokio::time::timeout(Duration::from_secs(2), signal.acquire()) + .await + .unwrap() + .unwrap() + .forget(); +} + +fn connect( + manager: &Arc, + path: &str, +) -> tokio::task::JoinHandle> { + let manager = Arc::clone(manager); + let path = path.to_string(); + tokio::spawn(async move { manager.connect(JadeTransportKind::Bluetooth, &path).await }) +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn disconnect_during_handshake_closes_the_pending_connection() { + let callback = Callback::new(); + let manager = Arc::new(JadeManager::new()); + let connection = connect(&manager, "jade"); + wait_for(&callback.writes).await; + + tokio::time::timeout(Duration::from_secs(1), manager.disconnect()) + .await + .unwrap() + .unwrap(); + callback.release_replies(); + + assert!(matches!( + connection.await.unwrap(), + Err(JadeError::UserCancelled) + )); + assert!(!manager.is_connected()); + assert!(manager.connected_device().await.is_none()); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn cancel_during_handshake_closes_the_pending_connection() { + let callback = Callback::new(); + let manager = Arc::new(JadeManager::new()); + let connection = connect(&manager, "jade"); + wait_for(&callback.writes).await; + + tokio::time::timeout(Duration::from_secs(1), manager.cancel()) + .await + .unwrap() + .unwrap(); + callback.release_replies(); + + assert!(matches!( + connection.await.unwrap(), + Err(JadeError::UserCancelled) + )); + assert!(!manager.is_connected()); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn overlapping_connections_close_the_previous_native_handle() { + let callback = Callback::new(); + let manager = Arc::new(JadeManager::new()); + let first = connect(&manager, "first"); + wait_for(&callback.writes).await; + let second = connect(&manager, "second"); + + // Poll the second connection until it either queues or opens its native handle. + let _ = tokio::time::timeout(Duration::from_millis(50), callback.opens.acquire_many(2)).await; + callback.release_replies(); + first.await.unwrap().unwrap(); + second.await.unwrap().unwrap(); + + assert_eq!(manager.connected_device().await.unwrap().path, "second"); + assert_eq!(callback.open_paths(), HashSet::from(["second".to_string()])); + manager.disconnect().await.unwrap(); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn scan_refuses_to_interrupt_a_pending_handshake() { + let callback = Callback::new(); + let manager = Arc::new(JadeManager::new()); + let connection = connect(&manager, "jade"); + wait_for(&callback.writes).await; + + let result = manager.scan(1).await; + manager.disconnect().await.unwrap(); + callback.release_replies(); + let _ = connection.await.unwrap(); + assert!(matches!(result, Err(JadeError::DeviceBusy))); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn disconnect_waits_for_native_open_and_closes_its_result() { + let callback = Callback::new(); + *callback.hold_open.lock().unwrap() = true; + let manager = Arc::new(JadeManager::new()); + let connection = connect(&manager, "jade"); + wait_for(&callback.opens).await; + + let disconnect = manager.disconnect(); + tokio::pin!(disconnect); + assert!( + tokio::time::timeout(Duration::from_millis(20), &mut disconnect) + .await + .is_err() + ); + callback.release_open(); + disconnect.await.unwrap(); + + assert!(matches!( + connection.await.unwrap(), + Err(JadeError::UserCancelled) + )); + assert!(!manager.is_connected()); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn disconnect_invalidates_a_connection_queued_behind_native_open() { + let callback = Callback::new(); + *callback.hold_open.lock().unwrap() = true; + let manager = Arc::new(JadeManager::new()); + let first = connect(&manager, "first"); + wait_for(&callback.opens).await; + let second = manager.connect(JadeTransportKind::Bluetooth, "second"); + tokio::pin!(second); + let queued = tokio::time::timeout(Duration::from_millis(20), &mut second) + .await + .is_err(); + let disconnect = manager.disconnect(); + tokio::pin!(disconnect); + let waiting = tokio::time::timeout(Duration::from_millis(20), &mut disconnect) + .await + .is_err(); + callback.release_open(); + + assert!(queued && waiting); + assert!(matches!( + first.await.unwrap(), + Err(JadeError::UserCancelled) + )); + assert!(matches!(second.await, Err(JadeError::UserCancelled))); + disconnect.await.unwrap(); + assert_eq!(callback.opens.available_permits(), 0); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn cancellation_during_previous_teardown_does_not_open_a_replacement() { + let callback = Callback::new(); + callback.release_replies(); + let manager = Arc::new(JadeManager::new()); + connect(&manager, "first").await.unwrap().unwrap(); + wait_for(&callback.opens).await; + *callback.hold_close.lock().unwrap() = true; + let replacement = connect(&manager, "second"); + wait_for(&callback.closes).await; + + let cancel = manager.cancel(); + tokio::pin!(cancel); + let waiting = tokio::time::timeout(Duration::from_millis(20), &mut cancel) + .await + .is_err(); + callback.release_close(); + + assert!(waiting); + assert!(matches!( + replacement.await.unwrap(), + Err(JadeError::UserCancelled) + )); + cancel.await.unwrap(); + assert_eq!(callback.opens.available_permits(), 0); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn cancellation_waits_for_failed_handshake_cleanup_before_reconnecting() { + let callback = Callback::new(); + callback.fail_read.store(true, Ordering::SeqCst); + callback.only_first_close.store(true, Ordering::SeqCst); + *callback.hold_close.lock().unwrap() = true; + let manager = Arc::new(JadeManager::new()); + let first = connect(&manager, "jade"); + wait_for(&callback.closes).await; + wait_for(&callback.opens).await; + + let cancel = manager.cancel(); + tokio::pin!(cancel); + let waiting = tokio::time::timeout(Duration::from_millis(20), &mut cancel) + .await + .is_err(); + callback.fail_read.store(false, Ordering::SeqCst); + callback.release_replies(); + let replacement = connect(&manager, "jade"); + let opened_early = tokio::time::timeout(Duration::from_millis(20), callback.opens.acquire()) + .await + .is_ok(); + callback.release_close(); + + assert!(waiting && !opened_early); + assert!(matches!( + first.await.unwrap(), + Err(JadeError::UserCancelled) + )); + cancel.await.unwrap(); + replacement.await.unwrap().unwrap(); + assert_eq!(callback.open_paths(), HashSet::from(["jade".to_string()])); + manager.disconnect().await.unwrap(); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn disconnect_does_not_wait_for_a_native_layer_that_keeps_reading_after_close() { + let callback = Callback::new(); + callback.reads_after_close.store(true, Ordering::SeqCst); + let manager = Arc::new(JadeManager::new()); + let connection = connect(&manager, "jade"); + wait_for(&callback.writes).await; + + tokio::time::timeout(Duration::from_secs(1), manager.disconnect()) + .await + .unwrap() + .unwrap(); + + assert!(matches!( + connection.await.unwrap(), + Err(JadeError::UserCancelled) + )); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn native_disconnect_clears_only_the_connected_path() { + let callback = Callback::new(); + callback.release_replies(); + let manager = Arc::new(JadeManager::new()); + connect(&manager, "jade").await.unwrap().unwrap(); + + manager.notify_disconnected("other").await; + assert!(manager.is_connected()); + assert!(manager.version_info().await.is_some()); + + manager.notify_disconnected("jade").await; + assert!(!manager.is_connected()); + assert!(manager.connected_device().await.is_none()); + assert!(manager.version_info().await.is_none()); + assert!(callback.open_paths().is_empty()); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn version_info_does_not_wait_for_an_operation_in_flight() { + let callback = Callback::new(); + callback.release_replies(); + let manager = Arc::new(JadeManager::new()); + connect(&manager, "jade").await.unwrap().unwrap(); + callback.hold_replies.store(true, Ordering::SeqCst); + callback.writes.forget_permits(usize::MAX); + let ping = { + let manager = Arc::clone(&manager); + tokio::spawn(async move { manager.ping().await }) + }; + wait_for(&callback.writes).await; + + let version = tokio::time::timeout(Duration::from_millis(200), manager.version_info()) + .await + .unwrap() + .unwrap(); + + assert_eq!(version.jade_version, "1.0.41"); + manager.disconnect().await.unwrap(); + assert!(ping.await.unwrap().is_err()); +} + +#[tokio::test] +async fn malformed_base64_psbt_is_rejected_before_reaching_the_device() { + let manager = JadeManager::new(); + + let result = manager + .sign_psbt(JadeNetwork::Regtest, "not a psbt!".to_string()) + .await; + + assert!(matches!(result, Err(JadeError::InvalidPsbt { .. }))); +} + +/// Start a ping and wait until its request has reached the native layer. +fn ping_in_flight( + manager: &Arc, +) -> tokio::task::JoinHandle> { + let manager = Arc::clone(manager); + tokio::spawn(async move { manager.ping().await }) +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn cancel_reports_user_cancelled_when_the_read_loop_is_idle() { + let callback = Callback::new(); + callback.release_replies(); + let manager = Arc::new(JadeManager::new()); + connect(&manager, "jade").await.unwrap().unwrap(); + callback.hold_replies.store(true, Ordering::SeqCst); + callback.writes.forget_permits(usize::MAX); + let ping = ping_in_flight(&manager); + wait_for(&callback.writes).await; + + manager.cancel().await.unwrap(); + + assert!(matches!(ping.await.unwrap(), Err(JadeError::UserCancelled))); +} + +#[tokio::test] +#[serial_test::serial(jade_callback)] +async fn cancel_reports_user_cancelled_when_it_lands_inside_a_read() { + // The other timing. A cancel closes the link as well as setting the abort + // flag, so a loop parked inside `read_chunk` sees the close first. That is + // where a real Bluetooth transport spends most of a confirmation, because it + // honours `timeout_ms`, and jade-client-rs 0.2.0 prefers the flag so both + // paths agree. Against 0.1.0 this returned `DeviceDisconnected`. + let callback = Callback::new(); + callback.release_replies(); + let manager = Arc::new(JadeManager::new()); + connect(&manager, "jade").await.unwrap().unwrap(); + callback.hold_replies.store(true, Ordering::SeqCst); + callback.writes.forget_permits(usize::MAX); + let ping = ping_in_flight(&manager); + wait_for(&callback.writes).await; + + // Only now, so the handshake above is not slowed down too. + callback.slow_read.store(true, Ordering::SeqCst); + tokio::time::sleep(Duration::from_millis(60)).await; + manager.cancel().await.unwrap(); + + assert!(matches!(ping.await.unwrap(), Err(JadeError::UserCancelled))); +} diff --git a/src/modules/jade/mod.rs b/src/modules/jade/mod.rs new file mode 100644 index 0000000..737d9b5 --- /dev/null +++ b/src/modules/jade/mod.rs @@ -0,0 +1,31 @@ +//! Blockstream Jade hardware wallet integration. +//! +//! The protocol lives in the `jade-client-rs` crate. This module is the FFI +//! adapter: it attaches UniFFI scaffolding to that crate's types, exposes the +//! transport contract the native application implements, and owns the session +//! state a free-function FFI surface implies. +//! +//! One hard rule for anything added here: no `#[uniffi::export]` item may be +//! `cfg` gated. All three build scripts generate bindings from the host library +//! rather than the target one, so a host only export would appear in the +//! generated Swift and Kotlin while being absent from the device library. + +mod callbacks; +mod implementation; +#[cfg(test)] +mod lifecycle_tests; +#[cfg(test)] +mod tests; +mod types; + +pub use callbacks::{ + jade_set_transport_callback, JadeNativeDevice, JadeTransportCallback, JadeTransportReadResult, + JadeTransportResult, +}; +pub use implementation::JadeManager; +pub(crate) use types::account_type_to_variant; +pub use types::{ + JadeAccount, JadeAccountExport, JadeAddressVariant, JadeDeviceInfo, JadeError, JadeNetwork, + JadePingStatus, JadeSignedMessage, JadeState, JadeTransportErrorCode, JadeTransportKind, + JadeVersionInfo, JadeXpubResponse, +}; diff --git a/src/modules/jade/tests.rs b/src/modules/jade/tests.rs new file mode 100644 index 0000000..b9f9de5 --- /dev/null +++ b/src/modules/jade/tests.rs @@ -0,0 +1,275 @@ +//! Tests for the FFI adapter. +//! +//! Protocol level behaviour (framing, correlation, the unlock exchange, PSBT +//! checks) is tested in the `jade-client-rs` crate. What is left here is the +//! adapter: the account type mapping, and the bridge from the foreign callback +//! onto the crate's transport trait. + +use super::callbacks::{ + CallbackTransport, JadeNativeDevice, JadeTransportCallback, JadeTransportReadResult, + JadeTransportResult, +}; +use super::types::{account_type_to_variant, JadeAddressVariant, JadeTransportKind}; +use crate::onchain::AccountType; +use jade_client_rs::{JadeError, JadeTransport, MAX_CHUNK_BYTES}; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +#[test] +fn account_types_map_to_descriptor_variants() { + let cases = [ + (AccountType::Legacy, JadeAddressVariant::Pkh), + (AccountType::WrappedSegwit, JadeAddressVariant::ShWpkh), + (AccountType::NativeSegwit, JadeAddressVariant::Wpkh), + (AccountType::Taproot, JadeAddressVariant::Tr), + ]; + for (account_type, expected) in cases { + assert_eq!(account_type_to_variant(account_type), expected); + } +} + +/// A callback that records what it was asked to do. +struct MockCallback { + chunk_size: u32, + writes: Mutex>>, + reads: Mutex>>, + fail_write: bool, +} + +impl MockCallback { + fn with_chunk_size(chunk_size: u32) -> Arc { + Arc::new(Self { + chunk_size, + writes: Mutex::new(Vec::new()), + reads: Mutex::new(Vec::new()), + fail_write: false, + }) + } + + fn failing() -> Arc { + Arc::new(Self { + chunk_size: 64, + writes: Mutex::new(Vec::new()), + reads: Mutex::new(Vec::new()), + fail_write: true, + }) + } +} + +impl JadeTransportCallback for MockCallback { + fn scan_devices(&self, _timeout_ms: u32) -> Vec { + vec![JadeNativeDevice { + path: "AA:BB:CC:DD:EE:FF".to_string(), + transport: JadeTransportKind::Bluetooth, + name: Some("Jade C0FFEE".to_string()), + serial_number: Some("C0FFEE".to_string()), + }] + } + + fn open_device(&self, _path: String) -> JadeTransportResult { + JadeTransportResult { + success: true, + error: String::new(), + error_code: None, + } + } + + fn close_device(&self, _path: String) -> JadeTransportResult { + JadeTransportResult { + success: true, + error: String::new(), + error_code: None, + } + } + + fn write_chunk(&self, _path: String, data: Vec) -> JadeTransportResult { + if self.fail_write { + return JadeTransportResult { + success: false, + error: "device went away".to_string(), + error_code: Some(jade_client_rs::JadeTransportErrorCode::Disconnected), + }; + } + self.writes.lock().unwrap().push(data); + JadeTransportResult { + success: true, + error: String::new(), + error_code: None, + } + } + + fn read_chunk(&self, _path: String, _timeout_ms: u32) -> JadeTransportReadResult { + let data = self.reads.lock().unwrap().pop().unwrap_or_default(); + JadeTransportReadResult { + success: true, + data, + error: String::new(), + error_code: None, + } + } + + fn get_chunk_size(&self, _path: String) -> u32 { + self.chunk_size + } +} + +#[tokio::test] +async fn writes_are_split_at_the_reported_chunk_size() { + let callback = MockCallback::with_chunk_size(4); + let transport = CallbackTransport::new(Arc::clone(&callback) as Arc<_>, "path".to_string()); + + transport + .write_all(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]) + .await + .unwrap(); + + let writes = callback.writes.lock().unwrap(); + assert_eq!(writes.len(), 3); + assert_eq!(writes[0], vec![1, 2, 3, 4]); + assert_eq!(writes[1], vec![5, 6, 7, 8]); + assert_eq!(writes[2], vec![9]); +} + +#[tokio::test] +async fn a_zero_chunk_size_does_not_stall_the_write_loop() { + // A native implementation can report 0 before the MTU is negotiated. + // Without clamping, chunks(0) panics and the loop never advances. + let callback = MockCallback::with_chunk_size(0); + let transport = CallbackTransport::new(Arc::clone(&callback) as Arc<_>, "path".to_string()); + + transport.write_all(vec![1, 2, 3]).await.unwrap(); + + let writes = callback.writes.lock().unwrap(); + assert_eq!( + writes.len(), + 3, + "a clamped size of 1 sends one byte per write" + ); +} + +#[tokio::test] +async fn an_oversized_chunk_size_is_capped_to_the_bluetooth_limit() { + let callback = MockCallback::with_chunk_size(100_000); + let transport = CallbackTransport::new(Arc::clone(&callback) as Arc<_>, "path".to_string()); + + let payload = vec![7u8; MAX_CHUNK_BYTES as usize + 10]; + transport.write_all(payload).await.unwrap(); + + let writes = callback.writes.lock().unwrap(); + assert_eq!(writes.len(), 2); + assert_eq!(writes[0].len(), MAX_CHUNK_BYTES as usize); + assert_eq!(writes[1].len(), 10); +} + +#[tokio::test] +async fn a_typed_transport_error_survives_the_bridge() { + // The trezor adapter has to encode its error code into a string and parse it + // back out, because its upstream crate offers no typed channel. This one + // carries the code the whole way, so the mapping is exact. + let callback = MockCallback::failing(); + let transport = CallbackTransport::new(callback as Arc<_>, "path".to_string()); + + let error = transport.write_all(vec![1]).await.unwrap_err(); + assert_eq!(error, JadeError::DeviceDisconnected); +} + +#[tokio::test] +async fn an_empty_read_is_not_an_error() { + // Success with no data means "nothing yet", which is the normal state while + // the user is deciding on the device. + let callback = MockCallback::with_chunk_size(64); + let transport = CallbackTransport::new(callback as Arc<_>, "path".to_string()); + + let data = transport + .read_some(Duration::from_millis(10)) + .await + .unwrap(); + assert!(data.is_empty()); +} + +/// A callback whose `read_chunk` parks until the test releases it, so a close +/// can land while a read is already inside the native layer. +struct BlockingReadCallback { + started: Mutex>>, + release: Mutex>>, +} + +impl JadeTransportCallback for BlockingReadCallback { + fn scan_devices(&self, _timeout_ms: u32) -> Vec { + Vec::new() + } + + fn open_device(&self, _path: String) -> JadeTransportResult { + JadeTransportResult { + success: true, + error: String::new(), + error_code: None, + } + } + + fn close_device(&self, _path: String) -> JadeTransportResult { + JadeTransportResult { + success: true, + error: String::new(), + error_code: None, + } + } + + fn write_chunk(&self, _path: String, _data: Vec) -> JadeTransportResult { + JadeTransportResult { + success: true, + error: String::new(), + error_code: None, + } + } + + fn read_chunk(&self, _path: String, _timeout_ms: u32) -> JadeTransportReadResult { + let started = self.started.lock().unwrap().take().expect("one read only"); + started.send(()).unwrap(); + let release = self.release.lock().unwrap().take().expect("one read only"); + release.recv().unwrap(); + JadeTransportReadResult { + success: true, + data: vec![1, 2, 3], + error: String::new(), + error_code: None, + } + } + + fn get_chunk_size(&self, _path: String) -> u32 { + 64 + } +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn bytes_arriving_after_close_are_discarded() { + // `close` cannot interrupt a `read_chunk` that is already inside the native + // layer, so the guard has to run after the callback returns too. Otherwise a + // read that completes for a released path feeds its bytes back to the + // parser. + let (started_tx, started_rx) = std::sync::mpsc::channel(); + let (release_tx, release_rx) = std::sync::mpsc::channel(); + let callback = Arc::new(BlockingReadCallback { + started: Mutex::new(Some(started_tx)), + release: Mutex::new(Some(release_rx)), + }); + let transport = Arc::new(CallbackTransport::new( + callback as Arc<_>, + "path".to_string(), + )); + + let reader = tokio::spawn({ + let transport = Arc::clone(&transport); + async move { transport.read_some(Duration::from_millis(250)).await } + }); + + // Only close once the read is parked inside the callback. + tokio::task::spawn_blocking(move || started_rx.recv().unwrap()) + .await + .unwrap(); + transport.close().await.unwrap(); + release_tx.send(()).unwrap(); + + let error = reader.await.unwrap().unwrap_err(); + assert_eq!(error, JadeError::DeviceDisconnected); +} diff --git a/src/modules/jade/types.rs b/src/modules/jade/types.rs new file mode 100644 index 0000000..fdac7f1 --- /dev/null +++ b/src/modules/jade/types.rs @@ -0,0 +1,156 @@ +//! UniFFI scaffolding for the `jade-client-rs` types. +//! +//! Every type here is defined in that crate, not this one. `#[uniffi::remote]` +//! attaches the same scaffolding `#[derive(uniffi::…)]` would, without a +//! mirrored set of structs and hand-written `From` conversions in both +//! directions. The trezor module predates this and pays that cost; this module +//! does not. +//! +//! The declarations below must match the upstream definitions variant for +//! variant and field for field. The compiler catches a mismatch, and the tests +//! in `tests.rs` exercise the round trip. + +pub use jade_client_rs::{ + JadeAccount, JadeAccountExport, JadeAddressVariant, JadeDeviceInfo, JadeError, JadeNetwork, + JadePingStatus, JadeSignedMessage, JadeState, JadeTransportErrorCode, JadeTransportKind, + JadeVersionInfo, JadeXpubResponse, +}; + +use crate::onchain::AccountType; + +#[uniffi::remote(Enum)] +pub enum JadeNetwork { + Mainnet, + Testnet, + Regtest, +} + +#[uniffi::remote(Enum)] +pub enum JadeTransportKind { + Bluetooth, + Serial, +} + +#[uniffi::remote(Enum)] +pub enum JadeAddressVariant { + Pkh, + Wpkh, + ShWpkh, + Tr, +} + +#[uniffi::remote(Enum)] +pub enum JadeState { + Uninit, + Unsaved, + Locked, + Ready, + Temp, + Unknown, +} + +#[uniffi::remote(Enum)] +pub enum JadePingStatus { + Idle, + Busy, + AwaitingUserInput, +} + +#[uniffi::remote(Enum)] +pub enum JadeTransportErrorCode { + DeviceBusy, + NotConnected, + Disconnected, + Timeout, + PermissionDenied, +} + +#[uniffi::remote(Record)] +pub struct JadeDeviceInfo { + pub path: String, + pub transport: JadeTransportKind, + pub name: Option, + pub serial_number: Option, +} + +#[uniffi::remote(Record)] +pub struct JadeVersionInfo { + pub jade_version: String, + pub jade_state: JadeState, + pub jade_networks: Option, + pub jade_has_pin: Option, + pub board_type: Option, + pub jade_config: Option, + pub jade_features: Option, + pub idf_version: Option, + pub chip_features: Option, + pub efuse_mac: Option, + pub battery_status: Option, + pub jade_ota_max_chunk: Option, +} + +#[uniffi::remote(Record)] +pub struct JadeXpubResponse { + pub xpub: String, + pub derivation_path: String, + pub master_fingerprint: String, +} + +#[uniffi::remote(Record)] +pub struct JadeAccount { + pub variant: JadeAddressVariant, + pub xpub: String, + pub derivation_path: String, +} + +#[uniffi::remote(Record)] +pub struct JadeAccountExport { + pub master_fingerprint: String, + pub account_index: u32, + pub accounts: Vec, +} + +#[uniffi::remote(Record)] +pub struct JadeSignedMessage { + pub signature: String, + pub address: String, + pub derivation_path: String, +} + +#[uniffi::remote(Error)] +pub enum JadeError { + TransportError { error_details: String }, + DeviceNotFound, + DeviceDisconnected, + DeviceBusy, + NotConnected, + NotInitialized, + ConnectionError { error_details: String }, + ProtocolError { error_details: String }, + Timeout, + UserCancelled, + DeviceLocked, + DeviceUninitialized, + InvalidPin, + NetworkMismatch { error_details: String }, + UnsupportedFirmware { installed: String, required: String }, + InvalidPath { error_details: String }, + InvalidPsbt { error_details: String }, + PsbtTooLarge { size: u64, max: u64 }, + FingerprintMismatch { device: String, psbt: String }, + NothingSigned, + AddressMismatch { expected: String, returned: String }, + PinServerError { error_details: String }, + DeviceError { error_details: String }, + IoError { error_details: String }, +} + +/// Map the signer-neutral account type onto Jade's descriptor variant. +pub(crate) fn account_type_to_variant(account_type: AccountType) -> JadeAddressVariant { + match account_type { + AccountType::Legacy => JadeAddressVariant::Pkh, + AccountType::WrappedSegwit => JadeAddressVariant::ShWpkh, + AccountType::NativeSegwit => JadeAddressVariant::Wpkh, + AccountType::Taproot => JadeAddressVariant::Tr, + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 3872dc2..33dc643 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -2,6 +2,7 @@ pub mod activity; pub mod blocktank; pub mod boltz; pub mod hardware_wallet; +pub mod jade; pub mod lnurl; pub mod onchain; pub mod pubky; diff --git a/src/modules/onchain/psbt.rs b/src/modules/onchain/psbt.rs index 0cf85d4..76e10e2 100644 --- a/src/modules/onchain/psbt.rs +++ b/src/modules/onchain/psbt.rs @@ -2,6 +2,9 @@ use base64::{engine::general_purpose::STANDARD, Engine}; use bitcoin::consensus::encode::serialize_hex; use bitcoin::psbt::Psbt; use bitcoin::secp256k1::Secp256k1; +use bitcoin::sighash::{EcdsaSighashType, TapSighashType}; +use bitcoin::{ScriptBuf, Witness}; +use miniscript::interpreter::{Interpreter, KeySigPair, SatisfiedConstraint}; use miniscript::psbt::{interpreter_check, PsbtExt}; use super::{CompletedTransaction, PsbtCompletionError}; @@ -35,6 +38,7 @@ pub fn finalize_psbt( reason: error.to_string(), } })?; + validate_signature_hash_types(&combined)?; let transaction = combined @@ -74,6 +78,70 @@ fn validate_signed_input_metadata( Ok(()) } +/// Reject any signature that does not commit to every input and output. +/// +/// `interpreter_check` verifies each signature under the sighash type the +/// signature itself carries, so a signer could return a valid `SIGHASH_NONE` or +/// `ANYONECANPAY` signature and leave the outputs open to rewriting after +/// broadcast. This walks the finalized satisfaction instead of the partial +/// signature fields, so a signer that returns already finalized inputs is +/// covered too. +fn validate_signature_hash_types(psbt: &Psbt) -> Result<(), PsbtCompletionError> { + let empty_script_sig = ScriptBuf::new(); + let empty_witness = Witness::default(); + for (index, input) in psbt.inputs.iter().enumerate() { + let script_pubkey = previous_output(psbt, index, "finalized")? + .map(|output| output.script_pubkey.clone()) + .ok_or_else(|| PsbtCompletionError::VerificationFailed { + reason: format!("finalized PSBT input {index} has no previous output"), + })?; + let script_sig = input + .final_script_sig + .as_deref() + .unwrap_or(&empty_script_sig); + let witness = input + .final_script_witness + .as_ref() + .unwrap_or(&empty_witness); + let interpreter = Interpreter::from_txdata( + &script_pubkey, + script_sig, + witness, + psbt.unsigned_tx.input[index].sequence, + psbt.unsigned_tx.lock_time, + ) + .map_err(|error| PsbtCompletionError::VerificationFailed { + reason: format!("input {index}: {error}"), + })?; + + for constraint in interpreter.iter_assume_sigs() { + let key_sig = + match constraint.map_err(|error| PsbtCompletionError::VerificationFailed { + reason: format!("input {index}: {error}"), + })? { + SatisfiedConstraint::PublicKey { key_sig } + | SatisfiedConstraint::PublicKeyHash { key_sig, .. } => key_sig, + _ => continue, + }; + let commits_to_transaction = match key_sig { + KeySigPair::Ecdsa(_, signature) => signature.sighash_type == EcdsaSighashType::All, + KeySigPair::Schnorr(_, signature) => matches!( + signature.sighash_type, + TapSighashType::Default | TapSighashType::All + ), + }; + if !commits_to_transaction { + return Err(PsbtCompletionError::VerificationFailed { + reason: format!( + "input {index} signature does not commit to the whole transaction" + ), + }); + } + } + } + Ok(()) +} + fn previous_output<'a>( psbt: &'a Psbt, index: usize, @@ -134,12 +202,13 @@ mod tests { use super::*; use bitcoin::absolute::LockTime; use bitcoin::hashes::Hash; - use bitcoin::key::CompressedPublicKey; + use bitcoin::key::{CompressedPublicKey, Keypair, TapTweak}; use bitcoin::secp256k1::{Message, SecretKey}; - use bitcoin::sighash::{EcdsaSighashType, SighashCache}; + use bitcoin::sighash::{Prevouts, SighashCache}; use bitcoin::transaction::Version; use bitcoin::{ - ecdsa, Address, Amount, Network, OutPoint, Sequence, Transaction, TxIn, TxOut, Txid, + ecdsa, taproot, Address, Amount, Network, OutPoint, Sequence, Transaction, TxIn, TxOut, + Txid, }; #[test] @@ -203,7 +272,49 @@ mod tests { assert!(matches!(error, PsbtCompletionError::CombineFailed { .. })); } + #[test] + fn rejects_ecdsa_signature_that_does_not_commit_to_outputs() { + let (original, signed) = native_segwit_psbts_with_sighash(EcdsaSighashType::None); + + let error = finalize_psbt(original, signed).unwrap_err(); + + assert!(matches!( + error, + PsbtCompletionError::VerificationFailed { reason } + if reason.contains("does not commit to the whole transaction") + )); + } + + #[test] + fn finalizes_taproot_key_spend_psbt() { + let (original, signed) = taproot_psbts(TapSighashType::Default); + + let completed = finalize_psbt(original, signed).unwrap(); + let transaction: Transaction = + bitcoin::consensus::deserialize(&hex::decode(&completed.serialized_tx).unwrap()) + .unwrap(); + + assert_eq!(transaction.input[0].witness.len(), 1); + } + + #[test] + fn rejects_taproot_signature_that_does_not_commit_to_outputs() { + let (original, signed) = taproot_psbts(TapSighashType::NonePlusAnyoneCanPay); + + let error = finalize_psbt(original, signed).unwrap_err(); + + assert!(matches!( + error, + PsbtCompletionError::VerificationFailed { reason } + if reason.contains("does not commit to the whole transaction") + )); + } + fn native_segwit_psbts() -> (String, String) { + native_segwit_psbts_with_sighash(EcdsaSighashType::All) + } + + fn native_segwit_psbts_with_sighash(sighash_type: EcdsaSighashType) -> (String, String) { let secp = Secp256k1::new(); let secret_key = SecretKey::from_slice(&[1; 32]).unwrap(); let public_key = bitcoin::PublicKey::new(secret_key.public_key(&secp)); @@ -230,7 +341,6 @@ mod tests { signed.inputs[0].witness_utxo = Some(spent_output.clone()); let original = signed.clone(); - let sighash_type = EcdsaSighashType::All; let sighash = SighashCache::new(&signed.unsigned_tx) .p2wpkh_signature_hash( 0, @@ -252,6 +362,48 @@ mod tests { (encode_psbt(&original), encode_psbt(&signed)) } + fn taproot_psbts(sighash_type: TapSighashType) -> (String, String) { + let secp = Secp256k1::new(); + let keypair = Keypair::from_secret_key(&secp, &SecretKey::from_slice(&[3; 32]).unwrap()); + let (internal_key, _) = keypair.x_only_public_key(); + let script_pubkey = + Address::p2tr(&secp, internal_key, None, Network::Regtest).script_pubkey(); + let spent_output = TxOut { + value: Amount::from_sat(50_000), + script_pubkey: script_pubkey.clone(), + }; + let transaction = Transaction { + version: Version::TWO, + lock_time: LockTime::ZERO, + input: vec![TxIn { + previous_output: OutPoint::new(Txid::all_zeros(), 0), + sequence: Sequence::ENABLE_RBF_NO_LOCKTIME, + ..Default::default() + }], + output: vec![TxOut { + value: Amount::from_sat(49_000), + script_pubkey, + }], + }; + let mut signed = Psbt::from_unsigned_tx(transaction).unwrap(); + signed.inputs[0].witness_utxo = Some(spent_output.clone()); + signed.inputs[0].tap_internal_key = Some(internal_key); + let original = signed.clone(); + + let sighash = SighashCache::new(&signed.unsigned_tx) + .taproot_key_spend_signature_hash(0, &Prevouts::All(&[spent_output]), sighash_type) + .unwrap(); + let tweaked = keypair.tap_tweak(&secp, None).to_inner(); + let signature = + secp.sign_schnorr_no_aux_rand(&Message::from_digest(sighash.to_byte_array()), &tweaked); + signed.inputs[0].tap_key_sig = Some(taproot::Signature { + signature, + sighash_type, + }); + + (encode_psbt(&original), encode_psbt(&signed)) + } + fn legacy_psbts_with_substituted_previous_output() -> (String, String) { let secp = Secp256k1::new(); let original_key =