4762ecf6 - Software-to-BitBox migration wizard with balance transfer - #884
Draft
TaprootFreak wants to merge 6 commits into
Draft
4762ecf6 - Software-to-BitBox migration wizard with balance transfer#884TaprootFreak wants to merge 6 commits into
TaprootFreak wants to merge 6 commits into
Conversation
- authenticateLinkedAccount: POST /v1/auth for a new address carrying the current session's bearer token, so the API links the address to the same account (OptionalJwtAuthGuard); 409 surfaces as AddressAlreadyLinkedException - bearerTokenOverride on authenticatedGet/Put/Post: explicit-token calls skip the 401 refresh (a refresh would mint a token for the wrong identity) - acquireUncommittedBitboxWallet/persistBitboxWallet: uncommitted draft with id-0 sentinel, idempotent persist deduplicated by address, no current-wallet switch (mirrors the software-wallet draft/commit pair) - getRegistrationInfoWith/registerWalletFor: registration flow in an explicit token+account context for the migration wizard - buildSignMessage now mirrors the API's environment-scoped auth message ([dev]_ prefix on testnet) — auth against the dev API was broken since the API introduced env-scoped sign messages
Settings entry (software wallets only) opening a guided wizard: pair the BitBox as an uncommitted draft via the existing connect sheet, link the new address to the current account and register it in the share register (one-tap, EIP-712 on the device), transfer the full REALU balance through the unchanged gasless SendProcessCubit (software wallet stays current throughout), then persist-deduplicated wallet row switch + session swap. Wizard is resumable at every step; a missing balance read fails loud instead of silently skipping the transfer.
…test suite A definitive (non-retryable) SendProcessFailure inside the embedded transfer flow left the user stuck: disabled retry button while the transferring state also blocked the system pop. The wizard cubit now leaves the transfer flow into its own retryable failure state, and retrying runs a fresh persist-and-prepare pass (balance re-read) instead of blindly re-sending the dead intent. The register retry now restores the stored RegisterReady state first — the previous pending-retry closure was a no-op against the state guard. Success-branch context use moved ahead of the await branch (use_build_context_synchronously). Adds the full wizard test suite: cubit state machine incl. every failure branch and the zero-balance / already-registered skips, page-manager routing per state, embedded-transfer listener behaviour, settings tile visibility, responsive matrix tests and surface-catalog entries for every sticky-CTA view.
mocktail's registerFallbackValue takes no type parameters; the explicit arguments were an analyzer error (wrong_number_of_type_arguments_method).
…test The cancelPairing test asserted before the stream listener microtask ran; the sheet test tapped the ConnectBitboxView cancel button, which pops via go_router, without a GoRouter in the tree — mount the manager on a single-entry GoRouter stack (same pattern as connect_bitbox_view_test).
TaprootFreak
force-pushed
the
feature/bitbox-migration
branch
from
August 3, 2026 16:21
2cf15fc to
64267a3
Compare
- BalanceService.fetchBalance: fresh fail-loud read for money-moving flows — throws on transport/non-200/parse instead of serving the stale cache the polling path may hold - session auth-token slot is now address-bound and getAuthToken discards a late auth response when the active wallet changed mid-flight, closing the race where a stale software refresh could overwrite the migrated BitBox JWT - signature cache is scoped to the exact signed message, so legacy testnet signatures invalidated by the environment-prefixed sign message fall back to a fresh sign instead of looping on rejected auth - @no-integration-test annotations on the BitBox address acquisition paths - import order fix in the registration service test
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.
What
Adds an in-app migration wizard that moves a user from the software wallet to a BitBox hardware wallet in one guided flow, including the wallet balance:
POST /v1/authfor the BitBox address carrying the current session's bearer token; the API'sOptionalJwtAuthGuardattaches the address to the same account, which makes the existing one-tapAddWalletregistration state reachable. The share-register registration is EIP-712-signed on the device.SendProcessCubitunchanged: the software wallet stays the app's current wallet throughout the wizard, so the existing software-only signing gate holds.Entry point: Settings → "Move to BitBox", visible only for software wallets (same local wallet-mode gate as the seed-backup tile).
Why
Users who started on a software wallet had no in-app path to a hardware wallet — upgrading meant manual re-onboarding and moving funds by hand.
Design notes
getRegistrationInfostates 1:1; a pending/manual-review registration stops the wizard before funds move. The only local gates are wallet-mode visibility and BitBox connectivity (physical capabilities).buildSignMessagenow mirrors the API's environment-scoped auth message ([dev]_prefix on testnet). Auth against the dev API had been broken since the API introduced env-scoped sign messages; this feature depends on dev-environment testability, so the fix is included here.Tests
Full local gate run (codegen chain →
flutter analyze→flutter test --exclude-tags golden): analyze clean, 5054 tests passed. New coverage: service-layer unit tests (linked auth incl. header/body/401-no-refresh assertions, wallet draft/persist dedup, explicit-context registration, env-scoped sign message), the complete wizard cubit state machine incl. every failure branch and the zero-balance / already-registered re-entry skips, page-manager routing per state, embedded-transfer listener behaviour, settings-tile visibility per wallet mode, plus responsive matrix tests and surface-catalog entries for every new sticky-CTA view.