@okx-dex/okx-dex-sdk
Version:
OKX DEX SDK
114 lines (113 loc) • 5.19 kB
JavaScript
;
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;