UNPKG

@okx-dex/okx-dex-sdk

Version:
138 lines (137 loc) 5.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SuiSwapExecutor = void 0; // src/api/swap/sui/sui-swap.ts const coin_sui_1 = require("@okxweb3/coin-sui"); const client_1 = require("@mysten/sui/client"); const transactions_1 = require("@mysten/sui/transactions"); class SuiSwapExecutor { constructor(config, networkConfig) { this.config = config; this.networkConfig = networkConfig; this.DEFAULT_GAS_BUDGET = 50000000; if (!this.config.sui) { throw new Error("Sui configuration required"); } this.client = new client_1.SuiClient({ url: (0, client_1.getFullnodeUrl)('mainnet') }); this.wallet = new coin_sui_1.SuiWallet(); } async executeSwap(swapData, params) { var _a, _b; 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; const txData = (_b = quoteData.tx) === null || _b === void 0 ? void 0 : _b.data; if (!txData) { throw new Error("Missing transaction data"); } try { const result = await this.executeSuiTransaction(txData); return this.formatSwapResult(result.txId, routerResult); } catch (error) { console.error("Swap execution failed:", error); throw error; } } async executeSuiTransaction(txData) { var _a, _b, _c; if (!((_a = this.config.sui) === null || _a === void 0 ? void 0 : _a.privateKey)) { throw new Error("Sui private key not found"); } let retryCount = 0; while (retryCount < (this.networkConfig.maxRetries || 3)) { try { // Create transaction block const txBlock = transactions_1.Transaction.from(txData); txBlock.setSender(this.config.sui.walletAddress); // Set gas parameters const referenceGasPrice = await this.client.getReferenceGasPrice(); txBlock.setGasPrice(BigInt(referenceGasPrice)); txBlock.setGasBudget(BigInt(this.DEFAULT_GAS_BUDGET)); // Build the transaction const builtTx = await txBlock.build({ client: this.client }); const txBytes = Buffer.from(builtTx).toString('base64'); // Sign transaction const signedTx = await this.wallet.signTransaction({ privateKey: this.config.sui.privateKey, data: { type: 'raw', data: txBytes } }); if (!(signedTx === null || signedTx === void 0 ? void 0 : signedTx.signature)) { throw new Error("Failed to sign transaction"); } // Execute transaction const result = await this.client.executeTransactionBlock({ transactionBlock: builtTx, signature: [signedTx.signature], options: { showEffects: true, showEvents: true, } }); if (!result.digest) { throw new Error('Transaction failed: No digest received'); } // Wait for confirmation const confirmation = await this.client.waitForTransaction({ digest: result.digest, options: { showEffects: true, showEvents: true, } }); const status = (_c = (_b = confirmation.effects) === null || _b === void 0 ? void 0 : _b.status) === null || _c === void 0 ? void 0 : _c.status; if (status !== 'success') { throw new Error(`Transaction failed with status: ${status}`); } return { txId: result.digest, confirmation, signature: signedTx.signature }; } catch (error) { retryCount++; if (retryCount === this.networkConfig.maxRetries) { throw error; } await new Promise(resolve => setTimeout(resolve, 2000 * retryCount)); } } throw new Error('Max retries exceeded'); } formatSwapResult(txId, 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: txId, explorerUrl: `https://suiscan.xyz/mainnet/tx/${txId}`, 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.SuiSwapExecutor = SuiSwapExecutor;