mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-10 06:20:58 +08:00
Feature/okx trading (#1177)
* feat: add OKX exchange trading support - Add OKX trader client with full trading API integration - Support API Key, Secret Key, and Passphrase authentication - Add OKX icon and frontend configuration modal - Update exchange store and types for OKX fields * fix: add passphrase column migration and fix exchange type mapping * fix: show OKX input fields in exchange config modal * fix: ensure all supported exchanges exist for user when listing * fix: simplify exchange type check condition for OKX * debug: add visible debug info for exchange id * fix: remove debug info from exchange config modal * fix: add OKX to exchange type condition in AITradersPage * feat: complete OKX trading support and fix exchange config issues - Add LIGHTER exchange UI support in AITradersPage - Add passphrase field to UpdateExchangeConfigRequest type - Fix OKX HTTP client to bypass proxy (disable system proxy) - Auto-fetch initial balance from exchange when not set - Support multiple balance field names for different exchanges - Add detailed error messages when trader fails to load - Add lighter_api_key_private_key field to exchange store
This commit is contained in:
@@ -23,6 +23,7 @@ interface ExchangeConfigModalProps {
|
||||
exchangeId: string,
|
||||
apiKey: string,
|
||||
secretKey?: string,
|
||||
passphrase?: string, // OKX专用
|
||||
testnet?: boolean,
|
||||
hyperliquidWalletAddr?: string,
|
||||
asterUser?: string,
|
||||
@@ -222,13 +223,17 @@ export function ExchangeConfigModal({
|
||||
// 根据交易所类型验证不同字段
|
||||
if (selectedExchange?.id === 'binance') {
|
||||
if (!apiKey.trim() || !secretKey.trim()) return
|
||||
await onSave(selectedExchangeId, apiKey.trim(), secretKey.trim(), testnet)
|
||||
await onSave(selectedExchangeId, apiKey.trim(), secretKey.trim(), '', testnet)
|
||||
} else if (selectedExchange?.id === 'okx') {
|
||||
if (!apiKey.trim() || !secretKey.trim() || !passphrase.trim()) return
|
||||
await onSave(selectedExchangeId, apiKey.trim(), secretKey.trim(), passphrase.trim(), testnet)
|
||||
} else if (selectedExchange?.id === 'hyperliquid') {
|
||||
if (!apiKey.trim() || !hyperliquidWalletAddr.trim()) return // 验证私钥和钱包地址
|
||||
await onSave(
|
||||
selectedExchangeId,
|
||||
apiKey.trim(),
|
||||
'',
|
||||
'',
|
||||
testnet,
|
||||
hyperliquidWalletAddr.trim()
|
||||
)
|
||||
@@ -239,6 +244,7 @@ export function ExchangeConfigModal({
|
||||
selectedExchangeId,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
testnet,
|
||||
undefined,
|
||||
asterUser.trim(),
|
||||
@@ -251,6 +257,7 @@ export function ExchangeConfigModal({
|
||||
selectedExchangeId,
|
||||
lighterPrivateKey.trim(),
|
||||
'',
|
||||
'',
|
||||
testnet,
|
||||
lighterWalletAddr.trim(),
|
||||
undefined,
|
||||
@@ -260,13 +267,10 @@ export function ExchangeConfigModal({
|
||||
lighterPrivateKey.trim(),
|
||||
lighterApiKeyPrivateKey.trim()
|
||||
)
|
||||
} else if (selectedExchange?.id === 'okx') {
|
||||
if (!apiKey.trim() || !secretKey.trim() || !passphrase.trim()) return
|
||||
await onSave(selectedExchangeId, apiKey.trim(), secretKey.trim(), testnet)
|
||||
} else {
|
||||
// 默认情况(其他CEX交易所)
|
||||
if (!apiKey.trim() || !secretKey.trim()) return
|
||||
await onSave(selectedExchangeId, apiKey.trim(), secretKey.trim(), testnet)
|
||||
await onSave(selectedExchangeId, apiKey.trim(), secretKey.trim(), '', testnet)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,12 +408,10 @@ export function ExchangeConfigModal({
|
||||
|
||||
{selectedExchange && (
|
||||
<>
|
||||
{/* Binance/Bybit 和其他 CEX 交易所的字段 */}
|
||||
{/* Binance/Bybit/OKX 的输入字段 */}
|
||||
{(selectedExchange.id === 'binance' ||
|
||||
selectedExchange.id === 'bybit' ||
|
||||
selectedExchange.type === 'cex') &&
|
||||
selectedExchange.id !== 'hyperliquid' &&
|
||||
selectedExchange.id !== 'aster' && (
|
||||
selectedExchange.id === 'okx') && (
|
||||
<>
|
||||
{/* 币安用户配置提示 (D1 方案) */}
|
||||
{selectedExchange.id === 'binance' && (
|
||||
|
||||
Reference in New Issue
Block a user