Skip to content

Conversation

@the-dev-z
Copy link
Collaborator

Pull Request - Frontend | 前端 PR

💡 提示 Tip: 推荐 PR 标题格式 `type(scope): description`
例如: `fix(web): fix button disabled validation for two-stage key input`


📝 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:

  1. User inputs: `0x` + 30 hex chars = 32 total characters
  2. Button disabled 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!)

Solution:

  • Normalize input (remove "0x") before checking length in button disabled conditions
  • Ensures button state is consistent with validation logic
  • Users only see enabled button when input is truly valid

中文:

本 PR 修復了兩階段私鑰輸入模態框中按鈕狀態與驗證邏輯不一致的問題:

問題:

場景:

  1. 用戶輸入:`0x` + 30 個 hex 字符 = 32 總字符
  2. 按鈕 disabled 檢查:`32 < 32` → false → ✅ 按鈕啟用
  3. 用戶點擊按鈕
  4. 驗證:標準化後 30 個 hex 字符 → `30 < 32` → ❌ 錯誤
  5. 錯誤訊息:「需要至少 32 個字符」(令人困惑!)

解決方案:

  • 在按鈕 disabled 條件中檢查長度之前標準化輸入(移除 "0x")
  • 確保按鈕狀態與驗證邏輯一致
  • 用戶只在輸入真正有效時才看到啟用的按鈕

🎯 Type of Change | 变更类型

  • ✨ New feature | 新功能
  • 🎨 Code style update | 代码样式更新
  • ♻️ Refactoring | 重构
  • 🐛 Bug fix | 修复 Bug
  • 💥 Breaking change | 破坏性变更
  • ⚡ Performance improvement | 性能优化

🔗 Related Issues | 相关 Issue

Fixes:

Related:


📋 Changes Made | 具体变更

Bug Details

File: `web/src/components/TwoStageKeyModal.tsx`

Line 230 (Stage 1 button):

// ❌ Before: Checks raw length
disabled={part1.length < expectedPart1Length || processing}

// ✅ After: Normalizes before checking
disabled={
  (part1.startsWith('0x') ? part1.slice(2) : part1).length <
    expectedPart1Length || processing
}

Line 301 (Stage 2 button):

// ❌ Before: Checks raw length
disabled={part2.length < expectedPart2Length}

// ✅ After: Normalizes before checking
disabled={
  (part2.startsWith('0x') ? part2.slice(2) : part2).length <
  expectedPart2Length
}

Logic Flow Comparison

Before (❌ Inconsistent):

Component Input Length Check Normalization Result
Button disabled `0x` + 30 hex Raw: `32 < 32` → false ❌ None Button enabled (wrong!)
Validation logic `0x` + 30 hex Normalized: `30 < 32` → true ✅ Removes "0x" Error shown

After (✅ Consistent):

Component Input Length Check Normalization Result
Button disabled `0x` + 30 hex Normalized: `30 < 32` → true ✅ Removes "0x" Button disabled (correct!)
Validation logic `0x` + 30 hex Normalized: `30 < 32` → true ✅ Removes "0x" N/A (can't click)

Test Scenarios

Input Format Total Chars Hex Chars Before (Button) After (Button) Validation
`0x` + 30 hex 32 30 ✅ Enabled (bug) ❌ Disabled ❌ Would fail
`0x` + 32 hex 34 32 ✅ Enabled ✅ Enabled ✅ Valid
32 hex (no prefix) 32 32 ✅ Enabled ✅ Enabled ✅ Valid
`0x` + 16 hex 18 16 ❌ Disabled ❌ Disabled N/A

🧪 Testing | 测试

Manual Testing | 手动测试

Test Case 1: Valid input with "0x" prefix

  • Input: `0x` + 32 hex characters
  • Expected: Button enabled, validation passes ✅
  • Result: ✅ Works correctly

Test Case 2: Valid input without prefix

  • Input: 32 hex characters (no "0x")
  • Expected: Button enabled, validation passes ✅
  • Result: ✅ Works correctly

Test Case 3: Insufficient hex chars with "0x" (bug scenario)

  • Input: `0x` + 30 hex characters (32 total)
  • Expected (Before): Button enabled (BUG) ❌
  • Expected (After): Button disabled ✅
  • Result: ✅ Fixed!

Test Case 4: Mixed formats

  • Part 1: `0x` + 32 hex, Part 2: 32 hex (no prefix)
  • Expected: Both buttons properly disabled until valid ✅
  • Result: ✅ Works correctly

Consistency Verification

Validation Path Normalization Logic
`handleStage1Next` ✅ Normalizes (PR #917)
`handleStage2Complete` ✅ Normalizes (PR #917)
`validatePrivateKeyFormat` ✅ Normalizes (existing)
Button disabled (Stage 1) ✅ Normalizes (this PR)
Button disabled (Stage 2) ✅ Normalizes (this PR)

Result: All validation paths now fully consistent ✅


📊 Impact Analysis | 影响分析

User Experience Improvement

Before:

  1. User enters `0x` + 30 hex characters
  2. Button becomes enabled (misleading)
  3. User clicks, gets error "需要至少 32 個字符"
  4. User confused: "I have 32 characters!" (counting the "0x")
  5. Poor UX ❌

After:

  1. User enters `0x` + 30 hex characters
  2. Button stays disabled (correct feedback)
  3. User adds 2 more hex characters
  4. Button enables, validation passes
  5. Smooth UX ✅

Code Quality

  • ✅ Consistency: All validation paths now use same normalization logic
  • ✅ Predictability: Button state accurately reflects validity
  • ✅ Maintainability: Single source of truth for "0x" handling
  • ✅ No breaking changes: Only fixes button state, doesn't change validation

✅ Checklist | 检查清单

Code Quality | 代码质量

  • Code follows project style | 代码遵循项目风格
  • Self-review completed | 已完成代码自查
  • Comments explain the fix | 已添加必要注释
  • Code builds successfully | 代码构建成功
  • No TypeScript errors | 无 TypeScript 错误

Testing | 测试

  • Manual testing completed | 完成手动测试
  • All test scenarios passed | 所有测试场景通过
  • Tested with various input formats | 測試各種輸入格式
  • Button state verified consistent | 驗證按鈕狀態一致

Documentation | 文档

  • Detailed commit message | 详细的提交信息
  • Clear PR description with examples | 清晰的 PR 描述與範例

Git

  • Commits follow conventional format | 提交遵循 Conventional Commits 格式
  • Rebased on latest `dev` branch | 已 rebase 到最新 `dev` 分支
  • No merge conflicts | 无合并冲突
  • Single focused commit | 單一聚焦提交

💡 Additional Notes | 补充说明

Why This Matters

Validation consistency is critical for UX:

  • Users should never see enabled button → click → error
  • Button state should be accurate feedback mechanism
  • Consistent "0x" handling across all validation points

This is a follow-up to PR #917:

Code Simplicity

  • Simple inline normalization: `(value.startsWith('0x') ? value.slice(2) : value).length`
  • No new functions needed
  • Matches existing pattern in validation logic
  • 2 small changes, big UX improvement

By submitting this PR, I confirm | 提交此 PR,我确认:

  • I have read the Contributing Guidelines | 已阅读贡献指南
  • I agree to the Code of Conduct | 同意行为准则
  • My contribution is licensed under AGPL-3.0 | 贡献遵循 AGPL-3.0 许可证

🌟 Thank you for reviewing! | 感谢审阅!

This PR completes the "0x" prefix support started in PR #917.

## 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>
@github-actions
Copy link

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ✅ Good - Follows Conventional Commits
PR Size: 🟢 Small (10 lines: +8 -2)

🔧 Backend Checks

Go Formatting: ✅ Good
Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

@tinkle-community tinkle-community merged commit 5ad731d into NoFxAiOS:dev Nov 12, 2025
16 checks passed
the-dev-z added a commit to the-dev-z/nofx that referenced this pull request Nov 12, 2025
…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>
the-dev-z added a commit to the-dev-z/nofx that referenced this pull request Nov 12, 2025
…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>
the-dev-z added a commit to the-dev-z/nofx that referenced this pull request Nov 12, 2025
合併 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>
bebest2010 pushed a commit to bebest2010/nofx that referenced this pull request Nov 18, 2025
…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>
tinkle-community added a commit that referenced this pull request Nov 26, 2025
## 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>
tinkle-community added a commit that referenced this pull request Nov 26, 2025
## 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>
tinkle-community pushed a commit that referenced this pull request Dec 7, 2025
## 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>
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