@drift-labs/sdk
Version:
SDK for Drift Protocol
180 lines (179 loc) • 6.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnifiedSwapClient = void 0;
const jupiterClient_1 = require("../jupiter/jupiterClient");
const titanClient_1 = require("../titan/titanClient");
class UnifiedSwapClient {
/**
* Create a unified swap client
* @param clientType - 'jupiter' or 'titan'
* @param connection - Solana connection
* @param authToken - For Titan: auth token (required when not using proxy). For Jupiter: API key (required for api.jup.ag, get free key at https://portal.jup.ag)
* @param url - Optional custom URL
* @param proxyUrl - Optional proxy URL for Titan
*/
constructor({ clientType, connection, authToken, url, proxyUrl, }) {
this.clientType = clientType;
if (clientType === 'jupiter') {
this.client = new jupiterClient_1.JupiterClient({
connection,
url,
apiKey: authToken,
});
}
else if (clientType === 'titan') {
this.client = new titanClient_1.TitanClient({
connection,
authToken: authToken || '', // Not needed when using proxy
url,
proxyUrl,
});
}
else {
throw new Error(`Unsupported client type: ${clientType}`);
}
}
/**
* Get a swap quote from the underlying client
*/
async getQuote(params) {
if (this.clientType === 'jupiter') {
const jupiterClient = this.client;
const { userPublicKey: _userPublicKey, // Not needed for Jupiter
sizeConstraint: _sizeConstraint, // Jupiter-specific params to exclude
accountsLimitWritable: _accountsLimitWritable, ...jupiterParams } = params;
return await jupiterClient.getQuote(jupiterParams);
}
else {
const titanClient = this.client;
const { autoSlippage: _autoSlippage, // Titan-specific params to exclude
maxAutoSlippageBps: _maxAutoSlippageBps, usdEstimate: _usdEstimate, ...titanParams } = params;
if (!titanParams.userPublicKey) {
throw new Error('userPublicKey is required for Titan quotes');
}
// Cast to ensure TypeScript knows userPublicKey is defined
const titanParamsWithUser = {
...titanParams,
userPublicKey: titanParams.userPublicKey,
swapMode: titanParams.swapMode, // Titan expects string
sizeConstraint: titanParams.sizeConstraint || 1280 - 375, // Use same default as getSwapInstructions
};
return await titanClient.getQuote(titanParamsWithUser);
}
}
/**
* Get a swap transaction from the underlying client
*/
async getSwap(params) {
if (this.clientType === 'jupiter') {
const jupiterClient = this.client;
// Cast the quote to Jupiter's specific QuoteResponse type
const jupiterParams = {
...params,
quote: params.quote,
};
const transaction = await jupiterClient.getSwap(jupiterParams);
return { transaction };
}
else {
const titanClient = this.client;
const { userPublicKey } = params;
// For Titan, we need to reconstruct the parameters from the quote
const result = await titanClient.getSwap({
userPublicKey,
});
return {
transactionMessage: result.transactionMessage,
lookupTables: result.lookupTables,
};
}
}
/**
* Get swap instructions from the underlying client (Jupiter or Titan)
* This is the core swap logic without any context preparation
*/
async getSwapInstructions({ inputMint, outputMint, amount, userPublicKey, slippageBps, swapMode = 'ExactIn', onlyDirectRoutes = false, quote, sizeConstraint, }) {
const isExactOut = swapMode === 'ExactOut';
let swapInstructions;
let lookupTables;
if (this.clientType === 'jupiter') {
const jupiterClient = this.client;
// Get quote if not provided
let finalQuote = quote;
if (!finalQuote) {
finalQuote = await jupiterClient.getQuote({
inputMint,
outputMint,
amount,
slippageBps,
swapMode,
onlyDirectRoutes,
});
}
if (!finalQuote) {
throw new Error('Could not fetch swap quote. Please try again.');
}
// Get swap transaction and extract instructions
const transaction = await jupiterClient.getSwap({
quote: finalQuote,
userPublicKey,
slippageBps,
});
const { transactionMessage, lookupTables: jupiterLookupTables } = await jupiterClient.getTransactionMessageAndLookupTables({
transaction,
});
swapInstructions = jupiterClient.getJupiterInstructions({
transactionMessage,
inputMint,
outputMint,
});
lookupTables = jupiterLookupTables;
}
else {
const titanClient = this.client;
// For Titan, get swap directly (it handles quote internally)
const { transactionMessage, lookupTables: titanLookupTables } = await titanClient.getSwap({
inputMint,
outputMint,
amount,
userPublicKey,
slippageBps,
swapMode: isExactOut ? titanClient_1.SwapMode.ExactOut : titanClient_1.SwapMode.ExactIn,
onlyDirectRoutes,
sizeConstraint: sizeConstraint || 1280 - 375, // MAX_TX_BYTE_SIZE - buffer for drift instructions
});
swapInstructions = titanClient.getTitanInstructions({
transactionMessage,
inputMint,
outputMint,
});
lookupTables = titanLookupTables;
}
return { instructions: swapInstructions, lookupTables };
}
/**
* Get the underlying client instance
*/
getClient() {
return this.client;
}
/**
* Get the client type
*/
getClientType() {
return this.clientType;
}
/**
* Check if this is a Jupiter client
*/
isJupiter() {
return this.clientType === 'jupiter';
}
/**
* Check if this is a Titan client
*/
isTitan() {
return this.clientType === 'titan';
}
}
exports.UnifiedSwapClient = UnifiedSwapClient;