Skip to content

Add mnemonic input and validation to configure keys step#8

Open
PastaPastaPasta wants to merge 2 commits intomainfrom
claude/bridge-mnemonic-identity-rduBg
Open

Add mnemonic input and validation to configure keys step#8
PastaPastaPasta wants to merge 2 commits intomainfrom
claude/bridge-mnemonic-identity-rduBg

Conversation

@PastaPastaPasta
Copy link
Owner

@PastaPastaPasta PastaPastaPasta commented Feb 11, 2026

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

  • Mnemonic validation function: Added validateMnemonicPhrase() to src/crypto/hd.ts that validates BIP39 mnemonic phrases using the @scure/bip39 library
  • State management: Implemented setMnemonic() function in src/ui/state.ts that validates user input and re-derives all identity keys from the provided mnemonic
  • UI components: Added mnemonic input textarea with label, hint text, and validation status display in the configure keys step
  • Event listeners: Implemented blur and paste event handlers for the mnemonic input field with real-time validation feedback
  • Exports: Exposed setMnemonic function through the UI state module exports

Implementation Details

  • Mnemonic input accepts 12 or 24 word BIP39 phrases with flexible whitespace handling (normalized to single spaces)
  • Validation occurs on blur and after paste events with a 50ms delay to allow paste completion
  • Invalid mnemonics display an error message; valid inputs silently update the state
  • Duplicate mnemonic submissions are skipped to avoid unnecessary re-derivation
  • The generated mnemonic is pre-populated in the textarea as a fallback option

https://claude.ai/code/session_01EwRHibfwa5HFVRc3j9dyp9

Summary by CodeRabbit

New Features

  • Mnemonic phrase input field added to the key configuration setup
  • Real-time validation of mnemonic phrases with error messaging
  • Wallet keys automatically derived from valid user-provided mnemonics
  • Integrated mnemonic support into the existing key setup workflow

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
@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

The 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

Cohort / File(s) Summary
Crypto Validation
src/crypto/hd.ts
Added validateMnemonicPhrase() function that validates BIP39 mnemonic phrases using the English wordlist from scure/bip39.
UI State Management
src/ui/state.ts, src/ui/index.ts
Added setMnemonic() state transition function that normalizes mnemonic input, validates via validateMnemonicPhrase(), derives identity keys using generateDefaultIdentityKeysHD(), and returns updated state or null on validation failure. Exported via index module.
UI Presentation
src/ui/components.ts, src/main.ts
Added mnemonic input section to configure-keys UI with textarea, label, and validation status element. Wired blur and paste event handlers to read mnemonic input, validate, and trigger state updates or display validation errors.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Mnemonics hopped into the code today,
With validation magic keeping chaos at bay,
Words transform to keys with derivation's dance,
HD wallets spark from mnemonic's chance,
A fluffy feature that makes users prance! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding mnemonic input and validation functionality to the configure keys step, which aligns with all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/bridge-mnemonic-identity-rduBg

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 | 🟡 Minor

Hardcoded "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.mnemonic differs from the originally generated one, or simply using a more neutral message).

src/ui/state.ts (1)

112-127: setMnemonic returns null for invalid input — diverges from the pattern of other state transitions.

All other state transition functions in this file return BridgeState unconditionally. Returning null here pushes validation responsibility to every caller. This works fine with the single caller in main.ts today, 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 between main.ts and state.ts.

Line 344 replicates trim().replace(/\s+/g, ' ') from setMnemonic (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 shared normalizeMnemonic helper.

Comment on lines +357 to +363
} 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';
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

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