@drift-labs/sdk 2.31.1-beta.1 → 2.31.1-beta.11

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 (42) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/mockUserAccountSubscriber.d.ts +23 -0
  3. package/lib/accounts/mockUserAccountSubscriber.js +31 -0
  4. package/lib/constants/perpMarkets.js +20 -0
  5. package/lib/driftClient.d.ts +12 -1
  6. package/lib/driftClient.js +92 -21
  7. package/lib/driftClientConfig.d.ts +4 -9
  8. package/lib/idl/drift.json +1 -1
  9. package/lib/index.d.ts +1 -0
  10. package/lib/index.js +1 -0
  11. package/lib/marinade/index.d.ts +11 -0
  12. package/lib/marinade/index.js +36 -0
  13. package/lib/marinade/types.d.ts +1963 -0
  14. package/lib/marinade/types.js +1965 -0
  15. package/lib/math/tiers.d.ts +4 -0
  16. package/lib/math/tiers.js +52 -0
  17. package/lib/tx/retryTxSender.d.ts +14 -3
  18. package/lib/tx/retryTxSender.js +27 -22
  19. package/lib/tx/types.d.ts +3 -2
  20. package/lib/user.d.ts +10 -1
  21. package/lib/user.js +39 -8
  22. package/lib/userConfig.d.ts +4 -0
  23. package/lib/userStats.js +4 -1
  24. package/lib/userStatsConfig.d.ts +2 -0
  25. package/package.json +1 -1
  26. package/src/accounts/mockUserAccountSubscriber.ts +53 -0
  27. package/src/config.ts +2 -2
  28. package/src/constants/perpMarkets.ts +20 -0
  29. package/src/driftClient.ts +134 -21
  30. package/src/driftClientConfig.ts +4 -9
  31. package/src/idl/drift.json +1 -1
  32. package/src/index.ts +1 -0
  33. package/src/marinade/idl/idl.json +1962 -0
  34. package/src/marinade/index.ts +64 -0
  35. package/src/marinade/types.ts +3925 -0
  36. package/src/math/tiers.ts +44 -0
  37. package/src/tx/retryTxSender.ts +46 -36
  38. package/src/tx/types.ts +4 -2
  39. package/src/user.ts +63 -12
  40. package/src/userConfig.ts +5 -0
  41. package/src/userStats.ts +4 -0
  42. package/src/userStatsConfig.ts +3 -0
@@ -95,6 +95,7 @@ import {
95
95
  PRICE_PRECISION,
96
96
  QUOTE_SPOT_MARKET_INDEX,
97
97
  ZERO,
98
+ QUOTE_PRECISION,
98
99
  } from './constants/numericConstants';
99
100
  import { findDirectionToClose, positionIsAvailable } from './math/position';
100
101
  import { getSignedTokenAmount, getTokenAmount } from './math/spotBalance';
@@ -115,6 +116,8 @@ import { fetchUserStatsAccount } from './accounts/fetch';
115
116
  import { castNumberToSpotPrecision } from './math/spotMarket';
116
117
  import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
117
118
  import { getNonIdleUserFilter } from './memcmp';
119
+ import { UserStatsSubscriptionConfig } from './userStatsConfig';
120
+ import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
118
121
 
119
122
  type RemainingAccountParams = {
120
123
  userAccounts: UserAccount[];
@@ -139,6 +142,7 @@ export class DriftClient {
139
142
  userStats?: UserStats;
140
143
  activeSubAccountId: number;
141
144
  userAccountSubscriptionConfig: UserSubscriptionConfig;
145
+ userStatsAccountSubscriptionConfig: UserStatsSubscriptionConfig;
142
146
  accountSubscriber: DriftClientAccountSubscriber;
143
147
  eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
144
148
  _isSubscribed = false;
@@ -152,6 +156,7 @@ export class DriftClient {
152
156
  authoritySubAccountMap?: Map<string, number[]>;
153
157
  skipLoadUsers?: boolean;
154
158
  txVersion: TransactionVersion;
159
+ txParams: TxParams;
155
160
 
156
161
  public get isSubscribed() {
157
162
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
@@ -180,6 +185,10 @@ export class DriftClient {
180
185
  this.activeSubAccountId = config.activeSubAccountId ?? 0;
181
186
  this.skipLoadUsers = config.skipLoadUsers ?? false;
182
187
  this.txVersion = config.txVersion ?? 'legacy';
188
+ this.txParams = {
189
+ computeUnits: config.txParams?.computeUnits ?? 600_000,
190
+ computeUnitsPrice: config.txParams?.computeUnitsPrice ?? 0,
191
+ };
183
192
 
184
193
  if (config.includeDelegates && config.subAccountIds) {
185
194
  throw new Error(
@@ -206,15 +215,23 @@ export class DriftClient {
206
215
  : new Map<string, number[]>();
207
216
 
208
217
  this.includeDelegates = config.includeDelegates ?? false;
209
- this.userAccountSubscriptionConfig =
210
- config.accountSubscription?.type === 'polling'
211
- ? {
212
- type: 'polling',
213
- accountLoader: config.accountSubscription.accountLoader,
214
- }
215
- : {
216
- type: 'websocket',
217
- };
218
+ if (config.accountSubscription?.type === 'polling') {
219
+ this.userAccountSubscriptionConfig = {
220
+ type: 'polling',
221
+ accountLoader: config.accountSubscription.accountLoader,
222
+ };
223
+ this.userStatsAccountSubscriptionConfig = {
224
+ type: 'polling',
225
+ accountLoader: config.accountSubscription.accountLoader,
226
+ };
227
+ } else {
228
+ this.userAccountSubscriptionConfig = {
229
+ type: 'websocket',
230
+ };
231
+ this.userStatsAccountSubscriptionConfig = {
232
+ type: 'websocket',
233
+ };
234
+ }
218
235
 
219
236
  if (config.userStats) {
220
237
  this.userStats = new UserStats({
@@ -257,12 +274,13 @@ export class DriftClient {
257
274
  );
258
275
  }
259
276
  this.eventEmitter = this.accountSubscriber.eventEmitter;
260
- this.txSender = new RetryTxSender(
261
- this.provider,
262
- config.txSenderConfig?.timeout,
263
- config.txSenderConfig?.retrySleep,
264
- config.txSenderConfig?.additionalConnections
265
- );
277
+ this.txSender =
278
+ config.txSender ??
279
+ new RetryTxSender({
280
+ connection: this.connection,
281
+ wallet: this.wallet,
282
+ opts: this.opts,
283
+ });
266
284
  }
267
285
 
268
286
  public getUserMapKey(subAccountId: number, authority: PublicKey): string {
@@ -503,7 +521,7 @@ export class DriftClient {
503
521
 
504
522
  this.skipLoadUsers = false;
505
523
  // Update provider for txSender with new wallet details
506
- this.txSender.provider = newProvider;
524
+ this.txSender.wallet = newWallet;
507
525
  this.wallet = newWallet;
508
526
  this.provider = newProvider;
509
527
  this.program = newProgram;
@@ -547,7 +565,7 @@ export class DriftClient {
547
565
  this.userStats = new UserStats({
548
566
  driftClient: this,
549
567
  userStatsAccountPublicKey: this.getUserStatsAccountPublicKey(),
550
- accountSubscription: this.userAccountSubscriptionConfig,
568
+ accountSubscription: this.userStatsAccountSubscriptionConfig,
551
569
  });
552
570
 
553
571
  await this.userStats.subscribe();
@@ -1033,11 +1051,19 @@ export class DriftClient {
1033
1051
  const userMapKey = this.getUserMapKey(subAccountId, authority);
1034
1052
 
1035
1053
  if (!this.users.has(userMapKey)) {
1036
- throw new Error(`Clearing House has no user for user id ${userMapKey}`);
1054
+ throw new Error(`DriftClient has no user for user id ${userMapKey}`);
1037
1055
  }
1038
1056
  return this.users.get(userMapKey);
1039
1057
  }
1040
1058
 
1059
+ public hasUser(subAccountId?: number, authority?: PublicKey): boolean {
1060
+ subAccountId = subAccountId ?? this.activeSubAccountId;
1061
+ authority = authority ?? this.authority;
1062
+ const userMapKey = this.getUserMapKey(subAccountId, authority);
1063
+
1064
+ return this.users.has(userMapKey);
1065
+ }
1066
+
1041
1067
  public getUsers(): User[] {
1042
1068
  // delegate users get added to the end
1043
1069
  return [...this.users.values()]
@@ -1695,7 +1721,7 @@ export class DriftClient {
1695
1721
  }
1696
1722
 
1697
1723
  /**
1698
- * Creates the Clearing House User account for a user, and deposits some initial collateral
1724
+ * Creates the User account for a user, and deposits some initial collateral
1699
1725
  * @param amount
1700
1726
  * @param userTokenAccount
1701
1727
  * @param marketIndex
@@ -2296,6 +2322,35 @@ export class DriftClient {
2296
2322
  });
2297
2323
  }
2298
2324
 
2325
+ public getQuoteValuePerLpShare(marketIndex: number): BN {
2326
+ const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
2327
+
2328
+ const openBids = BN.max(
2329
+ perpMarketAccount.amm.baseAssetReserve.sub(
2330
+ perpMarketAccount.amm.minBaseAssetReserve
2331
+ ),
2332
+ ZERO
2333
+ );
2334
+
2335
+ const openAsks = BN.max(
2336
+ perpMarketAccount.amm.maxBaseAssetReserve.sub(
2337
+ perpMarketAccount.amm.baseAssetReserve
2338
+ ),
2339
+ ZERO
2340
+ );
2341
+
2342
+ const oraclePriceData = this.getOracleDataForPerpMarket(marketIndex);
2343
+
2344
+ const maxOpenBidsAsks = BN.max(openBids, openAsks);
2345
+ const quoteValuePerLpShare = maxOpenBidsAsks
2346
+ .mul(oraclePriceData.price)
2347
+ .mul(QUOTE_PRECISION)
2348
+ .div(PRICE_PRECISION)
2349
+ .div(perpMarketAccount.amm.sqrtK);
2350
+
2351
+ return quoteValuePerLpShare;
2352
+ }
2353
+
2299
2354
  /**
2300
2355
  * @deprecated use {@link placePerpOrder} or {@link placeAndTakePerpOrder} instead
2301
2356
  */
@@ -3486,6 +3541,63 @@ export class DriftClient {
3486
3541
  return { beginSwapIx, endSwapIx };
3487
3542
  }
3488
3543
 
3544
+ public async stakeForMSOL({ amount }: { amount: BN }): Promise<TxSigAndSlot> {
3545
+ const ixs = await this.getStakeForMSOLIx({ amount });
3546
+ const tx = await this.buildTransaction(ixs);
3547
+ return this.sendTransaction(tx);
3548
+ }
3549
+
3550
+ public async getStakeForMSOLIx({
3551
+ amount,
3552
+ }: {
3553
+ amount: BN;
3554
+ }): Promise<TransactionInstruction[]> {
3555
+ const wSOLMint = this.getSpotMarketAccount(1).mint;
3556
+ const mSOLAccount = await this.getAssociatedTokenAccount(2);
3557
+ const wSOLAccount = await this.getAssociatedTokenAccount(1, false);
3558
+
3559
+ const wSOLAccountExists = await this.checkIfAccountExists(wSOLAccount);
3560
+
3561
+ const closeWSOLIx = createCloseAccountInstruction(
3562
+ wSOLAccount,
3563
+ this.wallet.publicKey,
3564
+ this.wallet.publicKey
3565
+ );
3566
+
3567
+ const createWSOLIx =
3568
+ await this.createAssociatedTokenAccountIdempotentInstruction(
3569
+ wSOLAccount,
3570
+ this.wallet.publicKey,
3571
+ this.wallet.publicKey,
3572
+ wSOLMint
3573
+ );
3574
+
3575
+ const { beginSwapIx, endSwapIx } = await this.getSwapIx({
3576
+ inMarketIndex: 1,
3577
+ outMarketIndex: 2,
3578
+ amountIn: amount,
3579
+ inTokenAccount: wSOLAccount,
3580
+ outTokenAccount: mSOLAccount,
3581
+ });
3582
+
3583
+ const program = getMarinadeFinanceProgram(this.provider);
3584
+ const depositIx = await getMarinadeDepositIx({
3585
+ program,
3586
+ mSOLAccount: mSOLAccount,
3587
+ transferFrom: this.wallet.publicKey,
3588
+ amount,
3589
+ });
3590
+
3591
+ const ixs = [];
3592
+
3593
+ if (!wSOLAccountExists) {
3594
+ ixs.push(createWSOLIx);
3595
+ }
3596
+ ixs.push(beginSwapIx, closeWSOLIx, depositIx, createWSOLIx, endSwapIx);
3597
+
3598
+ return ixs;
3599
+ }
3600
+
3489
3601
  public async triggerOrder(
3490
3602
  userAccountPublicKey: PublicKey,
3491
3603
  user: UserAccount,
@@ -5366,7 +5478,7 @@ export class DriftClient {
5366
5478
  lookupTables?: AddressLookupTableAccount[]
5367
5479
  ): Promise<Transaction | VersionedTransaction> {
5368
5480
  const allIx = [];
5369
- const computeUnits = txParams?.computeUnits ?? 600_000;
5481
+ const computeUnits = txParams?.computeUnits ?? this.txParams.computeUnits;
5370
5482
  if (computeUnits !== 200_000) {
5371
5483
  allIx.push(
5372
5484
  ComputeBudgetProgram.setComputeUnitLimit({
@@ -5374,7 +5486,8 @@ export class DriftClient {
5374
5486
  })
5375
5487
  );
5376
5488
  }
5377
- const computeUnitsPrice = txParams?.computeUnitsPrice ?? 0;
5489
+ const computeUnitsPrice =
5490
+ txParams?.computeUnitsPrice ?? this.txParams.computeUnitsPrice;
5378
5491
  if (computeUnitsPrice !== 0) {
5379
5492
  allIx.push(
5380
5493
  ComputeBudgetProgram.setComputeUnitPrice({
@@ -4,10 +4,11 @@ import {
4
4
  PublicKey,
5
5
  TransactionVersion,
6
6
  } from '@solana/web3.js';
7
- import { IWallet } from './types';
7
+ import { IWallet, TxParams } from './types';
8
8
  import { OracleInfo } from './oracles/types';
9
9
  import { BulkAccountLoader } from './accounts/bulkAccountLoader';
10
10
  import { DriftEnv } from './config';
11
+ import { TxSender } from './tx/types';
11
12
 
12
13
  export type DriftClientConfig = {
13
14
  connection: Connection;
@@ -16,7 +17,7 @@ export type DriftClientConfig = {
16
17
  programID?: PublicKey;
17
18
  accountSubscription?: DriftClientSubscriptionConfig;
18
19
  opts?: ConfirmOptions;
19
- txSenderConfig?: TxSenderConfig;
20
+ txSender?: TxSender;
20
21
  subAccountIds?: number[];
21
22
  activeSubAccountId?: number;
22
23
  perpMarketIndexes?: number[];
@@ -29,6 +30,7 @@ export type DriftClientConfig = {
29
30
  authoritySubAccountMap?: Map<string, number[]>; // if passed this will override subAccountIds and includeDelegates
30
31
  skipLoadUsers?: boolean; // if passed to constructor, no user accounts will be loaded. they will load if updateWallet is called afterwards.
31
32
  txVersion?: TransactionVersion; // which tx version to use
33
+ txParams?: TxParams; // default tx params to use
32
34
  };
33
35
 
34
36
  export type DriftClientSubscriptionConfig =
@@ -39,10 +41,3 @@ export type DriftClientSubscriptionConfig =
39
41
  type: 'polling';
40
42
  accountLoader: BulkAccountLoader;
41
43
  };
42
-
43
- type TxSenderConfig = {
44
- type: 'retry';
45
- timeout?: number;
46
- retrySleep?: number;
47
- additionalConnections?: Connection[];
48
- };
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.31.1-beta.1",
2
+ "version": "2.31.1-beta.11",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
package/src/index.ts CHANGED
@@ -46,6 +46,7 @@ export * from './math/orders';
46
46
  export * from './math/repeg';
47
47
  export * from './math/margin';
48
48
  export * from './math/insurance';
49
+ export * from './marinade';
49
50
  export * from './orderParams';
50
51
  export * from './slot/SlotSubscriber';
51
52
  export * from './wallet';