Commit Graph

197 Commits

Author SHA1 Message Date
Sue
7329e4d135 fix: 修复币安白名单IP复制功能失效问题 (#680)
## 🐛 问题描述
币安交易所配置页面中的服务器IP复制功能无法正常工作

## 🔍 根因分析
原始实现仅使用 navigator.clipboard.writeText() API:
- 在某些浏览器环境下不可用或被阻止
- 需要 HTTPS 或 localhost 环境
- 缺少错误处理和用户反馈

##  修复方案
1. **双重降级机制**:
   - 优先使用现代 Clipboard API
   - 降级到传统 execCommand 方法

2. **错误处理**:
   - 添加 try-catch 错误捕获
   - 失败时显示友好的错误提示
   - 提供IP地址供用户手动复制

3. **多语言支持**:
   - 添加 copyIPFailed 翻译键(中英文)

## 📝 修改文件
- web/src/components/AITradersPage.tsx
  - handleCopyIP 函数重构为异步函数
  - 添加双重复制机制和错误处理

- web/src/i18n/translations.ts
  - 添加 copyIPFailed 错误提示翻译

## 🧪 测试验证
 TypeScript 编译通过
 Vite 构建成功
 支持现代和传统浏览器环境

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-10 20:34:22 -05:00
0xYYBB | ZYY | Bobo
0514610f9d fix(web): display '—' for missing data instead of NaN% or 0% (#678)
* fix(web): display '—' for missing data instead of NaN% or 0% (#633)

- Add hasValidData validation for null/undefined/NaN
- Display '—' for invalid trader.total_pnl_pct
- Only show gap calculations when both values are valid
- Prevents misleading users with 0% when data is missing

Fixes #633

* test(web): add comprehensive unit tests for CompetitionPage NaN handling

- Test data validation logic (null/undefined/NaN detection)
- Test gap calculation with valid and invalid data
- Test display formatting (shows '—' instead of 'NaN%')
- Test leading/trailing message display conditions
- Test edge cases (Infinity, very small/large numbers)

All 25 test cases passed, covering:
1. hasValidData check (7 cases): valid/null/undefined/NaN/zero/negative
2. gap calculation (3 cases): valid data, invalid data, negative gap
3. display formatting (6 cases): positive/negative/null/undefined/NaN/zero
4. leading/trailing messages (5 cases): conditional display logic
5. edge cases (4 cases): Infinity, -Infinity, very small/large numbers

Related to PR #678 - ensures missing data displays as '—' instead of 'NaN%'.

🤖 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>
2025-11-10 20:30:03 -05:00
Deloz
3c90d2d739 fix(auth): 修复TraderConfigModal使用错误的token key (#882) 2025-11-10 12:44:34 -05:00
CoderMageFox
d3cbc023cc fix(auth): align PasswordChecklist special chars with validation logic (#860)
修复密码验证UI组件与验证逻辑之间的特殊字符不一致问题。

问题描述:
- PasswordChecklist组件默认接受所有特殊字符(如^_-~等)
- 实际验证函数isStrongPassword()仅接受@#$%!&*?共8个特殊字符
- 导致用户输入包含其他特殊字符时,UI显示绿色勾选但注册按钮仍禁用

修改内容:
- 在RegisterPage.tsx的PasswordChecklist组件添加specialCharsRegex属性
- 限制特殊字符为/[@#$%!&*?]/,与isStrongPassword()保持一致

影响范围:
- 仅影响注册页面的密码验证UI显示
- 不影响后端验证逻辑
- 提升用户体验,避免误导性的UI反馈

Closes #859

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-10 08:08:52 -07:00
0xYYBB | ZYY | Bobo
1502b7ba0c fix(web): remove circular dependency causing trading symbols input bug (#632) (#671)
**Problem:**
Unable to type comma-separated trading symbols in the input field.
When typing "BTCUSDT," → comma immediately disappears → cannot add more symbols.

**Root Cause:**
Circular state dependency between `useEffect` and `handleInputChange`:

```typescript
//  Lines 146-149: useEffect syncs selectedCoins → formData
useEffect(() => {
  const symbolsString = selectedCoins.join(',')
  setFormData(prev => ({ ...prev, trading_symbols: symbolsString }))
}, [selectedCoins])

// Lines 150-153: handleInputChange syncs formData → selectedCoins
if (field === 'trading_symbols') {
  const coins = value.split(',').map(...).filter(...)
  setSelectedCoins(coins)
}
```

**Execution Flow:**
1. User types: `"BTCUSDT,"`
2. `handleInputChange` fires → splits by comma → filters empty → `selectedCoins = ["BTCUSDT"]`
3. `useEffect` fires → joins → overwrites input to `"BTCUSDT"`  **Trailing comma removed!**
4. User cannot continue typing

**Solution:**
Remove the redundant `useEffect` (lines 146-149) and update `handleCoinToggle` to directly sync both states:

```typescript
//  handleCoinToggle now updates both states
const handleCoinToggle = (coin: string) => {
  setSelectedCoins(prev => {
    const newCoins = prev.includes(coin) ? ... : ...

    // Directly update formData.trading_symbols
    const symbolsString = newCoins.join(',')
    setFormData(current => ({ ...current, trading_symbols: symbolsString }))

    return newCoins
  })
}
```

**Why This Works:**
- **Quick selector buttons** (`handleCoinToggle`): Now updates both states 
- **Manual input** (`handleInputChange`): Already updates both states 
- **No useEffect interference**: User can type freely 

**Impact:**
-  Manual typing of comma-separated symbols now works
-  Quick selector buttons still work correctly
-  No circular dependency
-  Cleaner unidirectional data flow

Fixes #632

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-10 11:57:55 +08:00
0xYYBB | ZYY | Bobo
7b0b19708e feat(web): improve trader config UX for initial balance and prompt templates (#629 #630) (#673)
- Add onBlur validation for initial_balance input to enforce minimum of 100
- Add detailed prompt template descriptions with i18n support
- Fix Traditional Chinese to Simplified Chinese
- Extract hardcoded Chinese text to i18n translation system
- Add translation keys for all prompt templates and descriptions

Fixes #629, Fixes #630
2025-11-10 11:55:40 +08:00
Ember
a4d3cb41f1 bugfix dashboard empty state (#709) 2025-11-09 14:44:42 +08:00
Lawrence Liu
853c1d65b8 fix: 修复token过期未重新登录的问题 (#803)
* fix: 修复token过期未重新登录的问题

实现统一的401错误处理机制:
- 创建httpClient封装fetch API,添加响应拦截器
- 401时自动清理localStorage和React状态
- 显示"请先登录"提示并延迟1.5秒后跳转登录页
- 保存当前URL到sessionStorage用于登录后返回
- 改造所有API调用使用httpClient统一处理

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

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

* fix: 添加401处理的单例保护防止并发竞态

问题:
- 多个API同时返回401会导致多个通知叠加
- 多个style元素被添加到DOM造成内存泄漏
- 可能触发多次登录页跳转

解决方案:
- 添加静态标志位 isHandling401 防止重复处理
- 第一个401触发完整处理流程
- 后续401直接抛出错误,避免重复操作
- 确保只显示一次通知和一次跳转

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

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

* fix: 修复isHandling401标志永不重置的问题

问题:
- isHandling401标志在401处理后永不重置
- 导致用户重新登录后,后续401会被静默忽略
- 页面刷新或取消重定向后标志仍为true

解决方案:
- 在HttpClient中添加reset401Flag()公开方法
- 登录成功后调用reset401Flag()重置标志
- 页面加载时调用reset401Flag()确保新会话正常

影响范围:
- web/src/lib/httpClient.ts: 添加reset方法和导出函数
- web/src/contexts/AuthContext.tsx: 在登录和页面加载时重置

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

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

* fix(auth): consume returnUrl after successful login (BLOCKING-1)

修复登录后未跳转回原页面的问题。

问题:
- httpClient在401时保存returnUrl到sessionStorage
- 但登录成功后没有读取和使用returnUrl
- 导致用户登录后停留在登录页,无法回到原页面

修复:
- 在loginAdmin、verifyOTP、completeRegistration三个登录方法中
- 添加returnUrl检查和跳转逻辑
- 登录成功后优先跳转到returnUrl,如果没有则使用默认页面

影响:
- 用户token过期后重新登录,会自动返回之前访问的页面
- 提升用户体验,避免手动导航

测试场景:
1. 用户访问/traders → token过期 → 登录 → 自动回到/traders 
2. 用户直接访问/login → 登录 → 跳转到默认页面(/dashboard或/traders) 

Related: BLOCKING-1 in PR #803 code review

---------

Co-authored-by: sue <177699783@qq.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 12:18:47 +08:00
Ember
381621149b feat(ui): add password strength validation and toggle visibility in registration and reset password forms (#773)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 00:36:28 +08:00
Icyoung
cd5b39514a Dev api bugfix (#740)
* feat: remove admin mode

* feat: bugfix

* feat(crypto): 添加RSA-OAEP + AES-GCM混合加密服务

- 实现CryptoService加密服务,支持RSA-OAEP-2048 + AES-256-GCM混合加密
- 集成数据库层加密,自动加密存储敏感字段(API密钥、私钥等)
- 支持环境变量DATA_ENCRYPTION_KEY配置数据加密密钥
- 适配SQLite数据库加密存储(从PostgreSQL移植)
- 保持Hyperliquid代理钱包处理兼容性
- 更新.gitignore以正确处理crypto模块代码

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

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

* feat(scripts): 添加加密环境一键设置脚本

- setup_encryption.sh: 一键生成RSA密钥对+数据加密密钥+JWT密钥
- generate_rsa_keys.sh: 专业的RSA-2048密钥对生成工具
- generate_data_key.sh: 生成AES-256数据加密密钥和JWT认证密钥
- ENCRYPTION_README.md: 详细的加密系统说明文档
- 支持自动检测现有密钥并只生成缺失的密钥
- 完善的权限管理和安全验证
- 兼容macOS和Linux的跨平台支持

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

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

* feat(api): 添加加密API端点和Gin框架集成

- 新增CryptoHandler处理加密相关API请求
- 提供/api/crypto/public-key端点获取RSA公钥
- 提供/api/crypto/decrypt端点解密敏感数据
- 适配Gin框架的HTTP处理器格式
- 集成CryptoService到API服务器
- 支持前端加密数据传输和解密

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

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

* feat(web): 添加前端加密服务和两阶段密钥输入组件

- CryptoService: Web Crypto API集成,支持RSA-OAEP加密
- TwoStageKeyModal: 安全的两阶段私钥输入组件,支持剪贴板混淆
- 完善国际化翻译支持加密相关UI文本
- 修复TypeScript类型错误和编译问题
- 支持前端敏感数据加密传输到后端
- 增强用户隐私保护和数据安全

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

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

* feat(auth): 增强JWT认证安全性

- 优先使用环境变量JWT_SECRET而不是数据库配置
- 支持通过.env文件安全配置JWT认证密钥
- 保留数据库配置作为回退机制
- 改进JWT密钥来源日志显示
- 增强系统启动时的安全配置检查
- 支持运行时动态JWT密钥切换

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

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

* feat(docker): 集成加密环境变量到Docker部署

- 添加DATA_ENCRYPTION_KEY环境变量传递到容器
- 添加JWT_SECRET环境变量支持
- 挂载secrets目录使容器可访问RSA密钥文件
- 确保容器内加密服务正常工作
- 解决容器启动失败和加密初始化问题
- 完善Docker Compose加密环境配置

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

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

* feat(start): 集成自动加密环境检测和设置

- 增强check_encryption()函数检测JWT_SECRET和DATA_ENCRYPTION_KEY
- 自动运行setup_encryption.sh当检测到缺失密钥时
- 改进加密状态显示,包含RSA+AES+JWT全套加密信息
- 优化用户体验,提供清晰的加密配置反馈
- 支持一键设置完整加密环境
- 确保容器启动前加密环境就绪

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

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

* feat: format fix

* fix(security): 修复前端模型和交易所配置敏感数据明文传输

- 在handleSaveModelConfig中对API密钥进行RSA-OAEP加密
- 在handleSaveExchangeConfig中对API密钥、Secret密钥和Aster私钥进行加密
- 只有非空敏感数据才进行加密处理
- 添加加密失败错误处理和用户友好提示
- 增加encryptionFailed翻译键的中英文支持
- 使用用户ID和会话ID作为加密上下文增强安全性

这修复了之前敏感数据在网络传输中以明文形式发送的安全漏洞。

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

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

* fix(crypto): 修复后端加密服务集成和缺失的加密端点

- 添加Server结构体缺少的cryptoService字段
- 实现handleUpdateModelConfigsEncrypted处理器用于模型配置加密传输
- 修复handleUpdateExchangeConfigsEncrypted中的函数调用
- 在前端API中添加updateModelConfigsEncrypted方法
- 统一RSA密钥路径从secrets/rsa_key改为keys/rsa_private.key
- 确保前端可以使用加密端点安全传输敏感数据
- 兼容原有加密通信模式和二段输入私钥功能

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

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

* fix(crypto): 完善加密端点配置,简化API结构

- 移除多余的/models/encrypted端点,模型配置暂不加密
- 确认/exchanges端点已强制要求加密传输
- 统一前端使用标准端点,自动使用加密传输
- 修复前端API调用,移除不存在的updateModelConfigsEncrypted引用
- 确保后端和前端编译成功,加密功能正常工作

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

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

* fix(crypto): 为模型配置端点添加加密传输支持

- 前端updateModelConfigs方法现在使用加密传输
- 后端/api/models端点已强制要求加密载荷
- 模型配置界面保持普通输入,在提交时自动加密
- 确保API密钥等敏感数据通过RSA+AES混合加密传输
- 前端后端编译测试通过,加密功能正常工作

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

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

---------

Co-authored-by: icy <icyoung520@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-08 11:28:51 +08:00
Diego
8cb19df6de Fix(encryption)/aiconfig, exchange config and the encryption setup (#735) 2025-11-08 08:41:28 +08:00
Icyoung
079995e458 Dev Crypto (#730)
* feat: remove admin mode

* feat: bugfix

* feat(crypto): 添加RSA-OAEP + AES-GCM混合加密服务

- 实现CryptoService加密服务,支持RSA-OAEP-2048 + AES-256-GCM混合加密
- 集成数据库层加密,自动加密存储敏感字段(API密钥、私钥等)
- 支持环境变量DATA_ENCRYPTION_KEY配置数据加密密钥
- 适配SQLite数据库加密存储(从PostgreSQL移植)
- 保持Hyperliquid代理钱包处理兼容性
- 更新.gitignore以正确处理crypto模块代码

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

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

* feat(scripts): 添加加密环境一键设置脚本

- setup_encryption.sh: 一键生成RSA密钥对+数据加密密钥+JWT密钥
- generate_rsa_keys.sh: 专业的RSA-2048密钥对生成工具
- generate_data_key.sh: 生成AES-256数据加密密钥和JWT认证密钥
- ENCRYPTION_README.md: 详细的加密系统说明文档
- 支持自动检测现有密钥并只生成缺失的密钥
- 完善的权限管理和安全验证
- 兼容macOS和Linux的跨平台支持

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

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

* feat(api): 添加加密API端点和Gin框架集成

- 新增CryptoHandler处理加密相关API请求
- 提供/api/crypto/public-key端点获取RSA公钥
- 提供/api/crypto/decrypt端点解密敏感数据
- 适配Gin框架的HTTP处理器格式
- 集成CryptoService到API服务器
- 支持前端加密数据传输和解密

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

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

* feat(web): 添加前端加密服务和两阶段密钥输入组件

- CryptoService: Web Crypto API集成,支持RSA-OAEP加密
- TwoStageKeyModal: 安全的两阶段私钥输入组件,支持剪贴板混淆
- 完善国际化翻译支持加密相关UI文本
- 修复TypeScript类型错误和编译问题
- 支持前端敏感数据加密传输到后端
- 增强用户隐私保护和数据安全

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

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

* feat(auth): 增强JWT认证安全性

- 优先使用环境变量JWT_SECRET而不是数据库配置
- 支持通过.env文件安全配置JWT认证密钥
- 保留数据库配置作为回退机制
- 改进JWT密钥来源日志显示
- 增强系统启动时的安全配置检查
- 支持运行时动态JWT密钥切换

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

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

* feat(docker): 集成加密环境变量到Docker部署

- 添加DATA_ENCRYPTION_KEY环境变量传递到容器
- 添加JWT_SECRET环境变量支持
- 挂载secrets目录使容器可访问RSA密钥文件
- 确保容器内加密服务正常工作
- 解决容器启动失败和加密初始化问题
- 完善Docker Compose加密环境配置

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

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

* feat(start): 集成自动加密环境检测和设置

- 增强check_encryption()函数检测JWT_SECRET和DATA_ENCRYPTION_KEY
- 自动运行setup_encryption.sh当检测到缺失密钥时
- 改进加密状态显示,包含RSA+AES+JWT全套加密信息
- 优化用户体验,提供清晰的加密配置反馈
- 支持一键设置完整加密环境
- 确保容器启动前加密环境就绪

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

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

* feat: format fix

* fix(security): 修复前端模型和交易所配置敏感数据明文传输

- 在handleSaveModelConfig中对API密钥进行RSA-OAEP加密
- 在handleSaveExchangeConfig中对API密钥、Secret密钥和Aster私钥进行加密
- 只有非空敏感数据才进行加密处理
- 添加加密失败错误处理和用户友好提示
- 增加encryptionFailed翻译键的中英文支持
- 使用用户ID和会话ID作为加密上下文增强安全性

这修复了之前敏感数据在网络传输中以明文形式发送的安全漏洞。

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

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

* fix(crypto): 修复后端加密服务集成和缺失的加密端点

- 添加Server结构体缺少的cryptoService字段
- 实现handleUpdateModelConfigsEncrypted处理器用于模型配置加密传输
- 修复handleUpdateExchangeConfigsEncrypted中的函数调用
- 在前端API中添加updateModelConfigsEncrypted方法
- 统一RSA密钥路径从secrets/rsa_key改为keys/rsa_private.key
- 确保前端可以使用加密端点安全传输敏感数据
- 兼容原有加密通信模式和二段输入私钥功能

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

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

---------

Co-authored-by: icy <icyoung520@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-08 02:03:09 +08:00
web3gaoyutang
5c2a2bd77d refactor(AITradersPage): update model and exchange configuration checks (#728)
- Simplified the logic for determining configured models and exchanges by removing reliance on sensitive fields like apiKey.
- Enhanced filtering criteria to check for enabled status and non-sensitive fields, improving clarity and security.
- Updated UI class bindings to reflect the new configuration checks without compromising functionality.

This refactor aims to streamline the configuration process while ensuring sensitive information is not exposed.
2025-11-08 01:17:16 +08:00
Icyoung
96ad58315b Dev remove admin mode (#723)
* feat: remove admin mode

* feat: bugfix

---------

Co-authored-by: icy <icyoung520@gmail.com>
2025-11-07 23:37:23 +08:00
0xYYBB | ZYY | Bobo
b48dfe7bfd feat(hyperliquid): enhance Agent Wallet security model (#717)
## Background

Hyperliquid official documentation recommends using Agent Wallet pattern for API trading:
- Agent Wallet is used for signing only
- Main Wallet Address is used for querying account data
- Agent Wallet should not hold significant funds

Reference: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets

## Current Implementation

Current implementation allows auto-generating wallet address from private key,
which simplifies user configuration but may lead to potential security concerns
if users accidentally use their main wallet private key.

## Enhancement

Following the proven pattern already used in Aster exchange implementation
(which uses dual-address mode), this enhancement upgrades Hyperliquid to
Agent Wallet mode:

### Core Changes

1. **Mandatory dual-address configuration**
   - Agent Private Key (for signing)
   - Main Wallet Address (holds funds)

2. **Multi-layer security checks**
   - Detect if user accidentally uses main wallet private key
   - Validate Agent wallet balance (reject if > 100 USDC)
   - Provide detailed configuration guidance

3. **Design consistency**
   - Align with Aster's dual-address pattern
   - Follow Hyperliquid official best practices

### Code Changes

**config/database.go**:
- Add inline comments clarifying Agent Wallet security model

**trader/hyperliquid_trader.go**:
- Require explicit main wallet address (no auto-generation)
- Check if agent address matches main wallet address (security risk indicator)
- Query agent wallet balance and block if excessive
- Display both agent and main wallet addresses for transparency

**web/src/components/AITradersPage.tsx**:
- Add security alert banner explaining Agent Wallet mode
- Separate required inputs for Agent Private Key and Main Wallet Address
- Add field descriptions and validation

### Benefits

-  Aligns with Hyperliquid official security recommendations
-  Maintains design consistency with Aster implementation
-  Multi-layer protection against configuration mistakes
-  Detailed logging for troubleshooting

### Breaking Change

Users must now explicitly provide main wallet address (hyperliquid_wallet_addr).
Old configurations will receive clear error messages with migration guidance.

### Migration Guide

**Before** (single private key):
```json
{
  "hyperliquid_private_key": "0x..."
}
```

**After** (Agent Wallet mode):
```json
{
  "hyperliquid_private_key": "0x...",  // Agent Wallet private key
  "hyperliquid_wallet_addr": "0x..."   // Main Wallet address
}
```

Users can create Agent Wallet on Hyperliquid official website:
https://app.hyperliquid.xyz/ → Settings → API Wallets

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-07 23:26:56 +08:00
0xbigtang
28a63f4d48 fix: admin logout button visibility (#650) 2025-11-07 22:52:03 +08:00
Shui
90af9dbca6 Revert "fix(web): prevent NaN% display in competition gap calculation (#633) …" (#676)
This reverts commit 8db6dc3b06.
2025-11-06 20:58:13 -05:00
0xYYBB | ZYY | Bobo
8db6dc3b06 fix(web): prevent NaN% display in competition gap calculation (#633) (#670)
**Problem:**
Competition page shows "NaN%" for gap difference when trader P&L
percentages are null/undefined.

**Root Cause:**
Line 227: `const gap = trader.total_pnl_pct - opponent.total_pnl_pct`
- If either value is `undefined` or `null`, result is `NaN`
- Display shows "领先 NaN%" or "落后 NaN%"

**Solution:**
Add null coalescing to default undefined/null values to 0:
```typescript
const gap = (trader.total_pnl_pct ?? 0) - (opponent.total_pnl_pct ?? 0)
```

**Impact:**
-  Gap calculation returns 0 when data is missing (shows 0.00%)
-  Prevents confusing "NaN%" display
-  Graceful degradation for incomplete data

Fixes #633

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-06 20:35:58 -05:00
SkywalkerJi
12512ff7f3 fix: Fixed go vet issues. (#658)
* Fixed vet ./... errors.

* Fixed ESLint issues.
2025-11-07 02:28:01 +08:00
0xYYBB | ZYY | Bobo
cad984b220 fix(web): restore ESLint, Prettier, and Husky code quality tools (#648)
## Problem
PR #647 accidentally removed all code quality tools when adding test dependencies:
-  ESLint (9 packages) - code linting
-  Prettier - code formatting
-  Husky - Git hooks
-  lint-staged - pre-commit checks
-  Related scripts (lint, format, prepare)

This significantly impacts code quality and team collaboration.

## Root Cause
When adding test dependencies (vitest, @testing-library/react), the package.json
was incorrectly edited, removing all existing devDependencies.

## Solution
Restore all code quality tools while keeping the new test dependencies:

###  Restored packages:
- @eslint/js
- @typescript-eslint/eslint-plugin
- @typescript-eslint/parser
- eslint + plugins (prettier, react, react-hooks, react-refresh)
- prettier
- husky
- lint-staged

###  Kept test packages:
- @testing-library/jest-dom
- @testing-library/react
- jsdom
- vitest

###  Restored scripts:
```json
{
  "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
  "lint:fix": "eslint . --ext ts,tsx --fix",
  "format": "prettier --write \"src/**/*.{ts,tsx,css,json}\"",
  "format:check": "prettier --check \"src/**/*.{ts,tsx,css,json}\"",
  "test": "vitest run",
  "prepare": "husky"
}
```

###  Restored lint-staged config

## Impact
This fix restores:
- Automated code style enforcement
- Pre-commit quality checks
- Consistent code formatting
- Team collaboration standards

## Testing
- [x] npm install succeeds
- [x] npm run build succeeds
- [x] All scripts are functional

Related-To: PR #647

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-07 01:30:13 +08:00
tinkle
fa0cc5e064 update link 2025-11-07 01:26:18 +08:00
0xYYBB | ZYY | Bobo
d4f1e6a4d4 fix(web): resolve TypeScript type error in crypto.ts and add missing test dependencies (#647)
```
src/lib/crypto.ts(66,32): error TS2345: Argument of type 'Uint8Array<ArrayBuffer>'
is not assignable to parameter of type 'ArrayBuffer'.
```

`arrayBufferToBase64` function expected `ArrayBuffer` but received `Uint8Array.buffer`.
TypeScript strict type checking flagged the mismatch.

1. Update `arrayBufferToBase64` signature to accept `ArrayBuffer | Uint8Array`
2. Pass `result` directly instead of `result.buffer` (more accurate)
3. Add runtime type check with instanceof

```
error TS2307: Cannot find module 'vitest'
error TS2307: Cannot find module '@testing-library/react'
```

Install missing devDependencies:
- vitest
- @testing-library/react
- @testing-library/jest-dom

 Frontend builds successfully
 TypeScript compilation passes
 No type errors

Related-To: Docker frontend build failures
2025-11-07 01:19:48 +08:00
ZhouYongyou
8c575a0613 feat(security): add end-to-end encryption for sensitive data
## Summary
Add comprehensive encryption system to protect private keys and API secrets.

## Core Components
- `crypto/encryption.go`: RSA-4096 + AES-256-GCM encryption manager
- `crypto/secure_storage.go`: Database encryption layer + audit logs
- `crypto/aliyun_kms.go`: Optional Aliyun KMS integration
- `api/crypto_handler.go`: Encryption API endpoints
- `web/src/lib/crypto.ts`: Frontend two-stage encryption
- `scripts/migrate_encryption.go`: Data migration tool
- `deploy_encryption.sh`: One-click deployment

## Security Architecture
```
Frontend: Two-stage input + clipboard obfuscation
    ↓
Transport: RSA-4096 + AES-256-GCM hybrid encryption
    ↓
Storage: Database encryption + audit logs
```

## Features
 Zero breaking changes (backward compatible)
 Automatic migration of existing data
 <25ms overhead per operation
 Complete audit trail
 Optional cloud KMS support

## Migration
```bash
./deploy_encryption.sh  # 5 minutes, zero downtime
```

## Testing
```bash
go test ./crypto -v
```

Related-To: security-enhancement
2025-11-06 23:55:33 +08:00
Lawrence Liu
0b5d08f18a fix(web): 修正 FAQ 翻译文件中的错误信息 (#552)
- 删除 OKX 虚假支持声明(后端未实现)
- 补充 Aster DEX 的 API 配置说明
- 修正测试网说明为暂时不支持
2025-11-06 21:59:10 +08:00
Ember
ef12e9153a bugfix/ fix delete AI Model issue (#594)
* fix: 修复删除AI模型/交易所后UI未刷新的问题

问题描述:
在配置界面删除AI模型或交易所后,虽然后端数据已更新,但前端UI仍然显示已删除的配置项。

根本原因:
React的状态更新机制可能无法检测到数组内容的变化,特别是当API返回的数据与之前的引用相同时。

修复方案:
在 handleDeleteModelConfig 和 handleDeleteExchangeConfig 中使用数组展开运算符 [...items] 创建新数组,确保React能够检测到状态变化并触发重新渲染。

修改文件:
- web/src/components/AITradersPage.tsx

影响范围:
- AI模型删除功能
- 交易所删除功能

Fixes #591

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

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

* fix: 删除重复的确认对话框

问题描述:
删除AI模型或交易所时,确认对话框会弹出两次

根本原因:
1. ModelConfigModal 的删除按钮 onClick 中有一个 confirm
2. handleDeleteConfig 函数内部也有一个 confirm

修复方案:
移除 Modal 组件中的 confirm,保留 handleDeleteConfig 内部的确认逻辑,因为它包含了更完整的依赖检查功能

修改内容:
- 移除 ModelConfigModal 删除按钮中的 confirm
- 移除 ExchangeConfigModal 删除按钮中的 confirm
- 更新 title 属性为更合适的翻译键

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-06 12:25:25 +08:00
Diego
ed737e08d6 fix: 修复删除模型/交易所时界面卡死问题并增强依赖检查 (#578)
* fix: 修复删除模型/交易所时界面卡死问题并增强依赖检查

## 问题描述
1. 删除唯一的AI模型或交易所配置时,界面会卡死数秒
2. 删除后配置仍然显示在列表中
3. 可以删除被交易员使用的配置,导致数据不一致

## 修复内容

### 后端性能优化 (manager/trader_manager.go)
- 将循环内的重复数据库查询移到循环外
- 减少N次重复查询(GetAIModels + GetExchanges)为1次查询
- 大幅减少锁持有时间,从数秒降至毫秒级

### 前端显示修复 (web/src/components/AITradersPage.tsx)
- 过滤显示列表,只显示真正配置过的模型/交易所(有apiKey的)
- 删除后重新从后端获取最新数据,确保界面同步

### 前端依赖检查 (web/src/components/AITradersPage.tsx)
- 新增完整的依赖检查,包括停止状态的交易员
- 删除前检查是否有交易员使用该配置
- 显示使用该配置的交易员名称列表
- 阻止删除被使用的配置,保证数据一致性

### 多语言支持 (web/src/i18n/translations.ts)
- 添加依赖检查相关的中英文提示文本
- cannotDeleteModelInUse / cannotDeleteExchangeInUse
- tradersUsing / pleaseDeleteTradersFirst

## 测试建议
1. 创建交易员后尝试删除其使用的模型/交易所,应显示警告并阻止删除
2. 删除未使用的模型/交易所,应立即从列表消失且界面不卡死
3. 刷新页面后,已删除的配置不应再出现

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

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

* refactor: 重构删除配置函数减少重复代码

## 重构内容
- 创建通用的 handleDeleteConfig 函数
- 使用配置对象模式处理模型和交易所的删除逻辑
- 消除 handleDeleteModelConfig 和 handleDeleteExchangeConfig 之间的重复代码

## 重构效果
- 减少代码行数约 40%
- 提高代码可维护性和可读性
- 便于未来添加新的配置类型

## 功能保持不变
- 依赖检查逻辑完全相同
- 删除流程完全相同
- 用户体验完全相同

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-06 10:32:30 +08:00
SkywalkerJi
6d26a5cf15 fix: Fixed redundant key input fields and corrected formatting on the frontend. (#566)
* Eliminate redundant key input fields in the front-end.

* go / react Formatting.
2025-11-06 01:16:04 +08:00
Ember
b2e4be9152 Feature/faq (#546)
* feat(web): add FAQ page with search, sidebar, and i18n integration; update navigation and routes; include user feedback analysis docs (faq.md)

* docs: add filled frontend PR template for FAQ feature (PR_FRONTEND_FAQ.md)

* docs(web): add Contributing & Tasks FAQ category near top with guidance on using GitHub Projects and PR contribution standards

* feat(web,api): dynamically embed GitHub Projects roadmap in FAQ via /api/roadmap and RoadmapWidget; add env vars for GitHub token/org/project

* chore(docker): pass GitHub roadmap env vars into backend container

* docs(web): update FAQ with fork-based PR workflow, yellow links to roadmap/task dashboard, and contribution incentives; remove dynamic roadmap embed\n\nchore(api,docker): remove /api/roadmap endpoint and related env wiring

* chore: revert unintended changes (.env.example, api/server.go, docker-compose.yml); remove local-only files (PR_FRONTEND_FAQ.md, web/faq.md) from PR

* feat: 添加对重置密码页面的路由支持
2025-11-05 22:39:42 +08:00
Burt
be768d91a3 Feat: Enable admin password in admin mode (#540)
* WIP: save local changes before merging

* Enable admin password in admin mode #374
2025-11-05 21:48:28 +08:00
Sue
db68689475 feat(auth): implement password reset with Google Authenticator verification (#537)
实现忘记密码功能,用户可以通过邮箱和Google Authenticator验证码重置密码。

**后端改动:**
- 添加 `/api/reset-password` 接口
- 实现 `UpdateUserPassword` 数据库方法
- 验证邮箱、OTP和新密码

**前端改动:**
- 新增 `ResetPasswordPage` 组件
- 在登录页面添加"忘记密码"链接
- 实现密码重置表单(新密码、确认密码、OTP验证)
- 添加密码可见性切换功能
- 支持中英文国际化

**安全特性:**
- 要求Google Authenticator验证
- 密码强度验证(最少6位)
- 密码确认匹配检查
- 密码哈希存储

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-05 21:01:18 +08:00
SkywalkerJi
eb515d74e9 Resolved front-end linting issues. (#533) 2025-11-05 20:41:41 +08:00
CoderMageFox
86d2a07040 docs: clarify Aster only supports EVM wallets, not Solana wallets (#524) 2025-11-05 19:37:27 +08:00
Ember
a7385e5256 fix(web): remove undefined setHyperliquidWalletAddr call in ExchangeConfigModal (#525) 2025-11-05 19:35:57 +08:00
Sue
77c99499d7 feat(api): add server IP display for exchange whitelist configuration (#520)
Added functionality to display server public IP address for users to configure exchange API whitelists, specifically for Binance integration.

Backend changes (api/server.go):
- Add GET /api/server-ip endpoint requiring authentication
- Implement getPublicIPFromAPI() with fallback to multiple IP services
- Implement getPublicIPFromInterface() for local network interface detection
- Add isPrivateIP() helper to filter private IP addresses
- Import net package for IP address handling

Frontend changes (web/):
- Add getServerIP() API method in api.ts
- Display server IP in ExchangeConfigModal for Binance
- Add IP copy-to-clipboard functionality
- Load and display server IP when Binance exchange is selected
- Add i18n translations (en/zh) for whitelist IP messages:
  - whitelistIP, whitelistIPDesc, serverIPAddresses
  - copyIP, ipCopied, loadingServerIP

User benefits:
- Simplifies Binance API whitelist configuration
- Shows exact server IP to add to exchange whitelist
- One-click IP copy for convenience

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-05 18:15:33 +08:00
CoderMageFox
f7391adff9 feat: add i18n support for candidate coins warnings (#516)
- Add 13 translation keys for candidate coins warnings in both English and Chinese
- Update App.tsx to use t() function for all warning text
- Update AITradersPage.tsx to use t() function for signal source warnings
- Ensure proper internationalization for all user-facing messages

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-05 17:35:38 +08:00
CoderMageFox
2299a0e34f feat: 添加候选币种为0时的前端警告提示 (#515)
* feat: add frontend warnings for zero candidate coins

当候选币种数量为0时,在前端添加详细的错误提示和诊断信息

主要改动:
1. 决策日志中显示候选币种数量,为0时标红警告
2. 候选币种为0时显示详细警告卡片,包含可能原因和解决方案
3. 交易员列表页面添加信号源未配置的全局警告
4. 更新TraderInfo类型定义,添加use_coin_pool和use_oi_top字段

详细说明:
- 在App.tsx的账户状态摘要中添加候选币种显示
- 当候选币种为0时,显示详细的警告卡片,列出:
  * 可能原因(API未配置、连接超时、数据为空等)
  * 解决方案(配置自定义币种、配置API、禁用选项等)
- 在AITradersPage中添加信号源配置检查
  * 当交易员启用了币种池但未配置API时显示全局警告
  * 提供"立即配置信号源"快捷按钮
- 不改变任何后端逻辑,纯UI层面的用户提示改进

影响范围:
- web/src/App.tsx: 决策记录卡片中的警告显示
- web/src/components/AITradersPage.tsx: 交易员列表页警告
- web/src/types.ts: TraderInfo类型定义更新

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

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

* fix: import AlertTriangle from lucide-react in App.tsx

修复TypeScript编译错误:Cannot find name 'AlertTriangle'

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-05 17:11:04 +08:00
ERIC LEUNG
341b70a640 refactor(AITradersPage): remove unused hyperliquidWalletAddr state (#511) 2025-11-05 16:42:56 +08:00
Icyoung
d940ef43fd Merge branch 'dev' into fix/binance-multi-assets-api-error 2025-11-05 16:23:22 +08:00
Icyoung
6c21ce8386 Merge branch 'dev' into fix/trader-config-overwrite 2025-11-05 16:05:40 +08:00
tinkle-community
8c105599f6 Merge pull request #493 from simonjiang99/fix/3-minutes-minimum
fix(api):enforce minimum scan interval of three minutes
2025-11-05 16:02:04 +08:00
Icyoung
f3af7370e2 Merge branch 'dev' into fix/bug-fixes-collection-v2 2025-11-05 15:56:58 +08:00
CoderMageFox
ba31078d92 feat: add Aster API wallet links to help tooltips
Added direct links to Aster API wallet page in help tooltips for easier access.

Changes:
- Added English link: https://www.asterdex.com/en/api-wallet
- Added Chinese link: https://www.asterdex.com/zh-CN/api-wallet
- Updated asterSignerDesc with API wallet URL
- Updated asterPrivateKeyDesc with API wallet URL and security note
- Users can now directly access the API wallet page from tooltips

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 13:26:05 +08:00
CoderMageFox
cf2314c266 refactor: merge USDT warning into security warning box
Merged standalone USDT warning into existing security warning section for cleaner UI.

Changes:
- Removed separate red warning box for USDT
- Added USDT warning as first item in security warning box (conditional on Aster exchange)
- Now shows 4 warnings for Aster: USDT requirement + 3 general security warnings
- Cleaner, more organized warning presentation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 13:19:39 +08:00
CoderMageFox
df6f775f3c feat: add USDT warning for Aster exchange configuration
Added warning message to inform users that Aster only tracks USDT balance, preventing P&L calculation errors from asset price fluctuations.

Why this is important:
- Aster trader only tracks USDT balance (aster_trader.go:453)
- If users use BNB/ETH as margin, price fluctuations will cause:
  * Initial balance becomes inaccurate
  * P&L statistics will be wrong
  * Example: 10 BNB @ $100 = $1000, if BNB drops to $90, real equity is $900 but system still shows $1000

Changes:
- Added asterUsdtWarning translation in both EN and ZH
- Added red warning box below Aster private key field
- Clear message: "Please use USDT as margin currency"

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 13:15:49 +08:00
CoderMageFox
a03e4269ce feat: add help tooltips for Aster exchange configuration fields
Added interactive help icons with tooltips for Aster exchange fields (user, signer, privateKey) to guide users through correct configuration.

Changes:
- Added HelpCircle icon from lucide-react
- Created reusable Tooltip component with hover/click interaction
- Added bilingual help descriptions in translations.ts
- User field: explains main wallet address (login address)
- Signer field: explains API wallet address generation
- Private Key field: clarifies local-only usage, never transmitted

This prevents user confusion and configuration errors when setting up Aster exchange.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 13:03:41 +08:00
CoderMageFox
47f34f75a2 fix: 修复InitialBalance配置错误导致的P&L统计不准确问题
用户在使用Aster交易员时发现,即使没有开始交易,P&L统计也显示了12.5 USDT (83.33%)的盈亏。经过调查发现:

**根本原因**:
- 实际Aster账户余额:27.5 USDT
- Web界面配置的InitialBalance:15 USDT 
- 错误的P&L计算:27.5 - 15 = 12.5 USDT (83.33%)

**问题根源**:
1. Web界面创建交易员时默认initial_balance为1000 USDT
2. 用户手动修改时容易输入错误的值
3. 缺少自动获取实际余额的功能
4. 缺少明确的警告提示

**文件**: `trader/aster_trader.go`

-  验证Aster API完全兼容Binance格式
- 添加详细的注释说明字段含义
- 添加调试日志以便排查问题
- 确认balance字段不包含未实现盈亏(与Binance一致)

**关键确认**:
```go
//  Aster API完全兼容Binance API格式
// balance字段 = wallet balance(不包含未实现盈亏)
// crossUnPnl = unrealized profit(未实现盈亏)
// crossWalletBalance = balance + crossUnPnl(全仓钱包余额,包含盈亏)
```

**文件**: `web/src/components/TraderConfigModal.tsx`

**新增功能**:
1. **编辑模式**:添加"获取当前余额"按钮
   - 一键从交易所API获取当前账户净值
   - 自动填充到InitialBalance字段
   - 显示加载状态和错误提示

2. **创建模式**:添加警告提示
   - ⚠️ 提醒用户必须输入交易所的当前实际余额
   - 警告:如果输入不准确,P&L统计将会错误

3. **改进输入体验**:
   - 支持小数输入(step="0.01")
   - 必填字段标记(创建模式)
   - 实时错误提示

**代码实现**:
```typescript
const handleFetchCurrentBalance = async () => {
  const response = await fetch(`/api/account?trader_id=${traderData.trader_id}`);
  const data = await response.json();
  const currentBalance = data.total_equity; // 当前净值
  setFormData(prev => ({ ...prev, initial_balance: currentBalance }));
};
```

通过查阅Binance官方文档确认:

| 项目 | Binance | Aster (修复后) |
|------|---------|----------------|
| **余额字段** | balance = 钱包余额(不含盈亏) |  相同 |
| **盈亏字段** | crossUnPnl = 未实现盈亏 |  相同 |
| **总权益** | balance + crossUnPnl |  相同 |
| **P&L计算** | totalEquity - initialBalance |  相同 |

1. 编辑交易员配置
2. 点击"获取当前余额"按钮
3. 系统自动填充正确的InitialBalance
4. 保存配置

1. 查看交易所账户的实际余额
2. 准确输入到InitialBalance字段
3. 注意查看警告提示
4. 完成创建

- [x] 确认Aster API返回格式与Binance一致
- [x] 验证"获取当前余额"功能正常工作
- [x] 确认P&L计算公式正确
- [x] 前端构建成功
- [x] 警告提示正常显示

- **修复**: 解决InitialBalance配置错误导致的P&L统计不准确问题
- **改进**: 提升用户体验,减少配置错误
- **兼容**: 完全向后兼容,不影响现有功能

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 12:49:55 +08:00
simon
fc63fe1835 Enforce minimum scan interval of three minutes 2025-11-05 12:25:47 +08:00
Ember
11c767cdda feat: add ESLint and Prettier with pre-commit hook
- Install ESLint 9 with TypeScript and React support
- Install Prettier with custom configuration (no semicolons)
- Add husky and lint-staged for pre-commit hooks
- Configure lint-staged to auto-fix and format on commit
- Relax ESLint rules to avoid large-scale code changes
- Format all existing code with Prettier (no semicolons)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 11:41:14 +08:00
Ember
332d0fbdc0 test: verify pre-commit hook formatting 2025-11-05 11:40:05 +08:00
Ember
c664a54d5e test: add eslint and prettier configuration with pre-commit hook 2025-11-05 11:40:05 +08:00