Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Android bindings are built and published by `.github/workflows/gradle-publish.ym

```bash
cargo test # All tests
cargo test modules::<module> # Single module (scanner, lnurl, onchain, activity, blocktank, trezor, pubky)
cargo test modules::<module> # Single module (scanner, lnurl, onchain, activity, blocktank, boltz, trezor, jade, hardware_wallet, ur, pubky)
```

## Lint & Format
Expand All @@ -35,15 +35,16 @@ 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

## Key Constraints

- **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.

Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

- 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

- Prevent Android ARM32 startup crashes by generating `Int` carriers for direct unsigned 8-bit and 16-bit UniFFI returns while preserving Kotlin unsigned APIs.
Expand Down
125 changes: 125 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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/coreyphillips/jade-client-rs", rev = "d55fafb", 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/coreyphillips/jade-client-rs", rev = "d55fafb", features = ["reqwest-pinserver", "serial"] }

[dev-dependencies]
tokio = { version = "1.40.0", features = ["full"] }
serde_json = "1.0.114"
Expand Down
Loading