@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
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.145.0-beta.
|
|
1
|
+
2.145.0-beta.2
|
|
@@ -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);
|
|
@@ -3788,6 +3863,9 @@ class DriftClient {
|
|
|
3788
3863
|
if (orderParamsMessage.maxMarginRatio === undefined) {
|
|
3789
3864
|
orderParamsMessage.maxMarginRatio = null;
|
|
3790
3865
|
}
|
|
3866
|
+
if (orderParamsMessage.isolatedPositionDeposit === undefined) {
|
|
3867
|
+
orderParamsMessage.isolatedPositionDeposit = null;
|
|
3868
|
+
}
|
|
3791
3869
|
const anchorIxName = delegateSigner
|
|
3792
3870
|
? 'global' + ':' + 'SignedMsgOrderParamsDelegateMessage'
|
|
3793
3871
|
: 'global' + ':' + 'SignedMsgOrderParamsMessage';
|
|
@@ -3834,14 +3912,19 @@ class DriftClient {
|
|
|
3834
3912
|
return txSig;
|
|
3835
3913
|
}
|
|
3836
3914
|
async getPlaceSignedMsgTakerPerpOrderIxs(signedSignedMsgOrderParams, marketIndex, takerInfo, precedingIxs = [], overrideCustomIxIndex) {
|
|
3915
|
+
var _a;
|
|
3916
|
+
const isDelegateSigner = takerInfo.signingAuthority.equals(takerInfo.takerUserAccount.delegate);
|
|
3917
|
+
const borshBuf = Buffer.from(signedSignedMsgOrderParams.orderParams.toString(), 'hex');
|
|
3918
|
+
const signedMessage = this.decodeSignedMsgOrderParamsMessage(borshBuf, isDelegateSigner);
|
|
3919
|
+
const writableSpotMarketIndexes = ((_a = signedMessage.isolatedPositionDeposit) === null || _a === void 0 ? void 0 : _a.gt(numericConstants_1.ZERO))
|
|
3920
|
+
? [numericConstants_1.QUOTE_SPOT_MARKET_INDEX]
|
|
3921
|
+
: undefined;
|
|
3837
3922
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3838
3923
|
userAccounts: [takerInfo.takerUserAccount],
|
|
3839
3924
|
useMarketLastSlotCache: false,
|
|
3840
3925
|
readablePerpMarketIndex: marketIndex,
|
|
3926
|
+
writableSpotMarketIndexes,
|
|
3841
3927
|
});
|
|
3842
|
-
const isDelegateSigner = takerInfo.signingAuthority.equals(takerInfo.takerUserAccount.delegate);
|
|
3843
|
-
const borshBuf = Buffer.from(signedSignedMsgOrderParams.orderParams.toString(), 'hex');
|
|
3844
|
-
const signedMessage = this.decodeSignedMsgOrderParamsMessage(borshBuf, isDelegateSigner);
|
|
3845
3928
|
if ((0, orderParams_1.isUpdateHighLeverageMode)(signedMessage.signedMsgOrderParams.bitFlags)) {
|
|
3846
3929
|
remainingAccounts.push({
|
|
3847
3930
|
pubkey: (0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId),
|
|
@@ -10334,6 +10334,12 @@
|
|
|
10334
10334
|
"type": {
|
|
10335
10335
|
"option": "u16"
|
|
10336
10336
|
}
|
|
10337
|
+
},
|
|
10338
|
+
{
|
|
10339
|
+
"name": "isolatedPositionDeposit",
|
|
10340
|
+
"type": {
|
|
10341
|
+
"option": "u64"
|
|
10342
|
+
}
|
|
10337
10343
|
}
|
|
10338
10344
|
]
|
|
10339
10345
|
}
|
|
@@ -10399,6 +10405,12 @@
|
|
|
10399
10405
|
"type": {
|
|
10400
10406
|
"option": "u16"
|
|
10401
10407
|
}
|
|
10408
|
+
},
|
|
10409
|
+
{
|
|
10410
|
+
"name": "isolatedPositionDeposit",
|
|
10411
|
+
"type": {
|
|
10412
|
+
"option": "u64"
|
|
10413
|
+
}
|
|
10402
10414
|
}
|
|
10403
10415
|
]
|
|
10404
10416
|
}
|
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;
|
package/lib/browser/types.d.ts
CHANGED
|
@@ -1368,6 +1368,7 @@ export type SignedMsgOrderParamsMessage = {
|
|
|
1368
1368
|
maxMarginRatio?: number | null;
|
|
1369
1369
|
builderIdx?: number | null;
|
|
1370
1370
|
builderFeeTenthBps?: number | null;
|
|
1371
|
+
isolatedPositionDeposit?: BN | null;
|
|
1371
1372
|
};
|
|
1372
1373
|
export type SignedMsgOrderParamsDelegateMessage = {
|
|
1373
1374
|
signedMsgOrderParams: OrderParams;
|
|
@@ -1379,6 +1380,7 @@ export type SignedMsgOrderParamsDelegateMessage = {
|
|
|
1379
1380
|
maxMarginRatio?: number | null;
|
|
1380
1381
|
builderIdx?: number | null;
|
|
1381
1382
|
builderFeeTenthBps?: number | null;
|
|
1383
|
+
isolatedPositionDeposit?: BN | null;
|
|
1382
1384
|
};
|
|
1383
1385
|
export type SignedMsgTriggerOrderParams = {
|
|
1384
1386
|
triggerPrice: BN;
|
|
@@ -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>;
|