Repository navigation
feat(restore): enter the recovery phrase in word pills with suggestions - #205
Merged
Merged
Conversation
…list suggestions - One numbered pill per word in a 12 or 24-word grid, shaped like the backup screen's pills. Words past a smaller grid stay hidden, so switching to 12 words and back loses nothing. - A bar above the keyboard suggests matching wordlist words. A space, return or a picked word moves to the next pill, backspace in an empty pill steps back, and the bar steps aside by itself when another input takes the keyboard. - Each word is checked as it's typed. Restore stays off until the phrase passes the wordlist and checksum checks, with a note saying why: unknown words, a bad checksum, an empty pill, or how many words are in so far. - A pasted or scanned phrase spreads over the pills, and a valid scan restores straight away. - Mnemonic normalisation moves unchanged from AbstractHDWallet into modules/bip39, so the pills and the wallet split words the same way. The suggestion engine is modules/mnemonicWords and the grid rules are helpers/recoveryPhrase. - Drops the old text box, its keyboard toolbar and the unused label/triggerImport params. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…stops scrolling "This is your recovery phrase" wrapped to two lines, which left the backup screen 17pt taller than its scroll area on an iPhone 17/17 Pro (32pt on a 16e/17e): the checkbox's second line was cut off and a scroll bar showed. "Your recovery phrase" fits on one line and both phones fit. Settings > View recovery phrase gets the same title so the two screens match. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… CI emulator The import spec only runs when MNEMONIC_TEST is set, which CI doesn't do, so its last two steps had never passed. Run on an API 31 emulator set up like CI's, and on API 37: - TrueSheet makes Espresso find every view in a sheet twice, so the success sheet's Done button needs atIndex(0), like the sheet steps in 04-receive and 07-contacts. - With synchronization off (the restore starts a scan that never lets the app go idle), a toBeVisible() wait that starts while the sheet is sliding up, or while home comes back from under the modal, can miss the view arriving. waitUntilVisible retries short waits instead. 18 runs in a row pass, with 12 and 24-word phrases, across both emulators. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Restore now takes the recovery phrase one word per pill, with wordlist suggestions above the keyboard. The backup screen also fits without scrolling on current iPhones.
Restore: word pills
Under the hood
AbstractHDWallet.setSecretintomodules/bip39.ts, so the pills and the wallet split words the same way. It's nownormalizeMnemonic,mnemonicWordsandmnemonicWordsAsTyped.modules/mnemonicWords.tsdoes the word lookups and suggestions, with one lazily built index per wordlist.helpers/recoveryPhrase.tsholds the grid as plain data, with pure functions for placing pasted words and judging the phrase.hooks/useRecoveryPhraseInput.tshandles state, moving focus between pills, and whether the keyboard belongs to a pill.components/RecoveryPhraseGrid.tsxhas memoised pills, so a keystroke re-renders only its own pill.components/WordSuggestionBar.tsxis the bar, built onKeyboardStickyView.SafeAreaScrollViewtakes abottomOffset, so the focused pill stays clear of the bar.FieldMnemonicInput) and its iOS keyboard toolbar (DoneAndDismissKeyboardInputAccessory);label/triggerImportroute params;restore_mnemonic_label,restore_mnemonic_placeholder,send.input_clear,send.input_paste,wallet_birth.error_empty_mnemonic.restore_word_count,restore_word_label,restore_word_unknown,restore_no_matching_word,restore_unknown_words,restore_invalid_phrase,restore_missing_word,restore_words_entered.Backup screen title
E2E
03-wallet-importonly runs whenMNEMONIC_TESTis set, which CI doesn't do, so CI reports it as skipped. Its last two steps had never passed: on an emulator set up like CI's, it failed at the success sheet, and master's helper fails there too. The helper now:.atIndex(0)for the sheet, since TrueSheet makes Espresso find each sheet view twice (as in04-receiveand07-contacts);waitUntilVisible). With synchronization off, a wait that starts while a view is still arriving can miss it for its whole timeout.Testing
03-wallet-import, with 12 and 24-word phrases: 14/14 on an API 31 emulator set up like CI's (320×640dp, CI's options, animations off), and 4/4 on API 37.The backup title was measured on the 17 Pro and the 17e.
Not verified
🤖 Generated with Claude Code