fix(wallet): accept newline-separated seed words on import#3186
fix(wallet): accept newline-separated seed words on import#31860xPepeSilvia wants to merge 2 commits intotari-project:mainfrom
Conversation
The seed-words regex required exactly single-space separators, and the
downstream split(' ') consumers only split on a literal space. This
meant that users typing one word per line (pressing Enter between
words) or pasting a comma-separated phrase would see the mnemonic
error "Only ChineseSimplified, ChineseTraditional, English, ... are
defined natural languages" and the confirmation tick would never
become available.
- Broadened SEEDWORD_REGEX to accept any run of whitespace or commas
as a separator (24 alphabetic words, optional surrounding whitespace)
- Added normalizeSeedWordsInput() helper that collapses whitespace /
commas into single spaces
- Paste handler now uses the shared normalizer and passes
shouldValidate/shouldDirty so the tick updates immediately
- SeedWords and EmptySeedWords handleApply now split on /[\s,]+/ and
filter empties so the array sent to the Tauri import_seed_words
command is clean regardless of input format
Closes tari-project#3128
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request enhances seed word parsing by supporting commas and multiple whitespace formats, and introduces a normalization utility for consistent input handling. Key feedback includes expanding the validation regex to support non-English seed words and removing a redundant manual validation trigger in the paste handler.
| // means validation — and therefore the confirmation tick — works whether the | ||
| // user types words separated by spaces, presses Enter between words, or | ||
| // pastes a comma-separated list. | ||
| const SEEDWORD_REGEX = /^\s*([a-zA-Z]+)([\s,]+[a-zA-Z]+){23}\s*$/; |
There was a problem hiding this comment.
The regex [a-zA-Z]+ is too restrictive for BIP-39 seed words. As noted in the error message mentioned in the PR description, the wallet supports multiple languages including Japanese, Chinese, and Spanish, which contain non-ASCII characters or accents that do not match [a-zA-Z]. Using a more inclusive pattern like [^\s,]+ (any character except whitespace or commas) ensures that valid seed phrases in all supported languages can pass frontend validation.
| const SEEDWORD_REGEX = /^\s*([a-zA-Z]+)([\s,]+[a-zA-Z]+){23}\s*$/; | |
| const SEEDWORD_REGEX = /^\s*([^\s,]+)([\s,]+[^\s,]+){23}\s*$/; |
| setValue('seedWords', formattedSeedText, { shouldValidate: true, shouldDirty: true }); | ||
| trigger('seedWords'); | ||
| }, | ||
| [setValue, trigger] |
There was a problem hiding this comment.
The call to trigger('seedWords') is redundant because setValue is already invoked with { shouldValidate: true }, which automatically triggers validation for the field. Additionally, trigger should be removed from the useCallback dependency array if it is no longer used within the function.
| setValue('seedWords', formattedSeedText, { shouldValidate: true, shouldDirty: true }); | |
| trigger('seedWords'); | |
| }, | |
| [setValue, trigger] | |
| setValue('seedWords', formattedSeedText, { shouldValidate: true, shouldDirty: true }); | |
| }, | |
| [setValue] |
Addresses two review comments on the seed-word import:
* Widen SEEDWORD_REGEX from [a-zA-Z]+ to [^\s,]+ with the /u flag so
Japanese, Chinese (Simplified/Traditional), Korean, Spanish, French,
and Italian BIP-39 phrases — all supported by the backend — also pass
the frontend confirmation-tick check. The previous class silently
rejected any non-ASCII wordlist even though the backend would accept
it, funnelling users back into the same "Only ChineseSimplified, …
are defined natural languages" error path this PR was trying to fix.
* Remove the redundant trigger('seedWords') call in handlePaste: the
preceding setValue(..., { shouldValidate: true }) already runs the
validator, so calling trigger again just caused an extra form
re-render. Drop it from the useCallback dependency array too.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
The seed-words regex required exactly single-space separators, and the downstream `split(' ')` consumers only split on a literal space. This meant users who typed one word per line (pressing Enter between words), or pasted a comma-separated phrase, would hit the confusing error:
and the confirmation tick would never become available.
Changes
Closes #3128
Test plan
🤖 Generated with Claude Code
Bounty payout
If this PR is accepted as a bounty submission, please direct funds to the following Tari wallet address:
123JbAxCZ4Vrh4jCjFLXTu4z8sLeggUR87fejwNunsB55NMBSH9RpkjNiw1WL2GkKr8JhqRZhbrsSREchGanchw2Nhb