@drift-labs/sdk 2.152.0-beta.2 → 2.153.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/build-browser.js +58 -0
- package/bun.lock +182 -1
- package/esbuild-shims.js +12 -0
- package/lib/browser/constants/perpMarkets.js +12 -0
- package/lib/browser/driftClient.d.ts +7 -0
- package/lib/browser/driftClient.js +96 -0
- package/lib/browser/idl/drift.json +207 -18
- package/lib/browser/swap/UnifiedSwapClient.js +2 -0
- package/lib/browser/titan/titanClient.d.ts +3 -0
- package/lib/browser/titan/titanClient.js +58 -60
- package/lib/browser/user.d.ts +1 -1
- package/lib/node/constants/perpMarkets.d.ts.map +1 -1
- package/lib/node/constants/perpMarkets.js +12 -0
- package/lib/node/driftClient.d.ts +7 -0
- package/lib/node/driftClient.d.ts.map +1 -1
- package/lib/node/driftClient.js +96 -0
- package/lib/node/idl/drift.json +207 -18
- package/lib/node/swap/UnifiedSwapClient.d.ts.map +1 -1
- package/lib/node/swap/UnifiedSwapClient.js +2 -0
- package/lib/node/titan/titanClient.d.ts +3 -0
- package/lib/node/titan/titanClient.d.ts.map +1 -1
- package/lib/node/titan/titanClient.js +58 -60
- package/lib/node/user.d.ts +1 -1
- package/lib/node/user.d.ts.map +1 -1
- package/package.json +10 -2
- package/src/constants/perpMarkets.ts +13 -0
- package/src/driftClient.ts +213 -0
- package/src/idl/drift.json +207 -18
- package/src/swap/UnifiedSwapClient.ts +2 -0
- package/src/titan/titanClient.ts +88 -72
- package/src/user.ts +1 -1
package/src/titan/titanClient.ts
CHANGED
|
@@ -94,6 +94,8 @@ export class TitanClient {
|
|
|
94
94
|
url: string;
|
|
95
95
|
connection: Connection;
|
|
96
96
|
proxyUrl?: string;
|
|
97
|
+
private lastQuoteData?: SwapQuotes;
|
|
98
|
+
private lastQuoteParams?: string;
|
|
97
99
|
|
|
98
100
|
constructor({
|
|
99
101
|
connection,
|
|
@@ -112,15 +114,12 @@ export class TitanClient {
|
|
|
112
114
|
this.proxyUrl = proxyUrl;
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
* Get routes for a swap
|
|
117
|
-
*/
|
|
118
|
-
public async getQuote({
|
|
117
|
+
private buildParams({
|
|
119
118
|
inputMint,
|
|
120
119
|
outputMint,
|
|
121
120
|
amount,
|
|
122
121
|
userPublicKey,
|
|
123
|
-
maxAccounts
|
|
122
|
+
maxAccounts,
|
|
124
123
|
slippageBps,
|
|
125
124
|
swapMode,
|
|
126
125
|
onlyDirectRoutes,
|
|
@@ -134,32 +133,78 @@ export class TitanClient {
|
|
|
134
133
|
userPublicKey: PublicKey;
|
|
135
134
|
maxAccounts?: number;
|
|
136
135
|
slippageBps?: number;
|
|
137
|
-
swapMode?: string;
|
|
136
|
+
swapMode?: string | SwapMode;
|
|
138
137
|
onlyDirectRoutes?: boolean;
|
|
139
138
|
excludeDexes?: string[];
|
|
140
139
|
sizeConstraint?: number;
|
|
141
140
|
accountsLimitWritable?: number;
|
|
142
|
-
}):
|
|
143
|
-
|
|
141
|
+
}): URLSearchParams {
|
|
142
|
+
// Normalize swapMode to enum value
|
|
143
|
+
const normalizedSwapMode =
|
|
144
|
+
swapMode === 'ExactOut' || swapMode === SwapMode.ExactOut
|
|
145
|
+
? SwapMode.ExactOut
|
|
146
|
+
: SwapMode.ExactIn;
|
|
147
|
+
|
|
148
|
+
return new URLSearchParams({
|
|
144
149
|
inputMint: inputMint.toString(),
|
|
145
150
|
outputMint: outputMint.toString(),
|
|
146
151
|
amount: amount.toString(),
|
|
147
152
|
userPublicKey: userPublicKey.toString(),
|
|
148
153
|
...(slippageBps && { slippageBps: slippageBps.toString() }),
|
|
149
|
-
...(swapMode && {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}),
|
|
154
|
+
...(swapMode && { swapMode: normalizedSwapMode.toString() }),
|
|
155
|
+
...(maxAccounts && { accountsLimitTotal: maxAccounts.toString() }),
|
|
156
|
+
...(excludeDexes && { excludeDexes: excludeDexes.join(',') }),
|
|
153
157
|
...(onlyDirectRoutes && {
|
|
154
158
|
onlyDirectRoutes: onlyDirectRoutes.toString(),
|
|
155
159
|
}),
|
|
156
|
-
...(maxAccounts && { accountsLimitTotal: maxAccounts.toString() }),
|
|
157
|
-
...(excludeDexes && { excludeDexes: excludeDexes.join(',') }),
|
|
158
160
|
...(sizeConstraint && { sizeConstraint: sizeConstraint.toString() }),
|
|
159
161
|
...(accountsLimitWritable && {
|
|
160
162
|
accountsLimitWritable: accountsLimitWritable.toString(),
|
|
161
163
|
}),
|
|
162
164
|
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get routes for a swap
|
|
169
|
+
*/
|
|
170
|
+
public async getQuote({
|
|
171
|
+
inputMint,
|
|
172
|
+
outputMint,
|
|
173
|
+
amount,
|
|
174
|
+
userPublicKey,
|
|
175
|
+
maxAccounts = 50, // 50 is an estimated amount with buffer
|
|
176
|
+
slippageBps,
|
|
177
|
+
swapMode,
|
|
178
|
+
onlyDirectRoutes,
|
|
179
|
+
excludeDexes,
|
|
180
|
+
sizeConstraint,
|
|
181
|
+
accountsLimitWritable,
|
|
182
|
+
}: {
|
|
183
|
+
inputMint: PublicKey;
|
|
184
|
+
outputMint: PublicKey;
|
|
185
|
+
amount: BN;
|
|
186
|
+
userPublicKey: PublicKey;
|
|
187
|
+
maxAccounts?: number;
|
|
188
|
+
slippageBps?: number;
|
|
189
|
+
swapMode?: string;
|
|
190
|
+
onlyDirectRoutes?: boolean;
|
|
191
|
+
excludeDexes?: string[];
|
|
192
|
+
sizeConstraint?: number;
|
|
193
|
+
accountsLimitWritable?: number;
|
|
194
|
+
}): Promise<QuoteResponse> {
|
|
195
|
+
const params = this.buildParams({
|
|
196
|
+
inputMint,
|
|
197
|
+
outputMint,
|
|
198
|
+
amount,
|
|
199
|
+
userPublicKey,
|
|
200
|
+
maxAccounts,
|
|
201
|
+
slippageBps,
|
|
202
|
+
swapMode,
|
|
203
|
+
onlyDirectRoutes,
|
|
204
|
+
excludeDexes,
|
|
205
|
+
sizeConstraint,
|
|
206
|
+
accountsLimitWritable,
|
|
207
|
+
});
|
|
163
208
|
|
|
164
209
|
let response: Response;
|
|
165
210
|
|
|
@@ -195,11 +240,12 @@ export class TitanClient {
|
|
|
195
240
|
const buffer = await response.arrayBuffer();
|
|
196
241
|
const data = decode(buffer) as SwapQuotes;
|
|
197
242
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
243
|
+
// Cache the quote data and parameters for later use in getSwap
|
|
244
|
+
this.lastQuoteData = data;
|
|
245
|
+
this.lastQuoteParams = params.toString();
|
|
246
|
+
|
|
247
|
+
// We are only querying for the best avaiable route so use that
|
|
248
|
+
const route = data.quotes[Object.keys(data.quotes)[0]];
|
|
203
249
|
|
|
204
250
|
if (!route) {
|
|
205
251
|
throw new Error('No routes available');
|
|
@@ -268,66 +314,32 @@ export class TitanClient {
|
|
|
268
314
|
transactionMessage: TransactionMessage;
|
|
269
315
|
lookupTables: AddressLookupTableAccount[];
|
|
270
316
|
}> {
|
|
271
|
-
const params =
|
|
272
|
-
inputMint
|
|
273
|
-
outputMint
|
|
274
|
-
amount
|
|
275
|
-
userPublicKey
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
...(sizeConstraint && { sizeConstraint: sizeConstraint.toString() }),
|
|
284
|
-
...(accountsLimitWritable && {
|
|
285
|
-
accountsLimitWritable: accountsLimitWritable.toString(),
|
|
286
|
-
}),
|
|
317
|
+
const params = this.buildParams({
|
|
318
|
+
inputMint,
|
|
319
|
+
outputMint,
|
|
320
|
+
amount,
|
|
321
|
+
userPublicKey,
|
|
322
|
+
maxAccounts,
|
|
323
|
+
slippageBps,
|
|
324
|
+
swapMode,
|
|
325
|
+
onlyDirectRoutes,
|
|
326
|
+
excludeDexes,
|
|
327
|
+
sizeConstraint,
|
|
328
|
+
accountsLimitWritable,
|
|
287
329
|
});
|
|
288
330
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (this.proxyUrl) {
|
|
292
|
-
// Use proxy route - send parameters in request body
|
|
293
|
-
response = await fetch(this.proxyUrl, {
|
|
294
|
-
method: 'POST',
|
|
295
|
-
headers: {
|
|
296
|
-
'Content-Type': 'application/json',
|
|
297
|
-
},
|
|
298
|
-
body: JSON.stringify(Object.fromEntries(params.entries())),
|
|
299
|
-
});
|
|
300
|
-
} else {
|
|
301
|
-
// Direct request to Titan API
|
|
302
|
-
response = await fetch(
|
|
303
|
-
`${this.url}/api/v1/quote/swap?${params.toString()}`,
|
|
304
|
-
{
|
|
305
|
-
headers: {
|
|
306
|
-
Accept: 'application/vnd.msgpack',
|
|
307
|
-
'Accept-Encoding': 'gzip, deflate, br',
|
|
308
|
-
Authorization: `Bearer ${this.authToken}`,
|
|
309
|
-
},
|
|
310
|
-
}
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (!response.ok) {
|
|
315
|
-
if (response.status === 404) {
|
|
316
|
-
throw new Error('No routes available');
|
|
317
|
-
}
|
|
331
|
+
// Check if we have cached quote data that matches the current parameters
|
|
332
|
+
if (!this.lastQuoteData || this.lastQuoteParams !== params.toString()) {
|
|
318
333
|
throw new Error(
|
|
319
|
-
|
|
334
|
+
'No matching quote data found. Please get a fresh quote before attempting to swap.'
|
|
320
335
|
);
|
|
321
336
|
}
|
|
322
337
|
|
|
323
|
-
|
|
324
|
-
const data =
|
|
338
|
+
// Reuse the cached quote data
|
|
339
|
+
const data = this.lastQuoteData;
|
|
325
340
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
Object.keys(data.quotes).find((key) => key.toLowerCase() === 'titan') ||
|
|
329
|
-
''
|
|
330
|
-
];
|
|
341
|
+
// We are only querying for the best avaiable route so use that
|
|
342
|
+
const route = data.quotes[Object.keys(data.quotes)[0]];
|
|
331
343
|
|
|
332
344
|
if (!route) {
|
|
333
345
|
throw new Error('No routes available');
|
|
@@ -342,6 +354,10 @@ export class TitanClient {
|
|
|
342
354
|
throw new Error(
|
|
343
355
|
'Something went wrong with creating the Titan swap transaction. Please try again.'
|
|
344
356
|
);
|
|
357
|
+
} finally {
|
|
358
|
+
// Clear cached quote data after use
|
|
359
|
+
this.lastQuoteData = undefined;
|
|
360
|
+
this.lastQuoteParams = undefined;
|
|
345
361
|
}
|
|
346
362
|
}
|
|
347
363
|
throw new Error('No instructions provided in the route');
|
package/src/user.ts
CHANGED
|
@@ -4587,7 +4587,7 @@ export class User {
|
|
|
4587
4587
|
return calc;
|
|
4588
4588
|
}
|
|
4589
4589
|
|
|
4590
|
-
|
|
4590
|
+
public isPerpPositionIsolated(perpPosition: PerpPosition): boolean {
|
|
4591
4591
|
return (perpPosition.positionFlag & PositionFlag.IsolatedPosition) !== 0;
|
|
4592
4592
|
}
|
|
4593
4593
|
}
|