#!/usr/bin/env tsx /** * CLI 账户注入示例 * 演示如何通过命令行参数动态注入单个账户 */ import { CLIAccountInjector } from '../src/accounts/CLIAccountInjector.js' import { UnifiedAccountManager } from '../src/accounts/UnifiedAccountManager.js' import { logger } from '../src/utils/logger.js' async function cliAccountInjectionDemo() { console.log('⚡ CLI 账户注入演示') console.log('='.repeat(50)) try { // 1. 解析命令行参数 console.log('\n📋 第一步: 解析命令行参数...') const cliOptions = CLIAccountInjector.parseArgs() console.log('🔍 检测到的命令行参数:') Object.entries(cliOptions).forEach(([key, value]) => { if (value !== undefined) { console.log(` ${key}: ${value}`) } }) // 2. 检查必需参数 if (!cliOptions.exchange) { console.log('\n❌ 错误: 未指定交易所') showUsageHelp() return } // 3. 生成账户配置 console.log('\n🏗️ 第二步: 生成账户配置...') const accountConfig = CLIAccountInjector.createQuickAccount() console.log('✅ 生成的账户配置:') console.log(` 交易所: ${accountConfig.exchange}`) console.log(` 账户ID: ${accountConfig.accountId}`) console.log(` 别名: ${accountConfig.alias}`) console.log(` 优先级: ${accountConfig.priority}`) console.log(` 交易启用: ${accountConfig.tradingEnabled ? '✅' : '❌'}`) console.log(` 对冲启用: ${accountConfig.hedgingEnabled ? '✅' : '❌'}`) console.log(` 最大仓位: $${accountConfig.maxPositionUsd.toLocaleString()}`) console.log(` 最大日交易量: $${accountConfig.maxDailyVolumeUsd.toLocaleString()}`) // 4. 创建统一账户管理器 console.log('\n🚀 第三步: 创建统一账户管理器并注入账户...') const unifiedManager = new UnifiedAccountManager({ enableFailover: true, maxRetries: 3, retryDelayMs: 1000, }) // 5. 验证账户配置 console.log('\n🔍 第四步: 验证账户配置...') const validationResult = validateAccountConfig(accountConfig) if (validationResult.isValid) { console.log('✅ 账户配置验证通过') if (validationResult.warnings.length > 0) { console.log('⚠️ 警告:') validationResult.warnings.forEach(warning => { console.log(` - ${warning}`) }) } } else { console.log('❌ 账户配置验证失败:') validationResult.errors.forEach(error => { console.log(` - ${error}`) }) console.log('\n💡 请检查环境变量设置或命令行参数') return } // 6. 模拟注册账户 (实际环境中会连接真实交易所) console.log('\n📝 第五步: 注册账户...') if (cliOptions.dryRun) { console.log('🧪 干运行模式: 跳过实际注册') } else { console.log('⚠️ 注意: 这是演示模式,不会连接真实交易所') } try { // 在真实环境中这里会调用: // await unifiedManager.registerAccount(accountConfig) console.log(`✅ 账户 "${accountConfig.alias}" 注册成功`) console.log(` 状态: ${cliOptions.dryRun ? '模拟' : '实际'}`) console.log(` 交易所: ${accountConfig.exchange}`) console.log(` 账户ID: ${accountConfig.accountId}`) } catch (error) { console.error(`❌ 账户注册失败: ${error}`) return } // 7. 显示后续操作建议 console.log('\n🎯 第六步: 后续操作建议...') console.log('✅ CLI 账户注入完成!') console.log('\n📚 接下来你可以:') console.log('1. 查看账户余额: await unifiedManager.balances()') console.log('2. 查看账户仓位: await unifiedManager.positions()') console.log('3. 下单交易: await unifiedManager.placeOrder(...)') console.log('4. 启用 WebSocket: await unifiedManager.startWebSocket()') // 8. 演示模式下的额外信息 if (process.argv.includes('--verbose')) { console.log('\n🔧 详细信息:') console.log('账户配置对象:') console.log(JSON.stringify(accountConfig, null, 2)) } } catch (error) { console.error('❌ CLI 账户注入演示失败:', error) logger.error('CLI account injection demo failed', { error: error.message }) } } /** * 验证账户配置 */ function validateAccountConfig(config: any): { isValid: boolean errors: string[] warnings: string[] } { const result = { isValid: true, errors: [] as string[], warnings: [] as string[], } // 检查基本字段 if (!config.exchange) { result.errors.push('交易所未指定') } if (!config.accountId) { result.errors.push('账户ID未指定') } // 检查交易所特定配置 switch (config.exchange) { case 'pacifica': if (!process.env.PACIFICA_PRIVATE_KEY && !process.env.PACIFICA_PRIVATE_KEY_1) { result.errors.push('Pacifica 私钥环境变量未设置 (PACIFICA_PRIVATE_KEY 或 PACIFICA_PRIVATE_KEY_1)') } if (!process.env.PACIFICA_BASE_URL) { result.warnings.push('PACIFICA_BASE_URL 未设置,将使用默认值') } break case 'aster': if (!process.env.ASTER_ORDER_USER && !process.env.ASTER_ORDER_USER_1) { result.errors.push('Aster 用户地址环境变量未设置 (ASTER_ORDER_USER 或 ASTER_ORDER_USER_1)') } if (!process.env.PRIVATE_KEY && !process.env.ASTER_PRIVATE_KEY_1) { result.errors.push('Aster 私钥环境变量未设置 (PRIVATE_KEY 或 ASTER_PRIVATE_KEY_1)') } break case 'binance': if (!process.env.BINANCE_API_KEY && !process.env.BINANCE_API_KEY_1) { result.errors.push('Binance API密钥环境变量未设置 (BINANCE_API_KEY 或 BINANCE_API_KEY_1)') } if (!process.env.BINANCE_SECRET_KEY && !process.env.BINANCE_SECRET_KEY_1) { result.errors.push('Binance 密钥环境变量未设置 (BINANCE_SECRET_KEY 或 BINANCE_SECRET_KEY_1)') } break default: result.errors.push(`不支持的交易所: ${config.exchange}`) } // 检查数值范围 if (config.maxPositionUsd <= 0) { result.warnings.push('最大仓位金额应大于0') } if (config.maxDailyVolumeUsd <= config.maxPositionUsd) { result.warnings.push('最大日交易量应大于最大仓位金额') } result.isValid = result.errors.length === 0 return result } /** * 显示使用帮助信息 */ function showUsageHelp() { console.log('\n📚 CLI 账户注入使用说明:') console.log('\n🔹 基本用法:') console.log(' tsx cli_account_injection.ts --exchange [options]') console.log('\n🔹 必需参数:') console.log(' --exchange, -e 交易所类型 (pacifica|aster|binance)') console.log('\n🔹 可选参数:') console.log(' --account, -a 账户ID (默认: cli-account)') console.log(' --alias 账户别名 (默认: CLI-)') console.log(' --priority, -p 优先级 (默认: 999)') console.log(' --trading 是否启用交易 (true|false, 默认: true)') console.log(' --hedging 是否启用对冲 (true|false, 默认: true)') console.log(' --max-position 最大仓位USD (默认: 1000)') console.log(' --config, -c 配置文件路径 (可选)') console.log(' --dry-run 干运行模式,不实际注册') console.log(' --verbose 显示详细输出') console.log('\n🔹 示例:') console.log(' # 基本 Pacifica 账户注入') console.log(' tsx cli_account_injection.ts --exchange pacifica') console.log('\n # 完整参数 Aster 账户注入') console.log(' tsx cli_account_injection.ts \\') console.log(' --exchange aster \\') console.log(' --account my-aster-account \\') console.log(' --alias "我的Aster账户" \\') console.log(' --priority 1 \\') console.log(' --max-position 5000 \\') console.log(' --verbose') console.log('\n # 干运行模式 Binance 账户') console.log(' tsx cli_account_injection.ts \\') console.log(' --exchange binance \\') console.log(' --trading false \\') console.log(' --dry-run') console.log('\n🔹 环境变量配置:') console.log(' 请确保设置相应交易所的环境变量') console.log(' 参考 env.example 和 env.accounts.example 文件') } // 运行演示 if (import.meta.url === `file://${process.argv[1]}`) { // 检查是否需要显示帮助 if (process.argv.includes('--help') || process.argv.includes('-h')) { showUsageHelp() } else { cliAccountInjectionDemo() } }