-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix(web): fix button disabled validation for two-stage key input #937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(web): fix button disabled validation for two-stage key input #937
Conversation
## Problem PR NoFxAiOS#917 fixed the validation logic but missed fixing the button disabled state: **Issue:** - Button enabled/disabled check uses raw input length (includes "0x") - Validation logic uses normalized length (excludes "0x") - **Result:** Button can be enabled with insufficient hex characters **Example scenario:** 1. User inputs: `0x` + 30 hex chars = 32 total chars 2. Button check: `32 < 32` → false → ✅ Button enabled 3. User clicks button 4. Validation: normalized to 30 hex chars → `30 < 32` → ❌ Error 5. Error message: "需要至少 32 個字符" (confusing!) ## Root Cause **Lines 230 & 301**: Button disabled conditions don't normalize input ```typescript // ❌ Before: Checks raw length including "0x" disabled={part1.length < expectedPart1Length || processing} disabled={part2.length < expectedPart2Length} ``` ## Solution Normalize input before checking length in disabled conditions: ```typescript // ✅ After: Normalize before checking disabled={ (part1.startsWith('0x') ? part1.slice(2) : part1).length < expectedPart1Length || processing } disabled={ (part2.startsWith('0x') ? part2.slice(2) : part2).length < expectedPart2Length } ``` ## Testing | Input | Total Length | Normalized Length | Button (Before) | Button (After) | Click Result | |-------|--------------|-------------------|-----------------|----------------|--------------| | `0x` + 30 hex | 32 | 30 | ✅ Enabled (bug) | ❌ Disabled | N/A | | `0x` + 32 hex | 34 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | | 32 hex | 32 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | ## Impact - ✅ Button state now consistent with validation logic - ✅ Users won't see confusing "need 32 chars" errors when button is enabled - ✅ Better UX - button only enabled when input is truly valid **Related:** Follow-up to PR NoFxAiOS#917 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
…aracter requirements
## Problem
Users were confused about the character count requirements for the two-stage private key input:
**Issues:**
- Description said "32 characters" without specifying hexadecimal
- No mention of whether "0x" prefix should be included
- Users didn't know if they should input 32 total chars or 32 hex chars
- Led to confusion: "I have 32 characters but it says incomplete!"
**User Feedback:**
- "所以32是不包含0x?" (Does 32 include 0x or not?)
- Users need clear guidance on input format
## Solution
Added help text below each input field to clarify:
**English:**
- "💡 Accepts 32 hex characters with or without "0x" prefix"
**Chinese:**
- "💡 可包含或省略 "0x" 前綴(32 位 hex 字符)"
**Additional improvements:**
- Updated descriptions to say "hex characters" instead of just "characters"
- Help text appears in small gray font below input field
- Non-intrusive but clear guidance
## Changes
### 1. translations.ts (Lines 823-825, 1616-1617)
**English:**
```typescript
stage1Description: 'Enter the first {length} hex characters of your private key',
helpText: '💡 Accepts {length} hex characters with or without "0x" prefix',
```
**Chinese:**
```typescript
stage1Description: '请输入私钥的前 {length} 位十六进制字符',
helpText: '💡 可包含或省略 "0x" 前綴({length} 位 hex 字符)',
```
### 2. TwoStageKeyModal.tsx (Lines 223-227, 302-306)
Added help text below input fields:
```tsx
<div className="text-gray-400 text-xs mt-1">
{t('twoStageKey.helpText', language, {
length: expectedPart1Length,
})}
</div>
```
## UI Impact
**Before:**
```
第一部分 (32 位字符)
[輸入框]
```
**After:**
```
第一部分 (32 位字符)
[輸入框]
💡 可包含或省略 "0x" 前綴(32 位 hex 字符)
```
## Benefits
- ✅ Clear guidance: Users know they need 32 **hex** characters
- ✅ Format flexibility: Both "0x1234..." and "1234..." are valid
- ✅ Reduces confusion: No more "why is my 32-char input rejected?"
- ✅ Better UX: Proactive help instead of error messages
- ✅ Bilingual support: Both EN and ZH have clear explanations
## Testing
**Manual Test Cases:**
| Input Format | Display | Expected Behavior |
|--------------|---------|-------------------|
| User sees Stage 1 | Help text shown | ✅ "💡 Accepts 32 hex characters..." |
| User sees Stage 2 | Help text shown | ✅ "💡 Accepts 32 hex characters..." |
| Input `0x` + 32 hex | Button enabled | ✅ Accepted (34 total chars) |
| Input 32 hex (no prefix) | Button enabled | ✅ Accepted (32 total chars) |
| Input `0x` + 30 hex | Button disabled | ✅ Rejected (only 30 hex chars) |
**Related:** Follow-up UX improvement for PR NoFxAiOS#917 and PR NoFxAiOS#937
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
…aracter requirements
## Problem
Users were confused about the character count requirements for the two-stage private key input:
**Issues:**
- Description said "32 characters" without specifying hexadecimal
- No mention of whether "0x" prefix should be included
- Users didn't know if they should input 32 total chars or 32 hex chars
- Led to confusion: "I have 32 characters but it says incomplete!"
**User Feedback:**
- "所以32是不包含0x?" (Does 32 include 0x or not?)
- Users need clear guidance on input format
## Solution
Added help text below each input field to clarify:
**English:**
- "💡 Accepts 32 hex characters with or without "0x" prefix"
**Chinese:**
- "💡 可包含或省略 "0x" 前綴(32 位 hex 字符)"
**Additional improvements:**
- Updated descriptions to say "hex characters" instead of just "characters"
- Help text appears in small gray font below input field
- Non-intrusive but clear guidance
## Changes
### 1. translations.ts (Lines 823-825, 1616-1617)
**English:**
```typescript
stage1Description: 'Enter the first {length} hex characters of your private key',
helpText: '💡 Accepts {length} hex characters with or without "0x" prefix',
```
**Chinese:**
```typescript
stage1Description: '请输入私钥的前 {length} 位十六进制字符',
helpText: '💡 可包含或省略 "0x" 前綴({length} 位 hex 字符)',
```
### 2. TwoStageKeyModal.tsx (Lines 223-227, 302-306)
Added help text below input fields:
```tsx
<div className="text-gray-400 text-xs mt-1">
{t('twoStageKey.helpText', language, {
length: expectedPart1Length,
})}
</div>
```
## UI Impact
**Before:**
```
第一部分 (32 位字符)
[輸入框]
```
**After:**
```
第一部分 (32 位字符)
[輸入框]
💡 可包含或省略 "0x" 前綴(32 位 hex 字符)
```
## Benefits
- ✅ Clear guidance: Users know they need 32 **hex** characters
- ✅ Format flexibility: Both "0x1234..." and "1234..." are valid
- ✅ Reduces confusion: No more "why is my 32-char input rejected?"
- ✅ Better UX: Proactive help instead of error messages
- ✅ Bilingual support: Both EN and ZH have clear explanations
## Testing
**Manual Test Cases:**
| Input Format | Display | Expected Behavior |
|--------------|---------|-------------------|
| User sees Stage 1 | Help text shown | ✅ "💡 Accepts 32 hex characters..." |
| User sees Stage 2 | Help text shown | ✅ "💡 Accepts 32 hex characters..." |
| Input `0x` + 32 hex | Button enabled | ✅ Accepted (34 total chars) |
| Input 32 hex (no prefix) | Button enabled | ✅ Accepted (32 total chars) |
| Input `0x` + 30 hex | Button disabled | ✅ Rejected (only 30 hex chars) |
**Related:** Follow-up UX improvement for PR NoFxAiOS#917 and PR NoFxAiOS#937
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
合併 5 個上游 commits: - b7fe547: fix(web): unify password validation logic (NoFxAiOS#943) - 7af0daf: fix: improve two-stage private key input UX (NoFxAiOS#942) - 5ad731d: fix(web): fix button disabled validation (NoFxAiOS#937) - cca7bc5: feat: Hyperliquid Agent Wallet docs (NoFxAiOS#936) - 70adfd7: feat(docs): add Hyperliquid tutorial (NoFxAiOS#935) 解決衝突: - TwoStageKeyModal.tsx: 選擇上游英文註釋版本 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…AiOS#937) ## Problem PR NoFxAiOS#917 fixed the validation logic but missed fixing the button disabled state: **Issue:** - Button enabled/disabled check uses raw input length (includes "0x") - Validation logic uses normalized length (excludes "0x") - **Result:** Button can be enabled with insufficient hex characters **Example scenario:** 1. User inputs: `0x` + 30 hex chars = 32 total chars 2. Button check: `32 < 32` → false → ✅ Button enabled 3. User clicks button 4. Validation: normalized to 30 hex chars → `30 < 32` → ❌ Error 5. Error message: "需要至少 32 個字符" (confusing!) ## Root Cause **Lines 230 & 301**: Button disabled conditions don't normalize input ```typescript // ❌ Before: Checks raw length including "0x" disabled={part1.length < expectedPart1Length || processing} disabled={part2.length < expectedPart2Length} ``` ## Solution Normalize input before checking length in disabled conditions: ```typescript // ✅ After: Normalize before checking disabled={ (part1.startsWith('0x') ? part1.slice(2) : part1).length < expectedPart1Length || processing } disabled={ (part2.startsWith('0x') ? part2.slice(2) : part2).length < expectedPart2Length } ``` ## Testing | Input | Total Length | Normalized Length | Button (Before) | Button (After) | Click Result | |-------|--------------|-------------------|-----------------|----------------|--------------| | `0x` + 30 hex | 32 | 30 | ✅ Enabled (bug) | ❌ Disabled | N/A | | `0x` + 32 hex | 34 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | | 32 hex | 32 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | ## Impact - ✅ Button state now consistent with validation logic - ✅ Users won't see confusing "need 32 chars" errors when button is enabled - ✅ Better UX - button only enabled when input is truly valid **Related:** Follow-up to PR NoFxAiOS#917 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
## Problem PR #917 fixed the validation logic but missed fixing the button disabled state: **Issue:** - Button enabled/disabled check uses raw input length (includes "0x") - Validation logic uses normalized length (excludes "0x") - **Result:** Button can be enabled with insufficient hex characters **Example scenario:** 1. User inputs: `0x` + 30 hex chars = 32 total chars 2. Button check: `32 < 32` → false → ✅ Button enabled 3. User clicks button 4. Validation: normalized to 30 hex chars → `30 < 32` → ❌ Error 5. Error message: "需要至少 32 個字符" (confusing!) ## Root Cause **Lines 230 & 301**: Button disabled conditions don't normalize input ```typescript // ❌ Before: Checks raw length including "0x" disabled={part1.length < expectedPart1Length || processing} disabled={part2.length < expectedPart2Length} ``` ## Solution Normalize input before checking length in disabled conditions: ```typescript // ✅ After: Normalize before checking disabled={ (part1.startsWith('0x') ? part1.slice(2) : part1).length < expectedPart1Length || processing } disabled={ (part2.startsWith('0x') ? part2.slice(2) : part2).length < expectedPart2Length } ``` ## Testing | Input | Total Length | Normalized Length | Button (Before) | Button (After) | Click Result | |-------|--------------|-------------------|-----------------|----------------|--------------| | `0x` + 30 hex | 32 | 30 | ✅ Enabled (bug) | ❌ Disabled | N/A | | `0x` + 32 hex | 34 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | | 32 hex | 32 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | ## Impact - ✅ Button state now consistent with validation logic - ✅ Users won't see confusing "need 32 chars" errors when button is enabled - ✅ Better UX - button only enabled when input is truly valid **Related:** Follow-up to PR #917 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: tinkle-community <tinklefund@gmail.com>
## Problem PR #917 fixed the validation logic but missed fixing the button disabled state: **Issue:** - Button enabled/disabled check uses raw input length (includes "0x") - Validation logic uses normalized length (excludes "0x") - **Result:** Button can be enabled with insufficient hex characters **Example scenario:** 1. User inputs: `0x` + 30 hex chars = 32 total chars 2. Button check: `32 < 32` → false → ✅ Button enabled 3. User clicks button 4. Validation: normalized to 30 hex chars → `30 < 32` → ❌ Error 5. Error message: "需要至少 32 個字符" (confusing!) ## Root Cause **Lines 230 & 301**: Button disabled conditions don't normalize input ```typescript // ❌ Before: Checks raw length including "0x" disabled={part1.length < expectedPart1Length || processing} disabled={part2.length < expectedPart2Length} ``` ## Solution Normalize input before checking length in disabled conditions: ```typescript // ✅ After: Normalize before checking disabled={ (part1.startsWith('0x') ? part1.slice(2) : part1).length < expectedPart1Length || processing } disabled={ (part2.startsWith('0x') ? part2.slice(2) : part2).length < expectedPart2Length } ``` ## Testing | Input | Total Length | Normalized Length | Button (Before) | Button (After) | Click Result | |-------|--------------|-------------------|-----------------|----------------|--------------| | `0x` + 30 hex | 32 | 30 | ✅ Enabled (bug) | ❌ Disabled | N/A | | `0x` + 32 hex | 34 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | | 32 hex | 32 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | ## Impact - ✅ Button state now consistent with validation logic - ✅ Users won't see confusing "need 32 chars" errors when button is enabled - ✅ Better UX - button only enabled when input is truly valid **Related:** Follow-up to PR #917 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: tinkle-community <tinklefund@gmail.com>
## Problem PR #917 fixed the validation logic but missed fixing the button disabled state: **Issue:** - Button enabled/disabled check uses raw input length (includes "0x") - Validation logic uses normalized length (excludes "0x") - **Result:** Button can be enabled with insufficient hex characters **Example scenario:** 1. User inputs: `0x` + 30 hex chars = 32 total chars 2. Button check: `32 < 32` → false → ✅ Button enabled 3. User clicks button 4. Validation: normalized to 30 hex chars → `30 < 32` → ❌ Error 5. Error message: "需要至少 32 個字符" (confusing!) ## Root Cause **Lines 230 & 301**: Button disabled conditions don't normalize input ```typescript // ❌ Before: Checks raw length including "0x" disabled={part1.length < expectedPart1Length || processing} disabled={part2.length < expectedPart2Length} ``` ## Solution Normalize input before checking length in disabled conditions: ```typescript // ✅ After: Normalize before checking disabled={ (part1.startsWith('0x') ? part1.slice(2) : part1).length < expectedPart1Length || processing } disabled={ (part2.startsWith('0x') ? part2.slice(2) : part2).length < expectedPart2Length } ``` ## Testing | Input | Total Length | Normalized Length | Button (Before) | Button (After) | Click Result | |-------|--------------|-------------------|-----------------|----------------|--------------| | `0x` + 30 hex | 32 | 30 | ✅ Enabled (bug) | ❌ Disabled | N/A | | `0x` + 32 hex | 34 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | | 32 hex | 32 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | ## Impact - ✅ Button state now consistent with validation logic - ✅ Users won't see confusing "need 32 chars" errors when button is enabled - ✅ Better UX - button only enabled when input is truly valid **Related:** Follow-up to PR #917 Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: tinkle-community <tinklefund@gmail.com>
Pull Request - Frontend | 前端 PR
📝 Description | 描述
English:
This PR fixes a validation inconsistency in the two-stage private key input modal where button states didn't match validation logic:
Problem:
Scenario:
Solution:
中文:
本 PR 修復了兩階段私鑰輸入模態框中按鈕狀態與驗證邏輯不一致的問題:
問題:
場景:
解決方案:
🎯 Type of Change | 变更类型
🔗 Related Issues | 相关 Issue
Fixes:
Related:
📋 Changes Made | 具体变更
Bug Details
File: `web/src/components/TwoStageKeyModal.tsx`
Line 230 (Stage 1 button):
Line 301 (Stage 2 button):
Logic Flow Comparison
Before (❌ Inconsistent):
After (✅ Consistent):
Test Scenarios
🧪 Testing | 测试
Manual Testing | 手动测试
Test Case 1: Valid input with "0x" prefix
Test Case 2: Valid input without prefix
Test Case 3: Insufficient hex chars with "0x" (bug scenario)
Test Case 4: Mixed formats
Consistency Verification
Result: All validation paths now fully consistent ✅
📊 Impact Analysis | 影响分析
User Experience Improvement
Before:
After:
Code Quality
✅ Checklist | 检查清单
Code Quality | 代码质量
Testing | 测试
Documentation | 文档
Git
💡 Additional Notes | 补充说明
Why This Matters
Validation consistency is critical for UX:
This is a follow-up to PR #917:
Code Simplicity
By submitting this PR, I confirm | 提交此 PR,我确认:
🌟 Thank you for reviewing! | 感谢审阅!
This PR completes the "0x" prefix support started in PR #917.