fix(android): show BitBox pairing code simultaneously (unblock serial MethodChannel queue)#26
Merged
TaprootFreak merged 9 commits intoJun 9, 2026
Conversation
Release: develop -> main
Release: develop -> main
Release: develop -> main
Release: develop -> main
Release: develop -> main
Release: develop -> main
Release: develop -> main
Release: develop -> main
…ueue Run the blocking Api.initDevice() (Noise pairing handshake) on its own thread so the serial bitbox_usb MethodChannel task queue stays free. Previously init occupied the single queue for the whole on-device confirmation wait, so the concurrent getChannelHash poll could not run until after the user confirmed on the BitBox — making the pairing code appear in the app only after device confirmation. iOS already dispatches init to a background queue and was unaffected. Other device operations remain serial, preserving noise nonce order. Also propagate the real initDevice() result instead of always returning true.
This was referenced Jun 9, 2026
TaprootFreak
added a commit
to RealUnitCH/app
that referenced
this pull request
Jun 9, 2026
## Summary Bumps the `bitbox_flutter` dependency from `v0.0.7` to `v0.0.8`. `v0.0.8` contains the Android pairing-code fix (DFXswiss/bitbox_flutter#26): `initBitBox` now runs off the serial MethodChannel task queue, so the BitBox pairing code (channel hash) appears in the app and on the device **simultaneously**, instead of only after confirming on the device. iOS was already unaffected. ## Test plan - [ ] `flutter pub get` resolves `bitbox_flutter v0.0.8` - [ ] Android BitBox pairing: pairing code shows in-app at the same time as on the device (before on-device confirmation) - [ ] Existing BitBox flows (connect / sign) unaffected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Android, during BitBox pairing the channel-hash (pairing code) appeared in the
app only after the user confirmed on the device — not simultaneously. iOS was
unaffected and showed the code on app and device at the same time.
Root cause
The
bitbox_usbMethodChannel is bound to a serial background task queue(
makeBackgroundTaskQueue()inBitboxFlutterPlugin.kt).InitBitBoxOperationcalled
Api.initDevice()synchronously on that queue.Init()runs the Noise XXhandshake and then blocks until the on-device pairing confirmation
(
bitbox02-api-gopairing.go: the channel hash is stored before this blockingrawQuery, then the call waits). Because the queue is serial, the concurrentgetChannelHashpoll from the app could not be serviced untilinitBitBoxreturned —i.e. only after the user confirmed on the device. Hence the code showed device-first.
iOS does not hit this because it dispatches
initBitBoxto a background queue whilekeeping
getChannelHashlightweight, so the host reads the hash during the wait.Fix
Run the blocking
Api.initDevice()on its own thread so the serial MethodChannelqueue stays free and
getChannelHashis serviced while init is in flight. The pairingcode now appears on app and device simultaneously. All other device operations remain
on the serial queue, preserving the single noise-cipher nonce ordering. This mirrors
the existing async-reply pattern already used by
RequestPermissionOperation.initBitBoxnow also propagates the realApi.initDevice()result instead of alwaysreturning
true(consistent with the iOS implementation).Android-only change; no Go/native rebuild required.
Testing
flutter analyze+flutter pub getgreen (consumed via path override fromrealunit-app).
app at the same time as on the device, before any on-device confirmation. Rejecting
on the device must fall back cleanly.