feat(lighter): 完整集成 LIGHTER DEX - SDK + 前端配置 UI (#1085)

* feat(trader): add LIGHTER DEX integration (initial implementation)
Add pure Go implementation of LIGHTER DEX trader following NOFX architecture
Features:
-  Account management with Ethereum wallet authentication
-  Order operations: market/limit orders, cancel, query
-  Position & balance queries
-  Zero-fee trading support (Standard accounts)
-  Up to 50x leverage for BTC/ETH
Implementation:
- Pure Go (no CGO dependencies) for easy deployment
- Based on hyperliquid_trader.go architecture
- Uses Ethereum ECDSA signatures (like Hyperliquid)
- API base URL: https://mainnet.zklighter.elliot.ai
Files:
- lighter_trader.go: Core trader structure & auth
- lighter_orders.go: Order management (create/cancel/query)
- lighter_account.go: Balance & position queries
Status: ⚠️ Partial implementation
-  Core structure complete
- ⏸️ Auth token generation needs implementation
- ⏸️ Transaction signing logic needs completion
- ⏸️ Config integration pending
Next steps:
1. Complete auth token generation
2. Add to config/exchange registry
3. Add frontend UI support
4. Create test suite
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* feat: Add LIGHTER DEX integration (快速整合階段)
## 🚀 新增功能
-  添加 LIGHTER DEX 作為第四個支持的交易所 (Binance, Hyperliquid, Aster, LIGHTER)
-  完整的數據庫配置支持(ExchangeConfig 新增 LighterWalletAddr, LighterPrivateKey 字段)
-  交易所註冊與初始化(initDefaultData 註冊 "lighter")
-  TraderManager 集成(配置傳遞邏輯完成)
-  AutoTrader 支持(NewAutoTrader 添加 "lighter" case)
## 📝 實現細節
### 後端整合
1. **數據庫層** (config/database.go):
   - ExchangeConfig 添加 LIGHTER 字段
   - 創建表時添加 lighter_wallet_addr, lighter_private_key 欄位
   - ALTER TABLE 語句用於向後兼容
   - UpdateExchange/CreateExchange/GetExchanges 支持 LIGHTER
   - migrateExchangesTable 支持 LIGHTER 字段
2. **API 層** (api/server.go, api/utils.go):
   - UpdateExchangeConfigRequest 添加 LIGHTER 字段
   - SanitizeExchangeConfigForLog 添加脫敏處理
3. **Trader 層** (trader/):
   - lighter_trader.go: 核心結構、認證、初始化
   - lighter_account.go: 餘額、持倉、市場價格查詢
   - lighter_orders.go: 訂單管理(創建、取消、查詢)
   - lighter_trading.go: 交易功能實現(開多/空、平倉、止損/盈)
   - 實現完整 Trader interface (13個方法)
4. **Manager 層** (manager/trader_manager.go):
   - addTraderFromDB 添加 LIGHTER 配置設置
   - AutoTraderConfig 添加 LIGHTER 字段
### 實現的功能(快速整合階段)
 基礎交易功能 (OpenLong, OpenShort, CloseLong, CloseShort)
 餘額查詢 (GetBalance, GetAccountBalance)
 持倉查詢 (GetPositions, GetPosition)
 訂單管理 (CreateOrder, CancelOrder, CancelAllOrders)
 止損/止盈 (SetStopLoss, SetTakeProfit, CancelStopLossOrders)
 市場數據 (GetMarketPrice)
 格式化工具 (FormatQuantity)
## ⚠️ TODO(完整實現階段)
- [ ] 完整認證令牌生成邏輯 (refreshAuthToken)
- [ ] 完整交易簽名邏輯(參考 Python SDK)
- [ ] 從 API 獲取幣種精度
- [ ] 區分止損/止盈訂單類型
- [ ] 前端 UI 支持
- [ ] 完整測試套件
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* feat: 完整集成 LIGHTER DEX with SDK
- 集成官方 lighter-go SDK (v0.0.0-20251104171447-78b9b55ebc48)
- 集成 Poseidon2 Goldilocks 簽名庫 (poseidon_crypto v0.0.11)
- 實現完整的 LighterTraderV2 使用官方 SDK
- 實現 17 個 Trader 接口方法(賬戶、交易、訂單管理)
- 支持雙密鑰系統(L1 錢包 + API Key)
- V1/V2 自動切換機制(向後兼容)
- 自動認證令牌管理(8小時有效期)
- 添加完整集成文檔 LIGHTER_INTEGRATION.md
新增文件:
- trader/lighter_trader_v2.go - V2 核心結構和初始化
- trader/lighter_trader_v2_account.go - 賬戶查詢方法
- trader/lighter_trader_v2_trading.go - 交易操作方法
- trader/lighter_trader_v2_orders.go - 訂單管理方法
- LIGHTER_INTEGRATION.md - 完整文檔
修改文件:
- trader/auto_trader.go - 添加 LighterAPIKeyPrivateKey 配置
- config/database.go - 添加 API Key 字段支持
- go.mod, go.sum - 添加 SDK 依賴
🤖 Generated with Claude Code
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* feat(lighter): 實現完整 HTTP 調用與動態市場映射
### 實現的功能
#### 1. submitOrder() - 真實訂單提交
- 使用 POST /api/v1/sendTx 提交已簽名訂單
- tx_type: 14 (CREATE_ORDER)
- 價格保護機制 (price_protection)
- 完整錯誤處理與響應解析
#### 2. GetActiveOrders() - 查詢活躍訂單
- GET /api/v1/accountActiveOrders
- 使用認證令牌 (Authorization header)
- 支持按市場索引過濾
#### 3. CancelOrder() - 真實取消訂單
- 使用 SDK 簽名 CancelOrderTxReq
- POST /api/v1/sendTx with tx_type: 15 (CANCEL_ORDER)
- 自動 nonce 管理
#### 4. getMarketIndex() - 動態市場映射
- 從 GET /api/v1/orderBooks 獲取市場列表
- 內存緩存 (marketIndexMap) 提高性能
- 回退到硬編碼映射(API 失敗時)
- 線程安全 (sync.RWMutex)
### 技術實現
**數據結構**:
- SendTxRequest/SendTxResponse - sendTx 請求響應
- MarketInfo - 市場信息緩存
**並發安全**:
- marketMutex - 保護市場索引緩存
- 讀寫鎖優化性能
**錯誤處理**:
- API 失敗回退機制
- 詳細日誌記錄
- HTTP 狀態碼驗證
### 測試
 編譯通過 (CGO_ENABLED=1)
 所有 Trader 接口方法實現完整
 HTTP 調用格式符合 LIGHTER API 規範
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* feat(lighter): 數據庫遷移與前端類型支持
### 數據庫變更
#### 新增欄位
- `exchanges.lighter_api_key_private_key` TEXT DEFAULT ''
- 支持 LIGHTER V2 的 40 字節 API Key 私鑰
#### 遷移腳本
- 📄 `migrations/002_add_lighter_api_key.sql`
- 包含完整的驗證和統計查詢
- 向後兼容現有配置(默認為空,使用 V1)
#### Schema 更新
- `config/database.go`:
  - 更新 CREATE TABLE 語句
  - 更新 exchanges_new 表結構
  - 新增 ALTER TABLE 遷移命令
### 前端類型更新
#### types.ts
- 新增 `Exchange` 接口字段:
  - `lighterWalletAddr?: string` - L1 錢包地址
  - `lighterPrivateKey?: string` - L1 私鑰
  - `lighterApiKeyPrivateKey?: string` - API Key 私鑰(新增)
### 技術細節
**數據庫兼容性**:
- 使用 ALTER TABLE ADD COLUMN IF NOT EXISTS
- 默認值為空字符串
- 不影響現有數據
**類型安全**:
- TypeScript 可選字段
- 與後端 ExchangeConfig 結構對齊
### 下一步
 **待完成**:
1. ExchangeConfigModal 組件更新
2. API 調用參數傳遞
3. V1/V2 狀態顯示
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* docs(lighter): 更新 LIGHTER_INTEGRATION.md 文檔狀態
* feat(lighter): 前端完整實現 - API Key 配置與 V1/V2 狀態
**英文**:
- `lighterWalletAddress`, `lighterPrivateKey`, `lighterApiKeyPrivateKey`
- `lighterWalletAddressDesc`, `lighterPrivateKeyDesc`, `lighterApiKeyPrivateKeyDesc`
- `lighterApiKeyOptionalNote` - V1 模式提示
- `lighterV1Description`, `lighterV2Description` - 狀態說明
- `lighterPrivateKeyImported` - 導入成功提示
**中文(繁體)**:
- 完整的中文翻譯對應
- 專業術語保留原文(L1、API Key、Poseidon2)
**Exchange 接口**:
- `lighterWalletAddr?: string`
- `lighterPrivateKey?: string`
- `lighterApiKeyPrivateKey?: string`
**UpdateExchangeConfigRequest 接口**:
- `lighter_wallet_addr?: string`
- `lighter_private_key?: string`
- `lighter_api_key_private_key?: string`
**狀態管理**:
- 添加 3 個 LIGHTER 狀態變量
- 更新 `secureInputTarget` 類型包含 'lighter'
**表單字段**:
- L1 錢包地址(必填,text input)
- L1 私鑰(必填,password + 安全輸入)
- API Key 私鑰(可選,password,40 字節)
**V1/V2 狀態顯示**:
- 動態背景顏色(V1: 橙色 #3F2E0F,V2: 綠色 #0F3F2E)
- 圖標指示(V1: ⚠️,V2: )
- 狀態說明文字
**驗證邏輯**:
- 必填字段:錢包地址 + L1 私鑰
- API Key 為可選字段
- 自動 V1/V2 檢測
**安全輸入**:
- 支持通過 TwoStageKeyModal 安全導入私鑰
- 導入成功後顯示 toast 提示
**handleSaveExchange**:
- 添加 3 個 LIGHTER 參數
- 更新交易所對象(新增/更新)
- 構建 API 請求(snake_case 字段)
**V1 模式(無 API Key)**:
```
┌────────────────────────────────────────┐
│ ⚠️ LIGHTER V1                          │
│ 基本模式 - 功能受限,僅用於測試框架       │
└────────────────────────────────────────┘
背景: #3F2E0F (橙色調)
邊框: #F59E0B (橙色)
```
**V2 模式(有 API Key)**:
```
┌────────────────────────────────────────┐
│  LIGHTER V2                          │
│ 完整模式 - 支持 Poseidon2 簽名和真實交易 │
└────────────────────────────────────────┘
背景: #0F3F2E (綠色調)
邊框: #10B981 (綠色)
```
1. **類型安全**
   - 完整的 TypeScript 類型定義
   - Props 接口正確對齊
   -  無 LIGHTER 相關編譯錯誤
2. **用戶體驗**
   - 清晰的必填/可選字段區分
   - 實時 V1/V2 狀態反饋
   - 安全私鑰輸入支持
3. **向後兼容**
   - 不影響現有交易所配置
   - 所有字段為可選(Optional)
   - API 請求格式統一
 TypeScript 編譯通過(無 LIGHTER 錯誤)
 類型定義完整且正確
 所有必需文件已更新
 與後端 API 格式對齊
Modified:
- `web/src/i18n/translations.ts` - 中英文翻譯
- `web/src/types.ts` - 類型定義
- `web/src/components/traders/ExchangeConfigModal.tsx` - Modal 組件
- `web/src/hooks/useTraderActions.ts` - Actions hook
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* test(lighter): 添加 V1 測試套件與修復 SafeFloat64 缺失
- 新增 trader/helpers.go: 添加 SafeFloat64/SafeString/SafeInt 輔助函數
- 新增 trader/lighter_trader_test.go: LIGHTER V1 測試套件
  -  測試通過 (7/10):
    - NewTrader 驗證 (無效私鑰, 有效私鑰格式)
    - FormatQuantity
    - GetExchangeType
    - InvalidQuantity 驗證
    - InvalidLeverage 驗證
    - HelperFunctions (SafeFloat64)
  - ⚠️ 待改進 (3/10):
    - GetBalance (需要調整 mock 響應格式)
    - GetPositions (需要調整 mock 響應格式)
    - GetMarketPrice (需要調整 mock 響應格式)
- 修復 Bug: lighter_account.go 和 lighter_trader_v2_account.go 中未定義的 SafeFloat64
- 測試框架: httptest.Server mock LIGHTER API
- 安全: 使用固定測試私鑰 (不含真實資金)
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:
0xYYBB | ZYY | Bobo
2025-11-20 19:29:01 +08:00
committed by GitHub
parent e1b905a77d
commit e7e972a442
23 changed files with 3239 additions and 22 deletions

View File

@@ -28,7 +28,7 @@ type DatabaseInterface interface {
GetAIModels(userID string) ([]*AIModelConfig, error)
UpdateAIModel(userID, id string, enabled bool, apiKey, customAPIURL, customModelName string) error
GetExchanges(userID string) ([]*ExchangeConfig, error)
UpdateExchange(userID, id string, enabled bool, apiKey, secretKey string, testnet bool, hyperliquidWalletAddr, asterUser, asterSigner, asterPrivateKey string) error
UpdateExchange(userID, id string, enabled bool, apiKey, secretKey string, testnet bool, hyperliquidWalletAddr, asterUser, asterSigner, asterPrivateKey, lighterWalletAddr, lighterPrivateKey string) error
CreateAIModel(userID, id, name, provider string, enabled bool, apiKey, customAPIURL string) error
CreateExchange(userID, id, name, typ string, enabled bool, apiKey, secretKey string, testnet bool, hyperliquidWalletAddr, asterUser, asterSigner, asterPrivateKey string) error
CreateTrader(trader *TraderRecord) error
@@ -128,6 +128,10 @@ func (d *Database) createTables() error {
aster_user TEXT DEFAULT '',
aster_signer TEXT DEFAULT '',
aster_private_key TEXT DEFAULT '',
-- LIGHTER 特定字段
lighter_wallet_addr TEXT DEFAULT '',
lighter_private_key TEXT DEFAULT '',
lighter_api_key_private_key TEXT DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
@@ -244,6 +248,9 @@ func (d *Database) createTables() error {
`ALTER TABLE exchanges ADD COLUMN aster_user TEXT DEFAULT ''`,
`ALTER TABLE exchanges ADD COLUMN aster_signer TEXT DEFAULT ''`,
`ALTER TABLE exchanges ADD COLUMN aster_private_key TEXT DEFAULT ''`,
`ALTER TABLE exchanges ADD COLUMN lighter_wallet_addr TEXT DEFAULT ''`,
`ALTER TABLE exchanges ADD COLUMN lighter_private_key TEXT DEFAULT ''`,
`ALTER TABLE exchanges ADD COLUMN lighter_api_key_private_key TEXT DEFAULT ''`,
`ALTER TABLE traders ADD COLUMN custom_prompt TEXT DEFAULT ''`,
`ALTER TABLE traders ADD COLUMN override_base_prompt BOOLEAN DEFAULT 0`,
`ALTER TABLE traders ADD COLUMN is_cross_margin BOOLEAN DEFAULT 1`, // 默认为全仓模式
@@ -300,6 +307,7 @@ func (d *Database) initDefaultData() error {
{"binance", "Binance Futures", "binance"},
{"hyperliquid", "Hyperliquid", "hyperliquid"},
{"aster", "Aster DEX", "aster"},
{"lighter", "LIGHTER DEX", "lighter"},
}
for _, exchange := range exchanges {
@@ -374,6 +382,9 @@ func (d *Database) migrateExchangesTable() error {
aster_user TEXT DEFAULT '',
aster_signer TEXT DEFAULT '',
aster_private_key TEXT DEFAULT '',
lighter_wallet_addr TEXT DEFAULT '',
lighter_private_key TEXT DEFAULT '',
lighter_api_key_private_key TEXT DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id, user_id),
@@ -461,11 +472,15 @@ type ExchangeConfig struct {
// Reference: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets
HyperliquidWalletAddr string `json:"hyperliquidWalletAddr"` // Main Wallet Address (holds funds, never expose private key)
// Aster 特定字段
AsterUser string `json:"asterUser"`
AsterSigner string `json:"asterSigner"`
AsterPrivateKey string `json:"asterPrivateKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
AsterUser string `json:"asterUser"`
AsterSigner string `json:"asterSigner"`
AsterPrivateKey string `json:"asterPrivateKey"`
// LIGHTER 特定字段
LighterWalletAddr string `json:"lighterWalletAddr"` // Ethereum 钱包地址 (L1)
LighterPrivateKey string `json:"lighterPrivateKey"` // L1私钥用于识别账户
LighterAPIKeyPrivateKey string `json:"lighterAPIKeyPrivateKey"` // API Key私钥40字节用于签名交易
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// TraderRecord 交易员配置(数据库实体)
@@ -734,12 +749,14 @@ func (d *Database) UpdateAIModel(userID, id string, enabled bool, apiKey, custom
// GetExchanges 获取用户的交易所配置
func (d *Database) GetExchanges(userID string) ([]*ExchangeConfig, error) {
rows, err := d.db.Query(`
SELECT id, user_id, name, type, enabled, api_key, secret_key, testnet,
SELECT id, user_id, name, type, enabled, api_key, secret_key, testnet,
COALESCE(hyperliquid_wallet_addr, '') as hyperliquid_wallet_addr,
COALESCE(aster_user, '') as aster_user,
COALESCE(aster_signer, '') as aster_signer,
COALESCE(aster_private_key, '') as aster_private_key,
created_at, updated_at
COALESCE(lighter_wallet_addr, '') as lighter_wallet_addr,
COALESCE(lighter_private_key, '') as lighter_private_key,
created_at, updated_at
FROM exchanges WHERE user_id = ? ORDER BY id
`, userID)
if err != nil {
@@ -756,6 +773,7 @@ func (d *Database) GetExchanges(userID string) ([]*ExchangeConfig, error) {
&exchange.Enabled, &exchange.APIKey, &exchange.SecretKey, &exchange.Testnet,
&exchange.HyperliquidWalletAddr, &exchange.AsterUser,
&exchange.AsterSigner, &exchange.AsterPrivateKey,
&exchange.LighterWalletAddr, &exchange.LighterPrivateKey,
&exchange.CreatedAt, &exchange.UpdatedAt,
)
if err != nil {
@@ -766,6 +784,7 @@ func (d *Database) GetExchanges(userID string) ([]*ExchangeConfig, error) {
exchange.APIKey = d.decryptSensitiveData(exchange.APIKey)
exchange.SecretKey = d.decryptSensitiveData(exchange.SecretKey)
exchange.AsterPrivateKey = d.decryptSensitiveData(exchange.AsterPrivateKey)
exchange.LighterPrivateKey = d.decryptSensitiveData(exchange.LighterPrivateKey)
exchanges = append(exchanges, &exchange)
}
@@ -774,8 +793,8 @@ func (d *Database) GetExchanges(userID string) ([]*ExchangeConfig, error) {
}
// UpdateExchange 更新交易所配置,如果不存在则创建用户特定配置
// 🔒 安全特性空值不会覆盖现有的敏感字段api_key, secret_key, aster_private_key
func (d *Database) UpdateExchange(userID, id string, enabled bool, apiKey, secretKey string, testnet bool, hyperliquidWalletAddr, asterUser, asterSigner, asterPrivateKey string) error {
// 🔒 安全特性空值不会覆盖现有的敏感字段api_key, secret_key, aster_private_key, lighter_private_key
func (d *Database) UpdateExchange(userID, id string, enabled bool, apiKey, secretKey string, testnet bool, hyperliquidWalletAddr, asterUser, asterSigner, asterPrivateKey, lighterWalletAddr, lighterPrivateKey string) error {
log.Printf("🔧 UpdateExchange: userID=%s, id=%s, enabled=%v", userID, id, enabled)
// 构建动态 UPDATE SET 子句
@@ -786,9 +805,10 @@ func (d *Database) UpdateExchange(userID, id string, enabled bool, apiKey, secre
"hyperliquid_wallet_addr = ?",
"aster_user = ?",
"aster_signer = ?",
"lighter_wallet_addr = ?",
"updated_at = datetime('now')",
}
args := []interface{}{enabled, testnet, hyperliquidWalletAddr, asterUser, asterSigner}
args := []interface{}{enabled, testnet, hyperliquidWalletAddr, asterUser, asterSigner, lighterWalletAddr}
// 🔒 敏感字段:只在非空时更新(保护现有数据)
if apiKey != "" {
@@ -809,6 +829,12 @@ func (d *Database) UpdateExchange(userID, id string, enabled bool, apiKey, secre
args = append(args, encryptedAsterPrivateKey)
}
if lighterPrivateKey != "" {
encryptedLighterPrivateKey := d.encryptSensitiveData(lighterPrivateKey)
setClauses = append(setClauses, "lighter_private_key = ?")
args = append(args, encryptedLighterPrivateKey)
}
// WHERE 条件
args = append(args, id, userID)
@@ -849,6 +875,9 @@ func (d *Database) UpdateExchange(userID, id string, enabled bool, apiKey, secre
} else if id == "aster" {
name = "Aster DEX"
typ = "dex"
} else if id == "lighter" {
name = "LIGHTER DEX"
typ = "dex"
} else {
name = id + " Exchange"
typ = "cex"
@@ -856,12 +885,19 @@ func (d *Database) UpdateExchange(userID, id string, enabled bool, apiKey, secre
log.Printf("🆕 UpdateExchange: 创建新记录 ID=%s, name=%s, type=%s", id, name, typ)
// 加密敏感字段
encryptedAPIKey := d.encryptSensitiveData(apiKey)
encryptedSecretKey := d.encryptSensitiveData(secretKey)
encryptedAsterPrivateKey := d.encryptSensitiveData(asterPrivateKey)
encryptedLighterPrivateKey := d.encryptSensitiveData(lighterPrivateKey)
// 创建用户特定的配置使用原始的交易所ID
_, err = d.db.Exec(`
INSERT INTO exchanges (id, user_id, name, type, enabled, api_key, secret_key, testnet,
hyperliquid_wallet_addr, aster_user, aster_signer, aster_private_key, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
`, id, userID, name, typ, enabled, apiKey, secretKey, testnet, hyperliquidWalletAddr, asterUser, asterSigner, asterPrivateKey)
hyperliquid_wallet_addr, aster_user, aster_signer, aster_private_key,
lighter_wallet_addr, lighter_private_key, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
`, id, userID, name, typ, enabled, encryptedAPIKey, encryptedSecretKey, testnet, hyperliquidWalletAddr, asterUser, asterSigner, encryptedAsterPrivateKey, lighterWalletAddr, encryptedLighterPrivateKey)
if err != nil {
log.Printf("❌ UpdateExchange: 创建记录失败: %v", err)
@@ -892,8 +928,8 @@ func (d *Database) CreateExchange(userID, id, name, typ string, enabled bool, ap
encryptedAsterPrivateKey := d.encryptSensitiveData(asterPrivateKey)
_, err := d.db.Exec(`
INSERT OR IGNORE INTO exchanges (id, user_id, name, type, enabled, api_key, secret_key, testnet, hyperliquid_wallet_addr, aster_user, aster_signer, aster_private_key)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
INSERT OR IGNORE INTO exchanges (id, user_id, name, type, enabled, api_key, secret_key, testnet, hyperliquid_wallet_addr, aster_user, aster_signer, aster_private_key, lighter_wallet_addr, lighter_private_key)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '', '')
`, id, userID, name, typ, enabled, encryptedAPIKey, encryptedSecretKey, testnet, hyperliquidWalletAddr, asterUser, asterSigner, encryptedAsterPrivateKey)
return err
}
@@ -1014,6 +1050,8 @@ func (d *Database) GetTraderConfig(userID, traderID string) (*TraderRecord, *AIM
COALESCE(e.aster_user, '') as aster_user,
COALESCE(e.aster_signer, '') as aster_signer,
COALESCE(e.aster_private_key, '') as aster_private_key,
COALESCE(e.lighter_wallet_addr, '') as lighter_wallet_addr,
COALESCE(e.lighter_private_key, '') as lighter_private_key,
e.created_at, e.updated_at
FROM traders t
JOIN ai_models a ON t.ai_model_id = a.id AND t.user_id = a.user_id
@@ -1033,6 +1071,7 @@ func (d *Database) GetTraderConfig(userID, traderID string) (*TraderRecord, *AIM
&exchange.ID, &exchange.UserID, &exchange.Name, &exchange.Type, &exchange.Enabled,
&exchange.APIKey, &exchange.SecretKey, &exchange.Testnet,
&exchange.HyperliquidWalletAddr, &exchange.AsterUser, &exchange.AsterSigner, &exchange.AsterPrivateKey,
&exchange.LighterWalletAddr, &exchange.LighterPrivateKey,
&exchange.CreatedAt, &exchange.UpdatedAt,
)
@@ -1045,6 +1084,7 @@ func (d *Database) GetTraderConfig(userID, traderID string) (*TraderRecord, *AIM
exchange.APIKey = d.decryptSensitiveData(exchange.APIKey)
exchange.SecretKey = d.decryptSensitiveData(exchange.SecretKey)
exchange.AsterPrivateKey = d.decryptSensitiveData(exchange.AsterPrivateKey)
exchange.LighterPrivateKey = d.decryptSensitiveData(exchange.LighterPrivateKey)
return &trader, &aiModel, &exchange, nil
}