Skip to content

feat(wallet): transaction history sheet, Send/Receive as bottom sheets, Receive redesign#607

Open
dmnyc wants to merge 5 commits into
barrydeen:mainfrom
dmnyc:feat/tx-history-sheet
Open

feat(wallet): transaction history sheet, Send/Receive as bottom sheets, Receive redesign#607
dmnyc wants to merge 5 commits into
barrydeen:mainfrom
dmnyc:feat/tx-history-sheet

Conversation

@dmnyc

@dmnyc dmnyc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • On-chain detectionWalletTransaction gains isOnchain and pending flags; SparkRepository correctly identifies on-chain deposits/withdrawals (Spark SDK PaymentDetails.Deposit/Withdraw) and uses the txid as the payment hash instead of showing a UUID
  • Transaction detail drawer — tapping a row in the full history sheet expands an inline AnimatedVisibility panel showing status, type, amount, fee, date, note, and payment hash/txid with copy; on-chain rows add a mempool.space link; compact dashboard preview is unaffected (expandable = false)
  • transactionsChanged flowWalletProvider interface gains SharedFlow<Unit> emitted by SparkRepository on PaymentSucceeded/PaymentFailed/PaymentPending, triggering a silent transaction list refresh without a loading spinner
  • makeInvoice expiry paramexpirySecs: Int = 3600 threaded through WalletProviderSparkRepositoryNwcRepositoryNip47.MakeInvoice (NIP-47 optional expiry field)
  • bitcoin: prefix strippingprocessInput now strips bitcoin:/BITCOIN: in addition to lightning:/LIGHTNING:
  • Send/Receive as full-page bottom sheets — Send and Receive flows present as ModalBottomSheet overlays on the Home dashboard; home remains visible behind the sheet; a single sheet stays open for the entire flow so there's no close/reopen flicker between pages
  • WalletSheetDragHandle — custom drag handle using statusBarsPadding() so the grab pill sits below the status bar/camera cutout on full-height sheets
  • Send redesignBasicTextField dark-card input (min 120dp, nsec guard), Scan QR / Paste / Gallery action row, accent-colored Next button
  • Receive redesign — invoice form is primary; expiry selector (1 hour / 24 hours / Custom); compact lightning address row below the form with inline QR toggle (AnimatedVisibility) that auto-scrolls into view after expanding; local invoiceGenerating flag so the spinner only appears after the button is pressed, not on sheet open
  • Implementation guideWALLET_SHEET_UX.md documents the full pattern for dark-wisp and zap-cooking android

Test plan

  • Spark wallet: send a Lightning payment — transaction appears in history with correct hash (not UUID)
  • Spark wallet: on-chain transaction shows "On-chain" type in detail drawer and mempool.space link
  • Pending transaction shows "Pending ·" badge in the row; clears after confirmation
  • Tap a history row — detail drawer expands/collapses; dashboard preview rows do not expand
  • Send sheet opens over home dashboard; back/swipe dismisses to Home
  • Receive sheet opens over home dashboard; back/swipe dismisses to Home
  • Receive: expiry selector — 1h / 24h / Custom; Custom requires valid hours before enabling Create
  • Receive: lightning address QR toggles inline without navigating to a new page; page scrolls to show it
  • Receive: spinner only appears after tapping Create invoice, not on sheet open
  • NWC wallet: makeInvoice passes expiry correctly (check NIP-47 request payload)
  • Paste bitcoin:bc1q… into Send input — prefix stripped, routes correctly

dmnyc added 3 commits June 30, 2026 20:26
PaymentDetails.Deposit and PaymentDetails.Withdraw are now recognized as
on-chain payments; their txId is used as the payment hash instead of the
UUID payment ID. Adds pending and isOnchain fields to WalletTransaction.
Tapping a row in the full transaction history sheet expands an inline
detail panel showing status, type (on-chain/Lightning), amount, network
fee, date, note, and payment hash with a copy icon. On-chain transactions
get a "View on mempool.space" link. Compact home-screen list is unchanged.
…prefix handling

WalletProvider interface gains transactionsChanged SharedFlow (emitted on
payment succeeded/failed/pending) and makeInvoice(expirySecs: Int = 3600).
SparkRepository also calls refreshBalanceInternal() on PaymentPending.
NwcRepository wires expirySecs through to Nip47 MakeInvoice.
Nip47 serializes optional expiry field per NIP-47.
WalletViewModel: setSendAmount(), processInput strips bitcoin:/BITCOIN:
prefix, generateInvoice threads expirySecs through to the provider.
@dmnyc

dmnyc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@barrydeen The on-chain features here and in barrydeen/dark-wisp-android#49 and barrydeen/wisp-ios#395 are for display purposes only. All send/receive functionality is out of scope here.

… address QR

Send, Receive, and Transactions each present as full-page ModalBottomSheets
over the Home dashboard (swipe down to dismiss), matching iOS behavior.
WalletSheetDragHandle pushes the grab handle below the status bar so it
clears the camera cutout on full-height sheets.

Receive screen redesign: expiry selector (1 h / 24 h / Custom) replaces
the Invoice/Address tab row. Lightning address shown as a compact row below
the Create invoice button with bolt icon, address, QR toggle, and copy.
Tapping the QR icon expands an inline QR card within the sheet and
auto-scrolls to it; tapping again collapses. Loading indicator only appears
after the Create invoice button is pressed, not on sheet open.

Send screen redesign: tall dark-card BasicTextField replaces OutlinedTextField;
Scan / Paste / Gallery action row replaces OutlinedButton pair; accent-colored
Next button with disabled state.

Strings: wallet_receive_expires_*, wallet_receive_via_address,
wallet_send_input_hint_onchain, wallet_tx_pending, action_copy,
wallet_copy_address.
@dmnyc dmnyc force-pushed the feat/tx-history-sheet branch from d25f8de to 3c7f37b Compare July 1, 2026 01:39
…rk wallet on the same seed

On-chain deposits sit unclaimed until explicitly claimed once they have
enough confirmations; the SDK emits SdkEvent.UnclaimedDeposits when a
deposit becomes claimable, and we weren't calling claimDeposit at all.
Now claims automatically on that event and once more on connect (in
case a deposit became claimable while the app was closed).

Also stops trusting PaymentStatus.PENDING for on-chain rows in general:
transactions made through another wallet app on the same seed aren't
tracked by this SDK session, so the status can stay stuck at PENDING
long after the underlying transaction is confirmed on-chain. The
mempool.space link already lets users verify actual confirmation
status for on-chain transactions.
@dmnyc dmnyc force-pushed the feat/tx-history-sheet branch from 7e0065e to 7b7d91f Compare July 1, 2026 02:14
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.

1 participant