@drift-labs/sdk 2.30.0-beta.1 → 2.31.0-beta.0

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.
Files changed (46) hide show
  1. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
  2. package/lib/accounts/pollingTokenAccountSubscriber.js +5 -2
  3. package/lib/accounts/types.d.ts +3 -3
  4. package/lib/adminClient.d.ts +1 -0
  5. package/lib/adminClient.js +9 -0
  6. package/lib/constants/spotMarkets.js +10 -0
  7. package/lib/dlob/DLOB.d.ts +20 -1
  8. package/lib/dlob/DLOB.js +39 -0
  9. package/lib/driftClient.d.ts +13 -8
  10. package/lib/driftClient.js +32 -27
  11. package/lib/examples/makeTradeExample.js +1 -1
  12. package/lib/idl/drift.json +106 -15
  13. package/lib/jupiter/jupiterClient.d.ts +1 -1
  14. package/lib/jupiter/jupiterClient.js +7 -2
  15. package/lib/math/spotBalance.d.ts +41 -0
  16. package/lib/math/spotBalance.js +41 -0
  17. package/lib/token/index.d.ts +3 -2
  18. package/lib/token/index.js +9 -32
  19. package/lib/tokenFaucet.d.ts +3 -3
  20. package/lib/tokenFaucet.js +4 -9
  21. package/lib/tx/retryTxSender.js +3 -0
  22. package/lib/types.d.ts +22 -2
  23. package/lib/types.js +12 -1
  24. package/lib/wallet.d.ts +5 -3
  25. package/lib/wallet.js +19 -7
  26. package/package.json +2 -2
  27. package/src/accounts/pollingTokenAccountSubscriber.ts +8 -5
  28. package/src/accounts/types.ts +3 -3
  29. package/src/adminClient.ts +19 -0
  30. package/src/constants/spotMarkets.ts +11 -0
  31. package/src/dlob/DLOB.ts +75 -0
  32. package/src/driftClient.ts +57 -53
  33. package/src/examples/makeTradeExample.ts +2 -4
  34. package/src/idl/drift.json +106 -15
  35. package/src/jupiter/jupiterClient.ts +10 -2
  36. package/src/math/spotBalance.ts +41 -0
  37. package/src/token/index.ts +12 -36
  38. package/src/tokenFaucet.ts +15 -34
  39. package/src/tx/retryTxSender.ts +4 -0
  40. package/src/types.ts +23 -2
  41. package/src/wallet.ts +34 -12
  42. package/tests/dlob/helpers.ts +1 -0
  43. package/tests/dlob/test.ts +218 -40
  44. package/lib/util/getTokenAddress.d.ts +0 -2
  45. package/lib/util/getTokenAddress.js +0 -9
  46. package/src/util/getTokenAddress.ts +0 -18
package/lib/wallet.js CHANGED
@@ -15,12 +15,22 @@ class Wallet {
15
15
  tx.partialSign(this.payer);
16
16
  return tx;
17
17
  }
18
+ async signVersionedTransaction(tx) {
19
+ tx.sign([this.payer]);
20
+ return tx;
21
+ }
18
22
  async signAllTransactions(txs) {
19
23
  return txs.map((t) => {
20
24
  t.partialSign(this.payer);
21
25
  return t;
22
26
  });
23
27
  }
28
+ async signAllVersionedTransactions(txs) {
29
+ return txs.map((t) => {
30
+ t.sign([this.payer]);
31
+ return t;
32
+ });
33
+ }
24
34
  get publicKey() {
25
35
  return this.payer.publicKey;
26
36
  }
@@ -30,15 +40,17 @@ function loadKeypair(privateKey) {
30
40
  // try to load privateKey as a filepath
31
41
  let loadedKey;
32
42
  if (fs_1.default.existsSync(privateKey)) {
33
- loadedKey = new Uint8Array(JSON.parse(fs_1.default.readFileSync(privateKey).toString()));
43
+ privateKey = fs_1.default.readFileSync(privateKey).toString();
44
+ }
45
+ if (privateKey.includes('[') && privateKey.includes(']')) {
46
+ loadedKey = Uint8Array.from(JSON.parse(privateKey));
47
+ }
48
+ else if (privateKey.includes(',')) {
49
+ loadedKey = Uint8Array.from(privateKey.split(',').map((val) => Number(val)));
34
50
  }
35
51
  else {
36
- if (privateKey.includes(',')) {
37
- loadedKey = Uint8Array.from(privateKey.split(',').map((val) => Number(val)));
38
- }
39
- else {
40
- loadedKey = new Uint8Array(bs58_1.default.decode(privateKey));
41
- }
52
+ privateKey = privateKey.replace(/\s/g, '');
53
+ loadedKey = new Uint8Array(bs58_1.default.decode(privateKey));
42
54
  }
43
55
  return web3_js_1.Keypair.fromSecretKey(Uint8Array.from(loadedKey));
44
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.30.0-beta.1",
3
+ "version": "2.31.0-beta.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -37,7 +37,7 @@
37
37
  "@ellipsis-labs/phoenix-sdk": "^1.4.2",
38
38
  "@project-serum/serum": "^0.13.38",
39
39
  "@pythnetwork/client": "2.5.3",
40
- "@solana/spl-token": "^0.1.6",
40
+ "@solana/spl-token": "^0.3.7",
41
41
  "@solana/web3.js": "1.73.2",
42
42
  "strict-event-emitter-types": "^2.0.0",
43
43
  "uuid": "^8.3.2"
@@ -9,7 +9,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
9
9
  import { EventEmitter } from 'events';
10
10
  import { PublicKey } from '@solana/web3.js';
11
11
  import { BulkAccountLoader } from './bulkAccountLoader';
12
- import { AccountInfo } from '@solana/spl-token';
12
+ import { Account } from '@solana/spl-token';
13
13
  import { parseTokenAccount } from '../token';
14
14
 
15
15
  export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
@@ -22,7 +22,7 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
22
22
  callbackId?: string;
23
23
  errorCallbackId?: string;
24
24
 
25
- tokenAccountAndSlot?: DataAndSlot<AccountInfo>;
25
+ tokenAccountAndSlot?: DataAndSlot<Account>;
26
26
 
27
27
  public constructor(publicKey: PublicKey, accountLoader: BulkAccountLoader) {
28
28
  this.isSubscribed = false;
@@ -61,7 +61,7 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
61
61
  this.callbackId = await this.accountLoader.addAccount(
62
62
  this.publicKey,
63
63
  (buffer, slot: number) => {
64
- const tokenAccount = parseTokenAccount(buffer);
64
+ const tokenAccount = parseTokenAccount(buffer, this.publicKey);
65
65
  this.tokenAccountAndSlot = { data: tokenAccount, slot };
66
66
  // @ts-ignore
67
67
  this.eventEmitter.emit('tokenAccountUpdate', tokenAccount);
@@ -79,7 +79,10 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
79
79
  const { buffer, slot } = this.accountLoader.getBufferAndSlot(
80
80
  this.publicKey
81
81
  );
82
- this.tokenAccountAndSlot = { data: parseTokenAccount(buffer), slot };
82
+ this.tokenAccountAndSlot = {
83
+ data: parseTokenAccount(buffer, this.publicKey),
84
+ slot,
85
+ };
83
86
  }
84
87
 
85
88
  async unsubscribe(): Promise<void> {
@@ -104,7 +107,7 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
104
107
  }
105
108
  }
106
109
 
107
- public getTokenAccountAndSlot(): DataAndSlot<AccountInfo> {
110
+ public getTokenAccountAndSlot(): DataAndSlot<Account> {
108
111
  this.assertIsSubscribed();
109
112
  return this.tokenAccountAndSlot;
110
113
  }
@@ -9,7 +9,7 @@ import {
9
9
  import StrictEventEmitter from 'strict-event-emitter-types';
10
10
  import { EventEmitter } from 'events';
11
11
  import { PublicKey } from '@solana/web3.js';
12
- import { AccountInfo } from '@solana/spl-token';
12
+ import { Account } from '@solana/spl-token';
13
13
  import { OracleInfo, OraclePriceData } from '..';
14
14
 
15
15
  export interface AccountSubscriber<T> {
@@ -82,7 +82,7 @@ export interface UserAccountSubscriber {
82
82
  }
83
83
 
84
84
  export interface TokenAccountEvents {
85
- tokenAccountUpdate: (payload: AccountInfo) => void;
85
+ tokenAccountUpdate: (payload: Account) => void;
86
86
  update: void;
87
87
  error: (e: Error) => void;
88
88
  }
@@ -95,7 +95,7 @@ export interface TokenAccountSubscriber {
95
95
  fetch(): Promise<void>;
96
96
  unsubscribe(): Promise<void>;
97
97
 
98
- getTokenAccountAndSlot(): DataAndSlot<AccountInfo>;
98
+ getTokenAccountAndSlot(): DataAndSlot<Account>;
99
99
  }
100
100
 
101
101
  export interface OracleEvents {
@@ -544,6 +544,25 @@ export class AdminClient extends DriftClient {
544
544
  );
545
545
  }
546
546
 
547
+ public async updatePerpMarketTargetBaseAssetAmountPerLp(
548
+ perpMarketIndex: number,
549
+ targetBaseAssetAmountPerLP: number
550
+ ): Promise<TransactionSignature> {
551
+ return await this.program.rpc.updatePerpMarketTargetBaseAssetAmountPerLp(
552
+ targetBaseAssetAmountPerLP,
553
+ {
554
+ accounts: {
555
+ admin: this.wallet.publicKey,
556
+ state: await this.getStatePublicKey(),
557
+ perpMarket: await getPerpMarketPublicKey(
558
+ this.program.programId,
559
+ perpMarketIndex
560
+ ),
561
+ },
562
+ }
563
+ );
564
+ }
565
+
547
566
  public async updatePerpMarketMarginRatio(
548
567
  perpMarketIndex: number,
549
568
  marginRatioInitial: number,
@@ -6,6 +6,7 @@ import {
6
6
  LAMPORTS_EXP,
7
7
  LAMPORTS_PRECISION,
8
8
  SIX,
9
+ NINE,
9
10
  } from './numericConstants';
10
11
 
11
12
  export type SpotMarketConfig = {
@@ -82,6 +83,16 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
82
83
  '4DoNfFBfF7UokCC2FQzriy7yHK6DY6NVdYpuekQ5pRgg'
83
84
  ),
84
85
  },
86
+ {
87
+ symbol: 'mSOL',
88
+ marketIndex: 2,
89
+ oracle: new PublicKey('E4v1BBgoso9s64TQvmyownAVJbhbEPGyzA3qn4n46qj9'),
90
+ oracleSource: OracleSource.PYTH,
91
+ mint: new PublicKey('mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So'),
92
+ precision: new BN(10).pow(NINE),
93
+ precisionExp: NINE,
94
+ serumMarket: new PublicKey('9Lyhks5bQQxb9EyyX55NtgKQzpM4WK7JCmeaWuQ5MoXD'),
95
+ },
85
96
  ];
86
97
 
87
98
  export const SpotMarkets: { [key in DriftEnv]: SpotMarketConfig[] } = {
package/src/dlob/DLOB.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { getOrderSignature, getVammNodeGenerator, NodeList } from './NodeList';
2
2
  import {
3
+ BASE_PRECISION,
3
4
  BN,
4
5
  calculateAskPrice,
5
6
  calculateBidPrice,
@@ -24,12 +25,15 @@ import {
24
25
  OrderActionRecord,
25
26
  OrderRecord,
26
27
  PerpMarketAccount,
28
+ PositionDirection,
27
29
  PRICE_PRECISION,
30
+ QUOTE_PRECISION,
28
31
  SlotSubscriber,
29
32
  SpotMarketAccount,
30
33
  StateAccount,
31
34
  TriggerOrderNode,
32
35
  UserMap,
36
+ ZERO,
33
37
  } from '..';
34
38
  import { PublicKey } from '@solana/web3.js';
35
39
  import { ammPaused, exchangePaused, fillPaused } from '../math/exchangeStatus';
@@ -1849,4 +1853,75 @@ export class DLOB {
1849
1853
  asks,
1850
1854
  };
1851
1855
  }
1856
+
1857
+ private estimateFillExactBaseAmountInForSide(
1858
+ baseAmountIn: BN,
1859
+ oraclePriceData: OraclePriceData,
1860
+ slot: number,
1861
+ dlobSide: Generator<DLOBNode>
1862
+ ): BN {
1863
+ let runningSumQuote = ZERO;
1864
+ let runningSumBase = ZERO;
1865
+ for (const side of dlobSide) {
1866
+ const price = side.getPrice(oraclePriceData, slot); //side.order.quoteAssetAmount.div(side.order.baseAssetAmount);
1867
+ const baseAmountRemaining = side.order.baseAssetAmount.sub(
1868
+ side.order.baseAssetAmountFilled
1869
+ );
1870
+ if (runningSumBase.add(baseAmountRemaining).gt(baseAmountIn)) {
1871
+ const remainingBase = baseAmountIn.sub(runningSumBase);
1872
+ runningSumBase = runningSumBase.add(remainingBase);
1873
+ runningSumQuote = runningSumQuote.add(remainingBase.mul(price));
1874
+ break;
1875
+ } else {
1876
+ runningSumBase = runningSumBase.add(baseAmountRemaining);
1877
+ runningSumQuote = runningSumQuote.add(baseAmountRemaining.mul(price));
1878
+ }
1879
+ }
1880
+
1881
+ return runningSumQuote
1882
+ .mul(QUOTE_PRECISION)
1883
+ .div(BASE_PRECISION.mul(PRICE_PRECISION));
1884
+ }
1885
+
1886
+ /**
1887
+ *
1888
+ * @param param.marketIndex the index of the market
1889
+ * @param param.marketType the type of the market
1890
+ * @param param.baseAmount the base amount in to estimate
1891
+ * @param param.orderDirection the direction of the trade
1892
+ * @param param.slot current slot for estimating dlob node price
1893
+ * @param param.oraclePriceData the oracle price data
1894
+ * @returns the estimated quote amount filled: QUOTE_PRECISION
1895
+ */
1896
+ public estimateFillWithExactBaseAmount({
1897
+ marketIndex,
1898
+ marketType,
1899
+ baseAmount,
1900
+ orderDirection,
1901
+ slot,
1902
+ oraclePriceData,
1903
+ }: {
1904
+ marketIndex: number;
1905
+ marketType: MarketType;
1906
+ baseAmount: BN;
1907
+ orderDirection: PositionDirection;
1908
+ slot: number;
1909
+ oraclePriceData: OraclePriceData;
1910
+ }): BN {
1911
+ if (isVariant(orderDirection, 'long')) {
1912
+ return this.estimateFillExactBaseAmountInForSide(
1913
+ baseAmount,
1914
+ oraclePriceData,
1915
+ slot,
1916
+ this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData)
1917
+ );
1918
+ } else if (isVariant(orderDirection, 'short')) {
1919
+ return this.estimateFillExactBaseAmountInForSide(
1920
+ baseAmount,
1921
+ oraclePriceData,
1922
+ slot,
1923
+ this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData)
1924
+ );
1925
+ }
1926
+ }
1852
1927
  }
@@ -8,7 +8,10 @@ import {
8
8
  import bs58 from 'bs58';
9
9
  import {
10
10
  ASSOCIATED_TOKEN_PROGRAM_ID,
11
- Token,
11
+ createAssociatedTokenAccountInstruction,
12
+ createCloseAccountInstruction,
13
+ createInitializeAccountInstruction,
14
+ getAssociatedTokenAddress,
12
15
  TOKEN_PROGRAM_ID,
13
16
  } from '@solana/spl-token';
14
17
  import {
@@ -39,6 +42,7 @@ import {
39
42
  ModifyOrderParams,
40
43
  PhoenixV1FulfillmentConfigAccount,
41
44
  ModifyOrderPolicy,
45
+ SwapReduceOnly,
42
46
  } from './types';
43
47
  import * as anchor from '@coral-xyz/anchor';
44
48
  import driftIDL from './idl/drift.json';
@@ -113,7 +117,7 @@ import { isSpotPositionAvailable } from './math/spotPosition';
113
117
  import { calculateMarketMaxAvailableInsurance } from './math/market';
114
118
  import { fetchUserStatsAccount } from './accounts/fetch';
115
119
  import { castNumberToSpotPrecision } from './math/spotMarket';
116
- import { JupiterClient } from './jupiter/jupiterClient';
120
+ import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
117
121
 
118
122
  type RemainingAccountParams = {
119
123
  userAccounts: UserAccount[];
@@ -720,9 +724,7 @@ export class DriftClient {
720
724
 
721
725
  const state = this.getStateAccount();
722
726
  if (!state.whitelistMint.equals(PublicKey.default)) {
723
- const associatedTokenPublicKey = await Token.getAssociatedTokenAddress(
724
- ASSOCIATED_TOKEN_PROGRAM_ID,
725
- TOKEN_PROGRAM_ID,
727
+ const associatedTokenPublicKey = await getAssociatedTokenAddress(
726
728
  state.whitelistMint,
727
729
  this.wallet.publicKey
728
730
  );
@@ -1489,20 +1491,15 @@ export class DriftClient {
1489
1491
  return this.wallet.publicKey;
1490
1492
  }
1491
1493
  const mint = spotMarket.mint;
1492
- return await Token.getAssociatedTokenAddress(
1493
- ASSOCIATED_TOKEN_PROGRAM_ID,
1494
- TOKEN_PROGRAM_ID,
1495
- mint,
1496
- this.wallet.publicKey
1497
- );
1494
+ return await getAssociatedTokenAddress(mint, this.wallet.publicKey);
1498
1495
  }
1499
1496
 
1500
- public async createAssociatedTokenAccountIdempotentInstruction(
1497
+ public createAssociatedTokenAccountIdempotentInstruction(
1501
1498
  account: PublicKey,
1502
1499
  payer: PublicKey,
1503
1500
  owner: PublicKey,
1504
1501
  mint: PublicKey
1505
- ): Promise<TransactionInstruction> {
1502
+ ): TransactionInstruction {
1506
1503
  return new TransactionInstruction({
1507
1504
  keys: [
1508
1505
  { pubkey: payer, isSigner: true, isWritable: true },
@@ -1510,7 +1507,7 @@ export class DriftClient {
1510
1507
  { pubkey: owner, isSigner: false, isWritable: false },
1511
1508
  { pubkey: mint, isSigner: false, isWritable: false },
1512
1509
  {
1513
- pubkey: SystemProgram.programId,
1510
+ pubkey: anchor.web3.SystemProgram.programId,
1514
1511
  isSigner: false,
1515
1512
  isWritable: false,
1516
1513
  },
@@ -1582,8 +1579,7 @@ export class DriftClient {
1582
1579
  // Close the wrapped sol account at the end of the transaction
1583
1580
  if (createWSOLTokenAccount) {
1584
1581
  tx.add(
1585
- Token.createCloseAccountInstruction(
1586
- TOKEN_PROGRAM_ID,
1582
+ createCloseAccountInstruction(
1587
1583
  associatedTokenAccount,
1588
1584
  signerAuthority,
1589
1585
  signerAuthority,
@@ -1696,10 +1692,9 @@ export class DriftClient {
1696
1692
  );
1697
1693
 
1698
1694
  result.ixs.push(
1699
- Token.createInitAccountInstruction(
1700
- TOKEN_PROGRAM_ID,
1701
- WRAPPED_SOL_MINT,
1695
+ createInitializeAccountInstruction(
1702
1696
  wrappedSolAccount.publicKey,
1697
+ WRAPPED_SOL_MINT,
1703
1698
  authority
1704
1699
  )
1705
1700
  );
@@ -1713,17 +1708,12 @@ export class DriftClient {
1713
1708
  tokenMintAddress: PublicKey,
1714
1709
  associatedTokenAddress: PublicKey
1715
1710
  ): anchor.web3.TransactionInstruction {
1716
- const createAssociatedAccountIx =
1717
- Token.createAssociatedTokenAccountInstruction(
1718
- ASSOCIATED_TOKEN_PROGRAM_ID,
1719
- TOKEN_PROGRAM_ID,
1720
- tokenMintAddress,
1721
- associatedTokenAddress,
1722
- this.wallet.publicKey,
1723
- this.wallet.publicKey
1724
- );
1725
-
1726
- return createAssociatedAccountIx;
1711
+ return createAssociatedTokenAccountInstruction(
1712
+ this.wallet.publicKey,
1713
+ associatedTokenAddress,
1714
+ this.wallet.publicKey,
1715
+ tokenMintAddress
1716
+ );
1727
1717
  }
1728
1718
 
1729
1719
  /**
@@ -1825,8 +1815,7 @@ export class DriftClient {
1825
1815
  // Close the wrapped sol account at the end of the transaction
1826
1816
  if (createWSOLTokenAccount) {
1827
1817
  tx.add(
1828
- Token.createCloseAccountInstruction(
1829
- TOKEN_PROGRAM_ID,
1818
+ createCloseAccountInstruction(
1830
1819
  userTokenAccount,
1831
1820
  authority,
1832
1821
  authority,
@@ -1965,8 +1954,7 @@ export class DriftClient {
1965
1954
  // Close the wrapped sol account at the end of the transaction
1966
1955
  if (createWSOLTokenAccount) {
1967
1956
  tx.add(
1968
- Token.createCloseAccountInstruction(
1969
- TOKEN_PROGRAM_ID,
1957
+ createCloseAccountInstruction(
1970
1958
  associatedTokenAddress,
1971
1959
  authority,
1972
1960
  authority,
@@ -3300,6 +3288,7 @@ export class DriftClient {
3300
3288
  * @param inAssociatedTokenAccount the token account to
3301
3289
  * @param amount the amount of the token to sell
3302
3290
  * @param slippageBps the max slippage passed to jupiter api
3291
+ * @param route the jupiter route to use for the swap
3303
3292
  * @param txParams
3304
3293
  */
3305
3294
  public async swap({
@@ -3310,32 +3299,42 @@ export class DriftClient {
3310
3299
  inAssociatedTokenAccount,
3311
3300
  amount,
3312
3301
  slippageBps,
3302
+ swapMode,
3303
+ route,
3304
+ reduceOnly,
3313
3305
  txParams,
3314
3306
  }: {
3315
3307
  jupiterClient: JupiterClient;
3316
3308
  outMarketIndex: number;
3317
3309
  inMarketIndex: number;
3318
- outAssociatedTokenAccount: PublicKey;
3319
- inAssociatedTokenAccount: PublicKey;
3310
+ outAssociatedTokenAccount?: PublicKey;
3311
+ inAssociatedTokenAccount?: PublicKey;
3320
3312
  amount: BN;
3321
- slippageBps: number;
3313
+ slippageBps?: number;
3314
+ swapMode?: SwapMode;
3315
+ route?: Route;
3316
+ reduceOnly?: SwapReduceOnly;
3322
3317
  txParams?: TxParams;
3323
3318
  }): Promise<TransactionSignature> {
3324
3319
  const outMarket = this.getSpotMarketAccount(outMarketIndex);
3325
3320
  const inMarket = this.getSpotMarketAccount(inMarketIndex);
3326
3321
 
3327
- const routes = await jupiterClient.getRoutes({
3328
- inputMint: inMarket.mint,
3329
- outputMint: outMarket.mint,
3330
- amount,
3331
- slippageBps,
3332
- });
3322
+ if (!route) {
3323
+ const routes = await jupiterClient.getRoutes({
3324
+ inputMint: inMarket.mint,
3325
+ outputMint: outMarket.mint,
3326
+ amount,
3327
+ slippageBps,
3328
+ swapMode,
3329
+ });
3330
+
3331
+ if (!routes || routes.length === 0) {
3332
+ throw new Error('No jupiter routes found');
3333
+ }
3333
3334
 
3334
- if (!routes || routes.length === 0) {
3335
- throw new Error('No jupiter routes found');
3335
+ route = routes[0];
3336
3336
  }
3337
3337
 
3338
- const route = routes[0];
3339
3338
  const transaction = await jupiterClient.getSwapTransaction({
3340
3339
  route,
3341
3340
  userPublicKey: this.provider.wallet.publicKey,
@@ -3356,7 +3355,8 @@ export class DriftClient {
3356
3355
  const preInstructions = [];
3357
3356
  if (!outAssociatedTokenAccount) {
3358
3357
  outAssociatedTokenAccount = await this.getAssociatedTokenAccount(
3359
- outMarket.marketIndex
3358
+ outMarket.marketIndex,
3359
+ false
3360
3360
  );
3361
3361
 
3362
3362
  const accountInfo = await this.connection.getAccountInfo(
@@ -3376,7 +3376,8 @@ export class DriftClient {
3376
3376
 
3377
3377
  if (!inAssociatedTokenAccount) {
3378
3378
  inAssociatedTokenAccount = await this.getAssociatedTokenAccount(
3379
- inMarket.marketIndex
3379
+ inMarket.marketIndex,
3380
+ false
3380
3381
  );
3381
3382
 
3382
3383
  const accountInfo = await this.connection.getAccountInfo(
@@ -3400,6 +3401,7 @@ export class DriftClient {
3400
3401
  amountIn: amount,
3401
3402
  inTokenAccount: inAssociatedTokenAccount,
3402
3403
  outTokenAccount: outAssociatedTokenAccount,
3404
+ reduceOnly,
3403
3405
  });
3404
3406
 
3405
3407
  const instructions = [
@@ -3440,6 +3442,7 @@ export class DriftClient {
3440
3442
  inTokenAccount,
3441
3443
  outTokenAccount,
3442
3444
  limitPrice,
3445
+ reduceOnly,
3443
3446
  }: {
3444
3447
  outMarketIndex: number;
3445
3448
  inMarketIndex: number;
@@ -3447,6 +3450,7 @@ export class DriftClient {
3447
3450
  inTokenAccount: PublicKey;
3448
3451
  outTokenAccount: PublicKey;
3449
3452
  limitPrice?: BN;
3453
+ reduceOnly?: SwapReduceOnly;
3450
3454
  }): Promise<{
3451
3455
  beginSwapIx: TransactionInstruction;
3452
3456
  endSwapIx: TransactionInstruction;
@@ -3487,6 +3491,7 @@ export class DriftClient {
3487
3491
  inMarketIndex,
3488
3492
  outMarketIndex,
3489
3493
  limitPrice ?? null,
3494
+ reduceOnly ?? null,
3490
3495
  {
3491
3496
  accounts: {
3492
3497
  state: await this.getStatePublicKey(),
@@ -5011,8 +5016,7 @@ export class DriftClient {
5011
5016
 
5012
5017
  if (createWSOLTokenAccount) {
5013
5018
  tx.add(
5014
- Token.createCloseAccountInstruction(
5015
- TOKEN_PROGRAM_ID,
5019
+ createCloseAccountInstruction(
5016
5020
  tokenAccount,
5017
5021
  this.wallet.publicKey,
5018
5022
  this.wallet.publicKey,
@@ -5162,8 +5166,7 @@ export class DriftClient {
5162
5166
  // Close the wrapped sol account at the end of the transaction
5163
5167
  if (createWSOLTokenAccount) {
5164
5168
  tx.add(
5165
- Token.createCloseAccountInstruction(
5166
- TOKEN_PROGRAM_ID,
5169
+ createCloseAccountInstruction(
5167
5170
  tokenAccount,
5168
5171
  this.wallet.publicKey,
5169
5172
  this.wallet.publicKey,
@@ -5364,7 +5367,8 @@ export class DriftClient {
5364
5367
  allIx.push(instructions);
5365
5368
  }
5366
5369
 
5367
- if (this.txVersion === 'legacy') {
5370
+ txVersion = txVersion ?? this.txVersion;
5371
+ if (txVersion === 'legacy') {
5368
5372
  return new Transaction().add(...allIx);
5369
5373
  } else {
5370
5374
  const marketLookupTable = await this.fetchMarketLookupTableAccount();
@@ -5,7 +5,7 @@ import {
5
5
  getMarketOrderParams,
6
6
  Wallet,
7
7
  } from '..';
8
- import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
8
+ import { getAssociatedTokenAddress } from '@solana/spl-token';
9
9
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
10
10
  import {
11
11
  DriftClient,
@@ -25,9 +25,7 @@ export const getTokenAddress = (
25
25
  mintAddress: string,
26
26
  userPubKey: string
27
27
  ): Promise<PublicKey> => {
28
- return Token.getAssociatedTokenAddress(
29
- new PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`),
30
- TOKEN_PROGRAM_ID,
28
+ return getAssociatedTokenAddress(
31
29
  new PublicKey(mintAddress),
32
30
  new PublicKey(userPubKey)
33
31
  );