Skip to content

feat: deep link spending hw sign - #1176

Open
guzino wants to merge 4 commits into
synonymdev:masterfrom
guzino:feat/spending-hw-sign-deeplink
Open

feat: deep link spending hw sign#1176
guzino wants to merge 4 commits into
synonymdev:masterfrom
guzino:feat/spending-hw-sign-deeplink

Conversation

@guzino

@guzino guzino commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Refs #1126
Refs #1119

This PR opens the hardware-wallet transfer Sign screen from bitkit://screen/spending-hw-sign/{walletId}/{orderId}.

Description

#1119 left six transfer destinations InternalOnly because they read activity-scoped TransferViewModel state. SpendingHwSign was the closest: it already took a wallet id (the issue still says deviceId) and bounced home when spendingUiState.order was null. A generated link therefore could not reconstruct the Blocktank order.

ContentView now parses that URI and calls prepareSpendingHwSign before navController.handleDeepLink. Unknown wallet or missing order is refused with the existing Unhandled screen deeplink warning and does not navigate. A matching in-memory order is reused; otherwise blocktankRepo.getOrder(orderId, refresh = true) loads it and adoptSpendingOrder writes the same state onOrderCreated already wrote, without emitting TransferEffect.OnOrderCreated. The pending URI is consumed after that suspend, so the LaunchedEffect is not cancelled mid-fetch.

OnOrderCreated now carries orderId. Amount → Sign navigates Routes.SpendingHwSign(walletId, orderId) from the effect. The dest reads both route args and matches state.order to orderId.

  • Promotes Routes.SpendingHwSign to DeepLinkable with path bitkit://screen/spending-hw-sign/{walletId}/{orderId}.
  • Parses that path in ScreenDeepLinks.spendingHwSignLink via kebabId(Routes.SpendingHwSign::class).
  • Keeps SavingsProgress, SettingUp, SpendingAdvanced, SpendingConfirm, and SpendingHwSigned as InternalOnly. The rest of feat: deep link the late transfer screens #1126 stays a follow-up.

Preview

N/A

QA Notes

Dev mode is on by default on debug builds (Settings ▸ Advanced ▸ Dev Settings). The app must be past onboarding. The Sign path needs a paired hardware wallet and a live Blocktank order id.

Manual Tests

  • 1. Hardware Wallet detail → Transfer To Spending → Amount → Continue → Sign: lands on Sign With Your Device with the created order.
  • 2. From that Sign screen, adb shell am start -a android.intent.action.VIEW -d "bitkit://screen/spending-hw-sign/<walletId>/<orderId>" to.bitkit.dev → Sign opens with the same order.
  • 3. Cold start the same URI → Sign opens with that order, not Home.
  • 4. Same path with an unknown wallet id or a missing order → screen unchanged, logcat carries Unhandled screen deeplink.
  • 5. regression: bitkit://screen/spending-amount-hw/<walletId> → Amount still opens.

Automated Checks

  • Unit tests added in ScreenDeepLinksTest.kt: path pattern, wallet and order segments, missing order id.
  • Unit tests added in TransferViewModelTest.kt: known wallet loads the named order, unknown wallet and missing order are refused, in-memory order is reused without a second fetch.
  • Local: just compile, just test, just lint all pass, no new detekt findings.

Comment thread app/src/main/java/to/bitkit/ui/utils/ScreenDeepLinks.kt Fixed
@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds debug-only deep-link navigation into the hardware-wallet spending-sign flow, restoring the requested Blocktank order before navigation.

  • Extends the sign route and order-created effect with an order ID.
  • Validates the wallet, loads or reuses the requested order, and adopts it into transfer state.
  • Adds focused parsing, route-contract, preparation, and regression tests.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issue identified.

The deep link remains restricted by the existing debug and Dev Mode gates, prepares the exact requested order before navigation, rejects unavailable prerequisites, and keeps internal navigation synchronized through the new order ID.

Important Files Changed

Filename Overview
app/src/main/java/to/bitkit/ui/ContentView.kt Coordinates order preparation before deep-link navigation and registers the sign destination with both route arguments.
app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt Adds validated order restoration, centralizes spending-order adoption, and includes the order ID in creation effects.
app/src/main/java/to/bitkit/ui/utils/ScreenDeepLinks.kt Parses the hardware sign route's wallet and order path segments while retaining existing screen-link gating.
app/src/main/java/to/bitkit/ui/screens/transfer/hardware/SpendingHwSignScreen.kt Ensures the in-memory order matches the route order before rendering the signing flow.
app/src/test/java/to/bitkit/viewmodels/TransferViewModelTest.kt Covers successful restoration, unknown wallets, missing orders, and reuse of a matching in-memory order.
app/src/test/java/to/bitkit/ui/utils/ScreenDeepLinksTest.kt Covers the generated URI contract and extraction of both required route identifiers.

Sequence Diagram

sequenceDiagram
    participant Intent as Screen deep link
    participant AppVM as AppViewModel
    participant Content as ContentView
    participant TransferVM as TransferViewModel
    participant Blocktank as BlocktankRepo
    participant Nav as NavController
    Intent->>AppVM: queue URI when debug runtime and Dev Mode permit
    AppVM-->>Content: pendingScreenDeepLink
    Content->>TransferVM: prepareSpendingHwSign(walletId, orderId)
    alt matching order already in memory
        TransferVM-->>Content: true
    else order must be restored
        TransferVM->>Blocktank: "getOrder(orderId, refresh = true)"
        Blocktank-->>TransferVM: order or missing
        TransferVM-->>Content: preparation result
    end
    alt prepared
        Content->>Nav: handleDeepLink(uri)
    else rejected
        Content->>Content: log unhandled link
    end
    Content->>AppVM: consumeScreenDeepLink()
Loading

Reviews (1): Last reviewed commit: "fix: consume deeplink after prepare" | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants