Skip to content

Conversation

@the-dev-z
Copy link
Contributor

Pull Request - Frontend | 前端 PR

💡 提示 Tip: 推荐 PR 标题格式 `type(scope): description`
例如: `improve(web): enhance two-stage key input UX with clear format guidance`


📝 Description | 描述

English:

This PR enhances the two-stage private key input UX by adding clear guidance on character requirements:

Problems Solved:

  1. Users confused about whether "32 characters" includes "0x" prefix
  2. No guidance on supported input formats
  3. Users receiving "incomplete key" errors despite having correct number of characters

Solutions:

  1. Updated descriptions to explicitly say "hex characters" instead of just "characters"
  2. Added help text below input fields showing exact character counts for both formats
  3. Clear messaging: "Enter 32 hex chars (without 0x) or 34 chars (with 0x)"

中文:

本 PR 通過添加清晰的字符要求指導來增強兩階段私鑰輸入的用戶體驗:

解決的問題:

  1. 用戶困惑「32 位字符」是否包含 "0x" 前綴
  2. 沒有支持的輸入格式說明
  3. 用戶儘管輸入了正確數量的字符仍收到「私鑰不完整」錯誤

解決方案:

  1. 更新描述明確說明「十六進制字符」而不僅是「字符」
  2. 在輸入框下方添加幫助文本,顯示兩種格式的確切字符數
  3. 清晰的消息:「請輸入 32 位(不含 0x)或 34 位(含 0x 前綴)」

🎯 Type of Change | 变更类型

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

🔗 Related Issues | 相关 Issue

Improves:

User Feedback:

  • Users didn't know whether to include "0x" prefix
  • Confusion about exact character count needed
  • Need for clear, upfront guidance instead of error messages

📋 Changes Made | 具体变更

Change 1: Add Help Text (Commit 1)

File: `web/src/i18n/translations.ts`

English translations:

// Before
stage1Description: 'Enter the first {length} characters of your private key'

// After
stage1Description: 'Enter the first {length} hex characters of your private key'
helpText: '💡 Accepts {length} hex characters with or without "0x" prefix'

Chinese translations:

// Before
stage1Description: '请输入私钥的前 {length} 位字符'

// After  
stage1Description: '请输入私钥的前 {length} 位十六进制字符'
helpText: '💡 可包含或省略 "0x" 前綴({length} 位 hex 字符)'

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

Added help text below input fields:

<div className="text-gray-400 text-xs mt-1">
  {t('twoStageKey.helpText', language, {
    length: expectedPart1Length,
  })}
</div>

Change 2: Clarify Exact Character Counts (Commit 2)

Updated help text to show exact numbers:

English:

helpText: '💡 Enter {length} hex chars (without 0x) or {totalWithPrefix} chars (with 0x)'
// Displays: "💡 Enter 32 hex chars (without 0x) or 34 chars (with 0x)"

Chinese:

helpText: '💡 請輸入 {length} 位(不含 0x)或 {totalWithPrefix} 位(含 0x 前綴)'
// Displays: "💡 請輸入 32 位(不含 0x)或 34 位(含 0x 前綴)"

Added parameter:

{t('twoStageKey.helpText', language, {
  length: expectedPart1Length,          // 32
  totalWithPrefix: expectedPart1Length + 2,  // 34
})}

🎨 UI Impact | 界面影响

Before (修改前)

第一部分 (32 位字符)
┌─────────────────────────────┐
│ [密碼輸入框]                 │
└─────────────────────────────┘
                                ← ❌ No guidance
[下一步]  [取消]

Issues:

  • No explanation of what "32 characters" means
  • No guidance on "0x" prefix handling
  • Users must guess or encounter errors

After (修改後)

第一部分 (32 位字符)
┌─────────────────────────────┐
│ [密碼輸入框]                 │
└─────────────────────────────┘
💡 請輸入 32 位(不含 0x)      ← ✅ Clear guidance
   或 34 位(含 0x 前綴)
[下一步]  [取消]

Benefits:

  • Clear explanation: 32 hex chars OR 34 total chars
  • Upfront guidance prevents errors
  • Users know both formats are supported

🧪 Testing | 测试

Manual Testing | 手动测试

Test Case 1: User sees help text

  • Open two-stage modal
  • Expected: Help text visible below input
  • Result: ✅ "💡 請輸入 32 位(不含 0x)或 34 位(含 0x 前綴)"

Test Case 2: Input without 0x prefix

  • Input: 32 hex characters (no "0x")
  • Help text guidance: "32 位(不含 0x)"
  • Result: ✅ Accepted

Test Case 3: Input with 0x prefix

  • Input: "0x" + 32 hex characters (34 total)
  • Help text guidance: "34 位(含 0x 前綴)"
  • Result: ✅ Accepted

Test Case 4: Bilingual support

  • Switch language EN ↔ ZH
  • Expected: Help text updates correctly
  • Result: ✅ Both languages show clear guidance

Visual Testing | 视觉测试

Element Before After
Description "32 位字符" "32 位十六進制字符" ✅
Help Text ❌ None "💡 32 位(不含 0x)或 34 位" ✅
Clarity ❌ Ambiguous ✅ Crystal clear

📊 Impact Analysis | 影响分析

User Experience Improvement

Before:

  1. User opens modal: "Enter first 32 characters"
  2. User confused: "32 with or without 0x?"
  3. User tries: "0x" + 30 hex chars (32 total)
  4. Gets error: "Please enter at least 32 characters"
  5. User frustrated: "But I have 32 characters!"
  6. ❌ Poor UX

After:

  1. User opens modal: "Enter first 32 hex characters"
  2. Sees help text: "💡 32 位(不含 0x)或 34 位(含 0x 前綴)"
  3. User understands: "I need 32 hex chars, so 34 total with 0x"
  4. Inputs correctly on first try
  5. ✅ Smooth UX

Metrics

Metric Impact
User Confusion ⬇️ Reduced (clear guidance upfront)
Error Rate ⬇️ Reduced (know format before typing)
Success Rate ⬆️ Increased (first-try success)
Support Tickets ⬇️ Reduced (self-service guidance)

📦 Files Changed | 文件变更

web/src/components/TwoStageKeyModal.tsx  | 12 ++++++++++++
web/src/i18n/translations.ts             | 10 ++++++----
2 files changed, 18 insertions(+), 4 deletions(-)

Summary:

  • 2 files modified
  • 20 lines added, 4 lines modified
  • No breaking changes
  • Frontend-only changes (no backend impact)

✅ Checklist | 检查清单

Code Quality | 代码质量

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

Testing | 测试

  • Manual testing completed | 完成手动测试
  • All test scenarios passed | 所有测试场景通过
  • Tested both languages (EN/ZH) | 测试双语显示
  • Visual verification done | 完成视觉验证

Documentation | 文档

  • Detailed commit messages | 详细的提交信息
  • Clear PR description | 清晰的 PR 描述
  • Screenshots/examples provided | 提供截图/示例

Git

  • Commits follow conventional format | 提交遵循 Conventional Commits 格式
  • Rebased on latest `dev` branch | 已 rebase 到最新 `dev` 分支
  • No merge conflicts | 无合并冲突
  • Focused, logical commits | 聚焦、合理的提交

💡 Additional Notes | 补充说明

Why This Matters

User Psychology:

  • Users prefer upfront guidance over error messages
  • Clear expectations reduce anxiety and frustration
  • Explicit numbers (32 or 34) better than ambiguous descriptions

Design Principle:

  • "Make the right thing easy and the wrong thing hard"
  • Help text acts as inline documentation
  • Prevents errors instead of handling them

Implementation Details

Incremental Improvement:

  • Commit 1: Add basic help text with format explanation
  • Commit 2: Refine to show exact character counts (32 vs 34)
  • Result: Crystal clear guidance for users

Bilingual Consistency:

  • Both EN and ZH versions equally clear
  • No translation ambiguity
  • Consistent terminology ("hex chars")

Related Work

This PR builds on PR #937:


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 UX improvements for two-stage private key input.

Icyoung and others added 30 commits November 4, 2025 01:50
The chart was not showing data because the API response format changed.
Fixed the calculation of PnL percentage by computing it from total_pnl
and balance values (initial_balance = balance - total_pnl).

Now the AI competition chart should properly display performance comparison data.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add NOFX watermark to ComparisonChart (competition page)
- Add NOFX watermark to EquityChart (dashboard page)
- Fix empty state handling and internationalization in CompetitionPage

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fix(workflow): add title and size validation comments
fix(readme): update readme and pr reviewer
…ssing-fields

fix(database): GetTraderConfig missing critical fields causes edit to fail
Fix:fix the main branch history issue from November 3rd.
Merge pull request NoFxAiOS#395 from NoFxAiOS/beta
fix:fix the main branch history issue from November 3rd.
Enable automatic wallet address generation from private key for Hyperliquid
exchange, simplifying user onboarding and reducing configuration errors.

Backend Changes (trader/hyperliquid_trader.go):
- Import crypto/ecdsa package for ECDSA public key operations
- Enable wallet address auto-generation when walletAddr is empty
- Use crypto.PubkeyToAddress() to derive address from private key
- Add logging for both auto-generated and manually provided addresses

Frontend Changes (web/src/components/AITradersPage.tsx):
- Remove wallet address required validation (only private key required)
- Update button disabled state to only check private key
- Add "Optional" label to wallet address field
- Add dynamic placeholder with bilingual hint
- Show context-aware helper text based on input state
- Remove HTML required attribute from input field

Translation Updates (web/src/i18n/translations.ts):
- Add 'optional' translation (EN: "Optional", ZH: "可选")
- Add 'hyperliquidWalletAddressAutoGenerate' translation
  EN: "Leave blank to automatically generate wallet address from private key"
  ZH: "留空将自动从私钥生成钱包地址"

Benefits:
✅ Simplified UX - Users only need to provide private key
✅ Error prevention - Auto-generated address always matches private key
✅ Backward compatible - Manual address input still supported
✅ Better UX - Clear visual indicators for optional fields

Technical Details:
- Uses Ethereum standard ECDSA public key to address conversion
- Implementation was already present but commented out (lines 37-43)
- No database schema changes required (hyperliquid_wallet_addr already nullable)
- Fallback behavior: manual input > auto-generation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add Binance configuration tutorial image (guide.png)
- Implement "View Guide" button in exchange configuration modal
- Add tutorial display modal with image viewer
- Add i18n support for guide-related text (EN/ZH)
- Button only appears when configuring Binance exchange

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
 feat: Add Binance setup guide with tutorial modal
Problem:
- Users could input arbitrary initial balance when creating traders
- This didn't reflect the actual available balance in exchange account
- Could lead to incorrect position sizing and risk calculations

Solution:
- Before creating trader, query exchange API for actual balance
- Use GetBalance() from respective trader implementation:
  * Binance: NewFuturesTrader + GetBalance()
  * Hyperliquid: NewHyperliquidTrader + GetBalance()
  * Aster: NewAsterTrader + GetBalance()
- Extract 'available_balance' or 'balance' from response
- Override user input with actual balance
- Fallback to user input if query fails

Changes:
- Added 'nofx/trader' import
- Query GetExchanges() to find matching exchange config
- Create temporary trader instance based on exchange type
- Call GetBalance() to fetch actual available balance
- Use actualBalance instead of req.InitialBalance
- Comprehensive error handling with fallback logic

Benefits:
- ✅ Ensures accurate initial balance matches exchange account
- ✅ Prevents user errors in balance input
- ✅ Improves position sizing accuracy
- ✅ Maintains data integrity between system and exchange

Example logs:
✓ 查询到交易所实际余额: 150.00 USDT (用户输入: 100.00 USDT)
⚠️ 查询交易所余额失败,使用用户输入的初始资金: connection timeout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fixed compilation error caused by variable name mismatch:
- Line 404: defined as 'trader'
- Line 425: was using 'traderRecord' (undefined)

This aligns with upstream dev branch naming convention.
新增功能:
- update_stop_loss: 调整止损价格(追踪止损)
- update_take_profit: 调整止盈价格(技术位优化)
- partial_close: 部分平仓(分批止盈)

实现细节:
- Decision struct 新增字段:NewStopLoss, NewTakeProfit, ClosePercentage
- 新增执行函数:executeUpdateStopLossWithRecord, executeUpdateTakeProfitWithRecord, executePartialCloseWithRecord
- 修复持仓字段获取 bug(使用 "side" 并转大写)
- 更新 adaptive.txt 文档,包含详细使用示例和策略建议
- 优先级排序:平仓 > 调整止盈止损 > 开仓

命名统一:
- 与社区 PR NoFxAiOS#197 保持一致,使用 update_* 而非 adjust_*
- 独有功能:partial_close(部分平仓)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
問題根因:
- auto_trader.go 已實現 update_stop_loss/update_take_profit/partial_close 處理
- adaptive.txt 已描述這些功能
- 但 validateDecision 的 validActions map 缺少這三個動作
- 導致 AI 生成的決策在驗證階段被拒絕:「无效的action:update_stop_loss」

修復內容:
1. validActions 添加三個新動作
2. 為每個新動作添加參數驗證:
   - update_stop_loss: 驗證 NewStopLoss > 0
   - update_take_profit: 驗證 NewTakeProfit > 0
   - partial_close: 驗證 ClosePercentage 在 0-100 之間
3. 修正註釋:adjust_* → update_*

測試狀態:feature 分支,等待測試確認
問題:
- 調整止損/止盈時,直接調用 SetStopLoss/SetTakeProfit 會創建新訂單
- 但舊的止損/止盈單仍然存在,導致多個訂單共存
- 可能造成意外觸發或訂單衝突

解決方案(參考 PR NoFxAiOS#197):
1. 在 Trader 接口添加 CancelStopOrders 方法
2. 為三個交易所實現:
   - binance_futures.go: 過濾 STOP_MARKET/TAKE_PROFIT_MARKET 類型
   - aster_trader.go: 同樣邏輯
   - hyperliquid_trader.go: 過濾 trigger 訂單(有 triggerPx)
3. 在 executeUpdateStopLossWithRecord 和 executeUpdateTakeProfitWithRecord 中:
   - 先調用 CancelStopOrders 取消舊單
   - 然後設置新止損/止盈
   - 取消失敗不中斷執行(記錄警告)

優勢:
- ✅ 避免多個止損單同時存在
- ✅ 保留我們的價格驗證邏輯
- ✅ 保留執行價格記錄
- ✅ 詳細錯誤信息
- ✅ 取消失敗時繼續執行(更健壯)

測試建議:
- 開倉後調整止損,檢查舊止損單是否被取消
- 連續調整兩次,確認只有最新止損單存在

致謝:參考 PR NoFxAiOS#197 的實現思路
问题:部分平仓时,历史记录显示的是全仓位盈利,而非实际平仓部分的盈利

根本原因:
- AnalyzePerformance 使用开仓总数量计算部分平仓的盈利
- 应该使用 action.Quantity(实际平仓数量)而非 openPos["quantity"](总数量)

修复:
- 添加 actualQuantity 变量区分完整平仓和部分平仓
- partial_close 使用 action.Quantity
- 所有相关计算(PnL、PositionValue、MarginUsed)都使用 actualQuantity

影响范围:logger/decision_logger.go:428-465

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- OpenOrder 結構不暴露 trigger 字段
- 改為取消該幣種的所有掛單(安全做法)
- This PR should only contain backend core functionality
- prompts/adaptive.txt v2.0 is already in upstream
- Prompt enhancements will be in separate PR (Batch 3)
更新內容:
1. DecisionAction 註釋:添加 update_stop_loss, update_take_profit, partial_close
2. GetStatistics:partial_close 計入 TotalClosePositions
3. AnalyzePerformance 預填充邏輯:處理 partial_close(不刪除持倉記錄)
4. AnalyzePerformance 分析邏輯:
   - partial_close 正確判斷持倉方向
   - 記錄部分平倉的盈虧統計
   - 保留持倉記錄(因為還有剩餘倉位)

說明:partial_close 會記錄盈虧,但不刪除 openPositions,
      因為還有剩餘倉位可能繼續交易
the-dev-z and others added 11 commits November 11, 2025 21:21
…NoFxAiOS#918)

## Problem

User-facing messages were too generic and uninformative:

1. **Dashboard empty state**:
   - Title: "No Traders Configured" (cold, technical)
   - Description: Generic message with no action guidance
   - Button: "Go to Traders Page" (unclear what happens next)

2. **Login error messages**:
   - "Login failed" (too vague - why did it fail?)
   - "Registration failed" (no guidance on what to do)
   - "OTP verification failed" (users don't know how to fix)

**Impact**: Users felt confused and frustrated, no clear next steps.

## Solution

### 1. Improve Dashboard Empty State
**File**: `web/src/i18n/translations.ts`

**Before**:
```typescript
dashboardEmptyTitle: 'No Traders Configured'
dashboardEmptyDescription: "You haven't created any AI traders yet..."
goToTradersPage: 'Go to Traders Page'
```

**After**:
```typescript
dashboardEmptyTitle: "Let's Get Started!"  // ✅ Welcoming, encouraging
dashboardEmptyDescription: 'Create your first AI trader to automate your trading strategy. Connect an exchange, choose an AI model, and start trading in minutes!'  // ✅ Clear steps
goToTradersPage: 'Create Your First Trader'  // ✅ Clear action
```

**Changes**:
- ✅ More welcoming tone ("Let's Get Started!")
- ✅ Specific action steps (connect → choose → trade)
- ✅ Time expectation ("in minutes")
- ✅ Clear call-to-action button

---

### 2. Improve Error Messages
**File**: `web/src/i18n/translations.ts`

**Before**:
```typescript
loginFailed: 'Login failed'  // ❌ No guidance
registrationFailed: 'Registration failed'  // ❌ No guidance
verificationFailed: 'OTP verification failed'  // ❌ No guidance
```

**After**:
```typescript
loginFailed: 'Login failed. Please check your email and password.'  // ✅ Clear hint
registrationFailed: 'Registration failed. Please try again.'  // ✅ Clear action
verificationFailed: 'OTP verification failed. Please check the code and try again.'  // ✅ Clear steps
```

**Changes**:
- ✅ Specific error hints (check email/password)
- ✅ Clear remediation steps (try again, check code)
- ✅ User-friendly tone

---

### 3. Chinese Translations
All improvements mirrored in Chinese:

**Dashboard**:
- Title: "开始使用吧!" (Let's get started!)
- Description: Clear 3-step guidance
- Button: "创建您的第一个交易员" (Create your first trader)

**Errors**:
- "登录失败,请检查您的邮箱和密码。"
- "注册失败,请重试。"
- "OTP 验证失败,请检查验证码后重试。"

---

## Impact

### User Experience Improvements

| Message Type | Before | After | Benefit |
|--------------|--------|-------|---------|
| **Empty dashboard** | Cold, technical | Welcoming, actionable | ✅ Reduces confusion |
| **Login errors** | Vague | Specific hints | ✅ Faster problem resolution |
| **Registration errors** | No guidance | Clear next steps | ✅ Lower support burden |
| **OTP errors** | Confusing | Actionable | ✅ Higher success rate |

### Tone Shift

**Before**: Technical, system-centric
- "No Traders Configured"
- "Login failed"

**After**: User-centric, helpful
- "Let's Get Started!"
- "Login failed. Please check your email and password."

---

## Testing

**Manual Testing**:
- [x] Empty dashboard displays new messages correctly
- [x] Login error shows improved message
- [x] Registration error shows improved message
- [x] OTP error shows improved message
- [x] Chinese translations display correctly
- [x] Button text updated appropriately

**Language Coverage**:
- [x] English ✅
- [x] Chinese ✅

---

## Files Changed

**1 frontend file**:
- `web/src/i18n/translations.ts` (+12 lines, -6 lines)

**Lines affected**:
- English: Lines 149-152, 461-464
- Chinese: Lines 950-953, 1227-1229

---

**By submitting this PR, I confirm:**

- [x] I have read the Contributing Guidelines
- [x] I agree to the Code of Conduct
- [x] My contribution is licensed under AGPL-3.0

---

🌟 **Thank you for reviewing!**

This PR improves user experience with clearer, more helpful messages.

🤖 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>
* feat: add web crypto environment check

* fix: auto check env

* refactor:  WebCryptoEnvironmentCheck  swtich to map
* feat(market): add data staleness detection

## 問題背景
解決 PR NoFxAiOS#703 Part 2: 數據陳舊性檢測
- 修復 DOGEUSDT 式問題:連續價格不變表示數據源異常
- 防止系統處理僵化/過期的市場數據

## 技術方案

### 數據陳舊性檢測 (market/data.go)
- **函數**: `isStaleData(klines []Kline, symbol string) bool`
- **檢測邏輯**:
  - 連續 5 個 3 分鐘週期價格完全不變(15 分鐘無波動)
  - 價格波動容忍度:0.01%(避免誤報)
  - 成交量檢查:價格凍結 + 成交量為 0 → 確認陳舊

- **處理策略**:
  - 數據陳舊確認:跳過該幣種,返回錯誤
  - 極低波動市場:記錄警告但允許通過(價格穩定但有成交量)

### 調用時機
- 在 `Get()` 函數中,獲取 3m K線後立即檢測
- 早期返回:避免後續無意義的計算和 API 調用

## 實現細節
- **檢測閾值**: 5 個連續週期
- **容忍度**: 0.01% 價格波動
- **日誌**: 英文國際化版本
- **並發安全**: 函數無狀態,安全

## 影響範圍
- ✅ 修改 market/data.go: 新增 isStaleData() + 調用邏輯
- ✅ 新增 log 包導入
- ✅ 50 行新增代碼

## 測試建議
1. 模擬 DOGEUSDT 場景:連續價格不變 + 成交量為 0
2. 驗證日誌輸出:`stale data confirmed: price freeze + zero volume`
3. 正常市場:極低波動但有成交量,應允許通過並記錄警告

## 相關 Issue/PR
- 拆分自 **PR NoFxAiOS#703** (Part 2/3)
- 基於最新 upstream/dev (3112250)
- 依賴: 無
- 前置: Part 1 (OI 時間序列) - 已提交 PR NoFxAiOS#798
- 後續: Part 3 (手續費率傳遞)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(market): add comprehensive unit tests for isStaleData function

- Test normal fluctuating data (expects non-stale)
- Test price freeze with zero volume (expects stale)
- Test price freeze with volume (low volatility market)
- Test insufficient data edge case (<5 klines)
- Test boundary conditions (exactly 5 klines)
- Test tolerance threshold (0.01% price change)
- Test mixed scenario (normal → freeze transition)
- Test empty klines edge case

All 8 test cases passed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Shui <88711385+hzb1115@users.noreply.github.com>
…#934)

Add `user && token` guard to all authenticated SWR calls to prevent
requests with `Authorization: Bearer null` when users refresh the page
before AuthContext finishes loading the token from localStorage.

## Problem

When users refresh the page:
1. React components mount immediately
2. SWR hooks fire API requests
3. AuthContext is still loading token from localStorage
4. Requests sent with `Authorization: Bearer null`
5. Backend returns 401 errors

This causes:
- Unnecessary 401 errors in backend logs
- Error messages in browser console
- Poor user experience on page refresh

## Solution

Add auth check to SWR key conditions using pattern:
```typescript
user && token && condition ? key : null
```

When `user` or `token` is null, SWR key becomes `null`, preventing the request.
Once AuthContext loads, SWR automatically revalidates and fetches data.

## Changes

**TraderDashboard.tsx** (5 auth guards added):
- status: `user && token && selectedTraderId ? 'status-...' : null`
- account: `user && token && selectedTraderId ? 'account-...' : null`
- positions: `user && token && selectedTraderId ? 'positions-...' : null`
- decisions: `user && token && selectedTraderId ? 'decisions/...' : null`
- stats: `user && token && selectedTraderId ? 'statistics-...' : null`

**EquityChart.tsx** (2 auth guards added + useAuth import):
- Import `useAuth` from '../contexts/AuthContext'
- Add `const { user, token } = useAuth()`
- history: `user && token && traderId ? 'equity-history-...' : null`
- account: `user && token && traderId ? 'account-...' : null`

**apiGuard.test.ts** (new file, 370 lines):
- Comprehensive unit tests covering all auth guard scenarios
- Tests for null user, null token, valid auth states
- Tests for all 7 SWR calls (5 in TraderDashboard + 2 in EquityChart)

## Testing

- ✅ TypeScript compilation passed
- ✅ Vite build passed (2.81s)
- ✅ All modifications are additive (no logic changes)
- ✅ SWR auto-revalidation ensures data loads after auth completes

## Benefits

1. **No more 401 errors on refresh**: Auth guards prevent premature requests
2. **Cleaner logs**: Backend no longer receives invalid Bearer null requests
3. **Better UX**: No error flashes in console on page load
4. **Consistent pattern**: All authenticated endpoints use same guard logic

## Context

This PR supersedes closed PR NoFxAiOS#881, which had conflicts due to PR NoFxAiOS#872
(frontend refactor with React Router). This implementation is based on
the latest upstream/dev with the new architecture.

Related: PR NoFxAiOS#881 (closed), PR NoFxAiOS#872 (Frontend Refactor)

🤖 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>
…oFxAiOS#935)

- Add comprehensive Hyperliquid Agent Wallet setup guide with referral link
- Update all 5 language versions (EN, ZH, JA, RU, UK)
- Remove "Alternative" prefix from Hyperliquid and Aster DEX section titles
- Remove direct wallet method, only recommend secure Agent Wallet approach
- Include step-by-step registration, funding, and agent wallet creation
- Add security warnings and best practices for all languages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: tinkle <tinkle@tinkle.community>
Co-authored-by: Claude <noreply@anthropic.com>
* feat(docs): add Hyperliquid Agent Wallet tutorial for all languages

- Add comprehensive Hyperliquid Agent Wallet setup guide with referral link
- Update all 5 language versions (EN, ZH, JA, RU, UK)
- Remove "Alternative" prefix from Hyperliquid and Aster DEX section titles
- Remove direct wallet method, only recommend secure Agent Wallet approach
- Include step-by-step registration, funding, and agent wallet creation
- Add security warnings and best practices for all languages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(docs): add Hyperliquid and Aster DEX to Table of Contents in all languages

- Add navigation links for Hyperliquid and Aster DEX registration in all 5 README versions
- Ensure all three exchanges (Binance, Hyperliquid, Aster) have equal visibility in TOC
- Add complete TOC structure to Japanese README (was missing before)
- Maintain consistency across English, Chinese, Japanese, Russian, and Ukrainian versions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: tinkle <tinkle@tinkle.community>
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>
…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>
…elp text

## Problem

Previous help text was still ambiguous about exact character counts:
- "Accepts 32 hex characters with or without '0x' prefix"
- Users still confused: How many total characters if I include "0x"?
- Not explicit enough: 32 or 34?

**User Question:**
"用戶會知道包含0x就是前34位?不包含就是前32位?"
(Will users know it's 34 chars with 0x, or 32 without?)

## Solution

Made help text explicitly state both options:

**English:**
- Before: "💡 Accepts 32 hex characters with or without "0x" prefix"
- After: "💡 Enter 32 hex chars (without 0x) or 34 chars (with 0x)"

**Chinese:**
- Before: "💡 可包含或省略 "0x" 前綴(32 位 hex 字符)"
- After: "💡 請輸入 32 位(不含 0x)或 34 位(含 0x 前綴)"

## Changes

### translations.ts

**English (Line 830):**
```typescript
helpText: '💡 Enter {length} hex chars (without 0x) or {totalWithPrefix} chars (with 0x)',
```

**Chinese (Line 1621):**
```typescript
helpText: '💡 請輸入 {length} 位(不含 0x)或 {totalWithPrefix} 位(含 0x 前綴)',
```

### TwoStageKeyModal.tsx (Lines 224-227, 304-307)

Added `totalWithPrefix` parameter:
```tsx
{t('twoStageKey.helpText', language, {
  length: expectedPart1Length,          // 32
  totalWithPrefix: expectedPart1Length + 2,  // 34
})}
```

## UI Impact

**Stage 1 (32 hex chars needed):**

Before:
```
💡 Accepts 32 hex characters with or without "0x" prefix
```

After:
```
💡 Enter 32 hex chars (without 0x) or 34 chars (with 0x)
```

**Stage 2 (32 hex chars needed):**
```
💡 Enter 32 hex chars (without 0x) or 34 chars (with 0x)
```

## Benefits

- ✅ **Crystal clear**: Users see exact numbers (32 or 34)
- ✅ **No guessing**: Both options explicitly stated
- ✅ **Reduces confusion**: "I need 32 or 34 total chars"
- ✅ **Better UX**: Users know exactly what to input
- ✅ **Bilingual clarity**: Both EN and ZH versions equally clear

## Test Cases

| User Scenario | Help Text Shown | User Understanding |
|---------------|-----------------|-------------------|
| Opens Stage 1 | "32 or 34 chars" | ✅ Clear: 32 without 0x, 34 with |
| Opens Stage 2 | "32 or 34 chars" | ✅ Clear: Same rule applies |
| Inputs 32 chars (no 0x) | - | ✅ Correct length |
| Inputs 34 chars (with 0x) | - | ✅ Correct length (0x + 32 hex) |
| Inputs 33 chars | Button disabled | ✅ Neither format valid |

**Related:** Follow-up clarification for previous UX improvement

🤖 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: ⚠️ Suggestion - Consider using type(scope): description

Recommended format

Valid types: feat, fix, docs, style, refactor, perf, test, chore, ci, security, build

Examples:

  • feat(trader): add new trading strategy
  • fix(api): resolve authentication issue
  • docs: update README

PR Size: 🟢 Small (22 lines: +18 -4)

🔧 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.

@xqliu
Copy link
Contributor

xqliu commented Nov 12, 2025

感觉可以说不要前面的 0x 而不是十六进制,很多不学习计算机的不知道 16 进制跟 0x 对应

## Change

Replace "十六进制字符" (hexadecimal characters) with "字符" (characters)

**Before:**
- `stage1Description: '请输入私钥的前 {length} 位十六进制字符'`
- `stage2Description: '请输入私钥的后 {length} 位十六进制字符'`

**After:**
- `stage1Description: '请输入私钥的前 {length} 位字符'`
- `stage2Description: '请输入私钥的后 {length} 位字符'`

## Rationale

As @xqliu suggested in review: "很多不学习计算机的不知道 16 进制跟 0x 对应"

- Technical term "十六进制" (hexadecimal) is too jargon-heavy for non-technical users
- The helpText already clearly explains the format: "不含 0x" / "含 0x 前缀"
- Simpler description improves UX for wider audience

## Related

- Addresses review feedback in PR NoFxAiOS#940

🤖 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: ⚠️ Suggestion - Consider using type(scope): description

Recommended format

Valid types: feat, fix, docs, style, refactor, perf, test, chore, ci, security, build

Examples:

  • feat(trader): add new trading strategy
  • fix(api): resolve authentication issue
  • docs: update README

PR Size: 🟢 Small (18 lines: +16 -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.

the-dev-z added a commit to the-dev-z/alpha-trading that referenced this pull request Nov 12, 2025
Apply PR NoFxAiOS#940 review feedback to z-dev-v2

## Change

Replace "十六进制字符" (hexadecimal characters) with "字符" (characters)

**Before:**
- `stage1Description: '请输入私钥的前 {length} 位十六进制字符'`
- `stage2Description: '请输入私钥的后 {length} 位十六进制字符'`

**After:**
- `stage1Description: '请输入私钥的前 {length} 位字符'`
- `stage2Description: '请输入私钥的后 {length} 位字符'`

## Rationale

As @xqliu suggested in PR NoFxAiOS#940 review:
"很多不学习计算机的不知道 16 进制跟 0x 对应"

- Technical term "十六进制" (hexadecimal) is too jargon-heavy for non-technical users
- The helpText already clearly explains the format: "不含 0x" / "含 0x 前缀"
- Simpler description improves UX for wider audience

## Related

- Syncs z-dev-v2 with PR NoFxAiOS#940 review feedback (commit b56afaa)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@tinkle-community tinkle-community force-pushed the dev branch 4 times, most recently from 9384ffd to 5391f39 Compare December 12, 2025 15:30
@cla-assistant
Copy link

cla-assistant bot commented Dec 22, 2025

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 12 committers have signed the CLA.

✅ tinkle-community
❌ deloz
❌ ljh740
❌ xqliu
❌ tangmengqiu
❌ wquguru
❌ hzb1115
❌ 0xEmberZz
❌ Im-Sue
❌ CoderMageFox
❌ the-dev-z
❌ zpng
You have signed the CLA already but the status is still pending? Let us recheck it.

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.