Skip to content

Refactor and unify the send & multisig-propose flow#541

Open
n13 wants to merge 5 commits into
mainfrom
refactor_send_flow
Open

Refactor and unify the send & multisig-propose flow#541
n13 wants to merge 5 commits into
mainfrom
refactor_send_flow

Conversation

@n13

@n13 n13 commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

This branch started as a one-line fix for the scan→continue button bug, but the scope grew into a full refactor of the send experience. The regular send and multisig propose flows were near 1:1 duplicated screens; they are now unified behind a single set of screens driven by a SendStrategy, and several related fixes/features came along with it.

Net ~−800 lines (four duplicated multisig screens deleted), no new localization keys, and the regular send flow is visually unchanged from the original Figma design.

1. Unified send & multisig-propose flows (Strategy pattern)

The two flows (recipient → amount → review → done) were copy-pasted. They now share one implementation, with a SendStrategy encapsulating everything that differs between them:

  • send_strategy.dartSendStrategy + value types: SendStrings (per-flow labels), SendFee (RegularFee / ProposeFee), SendOutcome (Submitted / NeedsHardwareSignature / Failed), SendTerminalContent.
  • regular_send_strategy.dart — single-signer transfer from the active account (local signing, or Keystone hand-off).
  • multisig_propose_strategy.dart — multisig proposal (member affordability gating, propose-fee breakdown, proposal submission + provider invalidation).
  • Shared screens now take a strategy: select_recipient_screen.dart, input_amount_screen.dart, review_send_screen.dart, and a unified send_terminal_screen.dart (renamed from tx_submitted_screen.dart).
  • Deleted the duplicated multisig screens: propose_recipient_screen.dart, propose_amount_screen.dart, propose_review_screen.dart, propose_done_screen.dart.
  • Entry points updated: home_screen.dart, shared_address_action_sheet.dart.

Keystone signing seam: hardware signing is modeled as an orthogonal step via SendOutcome.NeedsHardwareSignature, threaded through keystone_sign_screen.dart / keystone_scan_signature_screen.dart. This leaves room for multisig + Keystone later without adding another branch.

2. "View in Explorer" on the terminal screen

  • The success screen now shows a "View in Explorer ↗" link built from the extrinsic hash returned by submission.
  • transaction_submission_service.dart now returns the extrinsic hash (it was already computed, just discarded); added an explorerImmediateTransactionUrl() helper.
  • Extracted a shared ExplorerLink widget and reused it across the terminal, the POS receipt (pos_qr_screen.dart), and the transaction/proposal detail sheets — removing three near-duplicate copies.

3. Self-send handling on the recipient screen

Entering or scanning your own address previously left the button silently disabled on "Enter address". Now it:

  • labels the (still-disabled) button "Can't Self Transfer", and
  • shows a warning toaster once on entry.

Works for both flows (strategy.sourceAccountId resolves to the active account for sends, the multisig address for proposals).

4. Debug QR scanner button

  • Added a kDebugMode-only button to the shared QrScannerPage that returns a test address, so the send / swap / add-account flows can be exercised in the simulator where the camera is unavailable.
  • Shared AppConstants.debugTestAddress, reused by the existing hardware-account debug fill.

5. Original fix (scan → continue button)

Scan and paste took different code paths; scan assigned the controller text inside setState, so the validation listener never enabled the button. Unified scan/paste/recent through a single _setRecipient helper (the path paste already used). This screen was subsequently folded into the refactor above.

Test plan

  • Regular send — recipient (scan / paste / recent / type) → amount → review → submit → terminal shows "sent" with a working explorer link
  • Regular send via Keystone — review hands off to the QR sign flow → broadcasts → terminal + explorer link
  • Multisig propose — recipient → amount → review → propose → terminal; proposal shows as pending
  • Self-send — entering/scanning own address shows "Can't Self Transfer" + toaster, button stays disabled (both flows)
  • Explorer link — terminal, POS receipt, and tx/proposal detail sheets all open the correct explorer URL
  • Pay mode (payment-URL QR) — recipient + amount prefilled
  • Regular send flow visually matches the original Figma design

n13 added 5 commits June 25, 2026 16:52
Scanning an address left the send and multisig-propose recipient buttons
stuck on "Enter address". Scan assigned the controller text inside
setState, firing the change listener's nested setState mid-update, so
validation never enabled the button.

Route scan, paste, and recent through a shared _setRecipient helper that
assigns the controller text outside setState (the same path paste already
used), letting the listener drive validation. Also removes the duplicated
assignment across the three input methods in both screens.
align with design, delete duplicated screens from msig
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