feat(self-custodial): UI/UX launch polish across settings and flows#3769
Open
esaugomez31 wants to merge 65 commits intofeat--spark-rollout-and-hardeningfrom
Open
feat(self-custodial): UI/UX launch polish across settings and flows#3769esaugomez31 wants to merge 65 commits intofeat--spark-rollout-and-hardeningfrom
esaugomez31 wants to merge 65 commits intofeat--spark-rollout-and-hardeningfrom
Conversation
This was referenced Apr 29, 2026
Collaborator
Author
Contributor
Contributor
|
When restoring, there is no loading state for balance, instead I see $0.00 which is quite bad UX since I expect to see the full balance. zero-balance-error.webm |
18d14a7 to
17e5ae9
Compare
Contributor
|
Reviewing on android emulator shows these still dont work:
|
9c9bf69 to
f8fc5f1
Compare
Contributor
|
@esaugomez31
|
b958e5f to
d93e65a
Compare
Collaborator
Author
Already fixed! |
…Advanced for self-custodial
…and remove unused i18n
…re in setActiveAccountId
…y-active account's backup state
…ts until they support multi-account
…ia Credential Manager and iCloud Keychain
…hitelisting SV and HN
…ranslations to match English source
…ount display currency and language maps
…ersistent-state helpers
…eLanguage adapters
… on currency change
… screens and LanguageSync
…y to avoid stale USD label
…o non-USD currencies render correctly
7bb7129 to
d464d96
Compare
16e3919 to
5c7a7ea
Compare
…te only new wallet creation
…pshot bug under Fabric
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.





Summary
UI/UX launch polish for the self-custodial (Spark) experience: stable-balance gating, settings reorganization, account redesign, delete flow, default-account preference, receive flow QR by default, single-screen backup phrase, dynamic success messaging, stablecoins-aware Dollar modal, removal of the legacy "You Are in Control" trust-model modal, country-aware account-type gating, a comprehensive multi-account stack with auto-convert UX polish, and SDK amount-adjust block on the convert-details screen.
Primary ticket: blinkbitcoin/blink-wip#692 — feat(spark/ui): Review and fixes. Also addresses blinkbitcoin/blink-wip#664 (Stablesats/Dollar popup modal — non-custodial variant).
Ticket blinkbitcoin/blink-wip#692 — Tasks
stableBalanceEnabledremote flag (defaultfalse) gatesisStableBalanceActive. Stable-balance settings hidden when off.SettingsGroupno longer renders.Wallet identifier/Lightning address/Backup statusboxed read-only fields (shared with the AccountInformation sub-screen viaSelfCustodialAccountFields), then the danger zone with the delete flow (balance check + warning screen + SDK storage wipe +activeAccountIdclear). Custodial layout untouched.TrustModelModal,useTrustModelSeenhook,trust-model-screenre-export, and the fourBackupNudge.trustModel*i18n keys deleted across 28 locales. Home-screen integration removed; regression test asserts the modal no longer renders even for SC users with positive balance (the previous trigger condition).SparkViewBackupPhraseScreenrenders all 12 words in a 2-column grid. Success screen accepts a dynamicmessageroute param ("Your backup phrase is correct" for the test-backup flow). Onboarding 2-step flow untouched.useAccountTypeOptionshides the Custodial card when the detected country isn't inCUSTODIAL_ALLOWED_COUNTRIES, and the SC card whennonCustodialEnabledis off. Loading skeleton while detection runs; banner explains the state when SC is temporarily disabled.Ticket blinkbitcoin/blink-wip#664 — Stablesats/Dollar popup modal
StableSatsModalaccepts avariantprop. SC variant renders close-X, Dollar pill, centered title, centered body explaining stablecoins, primary "Back home", secondary "Learn more" →https://www.blink.sv/en/dollar-account. Custodial variant unchanged.Additional work (beyond ticket scope)
Account & default preferences
selfCustodialDefaultWalletCurrency(BTC | USD), scoped per account; settings picker; honored in send and receive flows; currency list always loaded so SC users can pick.dollarStablecoini18n key. Custodial keeps "Dollar (Stablesats)".Multi-account preferences (display currency + language)
selfCustodialDisplayCurrencyByAccountId,selfCustodialLanguageByAccountId); migration is identity.useEffective*adapter hooks (useEffectiveDisplayCurrency,useEffectiveLanguage) unify custodial (GraphQL-backed) and self-custodial (persistent-state-backed) sources behind a single interface. Screens,LanguageSync, andusePriceConversionconsume the adapter and never bifurcate by account type.usePriceConversionis fixed at the root:displayCurrencynow flows from the adapter rather than from Apollo's cacheddenominatorCurrency(which kept showing the previous account's currency on switch). A guard discards a cached price whose denominator disagrees with the active preference, andfetchPolicy: "cache-and-network"on both the authed and unauthed price queries forces an immediate refresh on account switches (custodial→custodial included).ConvertQuote.feeAmountis typed asUsdMoneyAmount(the SDK returns the USDB swap fee in cents, pegged 1:1 to USD) and the conversion-flow hook converts it viaconvertMoneyAmountbefore formatting. Previously the fee row rendered "Currency issue. Refresh needed" for EUR, JPY, and any other non-USD locale.Self-custodial contact dedup
bridge/addContactis now an upsert: when a contact with the samepaymentIdentifieralready exists (matched case-insensitive and trimmed via the existingnormalizeStringhelper), it callssdk.updateContactwith the existing record's data — preserving any user-edited name (so a contact renamed "Mom" isn't clobbered back to its LN address) and bumpingupdatedAtfor future "recent contacts" sorting. When no match exists, it falls through tosdk.addContact. Fixes the bug where every payment to the same LN address created another duplicate contact.Account-type labels i18n alignment
Custodial/Non-custodiallabels shown under each account's title in the multi-account switcher were inconsistent across locales: the English source saidCustodial/Non-custodial, but all 28 translation files saidBlink/Spark(a brand-name swap, not a translation). All 28 locales were aligned to the English technical concept, with proper grammatical agreement per language (es:Custodiada/No custodiada; pt:Custodiada/Não custodiada; it:Custodito/Non custodito; de:Verwahrt/Selbstverwahrt; fr:Sous garde/Sans garde; and so on).Convert flow
FlooredToMinorIncreasedToAvoidDust). For dust adjustments the block is suppressed when the user already requested the full balance, since asymmetric conversion math can flag it spuriously at 100%.useConversionQuote.Auto-convert UX
Multi-account hardening
setActiveAccountId.BackendFeatureGatereturns blocked when the active account is SC, so feature gating respects the active account.useEffectruns.create-walletno longer clobbers the previously-active account's backup state.blink-spark-backup-{network}-{walletIdentifier}.jsonso different wallets no longer overwrite each other. The payload now embedswalletIdentifierand (when set)lightningAddressas plaintext metadata; only the mnemonic stays encrypted. On restore, the app lists all backups by prefix, parses metadata without decrypting, and shows a picker when more than one is present (LN address as the row title with the identifier as subtitle when set, or the identifier alone). A single backup auto-restores; an encrypted backup proceeds straight to the password step.Settings & UI polish for SC
Send flow
Performance
Out of scope
Test plan
stableBalanceEnabledremotely; confirm stable-balance settings appear / disappear and that toggling off mid-session re-aligns Receive to Dollar.activeAccountIdcleared).?icon next to the Dollar pill on Home: in custodial → Stablesats modal; in SC → stablecoins modal with "Learn more" linking toblink.sv/en/dollar-account.nonCustodialEnabledis off (with the "temporarily disabled" banner).blink-spark-backup-{network}-{pubkeyA}.json+{pubkeyB}.json) and neither overwrites the other.