account-generation.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. #!/usr/bin/env tsx
  2. /**
  3. * Pacifica 账户生成示例
  4. * 演示如何生成、配置和管理多个Pacifica交易账户
  5. */
  6. import { ethers } from 'ethers';
  7. import { promises as fs } from 'fs';
  8. import path from 'path';
  9. import crypto from 'crypto';
  10. // 账户配置接口
  11. interface AccountConfig {
  12. name: string;
  13. privateKey: string;
  14. initialUSDC: number;
  15. riskLimits: {
  16. maxPositionSize: number;
  17. maxDailyLoss: number;
  18. maxLeverage: number;
  19. stopLossThreshold: number;
  20. maxSlippage: number;
  21. minMarginRatio: number;
  22. };
  23. }
  24. // 加密工具类
  25. class EncryptionUtils {
  26. /**
  27. * 生成加密密钥
  28. */
  29. static generateKey(): string {
  30. return crypto.randomBytes(32).toString('hex');
  31. }
  32. /**
  33. * 简单的私钥加密(生产环境应使用更安全的方法)
  34. */
  35. static encryptPrivateKey(privateKey: string, password: string): string {
  36. const key = crypto.scryptSync(password, 'salt', 32);
  37. const iv = crypto.randomBytes(16);
  38. const cipher = crypto.createCipher('aes-256-cbc', key);
  39. let encrypted = cipher.update(privateKey, 'utf8', 'hex');
  40. encrypted += cipher.final('hex');
  41. return `${iv.toString('hex')}:${encrypted}`;
  42. }
  43. /**
  44. * 简单的私钥解密(生产环境应使用更安全的方法)
  45. */
  46. static decryptPrivateKey(encryptedKey: string, password: string): string {
  47. const [ivHex, encrypted] = encryptedKey.split(':');
  48. const key = crypto.scryptSync(password, 'salt', 32);
  49. const iv = Buffer.from(ivHex, 'hex');
  50. const decipher = crypto.createDecipher('aes-256-cbc', key);
  51. let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  52. decrypted += decipher.final('utf8');
  53. return decrypted;
  54. }
  55. }
  56. // 账户生成器类
  57. class AccountGenerator {
  58. private readonly configDir: string;
  59. private readonly accountsFile: string;
  60. constructor(configDir: string = './config') {
  61. this.configDir = configDir;
  62. this.accountsFile = path.join(configDir, 'accounts.json');
  63. }
  64. /**
  65. * 生成新的以太坊钱包
  66. */
  67. generateWallet(): { address: string; privateKey: string } {
  68. const wallet = ethers.Wallet.createRandom();
  69. return {
  70. address: wallet.address,
  71. privateKey: wallet.privateKey
  72. };
  73. }
  74. /**
  75. * 生成账户配置
  76. */
  77. generateAccountConfig(
  78. name: string,
  79. initialUSDC: number = 10000,
  80. riskProfile: 'conservative' | 'moderate' | 'aggressive' = 'moderate'
  81. ): AccountConfig {
  82. const wallet = this.generateWallet();
  83. // 根据风险偏好设置风险限制
  84. const riskLimits = this.getRiskLimits(riskProfile);
  85. return {
  86. name,
  87. privateKey: wallet.privateKey, // 在实际使用中应该加密
  88. initialUSDC,
  89. riskLimits
  90. };
  91. }
  92. /**
  93. * 获取风险限制配置
  94. */
  95. private getRiskLimits(riskProfile: 'conservative' | 'moderate' | 'aggressive') {
  96. const profiles = {
  97. conservative: {
  98. maxPositionSize: 0.05, // 5%
  99. maxDailyLoss: 0.02, // 2%
  100. maxLeverage: 5, // 5x
  101. stopLossThreshold: 0.02, // 2%
  102. maxSlippage: 0.0005, // 0.05%
  103. minMarginRatio: 0.2 // 20%
  104. },
  105. moderate: {
  106. maxPositionSize: 0.1, // 10%
  107. maxDailyLoss: 0.05, // 5%
  108. maxLeverage: 10, // 10x
  109. stopLossThreshold: 0.05, // 5%
  110. maxSlippage: 0.001, // 0.1%
  111. minMarginRatio: 0.15 // 15%
  112. },
  113. aggressive: {
  114. maxPositionSize: 0.2, // 20%
  115. maxDailyLoss: 0.1, // 10%
  116. maxLeverage: 20, // 20x
  117. stopLossThreshold: 0.1, // 10%
  118. maxSlippage: 0.002, // 0.2%
  119. minMarginRatio: 0.1 // 10%
  120. }
  121. };
  122. return profiles[riskProfile];
  123. }
  124. /**
  125. * 批量生成账户
  126. */
  127. generateMultipleAccounts(
  128. count: number,
  129. baseName: string = 'HedgeAccount',
  130. initialUSDC: number = 10000,
  131. riskProfile: 'conservative' | 'moderate' | 'aggressive' = 'moderate'
  132. ): AccountConfig[] {
  133. const accounts: AccountConfig[] = [];
  134. for (let i = 1; i <= count; i++) {
  135. const accountName = `${baseName}${i}`;
  136. const account = this.generateAccountConfig(accountName, initialUSDC, riskProfile);
  137. accounts.push(account);
  138. }
  139. return accounts;
  140. }
  141. /**
  142. * 保存账户配置到文件
  143. */
  144. async saveAccountsToFile(accounts: AccountConfig[], encrypt: boolean = false): Promise<void> {
  145. // 确保配置目录存在
  146. await fs.mkdir(this.configDir, { recursive: true });
  147. let accountsToSave = accounts;
  148. if (encrypt) {
  149. // 在实际应用中,密码应该从环境变量或安全输入获取
  150. const password = process.env.ENCRYPTION_PASSWORD || 'default-password-change-in-production';
  151. accountsToSave = accounts.map(account => ({
  152. ...account,
  153. privateKey: EncryptionUtils.encryptPrivateKey(account.privateKey, password)
  154. }));
  155. }
  156. await fs.writeFile(
  157. this.accountsFile,
  158. JSON.stringify(accountsToSave, null, 2),
  159. 'utf-8'
  160. );
  161. console.log(`✅ 已保存 ${accounts.length} 个账户配置到 ${this.accountsFile}`);
  162. }
  163. /**
  164. * 从文件加载账户配置
  165. */
  166. async loadAccountsFromFile(decrypt: boolean = false): Promise<AccountConfig[]> {
  167. try {
  168. const data = await fs.readFile(this.accountsFile, 'utf-8');
  169. const accounts: AccountConfig[] = JSON.parse(data);
  170. if (decrypt) {
  171. const password = process.env.ENCRYPTION_PASSWORD || 'default-password-change-in-production';
  172. return accounts.map(account => ({
  173. ...account,
  174. privateKey: EncryptionUtils.decryptPrivateKey(account.privateKey, password)
  175. }));
  176. }
  177. return accounts;
  178. } catch (error) {
  179. console.error('❌ 加载账户配置失败:', error);
  180. return [];
  181. }
  182. }
  183. /**
  184. * 验证账户配置
  185. */
  186. validateAccountConfig(account: AccountConfig): { isValid: boolean; errors: string[] } {
  187. const errors: string[] = [];
  188. // 验证账户名称
  189. if (!account.name || account.name.length < 3 || account.name.length > 30) {
  190. errors.push('账户名称必须在3-30个字符之间');
  191. }
  192. // 验证私钥格式
  193. if (!account.privateKey || !account.privateKey.startsWith('0x') || account.privateKey.length !== 66) {
  194. errors.push('私钥格式无效');
  195. }
  196. // 验证初始USDC余额
  197. if (account.initialUSDC <= 0) {
  198. errors.push('初始USDC余额必须大于0');
  199. }
  200. // 验证风险限制
  201. const { riskLimits } = account;
  202. if (riskLimits.maxPositionSize <= 0 || riskLimits.maxPositionSize > 1) {
  203. errors.push('最大持仓大小必须在0-1之间');
  204. }
  205. if (riskLimits.maxDailyLoss <= 0 || riskLimits.maxDailyLoss > 1) {
  206. errors.push('最大日损失必须在0-1之间');
  207. }
  208. if (riskLimits.maxLeverage < 1) {
  209. errors.push('最大杠杆必须大于等于1');
  210. }
  211. if (riskLimits.stopLossThreshold <= 0 || riskLimits.stopLossThreshold > 1) {
  212. errors.push('止损阈值必须在0-1之间');
  213. }
  214. if (riskLimits.maxSlippage < 0) {
  215. errors.push('最大滑点不能为负数');
  216. }
  217. if (riskLimits.minMarginRatio <= 0 || riskLimits.minMarginRatio > 1) {
  218. errors.push('最小保证金比率必须在0-1之间');
  219. }
  220. return {
  221. isValid: errors.length === 0,
  222. errors
  223. };
  224. }
  225. /**
  226. * 显示账户信息
  227. */
  228. displayAccountInfo(account: AccountConfig, showPrivateKey: boolean = false): void {
  229. console.log('\n📋 账户信息:');
  230. console.log(` 名称: ${account.name}`);
  231. console.log(` 地址: ${ethers.computeAddress(account.privateKey)}`);
  232. console.log(` 初始USDC: ${account.initialUSDC.toLocaleString()}`);
  233. if (showPrivateKey) {
  234. console.log(` 私钥: ${account.privateKey}`);
  235. } else {
  236. console.log(` 私钥: ${account.privateKey.substring(0, 10)}...${account.privateKey.substring(62)}`);
  237. }
  238. console.log(' 风险限制:');
  239. console.log(` 最大持仓大小: ${(account.riskLimits.maxPositionSize * 100).toFixed(1)}%`);
  240. console.log(` 最大日损失: ${(account.riskLimits.maxDailyLoss * 100).toFixed(1)}%`);
  241. console.log(` 最大杠杆: ${account.riskLimits.maxLeverage}x`);
  242. console.log(` 止损阈值: ${(account.riskLimits.stopLossThreshold * 100).toFixed(1)}%`);
  243. console.log(` 最大滑点: ${(account.riskLimits.maxSlippage * 100).toFixed(3)}%`);
  244. console.log(` 最小保证金比率: ${(account.riskLimits.minMarginRatio * 100).toFixed(1)}%`);
  245. }
  246. }
  247. // 示例使用函数
  248. async function runAccountGenerationExample() {
  249. console.log('🚀 Pacifica 账户生成示例\n');
  250. const generator = new AccountGenerator();
  251. // 示例1: 生成单个账户
  252. console.log('📝 示例1: 生成单个账户');
  253. const singleAccount = generator.generateAccountConfig(
  254. 'TestAccount1',
  255. 10000,
  256. 'moderate'
  257. );
  258. const validation = generator.validateAccountConfig(singleAccount);
  259. if (validation.isValid) {
  260. generator.displayAccountInfo(singleAccount);
  261. } else {
  262. console.log('❌ 账户配置验证失败:', validation.errors);
  263. }
  264. // 示例2: 批量生成账户
  265. console.log('\n📝 示例2: 批量生成5个账户');
  266. const multipleAccounts = generator.generateMultipleAccounts(
  267. 5,
  268. 'HedgeAccount',
  269. 10000,
  270. 'moderate'
  271. );
  272. console.log(`✅ 生成了 ${multipleAccounts.length} 个账户`);
  273. multipleAccounts.forEach((account, index) => {
  274. console.log(` ${index + 1}. ${account.name} - ${ethers.computeAddress(account.privateKey)}`);
  275. });
  276. // 示例3: 保存和加载账户配置
  277. console.log('\n📝 示例3: 保存和加载账户配置');
  278. await generator.saveAccountsToFile(multipleAccounts, false);
  279. const loadedAccounts = await generator.loadAccountsFromFile(false);
  280. console.log(`✅ 从文件加载了 ${loadedAccounts.length} 个账户`);
  281. // 示例4: 不同风险配置的账户
  282. console.log('\n📝 示例4: 不同风险配置的账户');
  283. const conservativeAccount = generator.generateAccountConfig('ConservativeAccount', 10000, 'conservative');
  284. const aggressiveAccount = generator.generateAccountConfig('AggressiveAccount', 10000, 'aggressive');
  285. console.log('保守型账户:');
  286. generator.displayAccountInfo(conservativeAccount);
  287. console.log('\n激进型账户:');
  288. generator.displayAccountInfo(aggressiveAccount);
  289. // 示例5: 创建对冲账户组合
  290. console.log('\n📝 示例5: 创建对冲账户组合');
  291. const hedgingAccounts = [
  292. generator.generateAccountConfig('HedgeLong1', 10000, 'moderate'),
  293. generator.generateAccountConfig('HedgeShort1', 10000, 'moderate'),
  294. generator.generateAccountConfig('HedgeLong2', 10000, 'moderate'),
  295. generator.generateAccountConfig('HedgeShort2', 10000, 'moderate'),
  296. ];
  297. await generator.saveAccountsToFile(hedgingAccounts, false);
  298. console.log('✅ 对冲账户组合已保存');
  299. // 显示账户组合信息
  300. console.log('\n📊 对冲账户组合:');
  301. hedgingAccounts.forEach((account, index) => {
  302. const address = ethers.computeAddress(account.privateKey);
  303. const side = account.name.includes('Long') ? '多头' : '空头';
  304. console.log(` ${index + 1}. ${account.name} (${side}) - ${address}`);
  305. });
  306. console.log('\n🎉 账户生成示例完成!');
  307. console.log('\n💡 下一步:');
  308. console.log(' 1. 将生成的账户配置导入到Pacifica DEX');
  309. console.log(' 2. 为每个账户充值USDC');
  310. console.log(' 3. 启动对冲交易系统');
  311. console.log(' 4. 监控账户状态和风险指标');
  312. }
  313. // 命令行参数处理
  314. async function main() {
  315. const args = process.argv.slice(2);
  316. if (args.length === 0) {
  317. // 运行完整示例
  318. await runAccountGenerationExample();
  319. } else if (args[0] === 'generate') {
  320. // 生成指定数量的账户
  321. const count = parseInt(args[1]) || 5;
  322. const baseName = args[2] || 'HedgeAccount';
  323. const riskProfile = (args[3] as 'conservative' | 'moderate' | 'aggressive') || 'moderate';
  324. const generator = new AccountGenerator();
  325. const accounts = generator.generateMultipleAccounts(count, baseName, 10000, riskProfile);
  326. await generator.saveAccountsToFile(accounts, false);
  327. console.log(`✅ 已生成并保存 ${count} 个账户`);
  328. accounts.forEach((account, index) => {
  329. console.log(` ${index + 1}. ${account.name} - ${ethers.computeAddress(account.privateKey)}`);
  330. });
  331. } else if (args[0] === 'validate') {
  332. // 验证现有账户配置
  333. const generator = new AccountGenerator();
  334. const accounts = await generator.loadAccountsFromFile(false);
  335. console.log(`📋 验证 ${accounts.length} 个账户配置:`);
  336. accounts.forEach((account, index) => {
  337. const validation = generator.validateAccountConfig(account);
  338. const status = validation.isValid ? '✅' : '❌';
  339. console.log(` ${index + 1}. ${status} ${account.name}`);
  340. if (!validation.isValid) {
  341. validation.errors.forEach(error => console.log(` - ${error}`));
  342. }
  343. });
  344. } else {
  345. console.log('使用方法:');
  346. console.log(' tsx examples/account-generation.ts # 运行完整示例');
  347. console.log(' tsx examples/account-generation.ts generate [count] [name] [risk] # 生成账户');
  348. console.log(' tsx examples/account-generation.ts validate # 验证账户配置');
  349. }
  350. }
  351. // 运行主函数
  352. if (import.meta.url === `file://${process.argv[1]}`) {
  353. main().catch(console.error);
  354. }
  355. export { AccountGenerator, EncryptionUtils, AccountConfig };