router.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { RouterQuote, ExecutionPlan } from './types'
  2. import { walletManager } from '../../infrastructure/wallet/walletManager'
  3. import { AsterAdapter, AsterConfig } from '../../exchanges/aster/asterAdapter'
  4. export class TradeRouter {
  5. private aster?: AsterAdapter
  6. constructor() {
  7. const asterRpc = process.env.ASTER_RPC_URL
  8. const asterChainId = process.env.ASTER_CHAIN_ID ? Number(process.env.ASTER_CHAIN_ID) : undefined
  9. const asterRouter = process.env.ASTER_ROUTER_ADDRESS
  10. if (asterRpc && asterChainId && asterRouter) {
  11. const cfg: AsterConfig = { rpcUrl: asterRpc, chainId: asterChainId, routerAddress: asterRouter }
  12. this.aster = new AsterAdapter(cfg, walletManager.wallet || undefined)
  13. }
  14. }
  15. async quoteSpot(symbol: string, quantity: number): Promise<RouterQuote> {
  16. const price = 0
  17. return {
  18. method: 'spot',
  19. expectedIn: Math.abs(quantity),
  20. expectedOut: Math.abs(quantity) * price,
  21. price,
  22. slippage: 0.0,
  23. gasEstimateUSD: 0,
  24. route: 'spot:placeholder',
  25. }
  26. }
  27. async quotePerp(symbol: string, quantity: number): Promise<RouterQuote> {
  28. if (!this.aster) throw new Error('Aster 适配器未配置')
  29. const side = quantity > 0 ? 'long' : 'short'
  30. const q = await this.aster.quote({ symbol, side, quantity: Math.abs(quantity), slippage: 0.005 })
  31. return {
  32. method: 'perp',
  33. expectedIn: Math.abs(quantity),
  34. expectedOut: Math.abs(quantity) * q.expectedPrice,
  35. price: q.expectedPrice,
  36. slippage: 0.0,
  37. gasEstimateUSD: 0,
  38. route: 'aster:router',
  39. }
  40. }
  41. async execute(plan: ExecutionPlan) {
  42. if (plan.method === 'spot') {
  43. const addr = await walletManager.getAddress()
  44. return { success: true, txHash: `0xspot_${plan.symbol}_${plan.quantity}_${addr}` }
  45. } else {
  46. if (!this.aster) throw new Error('Aster 适配器未配置')
  47. const side = plan.side === 'buy' ? 'long' : 'short'
  48. const res = await this.aster.openPerp({
  49. symbol: plan.symbol,
  50. side,
  51. quantity: plan.quantity,
  52. slippage: 0.005,
  53. deadlineSec: Math.floor(Date.now() / 1000) + 300,
  54. })
  55. return res
  56. }
  57. }
  58. }
  59. export const tradeRouter = new TradeRouter()