@drift-labs/sdk 2.145.0-beta.0 → 2.145.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/browser/driftClient.d.ts +25 -3
- package/lib/browser/driftClient.js +77 -2
- package/lib/browser/index.d.ts +1 -1
- package/lib/browser/index.js +3 -3
- package/lib/browser/jupiter/jupiterClient.d.ts +1 -1
- package/lib/browser/swap/UnifiedSwapClient.d.ts +86 -0
- package/lib/browser/swap/UnifiedSwapClient.js +179 -0
- package/lib/node/driftClient.d.ts +25 -3
- package/lib/node/driftClient.d.ts.map +1 -1
- package/lib/node/driftClient.js +77 -2
- package/lib/node/index.d.ts +1 -1
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +3 -3
- package/lib/node/jupiter/jupiterClient.d.ts +1 -1
- package/lib/node/jupiter/jupiterClient.d.ts.map +1 -1
- package/lib/node/swap/UnifiedSwapClient.d.ts +87 -0
- package/lib/node/swap/UnifiedSwapClient.d.ts.map +1 -0
- package/lib/node/swap/UnifiedSwapClient.js +179 -0
- package/package.json +1 -1
- package/src/driftClient.ts +152 -9
- package/src/index.ts +2 -1
- package/src/jupiter/jupiterClient.ts +1 -2
- package/src/swap/UnifiedSwapClient.ts +293 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.145.0-beta.
|
|
1
|
+
2.145.0-beta.1
|
|
@@ -18,7 +18,8 @@ import { User } from './user';
|
|
|
18
18
|
import { UserSubscriptionConfig } from './userConfig';
|
|
19
19
|
import { DriftEnv } from './config';
|
|
20
20
|
import { UserStats } from './userStats';
|
|
21
|
-
import { JupiterClient, QuoteResponse
|
|
21
|
+
import { JupiterClient, QuoteResponse } from './jupiter/jupiterClient';
|
|
22
|
+
import { SwapMode } from './swap/UnifiedSwapClient';
|
|
22
23
|
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
23
24
|
import { TxHandler } from './tx/txHandler';
|
|
24
25
|
import { WormholeCoreBridgeSolana } from '@pythnetwork/pyth-solana-receiver/lib/idl/wormhole_core_bridge_solana';
|
|
@@ -27,8 +28,10 @@ import { Slothash } from './slot/SlothashSubscriber';
|
|
|
27
28
|
import { SignedMsgOrderParams } from './types';
|
|
28
29
|
import { RevenueShareEscrowMap } from './userMap/revenueShareEscrowMap';
|
|
29
30
|
import { TitanClient } from './titan/titanClient';
|
|
31
|
+
import { UnifiedSwapClient } from './swap/UnifiedSwapClient';
|
|
30
32
|
/**
|
|
31
|
-
* Union type for swap clients (Titan and Jupiter)
|
|
33
|
+
* Union type for swap clients (Titan and Jupiter) - Legacy type
|
|
34
|
+
* @deprecated Use UnifiedSwapClient class instead
|
|
32
35
|
*/
|
|
33
36
|
export type SwapClient = TitanClient | JupiterClient;
|
|
34
37
|
type RemainingAccountParams = {
|
|
@@ -552,7 +555,7 @@ export declare class DriftClient {
|
|
|
552
555
|
* @param txParams
|
|
553
556
|
*/
|
|
554
557
|
swap({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, reduceOnly, txParams, v6, quote, onlyDirectRoutes, }: {
|
|
555
|
-
swapClient: SwapClient;
|
|
558
|
+
swapClient: UnifiedSwapClient | SwapClient;
|
|
556
559
|
outMarketIndex: number;
|
|
557
560
|
inMarketIndex: number;
|
|
558
561
|
outAssociatedTokenAccount?: PublicKey;
|
|
@@ -626,6 +629,25 @@ export declare class DriftClient {
|
|
|
626
629
|
beginSwapIx: TransactionInstruction;
|
|
627
630
|
endSwapIx: TransactionInstruction;
|
|
628
631
|
}>;
|
|
632
|
+
getSwapIxV2({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, quote, v6, }: {
|
|
633
|
+
swapClient: UnifiedSwapClient;
|
|
634
|
+
outMarketIndex: number;
|
|
635
|
+
inMarketIndex: number;
|
|
636
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
637
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
638
|
+
amount: BN;
|
|
639
|
+
slippageBps?: number;
|
|
640
|
+
swapMode?: SwapMode;
|
|
641
|
+
onlyDirectRoutes?: boolean;
|
|
642
|
+
reduceOnly?: SwapReduceOnly;
|
|
643
|
+
quote?: QuoteResponse;
|
|
644
|
+
v6?: {
|
|
645
|
+
quote?: QuoteResponse;
|
|
646
|
+
};
|
|
647
|
+
}): Promise<{
|
|
648
|
+
ixs: TransactionInstruction[];
|
|
649
|
+
lookupTables: AddressLookupTableAccount[];
|
|
650
|
+
}>;
|
|
629
651
|
stakeForMSOL({ amount }: {
|
|
630
652
|
amount: BN;
|
|
631
653
|
}): Promise<TxSigAndSlot>;
|
|
@@ -76,6 +76,7 @@ const webSocketDriftClientAccountSubscriber_1 = require("./accounts/webSocketDri
|
|
|
76
76
|
const orders_1 = require("./math/orders");
|
|
77
77
|
const builder_1 = require("./math/builder");
|
|
78
78
|
const titanClient_1 = require("./titan/titanClient");
|
|
79
|
+
const UnifiedSwapClient_1 = require("./swap/UnifiedSwapClient");
|
|
79
80
|
/**
|
|
80
81
|
* # DriftClient
|
|
81
82
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
@@ -3120,7 +3121,24 @@ class DriftClient {
|
|
|
3120
3121
|
*/
|
|
3121
3122
|
async swap({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, reduceOnly, txParams, v6, quote, onlyDirectRoutes = false, }) {
|
|
3122
3123
|
let res;
|
|
3123
|
-
|
|
3124
|
+
// Use unified SwapClient if available
|
|
3125
|
+
if (swapClient instanceof UnifiedSwapClient_1.UnifiedSwapClient) {
|
|
3126
|
+
res = await this.getSwapIxV2({
|
|
3127
|
+
swapClient,
|
|
3128
|
+
outMarketIndex,
|
|
3129
|
+
inMarketIndex,
|
|
3130
|
+
outAssociatedTokenAccount,
|
|
3131
|
+
inAssociatedTokenAccount,
|
|
3132
|
+
amount,
|
|
3133
|
+
slippageBps,
|
|
3134
|
+
swapMode,
|
|
3135
|
+
onlyDirectRoutes,
|
|
3136
|
+
reduceOnly,
|
|
3137
|
+
quote,
|
|
3138
|
+
v6,
|
|
3139
|
+
});
|
|
3140
|
+
}
|
|
3141
|
+
else if (swapClient instanceof titanClient_1.TitanClient) {
|
|
3124
3142
|
res = await this.getTitanSwapIx({
|
|
3125
3143
|
titanClient: swapClient,
|
|
3126
3144
|
outMarketIndex,
|
|
@@ -3151,7 +3169,7 @@ class DriftClient {
|
|
|
3151
3169
|
});
|
|
3152
3170
|
}
|
|
3153
3171
|
else {
|
|
3154
|
-
throw new Error('Invalid swap client type. Must be TitanClient or JupiterClient.');
|
|
3172
|
+
throw new Error('Invalid swap client type. Must be SwapClient, TitanClient, or JupiterClient.');
|
|
3155
3173
|
}
|
|
3156
3174
|
const ixs = res.ixs;
|
|
3157
3175
|
const lookupTables = res.lookupTables;
|
|
@@ -3373,6 +3391,63 @@ class DriftClient {
|
|
|
3373
3391
|
});
|
|
3374
3392
|
return { beginSwapIx, endSwapIx };
|
|
3375
3393
|
}
|
|
3394
|
+
async getSwapIxV2({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, quote, v6, }) {
|
|
3395
|
+
// Get market accounts to determine mints
|
|
3396
|
+
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
3397
|
+
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
3398
|
+
const isExactOut = swapMode === 'ExactOut';
|
|
3399
|
+
const exactOutBufferedAmountIn = amount.muln(1001).divn(1000); // Add 10bp buffer
|
|
3400
|
+
const preInstructions = [];
|
|
3401
|
+
// Handle token accounts if not provided
|
|
3402
|
+
let finalOutAssociatedTokenAccount = outAssociatedTokenAccount;
|
|
3403
|
+
let finalInAssociatedTokenAccount = inAssociatedTokenAccount;
|
|
3404
|
+
if (!finalOutAssociatedTokenAccount) {
|
|
3405
|
+
const tokenProgram = this.getTokenProgramForSpotMarket(outMarket);
|
|
3406
|
+
finalOutAssociatedTokenAccount = await this.getAssociatedTokenAccount(outMarket.marketIndex, false, tokenProgram);
|
|
3407
|
+
const accountInfo = await this.connection.getAccountInfo(finalOutAssociatedTokenAccount);
|
|
3408
|
+
if (!accountInfo) {
|
|
3409
|
+
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(finalOutAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, outMarket.mint, tokenProgram));
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
if (!finalInAssociatedTokenAccount) {
|
|
3413
|
+
const tokenProgram = this.getTokenProgramForSpotMarket(inMarket);
|
|
3414
|
+
finalInAssociatedTokenAccount = await this.getAssociatedTokenAccount(inMarket.marketIndex, false, tokenProgram);
|
|
3415
|
+
const accountInfo = await this.connection.getAccountInfo(finalInAssociatedTokenAccount);
|
|
3416
|
+
if (!accountInfo) {
|
|
3417
|
+
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(finalInAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, inMarket.mint, tokenProgram));
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
// Get drift swap instructions for begin and end
|
|
3421
|
+
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
3422
|
+
outMarketIndex,
|
|
3423
|
+
inMarketIndex,
|
|
3424
|
+
amountIn: isExactOut ? exactOutBufferedAmountIn : amount,
|
|
3425
|
+
inTokenAccount: finalInAssociatedTokenAccount,
|
|
3426
|
+
outTokenAccount: finalOutAssociatedTokenAccount,
|
|
3427
|
+
reduceOnly,
|
|
3428
|
+
});
|
|
3429
|
+
// Get core swap instructions from SwapClient
|
|
3430
|
+
const swapResult = await swapClient.getSwapInstructions({
|
|
3431
|
+
inputMint: inMarket.mint,
|
|
3432
|
+
outputMint: outMarket.mint,
|
|
3433
|
+
amount,
|
|
3434
|
+
userPublicKey: this.provider.wallet.publicKey,
|
|
3435
|
+
slippageBps,
|
|
3436
|
+
swapMode,
|
|
3437
|
+
onlyDirectRoutes,
|
|
3438
|
+
quote: quote !== null && quote !== void 0 ? quote : v6 === null || v6 === void 0 ? void 0 : v6.quote,
|
|
3439
|
+
});
|
|
3440
|
+
const allInstructions = [
|
|
3441
|
+
...preInstructions,
|
|
3442
|
+
beginSwapIx,
|
|
3443
|
+
...swapResult.instructions,
|
|
3444
|
+
endSwapIx,
|
|
3445
|
+
];
|
|
3446
|
+
return {
|
|
3447
|
+
ixs: allInstructions,
|
|
3448
|
+
lookupTables: swapResult.lookupTables,
|
|
3449
|
+
};
|
|
3450
|
+
}
|
|
3376
3451
|
async stakeForMSOL({ amount }) {
|
|
3377
3452
|
const ixs = await this.getStakeForMSOLIx({ amount });
|
|
3378
3453
|
const tx = await this.buildTransaction(ixs);
|
package/lib/browser/index.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ export * from './events/webSocketLogProvider';
|
|
|
52
52
|
export * from './events/parse';
|
|
53
53
|
export * from './events/pollingLogProvider';
|
|
54
54
|
export * from './jupiter/jupiterClient';
|
|
55
|
-
export
|
|
55
|
+
export * from './swap/UnifiedSwapClient';
|
|
56
56
|
export * from './math/auction';
|
|
57
57
|
export * from './math/builder';
|
|
58
58
|
export * from './math/spotMarket';
|
package/lib/browser/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.pyth = exports.PublicKey = exports.BN = exports.
|
|
20
|
+
exports.pyth = exports.PublicKey = exports.BN = exports.CustomizedCadenceBulkAccountLoader = exports.WebSocketDriftClientAccountSubscriberV2 = exports.WebSocketProgramAccountsSubscriberV2 = exports.WebSocketProgramUserAccountSubscriber = exports.WebSocketProgramAccountSubscriber = exports.WebSocketAccountSubscriberV2 = void 0;
|
|
21
21
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
22
22
|
Object.defineProperty(exports, "BN", { enumerable: true, get: function () { return anchor_1.BN; } });
|
|
23
23
|
const web3_js_1 = require("@solana/web3.js");
|
|
@@ -81,8 +81,8 @@ __exportStar(require("./events/webSocketLogProvider"), exports);
|
|
|
81
81
|
__exportStar(require("./events/parse"), exports);
|
|
82
82
|
__exportStar(require("./events/pollingLogProvider"), exports);
|
|
83
83
|
__exportStar(require("./jupiter/jupiterClient"), exports);
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
// Primary swap client interface - use this for all swap operations
|
|
85
|
+
__exportStar(require("./swap/UnifiedSwapClient"), exports);
|
|
86
86
|
__exportStar(require("./math/auction"), exports);
|
|
87
87
|
__exportStar(require("./math/builder"), exports);
|
|
88
88
|
__exportStar(require("./math/spotMarket"), exports);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { AddressLookupTableAccount, Connection, PublicKey, TransactionInstruction, TransactionMessage, VersionedTransaction } from '@solana/web3.js';
|
|
3
3
|
import { BN } from '@coral-xyz/anchor';
|
|
4
|
-
|
|
4
|
+
import { SwapMode } from '../swap/UnifiedSwapClient';
|
|
5
5
|
export interface MarketInfo {
|
|
6
6
|
id: string;
|
|
7
7
|
inAmount: number;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { Connection, PublicKey, TransactionMessage, AddressLookupTableAccount, VersionedTransaction, TransactionInstruction } from '@solana/web3.js';
|
|
3
|
+
import { BN } from '@coral-xyz/anchor';
|
|
4
|
+
import { JupiterClient, QuoteResponse as JupiterQuoteResponse } from '../jupiter/jupiterClient';
|
|
5
|
+
import { TitanClient, QuoteResponse as TitanQuoteResponse } from '../titan/titanClient';
|
|
6
|
+
export type SwapMode = 'ExactIn' | 'ExactOut';
|
|
7
|
+
export type SwapClientType = 'jupiter' | 'titan';
|
|
8
|
+
export type UnifiedQuoteResponse = JupiterQuoteResponse | TitanQuoteResponse;
|
|
9
|
+
export interface SwapQuoteParams {
|
|
10
|
+
inputMint: PublicKey;
|
|
11
|
+
outputMint: PublicKey;
|
|
12
|
+
amount: BN;
|
|
13
|
+
userPublicKey?: PublicKey;
|
|
14
|
+
maxAccounts?: number;
|
|
15
|
+
slippageBps?: number;
|
|
16
|
+
swapMode?: SwapMode;
|
|
17
|
+
onlyDirectRoutes?: boolean;
|
|
18
|
+
excludeDexes?: string[];
|
|
19
|
+
sizeConstraint?: number;
|
|
20
|
+
accountsLimitWritable?: number;
|
|
21
|
+
autoSlippage?: boolean;
|
|
22
|
+
maxAutoSlippageBps?: number;
|
|
23
|
+
usdEstimate?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface SwapTransactionParams {
|
|
26
|
+
quote: UnifiedQuoteResponse;
|
|
27
|
+
userPublicKey: PublicKey;
|
|
28
|
+
slippageBps?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface SwapTransactionResult {
|
|
31
|
+
transaction?: VersionedTransaction;
|
|
32
|
+
transactionMessage?: TransactionMessage;
|
|
33
|
+
lookupTables?: AddressLookupTableAccount[];
|
|
34
|
+
}
|
|
35
|
+
export declare class UnifiedSwapClient {
|
|
36
|
+
private client;
|
|
37
|
+
private clientType;
|
|
38
|
+
constructor({ clientType, connection, authToken, url, }: {
|
|
39
|
+
clientType: SwapClientType;
|
|
40
|
+
connection: Connection;
|
|
41
|
+
authToken?: string;
|
|
42
|
+
url?: string;
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* Get a swap quote from the underlying client
|
|
46
|
+
*/
|
|
47
|
+
getQuote(params: SwapQuoteParams): Promise<UnifiedQuoteResponse>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a swap transaction from the underlying client
|
|
50
|
+
*/
|
|
51
|
+
getSwap(params: SwapTransactionParams): Promise<SwapTransactionResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Get swap instructions from the underlying client (Jupiter or Titan)
|
|
54
|
+
* This is the core swap logic without any context preparation
|
|
55
|
+
*/
|
|
56
|
+
getSwapInstructions({ inputMint, outputMint, amount, userPublicKey, slippageBps, swapMode, onlyDirectRoutes, quote, sizeConstraint, }: {
|
|
57
|
+
inputMint: PublicKey;
|
|
58
|
+
outputMint: PublicKey;
|
|
59
|
+
amount: BN;
|
|
60
|
+
userPublicKey: PublicKey;
|
|
61
|
+
slippageBps?: number;
|
|
62
|
+
swapMode?: SwapMode;
|
|
63
|
+
onlyDirectRoutes?: boolean;
|
|
64
|
+
quote?: UnifiedQuoteResponse;
|
|
65
|
+
sizeConstraint?: number;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
instructions: TransactionInstruction[];
|
|
68
|
+
lookupTables: AddressLookupTableAccount[];
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Get the underlying client instance
|
|
72
|
+
*/
|
|
73
|
+
getClient(): JupiterClient | TitanClient;
|
|
74
|
+
/**
|
|
75
|
+
* Get the client type
|
|
76
|
+
*/
|
|
77
|
+
getClientType(): SwapClientType;
|
|
78
|
+
/**
|
|
79
|
+
* Check if this is a Jupiter client
|
|
80
|
+
*/
|
|
81
|
+
isJupiter(): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Check if this is a Titan client
|
|
84
|
+
*/
|
|
85
|
+
isTitan(): boolean;
|
|
86
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnifiedSwapClient = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
6
|
+
const jupiterClient_1 = require("../jupiter/jupiterClient");
|
|
7
|
+
const titanClient_1 = require("../titan/titanClient");
|
|
8
|
+
class UnifiedSwapClient {
|
|
9
|
+
constructor({ clientType, connection, authToken, url, }) {
|
|
10
|
+
this.clientType = clientType;
|
|
11
|
+
if (clientType === 'jupiter') {
|
|
12
|
+
this.client = new jupiterClient_1.JupiterClient({
|
|
13
|
+
connection,
|
|
14
|
+
url,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
else if (clientType === 'titan') {
|
|
18
|
+
if (!authToken) {
|
|
19
|
+
throw new Error('authToken is required for Titan client');
|
|
20
|
+
}
|
|
21
|
+
this.client = new titanClient_1.TitanClient({
|
|
22
|
+
connection,
|
|
23
|
+
authToken,
|
|
24
|
+
url,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw new Error(`Unsupported client type: ${clientType}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get a swap quote from the underlying client
|
|
33
|
+
*/
|
|
34
|
+
async getQuote(params) {
|
|
35
|
+
if (this.clientType === 'jupiter') {
|
|
36
|
+
const jupiterClient = this.client;
|
|
37
|
+
const { userPublicKey: _userPublicKey, // Not needed for Jupiter
|
|
38
|
+
sizeConstraint: _sizeConstraint, // Jupiter-specific params to exclude
|
|
39
|
+
accountsLimitWritable: _accountsLimitWritable, ...jupiterParams } = params;
|
|
40
|
+
return await jupiterClient.getQuote(jupiterParams);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const titanClient = this.client;
|
|
44
|
+
const { autoSlippage: _autoSlippage, // Titan-specific params to exclude
|
|
45
|
+
maxAutoSlippageBps: _maxAutoSlippageBps, usdEstimate: _usdEstimate, ...titanParams } = params;
|
|
46
|
+
if (!titanParams.userPublicKey) {
|
|
47
|
+
throw new Error('userPublicKey is required for Titan quotes');
|
|
48
|
+
}
|
|
49
|
+
// Cast to ensure TypeScript knows userPublicKey is defined
|
|
50
|
+
const titanParamsWithUser = {
|
|
51
|
+
...titanParams,
|
|
52
|
+
userPublicKey: titanParams.userPublicKey,
|
|
53
|
+
swapMode: titanParams.swapMode, // Titan expects string
|
|
54
|
+
};
|
|
55
|
+
return await titanClient.getQuote(titanParamsWithUser);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get a swap transaction from the underlying client
|
|
60
|
+
*/
|
|
61
|
+
async getSwap(params) {
|
|
62
|
+
if (this.clientType === 'jupiter') {
|
|
63
|
+
const jupiterClient = this.client;
|
|
64
|
+
// Cast the quote to Jupiter's QuoteResponse type
|
|
65
|
+
const jupiterParams = {
|
|
66
|
+
...params,
|
|
67
|
+
quote: params.quote,
|
|
68
|
+
};
|
|
69
|
+
const transaction = await jupiterClient.getSwap(jupiterParams);
|
|
70
|
+
return { transaction };
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const titanClient = this.client;
|
|
74
|
+
const { quote, userPublicKey, slippageBps } = params;
|
|
75
|
+
// For Titan, we need to reconstruct the parameters from the quote
|
|
76
|
+
const titanQuote = quote;
|
|
77
|
+
const result = await titanClient.getSwap({
|
|
78
|
+
inputMint: new web3_js_1.PublicKey(titanQuote.inputMint),
|
|
79
|
+
outputMint: new web3_js_1.PublicKey(titanQuote.outputMint),
|
|
80
|
+
amount: new anchor_1.BN(titanQuote.inAmount),
|
|
81
|
+
userPublicKey,
|
|
82
|
+
slippageBps: slippageBps || titanQuote.slippageBps,
|
|
83
|
+
swapMode: titanQuote.swapMode,
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
transactionMessage: result.transactionMessage,
|
|
87
|
+
lookupTables: result.lookupTables,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get swap instructions from the underlying client (Jupiter or Titan)
|
|
93
|
+
* This is the core swap logic without any context preparation
|
|
94
|
+
*/
|
|
95
|
+
async getSwapInstructions({ inputMint, outputMint, amount, userPublicKey, slippageBps, swapMode = 'ExactIn', onlyDirectRoutes = false, quote, sizeConstraint, }) {
|
|
96
|
+
const isExactOut = swapMode === 'ExactOut';
|
|
97
|
+
let swapInstructions;
|
|
98
|
+
let lookupTables;
|
|
99
|
+
if (this.clientType === 'jupiter') {
|
|
100
|
+
const jupiterClient = this.client;
|
|
101
|
+
// Get quote if not provided
|
|
102
|
+
let finalQuote = quote;
|
|
103
|
+
if (!finalQuote) {
|
|
104
|
+
finalQuote = await jupiterClient.getQuote({
|
|
105
|
+
inputMint,
|
|
106
|
+
outputMint,
|
|
107
|
+
amount,
|
|
108
|
+
slippageBps,
|
|
109
|
+
swapMode,
|
|
110
|
+
onlyDirectRoutes,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (!finalQuote) {
|
|
114
|
+
throw new Error("Could not fetch Jupiter's quote. Please try again.");
|
|
115
|
+
}
|
|
116
|
+
// Get swap transaction and extract instructions
|
|
117
|
+
const transaction = await jupiterClient.getSwap({
|
|
118
|
+
quote: finalQuote,
|
|
119
|
+
userPublicKey,
|
|
120
|
+
slippageBps,
|
|
121
|
+
});
|
|
122
|
+
const { transactionMessage, lookupTables: jupiterLookupTables } = await jupiterClient.getTransactionMessageAndLookupTables({
|
|
123
|
+
transaction,
|
|
124
|
+
});
|
|
125
|
+
swapInstructions = jupiterClient.getJupiterInstructions({
|
|
126
|
+
transactionMessage,
|
|
127
|
+
inputMint,
|
|
128
|
+
outputMint,
|
|
129
|
+
});
|
|
130
|
+
lookupTables = jupiterLookupTables;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
const titanClient = this.client;
|
|
134
|
+
// For Titan, get swap directly (it handles quote internally)
|
|
135
|
+
const { transactionMessage, lookupTables: titanLookupTables } = await titanClient.getSwap({
|
|
136
|
+
inputMint,
|
|
137
|
+
outputMint,
|
|
138
|
+
amount,
|
|
139
|
+
userPublicKey,
|
|
140
|
+
slippageBps,
|
|
141
|
+
swapMode: isExactOut ? titanClient_1.SwapMode.ExactOut : titanClient_1.SwapMode.ExactIn,
|
|
142
|
+
onlyDirectRoutes,
|
|
143
|
+
sizeConstraint: sizeConstraint || 1280 - 375, // MAX_TX_BYTE_SIZE - buffer for drift instructions
|
|
144
|
+
});
|
|
145
|
+
swapInstructions = titanClient.getTitanInstructions({
|
|
146
|
+
transactionMessage,
|
|
147
|
+
inputMint,
|
|
148
|
+
outputMint,
|
|
149
|
+
});
|
|
150
|
+
lookupTables = titanLookupTables;
|
|
151
|
+
}
|
|
152
|
+
return { instructions: swapInstructions, lookupTables };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get the underlying client instance
|
|
156
|
+
*/
|
|
157
|
+
getClient() {
|
|
158
|
+
return this.client;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get the client type
|
|
162
|
+
*/
|
|
163
|
+
getClientType() {
|
|
164
|
+
return this.clientType;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Check if this is a Jupiter client
|
|
168
|
+
*/
|
|
169
|
+
isJupiter() {
|
|
170
|
+
return this.clientType === 'jupiter';
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Check if this is a Titan client
|
|
174
|
+
*/
|
|
175
|
+
isTitan() {
|
|
176
|
+
return this.clientType === 'titan';
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.UnifiedSwapClient = UnifiedSwapClient;
|
|
@@ -18,7 +18,8 @@ import { User } from './user';
|
|
|
18
18
|
import { UserSubscriptionConfig } from './userConfig';
|
|
19
19
|
import { DriftEnv } from './config';
|
|
20
20
|
import { UserStats } from './userStats';
|
|
21
|
-
import { JupiterClient, QuoteResponse
|
|
21
|
+
import { JupiterClient, QuoteResponse } from './jupiter/jupiterClient';
|
|
22
|
+
import { SwapMode } from './swap/UnifiedSwapClient';
|
|
22
23
|
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
23
24
|
import { TxHandler } from './tx/txHandler';
|
|
24
25
|
import { WormholeCoreBridgeSolana } from '@pythnetwork/pyth-solana-receiver/lib/idl/wormhole_core_bridge_solana';
|
|
@@ -27,8 +28,10 @@ import { Slothash } from './slot/SlothashSubscriber';
|
|
|
27
28
|
import { SignedMsgOrderParams } from './types';
|
|
28
29
|
import { RevenueShareEscrowMap } from './userMap/revenueShareEscrowMap';
|
|
29
30
|
import { TitanClient } from './titan/titanClient';
|
|
31
|
+
import { UnifiedSwapClient } from './swap/UnifiedSwapClient';
|
|
30
32
|
/**
|
|
31
|
-
* Union type for swap clients (Titan and Jupiter)
|
|
33
|
+
* Union type for swap clients (Titan and Jupiter) - Legacy type
|
|
34
|
+
* @deprecated Use UnifiedSwapClient class instead
|
|
32
35
|
*/
|
|
33
36
|
export type SwapClient = TitanClient | JupiterClient;
|
|
34
37
|
type RemainingAccountParams = {
|
|
@@ -552,7 +555,7 @@ export declare class DriftClient {
|
|
|
552
555
|
* @param txParams
|
|
553
556
|
*/
|
|
554
557
|
swap({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, reduceOnly, txParams, v6, quote, onlyDirectRoutes, }: {
|
|
555
|
-
swapClient: SwapClient;
|
|
558
|
+
swapClient: UnifiedSwapClient | SwapClient;
|
|
556
559
|
outMarketIndex: number;
|
|
557
560
|
inMarketIndex: number;
|
|
558
561
|
outAssociatedTokenAccount?: PublicKey;
|
|
@@ -626,6 +629,25 @@ export declare class DriftClient {
|
|
|
626
629
|
beginSwapIx: TransactionInstruction;
|
|
627
630
|
endSwapIx: TransactionInstruction;
|
|
628
631
|
}>;
|
|
632
|
+
getSwapIxV2({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, quote, v6, }: {
|
|
633
|
+
swapClient: UnifiedSwapClient;
|
|
634
|
+
outMarketIndex: number;
|
|
635
|
+
inMarketIndex: number;
|
|
636
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
637
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
638
|
+
amount: BN;
|
|
639
|
+
slippageBps?: number;
|
|
640
|
+
swapMode?: SwapMode;
|
|
641
|
+
onlyDirectRoutes?: boolean;
|
|
642
|
+
reduceOnly?: SwapReduceOnly;
|
|
643
|
+
quote?: QuoteResponse;
|
|
644
|
+
v6?: {
|
|
645
|
+
quote?: QuoteResponse;
|
|
646
|
+
};
|
|
647
|
+
}): Promise<{
|
|
648
|
+
ixs: TransactionInstruction[];
|
|
649
|
+
lookupTables: AddressLookupTableAccount[];
|
|
650
|
+
}>;
|
|
629
651
|
stakeForMSOL({ amount }: {
|
|
630
652
|
amount: BN;
|
|
631
653
|
}): Promise<TxSigAndSlot>;
|