Add mnemonic input and validation to configure keys step#8
Add mnemonic input and validation to configure keys step#8PastaPastaPasta wants to merge 2 commits intomainfrom
Conversation
Add a mnemonic input field on the key configuration page so users can paste their own BIP39 mnemonic instead of always using a generated one. When a valid mnemonic is entered, all identity keys are re-derived from it. This enables creating identities for existing wallets. https://claude.ai/code/session_01EwRHibfwa5HFVRc3j9dyp9
📝 WalkthroughWalkthroughThe changes introduce HD wallet mnemonic support to the application. A new validation function checks BIP39 mnemonic phrases, UI components enable mnemonic input during key configuration, and state management functions process and derive keys from user-provided mnemonics. Changes
Sequence DiagramsequenceDiagram
participant User
participant Main as Main Event Handler
participant State as State Manager
participant Crypto as Crypto Validation
participant UI as UI Components
User->>UI: Enters/pastes mnemonic
UI->>Main: Blur or paste event triggered
Main->>Crypto: validateMnemonicPhrase(mnemonic)
Crypto-->>Main: Valid/invalid result
alt Valid Mnemonic
Main->>State: setMnemonic(state, mnemonic)
State->>Crypto: Mnemonic validation
Crypto-->>State: Validation result
State->>State: generateDefaultIdentityKeysHD()
State-->>Main: Updated BridgeState
Main->>UI: Update state.mnemonic
UI->>User: Display updated state
else Invalid Mnemonic
Main->>UI: Show validation error
UI->>User: Display error message
end
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/ui/components.ts (1)
521-521:⚠️ Potential issue | 🟡 MinorHardcoded "12 words" doesn't account for 24-word mnemonics.
Now that the PR accepts 24-word phrases, this message should reflect the actual word count.
Proposed fix
- mnemonicWarning.textContent = 'Write down these 12 words in order. This is the only way to recover your keys.'; + mnemonicWarning.textContent = `Write down these ${words.length} words in order. This is the only way to recover your keys.`;
🤖 Fix all issues with AI agents
In `@src/main.ts`:
- Around line 357-363: The issue is that when the textarea is cleared and
blurred the code path for value.trim().length === 0 does not update
state.mnemonic or the UI, leaving the previous mnemonic in state; update the
blur/input handler to explicitly clear state.mnemonic when the trimmed value is
empty, update the DOM (e.g., clear statusEl.textContent and set appropriate
class on statusEl) and trigger any existing re-render/validation flow so the
empty field is properly reflected; modify the block that currently only handles
value.trim().length > 0 to also handle the empty case by setting state.mnemonic
= '' and resetting statusEl and UI class names.
🧹 Nitpick comments (3)
src/ui/components.ts (1)
252-255: Hint text is always "A new mnemonic was generated", even after user provides their own.Once a user pastes their own mnemonic and it's accepted, this hint becomes misleading. Consider making it contextual (e.g., checking whether
state.mnemonicdiffers from the originally generated one, or simply using a more neutral message).src/ui/state.ts (1)
112-127:setMnemonicreturnsnullfor invalid input — diverges from the pattern of other state transitions.All other state transition functions in this file return
BridgeStateunconditionally. Returningnullhere pushes validation responsibility to every caller. This works fine with the single caller inmain.tstoday, but consider whether throwing or returning the unchanged state with an error flag would be more consistent. Not a blocker given the current usage.src/main.ts (1)
344-344: Duplicated normalization logic betweenmain.tsandstate.ts.Line 344 replicates
trim().replace(/\s+/g, ' ')fromsetMnemonic(state.ts line 117) for the duplicate-submission check. If the normalization rule evolves in one place but not the other, the skip check could break. Consider extracting a sharednormalizeMnemonichelper.
| } else if (value.trim().length > 0) { | ||
| // Show validation error | ||
| if (statusEl) { | ||
| statusEl.textContent = 'Invalid mnemonic. Enter a valid BIP39 phrase (12 or 24 words).'; | ||
| statusEl.className = 'mnemonic-validation-status error'; | ||
| } | ||
| } |
There was a problem hiding this comment.
Clearing the textarea leaves a stale mnemonic in state.
If the user clears the textarea and blurs, the empty string fails validation but value.trim().length > 0 is false, so no error is shown and no re-render occurs. The textarea appears empty while state.mnemonic still holds the previous value. The state will silently use the old mnemonic on "Continue". This is probably acceptable since the next render would re-populate the field, but it's worth being aware of.
🤖 Prompt for AI Agents
In `@src/main.ts` around lines 357 - 363, The issue is that when the textarea is
cleared and blurred the code path for value.trim().length === 0 does not update
state.mnemonic or the UI, leaving the previous mnemonic in state; update the
blur/input handler to explicitly clear state.mnemonic when the trimmed value is
empty, update the DOM (e.g., clear statusEl.textContent and set appropriate
class on statusEl) and trigger any existing re-render/validation flow so the
empty field is properly reflected; modify the block that currently only handles
value.trim().length > 0 to also handle the empty case by setting state.mnemonic
= '' and resetting statusEl and UI class names.
Summary
This PR adds the ability for users to input their own BIP39 mnemonic phrase during the configure keys step, allowing them to create identities for existing wallets. Previously, only generated mnemonics were supported.
Key Changes
validateMnemonicPhrase()tosrc/crypto/hd.tsthat validates BIP39 mnemonic phrases using the @scure/bip39 librarysetMnemonic()function insrc/ui/state.tsthat validates user input and re-derives all identity keys from the provided mnemonicsetMnemonicfunction through the UI state module exportsImplementation Details
https://claude.ai/code/session_01EwRHibfwa5HFVRc3j9dyp9
Summary by CodeRabbit
New Features