UNPKG

@okx-dex/okx-dex-sdk

Version:
114 lines (113 loc) 5.19 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SolanaSwapExecutor = void 0; // src/api/swap/solana/solana-swap.ts const web3_js_1 = require("@solana/web3.js"); const bs58_1 = __importDefault(require("bs58")); class SolanaSwapExecutor { constructor(config, networkConfig) { this.config = config; this.networkConfig = networkConfig; } async executeSwap(swapData, params) { var _a, _b, _c, _d, _e, _f; if (!this.config.solana) { throw new Error("Solana configuration required"); } // Get quote data const quoteData = (_a = swapData.data) === null || _a === void 0 ? void 0 : _a[0]; if (!(quoteData === null || quoteData === void 0 ? void 0 : quoteData.routerResult)) { throw new Error("Invalid swap data: missing router result"); } const { routerResult } = quoteData; // Validate token information if (!((_b = routerResult.fromToken) === null || _b === void 0 ? void 0 : _b.decimal) || !((_c = routerResult.toToken) === null || _c === void 0 ? void 0 : _c.decimal)) { throw new Error(`Missing decimal information for tokens: ${(_d = routerResult.fromToken) === null || _d === void 0 ? void 0 : _d.tokenSymbol} -> ${(_e = routerResult.toToken) === null || _e === void 0 ? void 0 : _e.tokenSymbol}`); } // Get transaction data const txData = (_f = quoteData.tx) === null || _f === void 0 ? void 0 : _f.data; if (!txData) { throw new Error("Missing transaction data"); } try { const result = await this.executeSolanaTransaction(txData); return this.formatSwapResult(result.signature, routerResult); } catch (error) { console.error("Swap execution failed:", error); throw error; } } async executeSolanaTransaction(txData) { const connection = this.config.solana.wallet.connection; const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed"); // Decode and prepare transaction const decodedTransaction = bs58_1.default.decode(txData); const transaction = await this.prepareTransaction(decodedTransaction, blockhash); // Sign and send transaction using wallet const { signature } = await this.config.solana.wallet.signAndSendTransaction(transaction, { skipPreflight: false, maxRetries: this.networkConfig.maxRetries, preflightCommitment: "confirmed", }); // Confirm transaction const confirmation = await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight, }, "confirmed"); if (confirmation.value.err) { throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`); } return { signature }; } async prepareTransaction(decodedTransaction, blockhash) { let transaction; try { // Try versioned transaction first transaction = web3_js_1.VersionedTransaction.deserialize(decodedTransaction); transaction.message.recentBlockhash = blockhash; } catch (_a) { // Fall back to legacy transaction transaction = web3_js_1.Transaction.from(decodedTransaction); transaction.recentBlockhash = blockhash; transaction.feePayer = this.config.solana.wallet.publicKey; // Add compute budget for legacy transactions const computeBudgetIx = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: this.config.solana.computeUnits || 300000, }); transaction.add(computeBudgetIx); } return transaction; } formatSwapResult(signature, routerResult) { const fromDecimals = parseInt(routerResult.fromToken.decimal); const toDecimals = parseInt(routerResult.toToken.decimal); const displayFromAmount = (Number(routerResult.fromTokenAmount) / Math.pow(10, fromDecimals)).toFixed(6); const displayToAmount = (Number(routerResult.toTokenAmount) / Math.pow(10, toDecimals)).toFixed(6); return { success: true, transactionId: signature, explorerUrl: `${this.networkConfig.explorer}/${signature}`, details: { fromToken: { symbol: routerResult.fromToken.tokenSymbol, amount: displayFromAmount, decimal: routerResult.fromToken.decimal, }, toToken: { symbol: routerResult.toToken.tokenSymbol, amount: displayToAmount, decimal: routerResult.toToken.decimal, }, priceImpact: routerResult.priceImpactPercent, }, }; } } exports.SolanaSwapExecutor = SolanaSwapExecutor;