import { loadConfig } from '../config.js' import type { OpenPositionEvent } from '../solana/openPositionListener.js' const cfg = loadConfig() export async function copyPosition(positionDetails: OpenPositionEvent['positionDetails']) { if (!positionDetails) return const mintA = positionDetails?.mintA || undefined const mintB = positionDetails?.mintB || undefined const mintASymbol = mintA?.symbol || undefined const mintBSymbol = mintB?.symbol || undefined const totalDeposit = positionDetails?.totalDeposit || undefined // const upperTick = positionDetails?.upperTick || undefined // const lowerTick = positionDetails?.lowerTick || undefined const positionAddress = positionDetails?.positionAddress || '' const providerAddress = positionDetails?.providerAddress || '' const nftMintAddress = positionDetails?.nftMintAddress || '' const copyConfig = cfg?.positionCopy?.config?.[`${mintASymbol}/${mintBSymbol}`] || undefined let maxUsdValue = 0.2 if (!copyConfig) { return 'no copy config' } const minimumDeposit = copyConfig?.minimumDeposit || 0 if (Number(totalDeposit) < minimumDeposit) { return } if (Number(totalDeposit) > 1000) { maxUsdValue = copyConfig?.copyMount?.[1000] || 2 } else if (Number(totalDeposit) > 500) { maxUsdValue = copyConfig?.copyMount?.[500] || 1 } else if (Number(totalDeposit) > minimumDeposit) { maxUsdValue = copyConfig?.copyMount?.[minimumDeposit] || 0.2 } console.log(`[${Date.now()}] 复制仓位: ${providerAddress.slice(0, 4)}...${providerAddress.slice(-4)} ${mintASymbol}/${mintBSymbol} ${maxUsdValue}$`) return fetch(cfg?.positionCopy?.url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Basic YWRtaW46YzU4ODk5Njc=' }, body: JSON.stringify({ nftMintAddress, positionAddress, maxUsdValue, }), }).then(res => res.json()).then((response: unknown) => { const data = response as { success?: boolean, error?: string } if (!data.success) { throw new Error(data.error ?? 'Failed to copy position') } console.log(`[${Date.now()}] 复制仓位成功`) // 发送Discord通知,使用embeds const solscanBaseUrl = 'https://solscan.io' const embed = { title: '✅ 仓位复制成功', description: `成功复制仓位:**${mintASymbol}/${mintBSymbol}**`, color: 0x00ff00, // 绿色 fields: [ { name: '💰 币对', value: `${mintASymbol}/${mintBSymbol}`, inline: true }, { name: '💵 总存款', value: `$${Number(totalDeposit).toFixed(2)}`, inline: true }, { name: '📊 复制金额', value: `$${maxUsdValue.toFixed(2)}`, inline: true }, { name: '👤 提供者地址', value: `[${providerAddress.slice(0, 4)}...${providerAddress.slice(-4)}](${solscanBaseUrl}/account/${providerAddress})`, inline: false }, { name: '📍 仓位地址', value: `[${positionAddress.slice(0, 8)}...${positionAddress.slice(-8)}](${solscanBaseUrl}/account/${positionAddress})`, inline: false }, { name: '🎨 NFT Mint', value: `[${nftMintAddress.slice(0, 8)}...${nftMintAddress.slice(-8)}](${solscanBaseUrl}/token/${nftMintAddress})`, inline: false } ], timestamp: new Date().toISOString(), footer: { text: 'ByReal Auto Trading' } } // 如果有价格信息,添加到字段中 if (mintA?.price && mintB?.price) { embed.fields.push({ name: '💹 价格信息', value: `${mintASymbol}: $${Number(mintA.price).toFixed(6)}\n${mintBSymbol}: $${Number(mintB.price).toFixed(6)}`, inline: false }) } return fetch('https://discord.com/api/webhooks/1457714616636280978/YFMGaZEj2gJwUjINpFfJIkagG1I3SLZRwz9bGpc2OlGFWBVa88r73cMIkBpX3iGpSIjV', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ embeds: [embed] }), }) }).catch(err => { // 发送失败通知 const errorEmbed = { title: '❌ 仓位复制失败', description: `复制仓位失败:**${mintASymbol}/${mintBSymbol}**`, color: 0xff0000, // 红色 fields: [ { name: '💰 币对', value: `${mintASymbol}/${mintBSymbol}`, inline: true }, { name: '💵 总存款', value: `$${Number(totalDeposit).toFixed(2)}`, inline: true }, { name: '📍 仓位地址', value: `[${positionAddress.slice(0, 8)}...${positionAddress.slice(-8)}](https://solscan.io/account/${positionAddress})`, inline: false }, { name: '⚠️ 错误信息', value: `\`\`\`${err instanceof Error ? err.message : String(err)}\`\`\``, inline: false } ], timestamp: new Date().toISOString(), footer: { text: 'ByReal Auto Trading' } } return fetch('https://discord.com/api/webhooks/1457714616636280978/YFMGaZEj2gJwUjINpFfJIkagG1I3SLZRwz9bGpc2OlGFWBVa88r73cMIkBpX3iGpSIjV', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ embeds: [errorEmbed] }), }).catch(notifyErr => { console.error(`[${Date.now()}] 发送Discord通知失败: ${notifyErr}`) }) }) }