Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
abe3f67
feat(jade): add Blockstream Jade hardware wallet support
coreyphillips Sep 3, 2026
15fb378
refactor(jade): move the protocol into the jade-client-rs crate
coreyphillips Sep 3, 2026
8414ec0
chore(jade): bump the jade-client-rs pin to d55fafb
coreyphillips Sep 4, 2026
4725a8a
feat(jade): connect to a path the last scan did not report
coreyphillips Sep 7, 2026
b5b681e
chore(jade): bump the jade-client-rs pin to 247c22f
coreyphillips Sep 7, 2026
2827c92
chore: prepare 0.5.15 artifacts
coreyphillips Sep 7, 2026
25e207a
chore(jade): update client pin
coreyphillips Sep 9, 2026
6e116c1
fix(jade): serialize connection setup and teardown
coreyphillips Sep 14, 2026
bd1f55d
chore: update jade-client-rs repo
coreyphillips Sep 15, 2026
c2bd7d9
chore: update jade-client-rs repo
coreyphillips Sep 15, 2026
9d1486f
chore: prepare 0.5.16 artifacts
coreyphillips Sep 15, 2026
43c3ffd
ci: install only platform-tools in android publish
coreyphillips Sep 15, 2026
74efa46
fix(jade): address review feedback
coreyphillips Sep 15, 2026
a8e0b99
fix(jade): address second round of review feedback
coreyphillips Sep 16, 2026
76eebaf
Merge branch 'master' into feat/jade-hardware-wallet
coreyphillips Sep 16, 2026
9a53bf3
style: apply rustfmt to backup_migration tests
coreyphillips Sep 16, 2026
6644a83
fix(ios): regenerate the Swift interface after the doc changes
coreyphillips Sep 16, 2026
9f794a6
fix(jade): correct the documented error for a cancelled operation
coreyphillips Sep 16, 2026
d6d415b
chore(jade): pull in jade-client-rs 0.2.0 for the cancellation fix
coreyphillips Sep 16, 2026
9724efd
chore: bump version to 0.5.17
coreyphillips Sep 16, 2026
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
29 changes: 27 additions & 2 deletions .github/workflows/gradle-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
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
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Loading
Loading