Skip to content

Redesign the mainnet migration screens - #650

Open
n13 wants to merge 2 commits into
mainfrom
n13/mainnet-migration-redesign
Open

Redesign the mainnet migration screens#650
n13 wants to merge 2 commits into
mainfrom
n13/mainnet-migration-redesign

Conversation

@n13

@n13 n13 commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the Figma "Mainnet Migration" section (node 372-6813), frames 01–07.

  • 01 Checking: Q mark, "Quantus is live on mainnet.", glacier progress bar, READING TESTNET HISTORY. No Next button any more: the page turns into the outcome on its own once the testnet check answers (1.5 s minimum so it never flashes past).
  • 02 Mined: block count, BLOCKS MINED ON TESTNET, "Keep this wallet." + body, single primary button.
  • 03 Didn't mine: "Nothing carried over." for both former holders and newcomers, Keep this wallet / Create a new wallet.
  • 04 Couldn't check: COULDN'T CHECK badge, two paragraphs, same two buttons. The Retry button is gone as in the design.
  • 05 / 06 Dialogs: "Create a new wallet?" confirmation; the check-failed variant carries the glacier banner and puts the emphasis on "Keep my wallet". "Keep my wallet" just closes the dialog.
  • 07 All set: MAINNET badge, "You're all set.", Get QTC (retires the notice and opens the Receive screen) and Go to wallet.

"Create new wallet" now does what the dialog copy says: it adds a fresh software wallet on the next free wallet index and keeps the existing one on the device (previously it went through the reset flow, which wipes the wallet). The creation logic was extracted from the welcome screen into createSoftwareWalletFlow, so the welcome screen and the migration screen share it; the new wallet's root becomes the active account and the flow lands on the existing Wallet Created page.

Testing buttons

Debug builds show the notice on every launch (AppConstants.debugMainnetMigration = true) and the checking page has a picker: miner, holder, newcomer, error, real. Each pick runs that flow with fake data; hot restart to pick another. Flip the constant to false to see the notice only when it is due.

Shared components (quantus_sdk)

  • QuantusDialog / showQuantusDialog: optional banner slot, cancelIsPrimary, title now Title/Screen (20) per the design, body scrolls instead of overflowing on short screens.
  • QuantusBanner: optional label on the icon layout (label in tone colour, message in muted caption).
  • QuantusBadge: dot for the leading status dot.

None of these change existing call sites.

Not included

Frame 08 (home activity empty state, "Nothing on mainnet yet / Your testnet activity stayed on testnet") is not in this PR: the copy only makes sense for wallets that came from testnet, and nothing persists that distinction today (creating or importing a wallet also sets the migration-done flag). Happy to add it with a stored marker if wanted.

Verification

  • flutter test in mobile-app: 446 tests pass, including the rewritten mainnet_migration_screen_test.dart (auto-advance, all three outcomes, both dialogs, Get QTC, failed completion write, debug picker).
  • quantus_sdk dialog/banner/badge tests pass with new cases for the additions.
  • Walked every page in the iOS simulator (iPhone 17 Pro): checking page with picker, mined, nothing carried over, couldn't check, both dialogs, all set, Get QTC into Receive, and Create new wallet landing on Wallet Created with the new account active.
  • Strings added to both app_en.arb and app_id.arb; flutter gen-l10n run.

The checking page turns into the outcome page on its own once testnet
answers (after a 1.5 s minimum), with one page per outcome: blocks
mined, nothing carried over, couldn't check. Keeping the wallet leads
to an all-set page with Get QTC and Go to wallet. Creating a new
wallet asks first and then adds a wallet next to the existing one via
the shared createSoftwareWalletFlow, which the welcome screen now uses
too. Debug builds show the notice on every launch with an outcome
picker on the checking page.

QuantusDialog gains a banner slot and cancelIsPrimary, QuantusBanner a
label on the icon layout, QuantusBadge a leading dot.
@n13 n13 added the bot-review Request automated review from review-bot label Sep 11, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer model: GPT 5.6 Sol

Verdict (advisory): Request changes

Blocking finding:

  • mobile-app/lib/services/wallet_creation_service.dart:61-81,93-115 — Make the new-wallet flow retry-safe once persistence has begun. createNewWallet stores the mnemonic and marks the mainnet migration done before it inserts the root account; after insertion, _createSoftwareWallet still awaits active-account selection and encrypted-account backfill. An insert failure therefore suppresses this migration screen after restart even though the requested wallet was not created. A failure in either later await is also caught and shown as “wallet creation failed” even though the new root is already stored; tapping Create again recomputes nextWalletIndex from that root and creates another wallet. Please define a commit point and either roll the operation back fully or treat post-commit work as best-effort/success, and add coverage for failures immediately before and after the root-account insert.

Validation:

  • Reviewed exact base 9eccf8d7 to head 6043373f; git diff --check passed.
  • Changed Dart files pass dart format --output=none --set-exit-if-changed --line-length=120.
  • mobile-app: all 446 tests passed.
  • quantus_sdk: all 484 non-native tests passed.
  • cold-wallet-app: all 285 tests passed, covering the shared dialog consumers.
  • Repository analysis completed cleanly for quantus_sdk, miner-app, and cold-wallet-app; local mobile analysis exceeded the required 10-second cutoff, while the PR's GitHub Analyze check is successful.
  • The linked Figma node was not accessible in this unattended environment, so visual fidelity was not independently compared.

@n13 n13 removed the bot-review Request automated review from review-bot label Sep 11, 2026
Text(l10n.mainnetMigrationChecking, style: text.bodyLarge.copyWith(color: colors.textMuted)),
if (onPickOutcome != null) ...[
const SizedBox(height: 24),
Text('DEBUG: pick the testnet outcome', style: text.caption.copyWith(color: colors.textMuted)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to remove this debug text

spacing: 8,
runSpacing: 8,
children: [
for (final outcome in [...debugTestnetOutcomes, null])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, so if debug Testnet is not exist, it will be null. Then outcome null will be passed. IDK this is kinda weird.

onDebugOutcome: (outcome) => ref.read(forcedTestnetOutcomeProvider.notifier).state = outcome,
),
_StatusPage(
_CheckingPage(l10n: l10n, onPickOutcome: ref.watch(debugMainnetMigrationProvider) ? _pickOutcome : null),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this checking page only for debugging?

trailingParagraphs: [l10n.mainnetMigrationMinerBalance(AppConstants.tokenSymbol)],
actions: [_finishButton(l10n.commonDone, TestnetUserKind.miner)],
TestnetUserKind.miner => _outcome(
kind: TestnetUserKind.miner,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be consistent whether we pass explicit enum or reuse the variable status.kind

dewabisma
dewabisma previously approved these changes Sep 11, 2026

@dewabisma dewabisma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few nits, overall good no blocker.

@dewabisma
dewabisma dismissed their stale review September 11, 2026 11:51

Woops, it seems AI found an issue.

The root-account insert is now the commit point. The mnemonic is written
first and deleted again if the insert fails, so a failed attempt leaves
nothing behind and the migration notice stays pending. The active-account,
wallet-origin and migration-done writes move after the insert and are
best-effort, as is the encrypted-account backfill: the wallet already
exists, and reporting those as a failed creation prompted a retry that
created a second wallet. The old existing-root branch, which overwrote a
stored wallet's mnemonic with a fresh one on retry, is gone with it.
@n13 n13 added the bot-review Request automated review from review-bot label Sep 11, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer model: GPT 5.6 Sol

Verdict (advisory): Approve

No blocking findings.

The follow-up commit resolves the earlier wallet-creation blocker: the root insert is now the commit point, a failed insert removes the just-written mnemonic and remains retryable, and failures after a persisted root no longer surface as a failed creation that invites an immediate duplicate. The old existing-root path that could replace a stored wallet's mnemonic is also gone, with focused coverage on both sides of the commit point.

Validation:

  • Reviewed the complete 19-file diff from exact base 9eccf8d7bdf74c0a92f8c461de774091672d5c1f to current head 1865bdf66da363fb783fceddf60eb9b877f2b7ac; the head was rechecked before posting.
  • git diff --check passed, and all 17 changed Dart files pass dart format --output=none --set-exit-if-changed --line-length=120.
  • mobile-app: all 448 tests passed.
  • quantus_sdk: all 484 non-native tests passed.
  • Repository analysis completed cleanly for cold-wallet-app, miner-app, and quantus_sdk; the local run was stopped at the required 10-second cutoff as mobile-app began, while the current GitHub Analyze check passes.
  • The linked Figma node was not accessible from this unattended environment, so visual fidelity was not independently compared.

@n13 n13 removed the bot-review Request automated review from review-bot label Sep 11, 2026
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