mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-07 04:50:57 +08:00
fix(ui): remove duplicate exchange configuration fields (Aster & Hyperliquid) (#921)
* fix(ui): remove duplicate Aster exchange form rendering 修復 Aster 交易所配置表單重複渲染問題。 Issue: - Aster 表單代碼在 AITradersPage.tsx 中出現兩次(lines 2334 和 2559) - 導致用戶界面顯示 6 個輸入欄位(應該是 3 個) - 用戶體驗混亂 Fix: - 刪除重複的 Aster 表單代碼塊(lines 2559-2710,共 153 行) - 保留第一個表單塊(lines 2334-2419) - 修復 prettier 格式問題 Result: - Aster 配置現在正確顯示 3 個欄位:user, signer, private key - Lint 檢查通過 - Hyperliquid Agent Wallet 翻譯已存在無需修改 Technical: - 刪除了完全重複的 JSX 條件渲染塊 - 移除空白行以符合 prettier 規範 Co-Authored-By: tinkle-community <tinklefund@gmail.com> * fix(ui): remove legacy Hyperliquid single private key field 修復 Hyperliquid 配置頁面顯示舊版私鑰欄位的問題。 Issue: - Hyperliquid 配置同時顯示舊版和新版欄位 - 舊版:單一「私钥」欄位(不安全,已廢棄) - 新版:「代理私钥」+「主钱包地址」(Agent Wallet 安全模式) - 用戶看到重複的欄位配置,造成混淆 Root Cause: - AITradersPage.tsx 存在兩個 Hyperliquid 條件渲染塊 - Lines 2302-2332: 舊版單私鑰模式(應刪除) - Lines 2424-2557: 新版 Agent Wallet 模式(正確) Fix: - 刪除舊版 Hyperliquid 單私鑰欄位代碼塊(lines 2302-2332,共 32 行) - 保留新版 Agent Wallet 配置(代理私鑰 + 主錢包地址) - 移除 `t('privateKey')` 和 `t('hyperliquidPrivateKeyDesc')` 舊版翻譯引用 Result: - Hyperliquid 配置現在只顯示正確的 Agent Wallet 欄位 - 安全提示 banner 正確顯示 - 用戶體驗改善,不再混淆 Technical Details: - 新版使用 `apiKey` 儲存 Agent Private Key - 新版使用 `hyperliquidWalletAddr` 儲存 Main Wallet Address - 符合 Hyperliquid Agent Wallet 最佳安全實踐 Related: - 之前已修復 Aster 重複渲染問題(commit 5462eba0) - Hyperliquid 翻譯 key 已存在於 translations.ts (lines 206-216, 1017-1027) Co-Authored-By: tinkle-community <tinklefund@gmail.com> * fix(i18n): add missing Hyperliquid Agent Wallet translation keys 補充 Hyperliquid 代理錢包配置的翻譯文本,修復前端顯示 key 名稱的問題。 Changes: - 新增 8 個英文翻譯 key (Agent Wallet 配置說明) - 新增 8 個中文翻譯 key (代理錢包配置說明) - 修正 Hyperliquid 配置頁面顯示問題(從顯示 key 名稱改為顯示翻譯文本) Technical Details: - hyperliquidAgentWalletTitle: Banner 標題 - hyperliquidAgentWalletDesc: 安全說明文字 - hyperliquidAgentPrivateKey: 代理私鑰欄位標籤 - hyperliquidMainWalletAddress: 主錢包地址欄位標籤 - 相應的 placeholder 和 description 文本 Related Issue: 用戶反饋前端顯示 key 名稱而非翻譯文本 Co-Authored-By: tinkle-community <tinklefund@gmail.com> --------- Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
committed by
GitHub
parent
1e0da2ee39
commit
70a6218704
@@ -2298,39 +2298,6 @@ function ExchangeConfigModal({
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Hyperliquid 交易所的字段 */}
|
||||
{selectedExchange.id === 'hyperliquid' && (
|
||||
<>
|
||||
<div>
|
||||
<label
|
||||
className="block text-sm font-semibold mb-2"
|
||||
style={{ color: '#EAECEF' }}
|
||||
>
|
||||
{t('privateKey', language)}
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={apiKey}
|
||||
onChange={(e) => setApiKey(e.target.value)}
|
||||
placeholder={t('enterPrivateKey', language)}
|
||||
className="w-full px-3 py-2 rounded"
|
||||
style={{
|
||||
background: '#0B0E11',
|
||||
border: '1px solid #2B3139',
|
||||
color: '#EAECEF',
|
||||
}}
|
||||
required
|
||||
/>
|
||||
<div
|
||||
className="text-xs mt-1"
|
||||
style={{ color: '#848E9C' }}
|
||||
>
|
||||
{t('hyperliquidPrivateKeyDesc', language)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Aster 交易所的字段 */}
|
||||
{selectedExchange.id === 'aster' && (
|
||||
<>
|
||||
@@ -2555,160 +2522,6 @@ function ExchangeConfigModal({
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Aster 交易所的字段 */}
|
||||
{selectedExchange.id === 'aster' && (
|
||||
<>
|
||||
<div>
|
||||
<label
|
||||
className="block text-sm font-semibold mb-2 flex items-center gap-2"
|
||||
style={{ color: '#EAECEF' }}
|
||||
>
|
||||
{t('user', language)}
|
||||
<Tooltip content={t('asterUserDesc', language)}>
|
||||
<HelpCircle
|
||||
className="w-4 h-4 cursor-help"
|
||||
style={{ color: '#F0B90B' }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={asterUser}
|
||||
onChange={(e) => setAsterUser(e.target.value)}
|
||||
placeholder={t('enterUser', language)}
|
||||
className="w-full px-3 py-2 rounded"
|
||||
style={{
|
||||
background: '#0B0E11',
|
||||
border: '1px solid #2B3139',
|
||||
color: '#EAECEF',
|
||||
}}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
className="block text-sm font-semibold mb-2 flex items-center gap-2"
|
||||
style={{ color: '#EAECEF' }}
|
||||
>
|
||||
{t('signer', language)}
|
||||
<Tooltip content={t('asterSignerDesc', language)}>
|
||||
<HelpCircle
|
||||
className="w-4 h-4 cursor-help"
|
||||
style={{ color: '#F0B90B' }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={asterSigner}
|
||||
onChange={(e) => setAsterSigner(e.target.value)}
|
||||
placeholder={t('enterSigner', language)}
|
||||
className="w-full px-3 py-2 rounded"
|
||||
style={{
|
||||
background: '#0B0E11',
|
||||
border: '1px solid #2B3139',
|
||||
color: '#EAECEF',
|
||||
}}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
className="block text-sm font-semibold mb-2 flex items-center gap-2"
|
||||
style={{ color: '#EAECEF' }}
|
||||
>
|
||||
{t('privateKey', language)}
|
||||
<Tooltip content={t('asterPrivateKeyDesc', language)}>
|
||||
<HelpCircle
|
||||
className="w-4 h-4 cursor-help"
|
||||
style={{ color: '#F0B90B' }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</label>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
type="text"
|
||||
value={maskSecret(asterPrivateKey)}
|
||||
readOnly
|
||||
placeholder={t('enterPrivateKey', language)}
|
||||
className="w-full px-3 py-2 rounded"
|
||||
style={{
|
||||
background: '#0B0E11',
|
||||
border: '1px solid #2B3139',
|
||||
color: '#EAECEF',
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSecureInputTarget('aster')}
|
||||
className="px-3 py-2 rounded text-xs font-semibold transition-all hover:scale-105"
|
||||
style={{
|
||||
background: '#F0B90B',
|
||||
color: '#000',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{asterPrivateKey
|
||||
? t('secureInputReenter', language)
|
||||
: t('secureInputButton', language)}
|
||||
</button>
|
||||
{asterPrivateKey && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setAsterPrivateKey('')}
|
||||
className="px-3 py-2 rounded text-xs font-semibold transition-all hover:scale-105"
|
||||
style={{
|
||||
background: '#1B1F2B',
|
||||
color: '#848E9C',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{t('secureInputClear', language)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{asterPrivateKey && (
|
||||
<div className="text-xs" style={{ color: '#848E9C' }}>
|
||||
{t('secureInputHint', language)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="p-4 rounded"
|
||||
style={{
|
||||
background: 'rgba(240, 185, 11, 0.1)',
|
||||
border: '1px solid rgba(240, 185, 11, 0.2)',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="text-sm font-semibold mb-2"
|
||||
style={{ color: '#F0B90B' }}
|
||||
>
|
||||
<span className="inline-flex items-center gap-1">
|
||||
<AlertTriangle className="w-4 h-4" />{' '}
|
||||
{t('securityWarning', language)}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="text-xs space-y-1"
|
||||
style={{ color: '#848E9C' }}
|
||||
>
|
||||
{selectedExchange.id === 'aster' && (
|
||||
<div>{t('asterUsdtWarning', language)}</div>
|
||||
)}
|
||||
<div>{t('exchangeConfigWarning1', language)}</div>
|
||||
<div>{t('exchangeConfigWarning2', language)}</div>
|
||||
<div>{t('exchangeConfigWarning3', language)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user