@okx-dex/okx-dex-sdk
Version:
OKX DEX SDK
82 lines (81 loc) • 3.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SolanaInstructionExecutor = void 0;
const web3_js_1 = require("@solana/web3.js");
class SolanaInstructionExecutor {
constructor(config, networkConfig) {
this.config = config;
this.networkConfig = networkConfig;
}
async executeInstructions(instrData) {
var _a;
if (!((_a = this.config.solana) === null || _a === void 0 ? void 0 : _a.wallet)) {
throw new Error("Solana wallet configuration required");
}
const connection = this.config.solana.wallet.connection;
// 获取最新区块信息
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
// 拉取 ALT 账户
const lookupTables = [];
if (Array.isArray(instrData.addressLookupTableAccount)) {
for (const addr of instrData.addressLookupTableAccount) {
const { value } = await connection.getAddressLookupTable(new web3_js_1.PublicKey(addr));
if (value)
lookupTables.push(value);
}
}
// 构建指令
const instructions = instrData.instructionLists.map((item) => {
const programId = new web3_js_1.PublicKey(item.programId);
const keys = (item.accounts || []).map((acc) => ({
pubkey: new web3_js_1.PublicKey(acc.pubkey),
isSigner: !!acc.isSigner,
isWritable: !!acc.isWritable,
}));
const data = Buffer.from(item.data, "base64");
return new web3_js_1.TransactionInstruction({ programId, keys, data });
});
// assemble v0
const message = new web3_js_1.TransactionMessage({
payerKey: this.config.solana.wallet.publicKey,
recentBlockhash: blockhash,
instructions,
}).compileToV0Message(lookupTables);
const vtx = new web3_js_1.VersionedTransaction(message);
// 签名并发送
const { signature } = await this.config.solana.wallet.signAndSendTransaction(vtx, {
skipPreflight: false,
maxRetries: this.networkConfig.maxRetries,
preflightCommitment: "confirmed",
});
// 确认交易
const confirmation = await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight }, "confirmed");
if (confirmation.value.err) {
throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
}
const router = instrData.routerResult;
const fromDecimals = parseInt(router.fromToken.decimal);
const toDecimals = parseInt(router.toToken.decimal);
const displayFromAmount = (Number(router.fromTokenAmount) / Math.pow(10, fromDecimals)).toFixed(6);
const displayToAmount = (Number(router.toTokenAmount) / Math.pow(10, toDecimals)).toFixed(6);
return {
success: true,
transactionId: signature,
explorerUrl: `${this.networkConfig.explorer}/${signature}`,
details: {
fromToken: {
symbol: router.fromToken.tokenSymbol,
amount: displayFromAmount,
decimal: router.fromToken.decimal,
},
toToken: {
symbol: router.toToken.tokenSymbol,
amount: displayToAmount,
decimal: router.toToken.decimal,
},
priceImpact: router.priceImpactPercent,
},
};
}
}
exports.SolanaInstructionExecutor = SolanaInstructionExecutor;