From d142ae6117cd664d8e471ceb16b85c904f3f2352 Mon Sep 17 00:00:00 2001 From: frijolo Date: Sun, 15 Mar 2026 19:59:41 +0100 Subject: [PATCH 1/2] feat: expose custom transport API via from_transport() Add a public BitBox::from_transport() that accepts any communication::ReadWrite implementation and performs the U2F-HID framing internally. This lets callers delegate raw USB I/O to platform-specific code (e.g. Android, where USB access requires Java APIs unavailable to hidapi) by implementing only the ReadWrite trait over their transport. - Make the communication module public to expose the ReadWrite trait and Error. - Remove the feature gate on FIRMWARE_CMD so from_transport (available without the usb/wasm/simulator features) can perform the framing. --- src/communication.rs | 1 - src/lib.rs | 34 +++++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/communication.rs b/src/communication.rs index 393148d..7be601f 100644 --- a/src/communication.rs +++ b/src/communication.rs @@ -6,7 +6,6 @@ use crate::util::Threading; use async_trait::async_trait; use thiserror::Error; -#[cfg(any(feature = "wasm", feature = "usb", feature = "simulator"))] pub const FIRMWARE_CMD: u8 = 0x80 + 0x40 + 0x01; #[derive(Error, Debug)] diff --git a/src/lib.rs b/src/lib.rs index e837f27..e3968e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,7 @@ pub use util::Threading; use communication::HwwCommunication; pub use communication::Product; +pub use communication::{Error as CommunicationError, ReadWrite}; const OP_I_CAN_HAS_HANDSHAEK: u8 = b'h'; const OP_HER_COMEZ_TEH_HANDSHAEK: u8 = b'H'; @@ -86,6 +87,25 @@ impl BitBox { }) } + /// Creates a new BitBox instance from a custom transport. + /// + /// The `transport` is a raw byte channel to the device (HID reports); this method wraps it + /// in the U2F-HID framing layer internally, so callers only need to implement + /// [`ReadWrite`] over their platform-specific transport. + /// + /// This enables use cases where USB I/O must be delegated to platform-specific code + /// (e.g., Android, where USB access requires Java APIs unavailable to `hidapi`). + pub async fn from_transport( + transport: Box, + noise_config: Box, + ) -> Result, Error> { + let comm = Box::new(communication::U2fHidCommunication::from( + transport, + communication::FIRMWARE_CMD, + )); + Self::from(comm, noise_config).await + } + /// Creates a new BitBox instance. The provided noise config determines how the pairing /// information is persisted. Use `usb::get_any_bitbox02()` to find a BitBox02 HID device. /// @@ -96,11 +116,7 @@ impl BitBox { device: hidapi::HidDevice, noise_config: Box, ) -> Result, Error> { - let comm = Box::new(communication::U2fHidCommunication::from( - Box::new(crate::usb::HidDevice::new(device)), - communication::FIRMWARE_CMD, - )); - Self::from(comm, noise_config).await + Self::from_transport(Box::new(crate::usb::HidDevice::new(device)), noise_config).await } #[cfg(feature = "simulator")] @@ -108,11 +124,11 @@ impl BitBox { endpoint: Option<&str>, noise_config: Box, ) -> Result, Error> { - let comm = Box::new(communication::U2fHidCommunication::from( + Self::from_transport( crate::simulator::try_connect::(endpoint).await?, - communication::FIRMWARE_CMD, - )); - Self::from(comm, noise_config).await + noise_config, + ) + .await } /// Invokes the device unlock and pairing. From 7ce956c254ab6e2011f29b9bdb22bc83384bec8f Mon Sep 17 00:00:00 2001 From: Marko Bencun Date: Sat, 18 Jul 2026 03:30:48 +0200 Subject: [PATCH 2/2] bump version to 0.13.0 --- CHANGELOG-rust.md | 3 +++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-rust.md b/CHANGELOG-rust.md index 3e0b446..c3775e4 100644 --- a/CHANGELOG-rust.md +++ b/CHANGELOG-rust.md @@ -2,6 +2,9 @@ ## [Unreleased] +## 0.13.0 +- Add `BitBox::from_transport()` + ## 0.12.1 - Serialize public API calls that talk to the device to avoid interleaving request/response sequences and breaking the device communication state. diff --git a/Cargo.lock b/Cargo.lock index 0c8bb7c..a4a0770 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,7 +126,7 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "bitbox-api" -version = "0.12.1" +version = "0.13.0" dependencies = [ "async-trait", "base32", diff --git a/Cargo.toml b/Cargo.toml index 1a88103..c4c7de3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bitbox-api" authors = ["Marko Bencun "] -version = "0.12.1" +version = "0.13.0" homepage = "https://bitbox.swiss/" repository = "https://github.com/BitBoxSwiss/bitbox-api-rs/" readme = "README-rust.md"