UNPKG

@nekoproject/swap

Version:

Cross-chain Swap Token

134 lines (125 loc) 4.15 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import axios from 'axios'; import { ethers } from 'ethers'; import { Transaction } from '@solana/web3.js'; import { SPLWallet } from '@nekoproject/wallets'; import { SPLNetwork } from '@nekoproject/networks'; import { Swap } from '../Swap'; import { CreateOrder, SPLSwapOrderRequest, SetApiParams } from '../types'; export class SPLSwap extends Swap { private _createOrderApi: string; private _buildTransApi: string; constructor(network: SPLNetwork, endpoint: string) { let fmt_endpoint: string; if (endpoint.endsWith('/')) { fmt_endpoint = endpoint.slice(0, endpoint.length - 1); } else { fmt_endpoint = endpoint; } super(network, fmt_endpoint); this._createOrderApi = this._endpoint + '/v2/swaps/create-order'; this._buildTransApi = this._endpoint + '/v2/swaps/build-transaction'; } set endpoint(endpoint: string) { this._endpoint = endpoint; } get endpoint() { return this._endpoint; } set api(params: SetApiParams) { this._createOrderApi = this._endpoint + params.createOrder; this._buildTransApi = this._endpoint + params.buildTransaction; } /** * * @param swapRequest * @returns */ async createSwapOrder( swapRequest: CreateOrder ): Promise<SPLSwapOrderRequest> { const destDecimals = swapRequest.destToken.tokenInfo.decimals ? swapRequest.destToken.tokenInfo.decimals : (await swapRequest.destToken.getInfo()).decimals; const srcDecimals = swapRequest.srcToken.tokenInfo.decimals ? swapRequest.srcToken.tokenInfo.decimals : (await swapRequest.srcToken.getInfo()).decimals; const unitAmount = ethers.utils.parseUnits( swapRequest.srcAmount, srcDecimals ); const data = { wallet_address: swapRequest.wallet_address, slippage: swapRequest.slippage, network: 'SOL', destDecimals: destDecimals, srcDecimals: srcDecimals, srcAmount: unitAmount.toString(), destToken: swapRequest.destToken.tokenInfo.mintAddress, srcToken: swapRequest.srcToken.tokenInfo.mintAddress, }; const orderResquest = await axios.post(this._createOrderApi, data); if (orderResquest.data.swap_order) { return orderResquest.data.swap_order; } else { throw new Error( `Error create order: ${orderResquest.data?.error?.message}` ); } } /** * * @param swapRequest * @param wallet * @returns */ async swapToken( swapRequest: SPLSwapOrderRequest, wallet: SPLWallet ): Promise<string> { const buildTransactionOrder = { slippage: swapRequest.slippage, wallet_address: wallet.address, network: 'SOL', swap_order_id: swapRequest.id.toString(), }; const buildResponse = await axios.post( this._buildTransApi, buildTransactionOrder ); const transactions = buildResponse.data.transaction; // setup transaction if must have if (transactions.setupTransaction) { const instructions = Transaction.from( Buffer.from(transactions.setupTransaction, 'base64') ).instructions; const txSetUp = new Transaction().add(...instructions); await this.network.provider.sendTransaction(txSetUp, [wallet.signer], { skipPreflight: false, }); } // execute swap const swapInstructions = Transaction.from( Buffer.from(transactions.swapTransaction, 'base64') ).instructions; const transactionSwap = new Transaction().add(...swapInstructions); const signature = await this.network.provider.sendTransaction( transactionSwap, [wallet.signer], { skipPreflight: false, } ); // clear cache if possible if (transactions.cleanupTransaction) { const cleanInstruction = Transaction.from( Buffer.from(transactions.swapTransaction, 'base64') ).instructions; const txClean = new Transaction().add(...cleanInstruction); await this.network.provider.sendTransaction(txClean, [wallet.signer], { skipPreflight: false, }); } return signature; } }