@drift-labs/sdk
Version:
SDK for Drift Protocol
143 lines (142 loc) • 6.34 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JupiterClient = exports.RECOMMENDED_JUPITER_API = exports.RECOMMENDED_JUPITER_API_VERSION = void 0;
const web3_js_1 = require("@solana/web3.js");
const node_fetch_1 = __importDefault(require("node-fetch"));
exports.RECOMMENDED_JUPITER_API_VERSION = '/v1';
exports.RECOMMENDED_JUPITER_API = 'https://lite-api.jup.ag/swap';
class JupiterClient {
constructor({ connection, url }) {
this.lookupTableCahce = new Map();
this.connection = connection;
this.url = url !== null && url !== void 0 ? url : exports.RECOMMENDED_JUPITER_API;
}
/**
* Get routes for a swap
* @param inputMint the mint of the input token
* @param outputMint the mint of the output token
* @param amount the amount of the input token
* @param slippageBps the slippage tolerance in basis points
* @param swapMode the swap mode (ExactIn or ExactOut)
* @param onlyDirectRoutes whether to only return direct routes
*/
async getQuote({ inputMint, outputMint, amount, maxAccounts = 50, // 50 is an estimated amount with buffer
slippageBps = 50, swapMode = 'ExactIn', onlyDirectRoutes = false, excludeDexes, autoSlippage = false, maxAutoSlippageBps, usdEstimate, }) {
const params = new URLSearchParams({
inputMint: inputMint.toString(),
outputMint: outputMint.toString(),
amount: amount.toString(),
slippageBps: autoSlippage ? '0' : slippageBps.toString(),
swapMode,
onlyDirectRoutes: onlyDirectRoutes.toString(),
maxAccounts: maxAccounts.toString(),
autoSlippage: autoSlippage.toString(),
maxAutoSlippageBps: autoSlippage ? maxAutoSlippageBps.toString() : '0',
autoSlippageCollisionUsdValue: autoSlippage
? usdEstimate.toString()
: '0',
...(excludeDexes && { excludeDexes: excludeDexes.join(',') }),
});
if (swapMode === 'ExactOut') {
params.delete('maxAccounts');
}
const apiVersionParam = this.url === exports.RECOMMENDED_JUPITER_API
? exports.RECOMMENDED_JUPITER_API_VERSION
: '';
const quote = await (await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/quote?${params.toString()}`)).json();
return quote;
}
/**
* Get a swap transaction for quote
* @param quoteResponse quote to perform swap
* @param userPublicKey the signer's wallet public key
* @param slippageBps the slippage tolerance in basis points
*/
async getSwap({ quote, userPublicKey, slippageBps = 50, }) {
var _a;
if (!quote) {
throw new Error('Jupiter swap quote not provided. Please try again.');
}
const apiVersionParam = this.url === exports.RECOMMENDED_JUPITER_API
? exports.RECOMMENDED_JUPITER_API_VERSION
: '';
const resp = await (await (0, node_fetch_1.default)(`${this.url}${apiVersionParam}/swap`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
quoteResponse: quote,
userPublicKey,
slippageBps,
}),
})).json();
if (!('swapTransaction' in resp)) {
throw new Error(`swapTransaction not found, error from Jupiter: ${resp.error} ${', ' + ((_a = resp.message) !== null && _a !== void 0 ? _a : '')}`);
}
const { swapTransaction } = resp;
try {
const swapTransactionBuf = Buffer.from(swapTransaction, 'base64');
return web3_js_1.VersionedTransaction.deserialize(swapTransactionBuf);
}
catch (err) {
throw new Error('Something went wrong with creating the Jupiter swap transaction. Please try again.');
}
}
/**
* Get the transaction message and lookup tables for a transaction
* @param transaction
*/
async getTransactionMessageAndLookupTables({ transaction, }) {
const message = transaction.message;
const lookupTables = (await Promise.all(message.addressTableLookups.map(async (lookup) => {
return await this.getLookupTable(lookup.accountKey);
}))).filter((lookup) => lookup);
const transactionMessage = web3_js_1.TransactionMessage.decompile(message, {
addressLookupTableAccounts: lookupTables,
});
return {
transactionMessage,
lookupTables,
};
}
async getLookupTable(accountKey) {
if (this.lookupTableCahce.has(accountKey.toString())) {
return this.lookupTableCahce.get(accountKey.toString());
}
return (await this.connection.getAddressLookupTable(accountKey)).value;
}
/**
* Get the jupiter instructions from transaction by filtering out instructions to compute budget and associated token programs
* @param transactionMessage the transaction message
* @param inputMint the input mint
* @param outputMint the output mint
*/
getJupiterInstructions({ transactionMessage, inputMint, outputMint, }) {
return transactionMessage.instructions.filter((instruction) => {
if (instruction.programId.toString() ===
'ComputeBudget111111111111111111111111111111') {
return false;
}
if (instruction.programId.toString() ===
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') {
return false;
}
if (instruction.programId.toString() === '11111111111111111111111111111111') {
return false;
}
if (instruction.programId.toString() ===
'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL') {
const mint = instruction.keys[3].pubkey;
if (mint.equals(inputMint) || mint.equals(outputMint)) {
return false;
}
}
return true;
});
}
}
exports.JupiterClient = JupiterClient;
;