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