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

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/lib/user.js CHANGED
@@ -12,6 +12,7 @@ const pollingUserAccountSubscriber_1 = require("./accounts/pollingUserAccountSub
12
12
  const webSocketUserAccountSubscriber_1 = require("./accounts/webSocketUserAccountSubscriber");
13
13
  const spotPosition_1 = require("./math/spotPosition");
14
14
  const oracles_1 = require("./math/oracles");
15
+ const tiers_1 = require("./math/tiers");
15
16
  class User {
16
17
  get isSubscribed() {
17
18
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
@@ -20,13 +21,16 @@ class User {
20
21
  this._isSubscribed = val;
21
22
  }
22
23
  constructor(config) {
23
- var _a;
24
+ var _a, _b;
24
25
  this._isSubscribed = false;
25
26
  this.driftClient = config.driftClient;
26
27
  this.userAccountPublicKey = config.userAccountPublicKey;
27
28
  if (((_a = config.accountSubscription) === null || _a === void 0 ? void 0 : _a.type) === 'polling') {
28
29
  this.accountSubscriber = new pollingUserAccountSubscriber_1.PollingUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey, config.accountSubscription.accountLoader);
29
30
  }
31
+ else if (((_b = config.accountSubscription) === null || _b === void 0 ? void 0 : _b.type) === 'custom') {
32
+ this.accountSubscriber = config.accountSubscription.userAccountSubscriber;
33
+ }
30
34
  else {
31
35
  this.accountSubscriber = new webSocketUserAccountSubscriber_1.WebSocketUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey);
32
36
  }
@@ -176,7 +180,9 @@ class User {
176
180
  * @returns : pnl from settle
177
181
  */
178
182
  getPerpPositionWithLPSettle(marketIndex, originalPosition) {
179
- originalPosition = originalPosition !== null && originalPosition !== void 0 ? originalPosition : this.getPerpPosition(marketIndex);
183
+ var _a;
184
+ originalPosition =
185
+ (_a = originalPosition !== null && originalPosition !== void 0 ? originalPosition : this.getPerpPosition(marketIndex)) !== null && _a !== void 0 ? _a : this.getEmptyPosition(marketIndex);
180
186
  if (originalPosition.lpShares.eq(numericConstants_1.ZERO)) {
181
187
  return [originalPosition, numericConstants_1.ZERO, numericConstants_1.ZERO];
182
188
  }
@@ -228,7 +234,7 @@ class User {
228
234
  let pnl;
229
235
  if (updateType == 'open' || updateType == 'increase') {
230
236
  newQuoteEntry = position.quoteEntryAmount.add(deltaQaa);
231
- pnl = 0;
237
+ pnl = numericConstants_1.ZERO;
232
238
  }
233
239
  else if (updateType == 'reduce' || updateType == 'close') {
234
240
  newQuoteEntry = position.quoteEntryAmount.sub(position.quoteEntryAmount
@@ -305,6 +311,9 @@ class User {
305
311
  !(pos.openOrders == 0) ||
306
312
  !pos.lpShares.eq(numericConstants_1.ZERO));
307
313
  }
314
+ getActiveSpotPositions() {
315
+ return this.getUserAccount().spotPositions.filter((pos) => !(0, spotPosition_1.isSpotPositionAvailable)(pos));
316
+ }
308
317
  /**
309
318
  * calculates unrealized position price pnl
310
319
  * @returns : Precision QUOTE_PRECISION
@@ -601,7 +610,8 @@ class User {
601
610
  * @returns : Precision QUOTE_PRECISION
602
611
  */
603
612
  getPerpPositionValue(marketIndex, oraclePriceData, includeOpenOrders = false) {
604
- const userPosition = this.getPerpPosition(marketIndex) || this.getEmptyPosition(marketIndex);
613
+ const userPosition = this.getPerpPositionWithLPSettle(marketIndex)[0] ||
614
+ this.getEmptyPosition(marketIndex);
605
615
  const market = this.driftClient.getPerpMarketAccount(userPosition.marketIndex);
606
616
  return (0, margin_1.calculateBaseAssetValueWithOracle)(market, userPosition, oraclePriceData, includeOpenOrders);
607
617
  }
@@ -775,12 +785,16 @@ class User {
775
785
  const totalCollateral = this.getTotalCollateral('Maintenance');
776
786
  // if user being liq'd, can continue to be liq'd until total collateral above the margin requirement plus buffer
777
787
  let liquidationBuffer = undefined;
778
- const isBeingLiquidated = (0, types_1.isVariant)(this.getUserAccount().status, 'beingLiquidated');
779
- if (isBeingLiquidated) {
788
+ if (this.isBeingLiquidated()) {
780
789
  liquidationBuffer = new _1.BN(this.driftClient.getStateAccount().liquidationMarginBufferRatio);
781
790
  }
782
- const maintenanceRequirement = this.getMaintenanceMarginRequirement(liquidationBuffer);
783
- return totalCollateral.lt(maintenanceRequirement);
791
+ const marginRequirement = this.getMaintenanceMarginRequirement(liquidationBuffer);
792
+ const canBeLiquidated = totalCollateral.lt(marginRequirement);
793
+ return {
794
+ canBeLiquidated,
795
+ marginRequirement,
796
+ totalCollateral,
797
+ };
784
798
  }
785
799
  isBeingLiquidated() {
786
800
  return (0, types_1.isOneOfVariant)(this.getUserAccount().status, [
@@ -1281,6 +1295,23 @@ class User {
1281
1295
  }
1282
1296
  return true;
1283
1297
  }
1298
+ getSafestTiers() {
1299
+ let safestPerpTier = 4;
1300
+ let safestSpotTier = 4;
1301
+ for (const perpPosition of this.getActivePerpPositions()) {
1302
+ safestPerpTier = Math.min(safestPerpTier, (0, tiers_1.getPerpMarketTierNumber)(this.driftClient.getPerpMarketAccount(perpPosition.marketIndex)));
1303
+ }
1304
+ for (const spotPosition of this.getActiveSpotPositions()) {
1305
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'deposit')) {
1306
+ continue;
1307
+ }
1308
+ safestSpotTier = Math.min(safestSpotTier, (0, tiers_1.getSpotMarketTierNumber)(this.driftClient.getSpotMarketAccount(spotPosition.marketIndex)));
1309
+ }
1310
+ return {
1311
+ perpTier: safestPerpTier,
1312
+ spotTier: safestSpotTier,
1313
+ };
1314
+ }
1284
1315
  /**
1285
1316
  * Get the total position value, excluding any position coming from the given target market
1286
1317
  * @param marketToIgnore
@@ -1,6 +1,7 @@
1
1
  import { DriftClient } from './driftClient';
2
2
  import { PublicKey } from '@solana/web3.js';
3
3
  import { BulkAccountLoader } from './accounts/bulkAccountLoader';
4
+ import { UserAccountSubscriber } from './accounts/types';
4
5
  export type UserConfig = {
5
6
  accountSubscription?: UserSubscriptionConfig;
6
7
  driftClient: DriftClient;
@@ -11,4 +12,7 @@ export type UserSubscriptionConfig = {
11
12
  } | {
12
13
  type: 'polling';
13
14
  accountLoader: BulkAccountLoader;
15
+ } | {
16
+ type: 'custom';
17
+ userAccountSubscriber: UserAccountSubscriber;
14
18
  };
package/lib/userStats.js CHANGED
@@ -7,12 +7,15 @@ const webSocketUserStatsAccountSubsriber_1 = require("./accounts/webSocketUserSt
7
7
  const pda_1 = require("./addresses/pda");
8
8
  class UserStats {
9
9
  constructor(config) {
10
- var _a;
10
+ var _a, _b;
11
11
  this.driftClient = config.driftClient;
12
12
  this.userStatsAccountPublicKey = config.userStatsAccountPublicKey;
13
13
  if (((_a = config.accountSubscription) === null || _a === void 0 ? void 0 : _a.type) === 'polling') {
14
14
  this.accountSubscriber = new pollingUserStatsAccountSubscriber_1.PollingUserStatsAccountSubscriber(config.driftClient.program, config.userStatsAccountPublicKey, config.accountSubscription.accountLoader);
15
15
  }
16
+ else if (((_b = config.accountSubscription) === null || _b === void 0 ? void 0 : _b.type) === 'custom') {
17
+ throw new Error('Custom account subscription not yet implemented for user stats');
18
+ }
16
19
  else {
17
20
  this.accountSubscriber = new webSocketUserStatsAccountSubsriber_1.WebSocketUserStatsAccountSubscriber(config.driftClient.program, config.userStatsAccountPublicKey);
18
21
  }
@@ -11,4 +11,6 @@ export type UserStatsSubscriptionConfig = {
11
11
  } | {
12
12
  type: 'polling';
13
13
  accountLoader: BulkAccountLoader;
14
+ } | {
15
+ type: 'custom';
14
16
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.31.1-beta.1",
3
+ "version": "2.31.1-beta.10",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -0,0 +1,53 @@
1
+ import { DataAndSlot, UserAccountEvents, UserAccountSubscriber } from './types';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import StrictEventEmitter from 'strict-event-emitter-types';
4
+ import { EventEmitter } from 'events';
5
+ import { UserAccount } from '../types';
6
+
7
+ export class MockUserAccountSubscriber implements UserAccountSubscriber {
8
+ isSubscribed: boolean;
9
+ eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
10
+ userAccountPublicKey: PublicKey;
11
+
12
+ callbackId?: string;
13
+ errorCallbackId?: string;
14
+
15
+ user: DataAndSlot<UserAccount>;
16
+
17
+ public constructor(
18
+ userAccountPublicKey: PublicKey,
19
+ data: UserAccount,
20
+ slot: number
21
+ ) {
22
+ this.isSubscribed = true;
23
+ this.eventEmitter = new EventEmitter();
24
+ this.userAccountPublicKey = userAccountPublicKey;
25
+ this.user = { data, slot };
26
+ }
27
+
28
+ async subscribe(_userAccount?: UserAccount): Promise<boolean> {
29
+ return true;
30
+ }
31
+
32
+ async addToAccountLoader(): Promise<void> {}
33
+
34
+ async fetch(): Promise<void> {}
35
+
36
+ doesAccountExist(): boolean {
37
+ return this.user !== undefined;
38
+ }
39
+
40
+ async unsubscribe(): Promise<void> {}
41
+
42
+ assertIsSubscribed(): void {}
43
+
44
+ public getUserAccountAndSlot(): DataAndSlot<UserAccount> {
45
+ return this.user;
46
+ }
47
+
48
+ public updateData(userAccount: UserAccount, slot: number): void {
49
+ this.user = { data: userAccount, slot };
50
+ this.eventEmitter.emit('userAccountUpdate', userAccount);
51
+ this.eventEmitter.emit('update');
52
+ }
53
+ }
package/src/config.ts CHANGED
@@ -131,7 +131,7 @@ export async function findAllMarketAndOracles(program: Program): Promise<{
131
131
  (await program.account.spotMarket.all()) as ProgramAccount<SpotMarketAccount>[];
132
132
 
133
133
  for (const perpMarketProgramAccount of perpMarketProgramAccounts) {
134
- const perpMarket = perpMarketProgramAccount.account;
134
+ const perpMarket = perpMarketProgramAccount.account as PerpMarketAccount;
135
135
  perpMarketIndexes.push(perpMarket.marketIndex);
136
136
  oracleInfos.set(perpMarket.amm.oracle.toString(), {
137
137
  publicKey: perpMarket.amm.oracle,
@@ -140,7 +140,7 @@ export async function findAllMarketAndOracles(program: Program): Promise<{
140
140
  }
141
141
 
142
142
  for (const spotMarketProgramAccount of spotMarketProgramAccounts) {
143
- const spotMarket = spotMarketProgramAccount.account;
143
+ const spotMarket = spotMarketProgramAccount.account as SpotMarketAccount;
144
144
  spotMarketIndexes.push(spotMarket.marketIndex);
145
145
  oracleInfos.set(spotMarket.oracle.toString(), {
146
146
  publicKey: spotMarket.oracle,
@@ -134,6 +134,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
134
134
  launchTs: 1683125906000,
135
135
  oracleSource: OracleSource.PYTH,
136
136
  },
137
+ {
138
+ fullName: 'RNDR',
139
+ category: ['Infra'],
140
+ symbol: 'RNDR-PERP',
141
+ baseAssetSymbol: 'RNDR',
142
+ marketIndex: 12,
143
+ oracle: new PublicKey('C2QvUPBiU3fViSyqA4nZgGyYqLgYf9PRpd8B8oLoo48w'),
144
+ launchTs: 1683125906000,
145
+ oracleSource: OracleSource.PYTH,
146
+ },
137
147
  ];
138
148
 
139
149
  export const MainnetPerpMarkets: PerpMarketConfig[] = [
@@ -257,6 +267,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
257
267
  launchTs: 1683125906000,
258
268
  oracleSource: OracleSource.PYTH,
259
269
  },
270
+ {
271
+ fullName: 'RNDR',
272
+ category: ['Infra'],
273
+ symbol: 'RNDR-PERP',
274
+ baseAssetSymbol: 'RNDR',
275
+ marketIndex: 12,
276
+ oracle: new PublicKey('CYGfrBJB9HgLf9iZyN4aH5HvUAi2htQ4MjPxeXMf4Egn'),
277
+ launchTs: 1683125906000,
278
+ oracleSource: OracleSource.PYTH,
279
+ },
260
280
  ];
261
281
 
262
282
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
@@ -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,7 @@ 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';
118
120
 
119
121
  type RemainingAccountParams = {
120
122
  userAccounts: UserAccount[];
@@ -139,6 +141,7 @@ export class DriftClient {
139
141
  userStats?: UserStats;
140
142
  activeSubAccountId: number;
141
143
  userAccountSubscriptionConfig: UserSubscriptionConfig;
144
+ userStatsAccountSubscriptionConfig: UserStatsSubscriptionConfig;
142
145
  accountSubscriber: DriftClientAccountSubscriber;
143
146
  eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
144
147
  _isSubscribed = false;
@@ -152,6 +155,7 @@ export class DriftClient {
152
155
  authoritySubAccountMap?: Map<string, number[]>;
153
156
  skipLoadUsers?: boolean;
154
157
  txVersion: TransactionVersion;
158
+ txParams: TxParams;
155
159
 
156
160
  public get isSubscribed() {
157
161
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
@@ -180,6 +184,10 @@ export class DriftClient {
180
184
  this.activeSubAccountId = config.activeSubAccountId ?? 0;
181
185
  this.skipLoadUsers = config.skipLoadUsers ?? false;
182
186
  this.txVersion = config.txVersion ?? 'legacy';
187
+ this.txParams = {
188
+ computeUnits: config.txParams?.computeUnits ?? 600_000,
189
+ computeUnitsPrice: config.txParams?.computeUnitsPrice ?? 0,
190
+ };
183
191
 
184
192
  if (config.includeDelegates && config.subAccountIds) {
185
193
  throw new Error(
@@ -206,15 +214,23 @@ export class DriftClient {
206
214
  : new Map<string, number[]>();
207
215
 
208
216
  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
- };
217
+ if (config.accountSubscription?.type === 'polling') {
218
+ this.userAccountSubscriptionConfig = {
219
+ type: 'polling',
220
+ accountLoader: config.accountSubscription.accountLoader,
221
+ };
222
+ this.userStatsAccountSubscriptionConfig = {
223
+ type: 'polling',
224
+ accountLoader: config.accountSubscription.accountLoader,
225
+ };
226
+ } else {
227
+ this.userAccountSubscriptionConfig = {
228
+ type: 'websocket',
229
+ };
230
+ this.userStatsAccountSubscriptionConfig = {
231
+ type: 'websocket',
232
+ };
233
+ }
218
234
 
219
235
  if (config.userStats) {
220
236
  this.userStats = new UserStats({
@@ -257,12 +273,13 @@ export class DriftClient {
257
273
  );
258
274
  }
259
275
  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
- );
276
+ this.txSender =
277
+ config.txSender ??
278
+ new RetryTxSender({
279
+ connection: this.connection,
280
+ wallet: this.wallet,
281
+ opts: this.opts,
282
+ });
266
283
  }
267
284
 
268
285
  public getUserMapKey(subAccountId: number, authority: PublicKey): string {
@@ -503,7 +520,7 @@ export class DriftClient {
503
520
 
504
521
  this.skipLoadUsers = false;
505
522
  // Update provider for txSender with new wallet details
506
- this.txSender.provider = newProvider;
523
+ this.txSender.wallet = newWallet;
507
524
  this.wallet = newWallet;
508
525
  this.provider = newProvider;
509
526
  this.program = newProgram;
@@ -547,7 +564,7 @@ export class DriftClient {
547
564
  this.userStats = new UserStats({
548
565
  driftClient: this,
549
566
  userStatsAccountPublicKey: this.getUserStatsAccountPublicKey(),
550
- accountSubscription: this.userAccountSubscriptionConfig,
567
+ accountSubscription: this.userStatsAccountSubscriptionConfig,
551
568
  });
552
569
 
553
570
  await this.userStats.subscribe();
@@ -1033,11 +1050,19 @@ export class DriftClient {
1033
1050
  const userMapKey = this.getUserMapKey(subAccountId, authority);
1034
1051
 
1035
1052
  if (!this.users.has(userMapKey)) {
1036
- throw new Error(`Clearing House has no user for user id ${userMapKey}`);
1053
+ throw new Error(`DriftClient has no user for user id ${userMapKey}`);
1037
1054
  }
1038
1055
  return this.users.get(userMapKey);
1039
1056
  }
1040
1057
 
1058
+ public hasUser(subAccountId?: number, authority?: PublicKey): boolean {
1059
+ subAccountId = subAccountId ?? this.activeSubAccountId;
1060
+ authority = authority ?? this.authority;
1061
+ const userMapKey = this.getUserMapKey(subAccountId, authority);
1062
+
1063
+ return this.users.has(userMapKey);
1064
+ }
1065
+
1041
1066
  public getUsers(): User[] {
1042
1067
  // delegate users get added to the end
1043
1068
  return [...this.users.values()]
@@ -1695,7 +1720,7 @@ export class DriftClient {
1695
1720
  }
1696
1721
 
1697
1722
  /**
1698
- * Creates the Clearing House User account for a user, and deposits some initial collateral
1723
+ * Creates the User account for a user, and deposits some initial collateral
1699
1724
  * @param amount
1700
1725
  * @param userTokenAccount
1701
1726
  * @param marketIndex
@@ -2296,6 +2321,35 @@ export class DriftClient {
2296
2321
  });
2297
2322
  }
2298
2323
 
2324
+ public getQuoteValuePerLpShare(marketIndex: number): BN {
2325
+ const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
2326
+
2327
+ const openBids = BN.max(
2328
+ perpMarketAccount.amm.baseAssetReserve.sub(
2329
+ perpMarketAccount.amm.minBaseAssetReserve
2330
+ ),
2331
+ ZERO
2332
+ );
2333
+
2334
+ const openAsks = BN.max(
2335
+ perpMarketAccount.amm.maxBaseAssetReserve.sub(
2336
+ perpMarketAccount.amm.baseAssetReserve
2337
+ ),
2338
+ ZERO
2339
+ );
2340
+
2341
+ const oraclePriceData = this.getOracleDataForPerpMarket(marketIndex);
2342
+
2343
+ const maxOpenBidsAsks = BN.max(openBids, openAsks);
2344
+ const quoteValuePerLpShare = maxOpenBidsAsks
2345
+ .mul(oraclePriceData.price)
2346
+ .mul(QUOTE_PRECISION)
2347
+ .div(PRICE_PRECISION)
2348
+ .div(perpMarketAccount.amm.sqrtK);
2349
+
2350
+ return quoteValuePerLpShare;
2351
+ }
2352
+
2299
2353
  /**
2300
2354
  * @deprecated use {@link placePerpOrder} or {@link placeAndTakePerpOrder} instead
2301
2355
  */
@@ -5366,7 +5420,7 @@ export class DriftClient {
5366
5420
  lookupTables?: AddressLookupTableAccount[]
5367
5421
  ): Promise<Transaction | VersionedTransaction> {
5368
5422
  const allIx = [];
5369
- const computeUnits = txParams?.computeUnits ?? 600_000;
5423
+ const computeUnits = txParams?.computeUnits ?? this.txParams.computeUnits;
5370
5424
  if (computeUnits !== 200_000) {
5371
5425
  allIx.push(
5372
5426
  ComputeBudgetProgram.setComputeUnitLimit({
@@ -5374,7 +5428,8 @@ export class DriftClient {
5374
5428
  })
5375
5429
  );
5376
5430
  }
5377
- const computeUnitsPrice = txParams?.computeUnitsPrice ?? 0;
5431
+ const computeUnitsPrice =
5432
+ txParams?.computeUnitsPrice ?? this.txParams.computeUnitsPrice;
5378
5433
  if (computeUnitsPrice !== 0) {
5379
5434
  allIx.push(
5380
5435
  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.10",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -0,0 +1,44 @@
1
+ import { isVariant, PerpMarketAccount, SpotMarketAccount } from '../types';
2
+
3
+ export function getPerpMarketTierNumber(perpMarket: PerpMarketAccount): number {
4
+ if (isVariant(perpMarket.contractTier, 'a')) {
5
+ return 0;
6
+ } else if (isVariant(perpMarket.contractTier, 'b')) {
7
+ return 1;
8
+ } else if (isVariant(perpMarket.contractTier, 'c')) {
9
+ return 2;
10
+ } else if (isVariant(perpMarket.contractTier, 'speculative')) {
11
+ return 3;
12
+ } else if (isVariant(perpMarket.contractTier, 'isolated')) {
13
+ return 4;
14
+ } else {
15
+ return 5;
16
+ }
17
+ }
18
+
19
+ export function getSpotMarketTierNumber(spotMarket: SpotMarketAccount): number {
20
+ if (isVariant(spotMarket.assetTier, 'collateral')) {
21
+ return 0;
22
+ } else if (isVariant(spotMarket.assetTier, 'protected')) {
23
+ return 1;
24
+ } else if (isVariant(spotMarket.assetTier, 'cross')) {
25
+ return 2;
26
+ } else if (isVariant(spotMarket.assetTier, 'isolated')) {
27
+ return 3;
28
+ } else if (isVariant(spotMarket.assetTier, 'unlisted')) {
29
+ return 4;
30
+ } else {
31
+ return 5;
32
+ }
33
+ }
34
+
35
+ export function perpTierIsAsSafeAs(
36
+ perpTier: number,
37
+ otherPerpTier: number,
38
+ otherSpotTier: number
39
+ ): boolean {
40
+ const asSafeAsPerp = perpTier <= otherPerpTier;
41
+ const asSafeAsSpot =
42
+ otherSpotTier === 4 || (otherSpotTier >= 2 && perpTier <= 2);
43
+ return asSafeAsSpot && asSafeAsPerp;
44
+ }