@drift-labs/sdk 2.145.0-beta.0 → 2.145.0-beta.2
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 +88 -5
- package/lib/browser/idl/drift.json +12 -0
- 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/browser/types.d.ts +2 -0
- package/lib/node/driftClient.d.ts +25 -3
- package/lib/node/driftClient.d.ts.map +1 -1
- package/lib/node/driftClient.js +88 -5
- package/lib/node/idl/drift.json +12 -0
- 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/lib/node/types.d.ts +2 -0
- package/lib/node/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/driftClient.ts +169 -15
- package/src/idl/drift.json +12 -0
- package/src/index.ts +2 -1
- package/src/jupiter/jupiterClient.ts +1 -2
- package/src/swap/UnifiedSwapClient.ts +293 -0
- package/src/types.ts +2 -0
|
@@ -8,8 +8,7 @@ import {
|
|
|
8
8
|
} from '@solana/web3.js';
|
|
9
9
|
import fetch from 'node-fetch';
|
|
10
10
|
import { BN } from '@coral-xyz/anchor';
|
|
11
|
-
|
|
12
|
-
export type SwapMode = 'ExactIn' | 'ExactOut';
|
|
11
|
+
import { SwapMode } from '../swap/UnifiedSwapClient';
|
|
13
12
|
|
|
14
13
|
export interface MarketInfo {
|
|
15
14
|
id: string;
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Connection,
|
|
3
|
+
PublicKey,
|
|
4
|
+
TransactionMessage,
|
|
5
|
+
AddressLookupTableAccount,
|
|
6
|
+
VersionedTransaction,
|
|
7
|
+
TransactionInstruction,
|
|
8
|
+
} from '@solana/web3.js';
|
|
9
|
+
import { BN } from '@coral-xyz/anchor';
|
|
10
|
+
import {
|
|
11
|
+
JupiterClient,
|
|
12
|
+
QuoteResponse as JupiterQuoteResponse,
|
|
13
|
+
} from '../jupiter/jupiterClient';
|
|
14
|
+
import {
|
|
15
|
+
TitanClient,
|
|
16
|
+
QuoteResponse as TitanQuoteResponse,
|
|
17
|
+
SwapMode as TitanSwapMode,
|
|
18
|
+
} from '../titan/titanClient';
|
|
19
|
+
|
|
20
|
+
export type SwapMode = 'ExactIn' | 'ExactOut';
|
|
21
|
+
export type SwapClientType = 'jupiter' | 'titan';
|
|
22
|
+
|
|
23
|
+
export type UnifiedQuoteResponse = JupiterQuoteResponse | TitanQuoteResponse;
|
|
24
|
+
|
|
25
|
+
export interface SwapQuoteParams {
|
|
26
|
+
inputMint: PublicKey;
|
|
27
|
+
outputMint: PublicKey;
|
|
28
|
+
amount: BN;
|
|
29
|
+
userPublicKey?: PublicKey; // Required for Titan, optional for Jupiter
|
|
30
|
+
maxAccounts?: number;
|
|
31
|
+
slippageBps?: number;
|
|
32
|
+
swapMode?: SwapMode;
|
|
33
|
+
onlyDirectRoutes?: boolean;
|
|
34
|
+
excludeDexes?: string[];
|
|
35
|
+
sizeConstraint?: number; // Titan-specific
|
|
36
|
+
accountsLimitWritable?: number; // Titan-specific
|
|
37
|
+
autoSlippage?: boolean; // Jupiter-specific
|
|
38
|
+
maxAutoSlippageBps?: number; // Jupiter-specific
|
|
39
|
+
usdEstimate?: number; // Jupiter-specific
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface SwapTransactionParams {
|
|
43
|
+
quote: UnifiedQuoteResponse;
|
|
44
|
+
userPublicKey: PublicKey;
|
|
45
|
+
slippageBps?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface SwapTransactionResult {
|
|
49
|
+
transaction?: VersionedTransaction; // Jupiter returns this
|
|
50
|
+
transactionMessage?: TransactionMessage; // Titan returns this
|
|
51
|
+
lookupTables?: AddressLookupTableAccount[]; // Titan returns this
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class UnifiedSwapClient {
|
|
55
|
+
private client: JupiterClient | TitanClient;
|
|
56
|
+
private clientType: SwapClientType;
|
|
57
|
+
|
|
58
|
+
constructor({
|
|
59
|
+
clientType,
|
|
60
|
+
connection,
|
|
61
|
+
authToken,
|
|
62
|
+
url,
|
|
63
|
+
}: {
|
|
64
|
+
clientType: SwapClientType;
|
|
65
|
+
connection: Connection;
|
|
66
|
+
authToken?: string; // Required for Titan, optional for Jupiter
|
|
67
|
+
url?: string; // Optional custom URL
|
|
68
|
+
}) {
|
|
69
|
+
this.clientType = clientType;
|
|
70
|
+
|
|
71
|
+
if (clientType === 'jupiter') {
|
|
72
|
+
this.client = new JupiterClient({
|
|
73
|
+
connection,
|
|
74
|
+
url,
|
|
75
|
+
});
|
|
76
|
+
} else if (clientType === 'titan') {
|
|
77
|
+
if (!authToken) {
|
|
78
|
+
throw new Error('authToken is required for Titan client');
|
|
79
|
+
}
|
|
80
|
+
this.client = new TitanClient({
|
|
81
|
+
connection,
|
|
82
|
+
authToken,
|
|
83
|
+
url,
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
throw new Error(`Unsupported client type: ${clientType}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get a swap quote from the underlying client
|
|
92
|
+
*/
|
|
93
|
+
public async getQuote(
|
|
94
|
+
params: SwapQuoteParams
|
|
95
|
+
): Promise<UnifiedQuoteResponse> {
|
|
96
|
+
if (this.clientType === 'jupiter') {
|
|
97
|
+
const jupiterClient = this.client as JupiterClient;
|
|
98
|
+
const {
|
|
99
|
+
userPublicKey: _userPublicKey, // Not needed for Jupiter
|
|
100
|
+
sizeConstraint: _sizeConstraint, // Jupiter-specific params to exclude
|
|
101
|
+
accountsLimitWritable: _accountsLimitWritable,
|
|
102
|
+
...jupiterParams
|
|
103
|
+
} = params;
|
|
104
|
+
|
|
105
|
+
return await jupiterClient.getQuote(jupiterParams);
|
|
106
|
+
} else {
|
|
107
|
+
const titanClient = this.client as TitanClient;
|
|
108
|
+
const {
|
|
109
|
+
autoSlippage: _autoSlippage, // Titan-specific params to exclude
|
|
110
|
+
maxAutoSlippageBps: _maxAutoSlippageBps,
|
|
111
|
+
usdEstimate: _usdEstimate,
|
|
112
|
+
...titanParams
|
|
113
|
+
} = params;
|
|
114
|
+
|
|
115
|
+
if (!titanParams.userPublicKey) {
|
|
116
|
+
throw new Error('userPublicKey is required for Titan quotes');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Cast to ensure TypeScript knows userPublicKey is defined
|
|
120
|
+
const titanParamsWithUser = {
|
|
121
|
+
...titanParams,
|
|
122
|
+
userPublicKey: titanParams.userPublicKey,
|
|
123
|
+
swapMode: titanParams.swapMode as string, // Titan expects string
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return await titanClient.getQuote(titanParamsWithUser);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get a swap transaction from the underlying client
|
|
132
|
+
*/
|
|
133
|
+
public async getSwap(
|
|
134
|
+
params: SwapTransactionParams
|
|
135
|
+
): Promise<SwapTransactionResult> {
|
|
136
|
+
if (this.clientType === 'jupiter') {
|
|
137
|
+
const jupiterClient = this.client as JupiterClient;
|
|
138
|
+
// Cast the quote to Jupiter's QuoteResponse type
|
|
139
|
+
const jupiterParams = {
|
|
140
|
+
...params,
|
|
141
|
+
quote: params.quote as JupiterQuoteResponse,
|
|
142
|
+
};
|
|
143
|
+
const transaction = await jupiterClient.getSwap(jupiterParams);
|
|
144
|
+
return { transaction };
|
|
145
|
+
} else {
|
|
146
|
+
const titanClient = this.client as TitanClient;
|
|
147
|
+
const { quote, userPublicKey, slippageBps } = params;
|
|
148
|
+
|
|
149
|
+
// For Titan, we need to reconstruct the parameters from the quote
|
|
150
|
+
const titanQuote = quote as TitanQuoteResponse;
|
|
151
|
+
const result = await titanClient.getSwap({
|
|
152
|
+
inputMint: new PublicKey(titanQuote.inputMint),
|
|
153
|
+
outputMint: new PublicKey(titanQuote.outputMint),
|
|
154
|
+
amount: new BN(titanQuote.inAmount),
|
|
155
|
+
userPublicKey,
|
|
156
|
+
slippageBps: slippageBps || titanQuote.slippageBps,
|
|
157
|
+
swapMode: titanQuote.swapMode,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
transactionMessage: result.transactionMessage,
|
|
162
|
+
lookupTables: result.lookupTables,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get swap instructions from the underlying client (Jupiter or Titan)
|
|
169
|
+
* This is the core swap logic without any context preparation
|
|
170
|
+
*/
|
|
171
|
+
public async getSwapInstructions({
|
|
172
|
+
inputMint,
|
|
173
|
+
outputMint,
|
|
174
|
+
amount,
|
|
175
|
+
userPublicKey,
|
|
176
|
+
slippageBps,
|
|
177
|
+
swapMode = 'ExactIn',
|
|
178
|
+
onlyDirectRoutes = false,
|
|
179
|
+
quote,
|
|
180
|
+
sizeConstraint,
|
|
181
|
+
}: {
|
|
182
|
+
inputMint: PublicKey;
|
|
183
|
+
outputMint: PublicKey;
|
|
184
|
+
amount: BN;
|
|
185
|
+
userPublicKey: PublicKey;
|
|
186
|
+
slippageBps?: number;
|
|
187
|
+
swapMode?: SwapMode;
|
|
188
|
+
onlyDirectRoutes?: boolean;
|
|
189
|
+
quote?: UnifiedQuoteResponse;
|
|
190
|
+
sizeConstraint?: number;
|
|
191
|
+
}): Promise<{
|
|
192
|
+
instructions: TransactionInstruction[];
|
|
193
|
+
lookupTables: AddressLookupTableAccount[];
|
|
194
|
+
}> {
|
|
195
|
+
const isExactOut = swapMode === 'ExactOut';
|
|
196
|
+
let swapInstructions: TransactionInstruction[];
|
|
197
|
+
let lookupTables: AddressLookupTableAccount[];
|
|
198
|
+
|
|
199
|
+
if (this.clientType === 'jupiter') {
|
|
200
|
+
const jupiterClient = this.client as JupiterClient;
|
|
201
|
+
|
|
202
|
+
// Get quote if not provided
|
|
203
|
+
let finalQuote = quote as JupiterQuoteResponse;
|
|
204
|
+
if (!finalQuote) {
|
|
205
|
+
finalQuote = await jupiterClient.getQuote({
|
|
206
|
+
inputMint,
|
|
207
|
+
outputMint,
|
|
208
|
+
amount,
|
|
209
|
+
slippageBps,
|
|
210
|
+
swapMode,
|
|
211
|
+
onlyDirectRoutes,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (!finalQuote) {
|
|
216
|
+
throw new Error("Could not fetch Jupiter's quote. Please try again.");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Get swap transaction and extract instructions
|
|
220
|
+
const transaction = await jupiterClient.getSwap({
|
|
221
|
+
quote: finalQuote,
|
|
222
|
+
userPublicKey,
|
|
223
|
+
slippageBps,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const { transactionMessage, lookupTables: jupiterLookupTables } =
|
|
227
|
+
await jupiterClient.getTransactionMessageAndLookupTables({
|
|
228
|
+
transaction,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
swapInstructions = jupiterClient.getJupiterInstructions({
|
|
232
|
+
transactionMessage,
|
|
233
|
+
inputMint,
|
|
234
|
+
outputMint,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
lookupTables = jupiterLookupTables;
|
|
238
|
+
} else {
|
|
239
|
+
const titanClient = this.client as TitanClient;
|
|
240
|
+
|
|
241
|
+
// For Titan, get swap directly (it handles quote internally)
|
|
242
|
+
const { transactionMessage, lookupTables: titanLookupTables } =
|
|
243
|
+
await titanClient.getSwap({
|
|
244
|
+
inputMint,
|
|
245
|
+
outputMint,
|
|
246
|
+
amount,
|
|
247
|
+
userPublicKey,
|
|
248
|
+
slippageBps,
|
|
249
|
+
swapMode: isExactOut ? TitanSwapMode.ExactOut : TitanSwapMode.ExactIn,
|
|
250
|
+
onlyDirectRoutes,
|
|
251
|
+
sizeConstraint: sizeConstraint || 1280 - 375, // MAX_TX_BYTE_SIZE - buffer for drift instructions
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
swapInstructions = titanClient.getTitanInstructions({
|
|
255
|
+
transactionMessage,
|
|
256
|
+
inputMint,
|
|
257
|
+
outputMint,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
lookupTables = titanLookupTables;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return { instructions: swapInstructions, lookupTables };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Get the underlying client instance
|
|
268
|
+
*/
|
|
269
|
+
public getClient(): JupiterClient | TitanClient {
|
|
270
|
+
return this.client;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Get the client type
|
|
275
|
+
*/
|
|
276
|
+
public getClientType(): SwapClientType {
|
|
277
|
+
return this.clientType;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Check if this is a Jupiter client
|
|
282
|
+
*/
|
|
283
|
+
public isJupiter(): boolean {
|
|
284
|
+
return this.clientType === 'jupiter';
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Check if this is a Titan client
|
|
289
|
+
*/
|
|
290
|
+
public isTitan(): boolean {
|
|
291
|
+
return this.clientType === 'titan';
|
|
292
|
+
}
|
|
293
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1337,6 +1337,7 @@ export type SignedMsgOrderParamsMessage = {
|
|
|
1337
1337
|
maxMarginRatio?: number | null;
|
|
1338
1338
|
builderIdx?: number | null;
|
|
1339
1339
|
builderFeeTenthBps?: number | null;
|
|
1340
|
+
isolatedPositionDeposit?: BN | null;
|
|
1340
1341
|
};
|
|
1341
1342
|
|
|
1342
1343
|
export type SignedMsgOrderParamsDelegateMessage = {
|
|
@@ -1349,6 +1350,7 @@ export type SignedMsgOrderParamsDelegateMessage = {
|
|
|
1349
1350
|
maxMarginRatio?: number | null;
|
|
1350
1351
|
builderIdx?: number | null;
|
|
1351
1352
|
builderFeeTenthBps?: number | null;
|
|
1353
|
+
isolatedPositionDeposit?: BN | null;
|
|
1352
1354
|
};
|
|
1353
1355
|
|
|
1354
1356
|
export type SignedMsgTriggerOrderParams = {
|