Repository navigation
feat(onboarding): import a wallet from a recovery phrase or secret key - #3091
Draft
aristidesstaffieri wants to merge 3 commits into
Draft
aristidesstaffieri wants to merge 3 commits into
aristidesstaffieri wants to merge 3 commits into
Conversation
Onboarding import takes a single input and detects whether it is a 12/24-word recovery phrase or a Stellar secret key. A secret key creates a wallet with one imported account, a secret-key source and no recovery phrase, through a new RECOVER_ACCOUNT_FROM_SECRET_KEY handler that shares its wipe and finish steps with recoverAccount. "Show recovery phrase" is hidden for wallets with no phrase source. The e2e login and onboarding helpers follow the new screen order.
Contributor
|
PR Preview build is ready: https://github.com/stellar/freighter/releases/tag/untagged-9455dadb65eb0b7b8850 |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Failed recovery can leave orphaned keystores, successful imports can preserve stale onboarding state that returns users to wallet creation, and pending imports can trigger navigation after unmount.
3 open issues
What changed in this PR
Adds secret-key onboarding alongside recovery-phrase import, using the existing account-source model introduced in #3084. Both import methods now share a single input screen before password creation.
Changes:
- Adds validated, masked import input with password, importing, and ready steps.
- Introduces a locked background secret-key recovery handler and shared recovery lifecycle helpers.
- Hides recovery-phrase access for key-only wallets and updates metrics, translations, and tests.
| File | Description |
|---|---|
extension/src/popup/views/Security/index.tsx |
Hides phrase access for key-only wallets. |
extension/src/popup/views/RecoverAccount/styles.scss |
Styles unified input and status screens. |
extension/src/popup/views/RecoverAccount/index.tsx |
Implements the new import flow. |
extension/src/popup/views/RecoverAccount/ImportStatus.tsx |
Displays importing and ready states. |
extension/src/popup/views/DisplayBackupPhrase/index.tsx |
Redirects wallets without a phrase. |
extension/src/popup/views/__tests__/Security.test.tsx |
Tests phrase-access visibility and routing. |
extension/src/popup/views/__tests__/RecoverAccount.test.tsx |
Tests validation, navigation, submission, and errors. |
extension/src/popup/metrics/authServices.ts |
Records secret-key recovery outcomes. |
extension/src/popup/metrics/__tests__/authServices.test.ts |
Tests recovery metric payloads. |
extension/src/popup/locales/pt/translation.json |
Adds Portuguese import text. |
extension/src/popup/locales/en/translation.json |
Adds English import text. |
extension/src/popup/helpers/parseImportSecret.ts |
Classifies and validates import input. |
extension/src/popup/helpers/hasRecoveryPhrase.ts |
Checks source types for phrase availability. |
extension/src/popup/helpers/__tests__/parseImportSecret.test.ts |
Tests phrase and key classification. |
extension/src/popup/helpers/__tests__/hasRecoveryPhrase.test.ts |
Tests phrase-availability checks. |
extension/src/popup/ducks/accountServices.ts |
Adds secret-key recovery state handling. |
extension/src/background/messageListener/popupMessageListener.ts |
Routes the new recovery message. |
extension/src/background/messageListener/helpers/recovery-lifecycle.ts |
Shares cleanup, activation, and response helpers. |
extension/src/background/messageListener/handlers/recoverAccountFromSecretKey.ts |
Implements key validation, storage, and rollback. |
extension/src/background/messageListener/handlers/recoverAccount.ts |
Uses shared recovery lifecycle helpers. |
extension/src/background/messageListener/__tests__/recoverAccountFromSecretKey.test.ts |
Tests key recovery and failure cleanup. |
extension/src/background/helpers/account-mutation-lock.ts |
Serializes secret-key recovery with account mutations. |
extension/e2e-tests/translations-pt.test.ts |
Updates Portuguese import-flow assertions. |
extension/e2e-tests/onboarding.test.ts |
Covers the revised flow and secret-key onboarding. |
extension/e2e-tests/helpers/onboarding.ts |
Provides helpers for the new screen order. |
extension/e2e-tests/helpers/login.ts |
Uses the revised import helpers. |
extension/e2e-tests/helpers/login-pt.ts |
Updates Portuguese login sequencing. |
@shared/constants/services.ts |
Defines the secret-key recovery message. |
@shared/api/types/message-request.ts |
Types the new recovery request. |
@shared/api/internal.ts |
Adds the internal secret-key recovery API. |
Review effort: Balanced
Comment on lines
+252
to
+254
| readyTimer.current = setTimeout(() => { | ||
| navigateTo(ROUTES.recoverAccountSuccess, navigate); | ||
| }, READY_SCREEN_MS); |
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.


What
Onboarding "Import wallet" now takes a single input and works out whether it holds a 12 or 24-word recovery phrase or a Stellar secret key before asking for a password.
A secret key goes through a new
RECOVER_ACCOUNT_FROM_SECRET_KEYmessage, which checks the key before wiping anything and stores one imported account with a secret-key source and no phrase. It runs behind the account-mutation lock. If storing fails after the wipe, the handler wipes again and clearsAPPLICATION_IDandKEY_ID, so the install is left fresh and the user can retry. The wipe and finish steps move out ofrecoverAccountinto shared helpers. The phrase path keeps its handler and order, but the popup now lowercases the phrase, collapses whitespace and checks the checksum before sending it."Show recovery phrase" and its route are hidden for a wallet whose sources hold no phrase. Secret-key onboarding is counted as
account_recovery.completedandaccount_recovery.failedwithrecovery_method: "secret_key". The e2e login and onboarding helpers follow the new screen order, and a new spec onboards with a secret key.Stacked on #3084.
Why
Onboarding could only import a recovery phrase, and importing a secret key from Add account needs an existing wallet, so someone with only a secret key had no way to set up Freighter. The designs fold both imports into one screen.
Closes stellar/freighter-private#53
Screenshots / video
Test plan
RECOVER_ACCOUNT_FROM_SECRET_KEY: one imported account with no phrase, invalid key leaves storage untouched, overwrite clears the old wallet, a failed store or source registration leaves a fresh install, lock membershiprecoverAccounttests pass unchanged after the helper extractiontsc --noEmitclean,yarn test:cihas no failing testsonboarding,login,accountSwitcherandtranslations-ptpass (Chrome)Checklist