@drift-labs/sdk 2.20.0-beta.3 → 2.21.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.
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="bn.js" />
3
- import { AnchorProvider, BN, Program } from '@project-serum/anchor';
3
+ import { AnchorProvider, BN, Program, ProgramAccount } from '@project-serum/anchor';
4
4
  import { StateAccount, IWallet, PositionDirection, UserAccount, PerpMarketAccount, OrderParams, Order, SpotMarketAccount, SpotPosition, MakerInfo, TakerInfo, OptionalOrderParams, OrderType, ReferrerInfo, MarketType, TxParams, SerumV3FulfillmentConfigAccount, ReferrerNameAccount, OrderTriggerCondition, PerpMarketExtendedInfo } from './types';
5
5
  import * as anchor from '@project-serum/anchor';
6
6
  import { Connection, PublicKey, TransactionSignature, ConfirmOptions, Transaction, TransactionInstruction, AccountMeta, Signer, AddressLookupTableAccount } from '@solana/web3.js';
@@ -101,6 +101,7 @@ export declare class DriftClient {
101
101
  updateUserCustomMarginRatio(marginRatio: number, subAccountId?: number): Promise<TransactionSignature>;
102
102
  updateUserMarginTradingEnabled(marginTradingEnabled: boolean, subAccountId?: number): Promise<TransactionSignature>;
103
103
  updateUserDelegate(delegate: PublicKey, subAccountId?: number): Promise<TransactionSignature>;
104
+ fetchAllUserAccounts(includeIdle?: boolean): Promise<ProgramAccount<UserAccount>[]>;
104
105
  getUserAccountsForDelegate(delegate: PublicKey): Promise<UserAccount[]>;
105
106
  getUserAccountsForAuthority(authority: PublicKey): Promise<UserAccount[]>;
106
107
  deleteUser(subAccountId?: number, txParams?: TxParams): Promise<TransactionSignature>;
@@ -200,8 +201,10 @@ export declare class DriftClient {
200
201
  getTriggerOrderIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, order: Order): Promise<TransactionInstruction>;
201
202
  forceCancelOrders(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
202
203
  getForceCancelOrdersIx(userAccountPublicKey: PublicKey, userAccount: UserAccount): Promise<TransactionInstruction>;
203
- placeAndTakePerpOrder(orderParams: OptionalOrderParams, makerInfo?: MakerInfo, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
204
- getPlaceAndTakePerpOrderIx(orderParams: OptionalOrderParams, makerInfo?: MakerInfo, referrerInfo?: ReferrerInfo): Promise<TransactionInstruction>;
204
+ updateUserInactive(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
205
+ getUpdateUserInactiveIx(userAccountPublicKey: PublicKey, userAccount: UserAccount): Promise<TransactionInstruction>;
206
+ placeAndTakePerpOrder(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
207
+ getPlaceAndTakePerpOrderIx(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo): Promise<TransactionInstruction>;
205
208
  placeAndMakePerpOrder(orderParams: OptionalOrderParams, takerInfo: TakerInfo, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
206
209
  getPlaceAndMakePerpOrderIx(orderParams: OptionalOrderParams, takerInfo: TakerInfo, referrerInfo?: ReferrerInfo): Promise<TransactionInstruction>;
207
210
  placeAndTakeSpotOrder(orderParams: OptionalOrderParams, fulfillmentConfig?: SerumV3FulfillmentConfigAccount, makerInfo?: MakerInfo, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
@@ -424,6 +424,20 @@ class DriftClient {
424
424
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
425
425
  return txSig;
426
426
  }
427
+ async fetchAllUserAccounts(includeIdle = true) {
428
+ let filters = undefined;
429
+ if (!includeIdle) {
430
+ filters = [
431
+ {
432
+ memcmp: {
433
+ offset: 4350,
434
+ bytes: bs58_1.default.encode(Uint8Array.from([0])),
435
+ },
436
+ },
437
+ ];
438
+ }
439
+ return (await this.program.account.user.all(filters));
440
+ }
427
441
  async getUserAccountsForDelegate(delegate) {
428
442
  const programAccounts = await this.program.account.user.all([
429
443
  {
@@ -1578,6 +1592,25 @@ class DriftClient {
1578
1592
  remainingAccounts,
1579
1593
  });
1580
1594
  }
1595
+ async updateUserInactive(userAccountPublicKey, user, txParams) {
1596
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateUserInactiveIx(userAccountPublicKey, user), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1597
+ return txSig;
1598
+ }
1599
+ async getUpdateUserInactiveIx(userAccountPublicKey, userAccount) {
1600
+ const fillerPublicKey = await this.getUserAccountPublicKey();
1601
+ const remainingAccounts = this.getRemainingAccounts({
1602
+ userAccounts: [userAccount],
1603
+ });
1604
+ return await this.program.instruction.updateUserInactive({
1605
+ accounts: {
1606
+ state: await this.getStatePublicKey(),
1607
+ filler: fillerPublicKey,
1608
+ user: userAccountPublicKey,
1609
+ authority: this.wallet.publicKey,
1610
+ },
1611
+ remainingAccounts,
1612
+ });
1613
+ }
1581
1614
  async placeAndTakePerpOrder(orderParams, makerInfo, referrerInfo, txParams) {
1582
1615
  const { txSig, slot } = await this.sendTransaction((0, utils_1.wrapInTx)(await this.getPlaceAndTakePerpOrderIx(orderParams, makerInfo, referrerInfo), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1583
1616
  this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
@@ -1587,42 +1620,49 @@ class DriftClient {
1587
1620
  orderParams = this.getOrderParams(orderParams, types_1.MarketType.PERP);
1588
1621
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
1589
1622
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1623
+ makerInfo = Array.isArray(makerInfo)
1624
+ ? makerInfo
1625
+ : makerInfo
1626
+ ? [makerInfo]
1627
+ : [];
1590
1628
  const userAccounts = [this.getUserAccount()];
1591
- if (makerInfo !== undefined) {
1592
- userAccounts.push(makerInfo.makerUserAccount);
1629
+ for (const maker of makerInfo) {
1630
+ userAccounts.push(maker.makerUserAccount);
1593
1631
  }
1594
1632
  const remainingAccounts = this.getRemainingAccounts({
1595
1633
  userAccounts,
1596
1634
  useMarketLastSlotCache: true,
1597
1635
  writablePerpMarketIndexes: [orderParams.marketIndex],
1598
1636
  });
1599
- let makerOrderId = null;
1600
- if (makerInfo) {
1601
- makerOrderId = makerInfo.order.orderId;
1602
- remainingAccounts.push({
1603
- pubkey: makerInfo.maker,
1604
- isSigner: false,
1605
- isWritable: true,
1606
- });
1607
- remainingAccounts.push({
1608
- pubkey: makerInfo.makerStats,
1609
- isSigner: false,
1610
- isWritable: true,
1611
- });
1612
- }
1613
- if (referrerInfo) {
1637
+ for (const maker of makerInfo) {
1614
1638
  remainingAccounts.push({
1615
- pubkey: referrerInfo.referrer,
1639
+ pubkey: maker.maker,
1616
1640
  isWritable: true,
1617
1641
  isSigner: false,
1618
1642
  });
1619
1643
  remainingAccounts.push({
1620
- pubkey: referrerInfo.referrerStats,
1644
+ pubkey: maker.makerStats,
1621
1645
  isWritable: true,
1622
1646
  isSigner: false,
1623
1647
  });
1624
1648
  }
1625
- return await this.program.instruction.placeAndTakePerpOrder(orderParams, makerOrderId, {
1649
+ if (referrerInfo) {
1650
+ const referrerIsMaker = makerInfo.find((maker) => maker.maker.equals(referrerInfo.referrer)) !==
1651
+ undefined;
1652
+ if (!referrerIsMaker) {
1653
+ remainingAccounts.push({
1654
+ pubkey: referrerInfo.referrer,
1655
+ isWritable: true,
1656
+ isSigner: false,
1657
+ });
1658
+ remainingAccounts.push({
1659
+ pubkey: referrerInfo.referrerStats,
1660
+ isWritable: true,
1661
+ isSigner: false,
1662
+ });
1663
+ }
1664
+ }
1665
+ return await this.program.instruction.placeAndTakePerpOrder(orderParams, null, {
1626
1666
  accounts: {
1627
1667
  state: await this.getStatePublicKey(),
1628
1668
  user: userAccountPublicKey,
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.20.0-beta.3",
2
+ "version": "2.21.0-beta.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -4543,7 +4543,7 @@
4543
4543
  "type": "u64"
4544
4544
  },
4545
4545
  {
4546
- "name": "liquidationStartSlot",
4546
+ "name": "lastActiveSlot",
4547
4547
  "type": "u64"
4548
4548
  },
4549
4549
  {
@@ -4572,12 +4572,16 @@
4572
4572
  "name": "isMarginTradingEnabled",
4573
4573
  "type": "bool"
4574
4574
  },
4575
+ {
4576
+ "name": "idle",
4577
+ "type": "bool"
4578
+ },
4575
4579
  {
4576
4580
  "name": "padding",
4577
4581
  "type": {
4578
4582
  "array": [
4579
4583
  "u8",
4580
- 26
4584
+ 25
4581
4585
  ]
4582
4586
  }
4583
4587
  }
@@ -8733,6 +8737,11 @@
8733
8737
  "code": 6237,
8734
8738
  "name": "UnableToLoadUserStatsAccount",
8735
8739
  "msg": "UnableToLoadUserStatsAccount"
8740
+ },
8741
+ {
8742
+ "code": 6238,
8743
+ "name": "UserNotInactive",
8744
+ "msg": "User Not Inactive"
8736
8745
  }
8737
8746
  ]
8738
8747
  }
package/lib/types.d.ts CHANGED
@@ -845,8 +845,9 @@ export type UserAccount = {
845
845
  totalSocialLoss: BN;
846
846
  cumulativePerpFunding: BN;
847
847
  liquidationMarginFreed: BN;
848
- liquidationStartSlot: BN;
848
+ lastActiveSlot: BN;
849
849
  isMarginTradingEnabled: boolean;
850
+ inactive: boolean;
850
851
  };
851
852
  export type SpotPosition = {
852
853
  marketIndex: number;
package/lib/user.d.ts CHANGED
@@ -269,6 +269,7 @@ export declare class User {
269
269
  depositAmount: BN;
270
270
  maxDepositAmount: BN;
271
271
  };
272
+ canMakeIdle(slot: BN, slotsBeforeIdle: BN): boolean;
272
273
  /**
273
274
  * Get the total position value, excluding any position coming from the given target market
274
275
  * @param marketToIgnore
package/lib/user.js CHANGED
@@ -1212,6 +1212,38 @@ class User {
1212
1212
  depositAmount,
1213
1213
  };
1214
1214
  }
1215
+ canMakeIdle(slot, slotsBeforeIdle) {
1216
+ const userAccount = this.getUserAccount();
1217
+ if (userAccount.inactive) {
1218
+ return false;
1219
+ }
1220
+ const userLastActiveSlot = userAccount.lastActiveSlot;
1221
+ if (userLastActiveSlot.lt(slotsBeforeIdle)) {
1222
+ return false;
1223
+ }
1224
+ if (this.isBeingLiquidated()) {
1225
+ return false;
1226
+ }
1227
+ for (const perpPosition of userAccount.perpPositions) {
1228
+ if (!(0, position_1.positionIsAvailable)(perpPosition)) {
1229
+ return false;
1230
+ }
1231
+ }
1232
+ for (const spotPosition of userAccount.spotPositions) {
1233
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
1234
+ return false;
1235
+ }
1236
+ if (spotPosition.openOrders !== 0) {
1237
+ return false;
1238
+ }
1239
+ }
1240
+ for (const order of userAccount.orders) {
1241
+ if (!(0, types_1.isVariant)(order.status, 'init')) {
1242
+ return false;
1243
+ }
1244
+ }
1245
+ return true;
1246
+ }
1215
1247
  /**
1216
1248
  * Get the total position value, excluding any position coming from the given target market
1217
1249
  * @param marketToIgnore
@@ -15,7 +15,7 @@ export declare class UserMap implements UserMapInterface {
15
15
  private driftClient;
16
16
  private accountSubscription;
17
17
  constructor(driftClient: DriftClient, accountSubscription: UserSubscriptionConfig);
18
- fetchAllUsers(): Promise<void>;
18
+ fetchAllUsers(includeIdle?: boolean): Promise<void>;
19
19
  addPubkey(userAccountPublicKey: PublicKey): Promise<void>;
20
20
  has(key: string): boolean;
21
21
  /**
@@ -9,10 +9,10 @@ class UserMap {
9
9
  this.driftClient = driftClient;
10
10
  this.accountSubscription = accountSubscription;
11
11
  }
12
- async fetchAllUsers() {
12
+ async fetchAllUsers(includeIdle = true) {
13
13
  const userArray = [];
14
14
  const userAccountArray = [];
15
- const programUserAccounts = (await this.driftClient.program.account.user.all());
15
+ const programUserAccounts = await this.driftClient.fetchAllUserAccounts(includeIdle);
16
16
  for (const programUserAccount of programUserAccounts) {
17
17
  if (this.userMap.has(programUserAccount.publicKey.toString())) {
18
18
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.20.0-beta.3",
3
+ "version": "2.21.0-beta.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -1,4 +1,10 @@
1
- import { AnchorProvider, BN, Idl, Program } from '@project-serum/anchor';
1
+ import {
2
+ AnchorProvider,
3
+ BN,
4
+ Idl,
5
+ Program,
6
+ ProgramAccount,
7
+ } from '@project-serum/anchor';
2
8
  import bs58 from 'bs58';
3
9
  import {
4
10
  ASSOCIATED_TOKEN_PROGRAM_ID,
@@ -713,6 +719,25 @@ export class DriftClient {
713
719
  return txSig;
714
720
  }
715
721
 
722
+ public async fetchAllUserAccounts(
723
+ includeIdle = true
724
+ ): Promise<ProgramAccount<UserAccount>[]> {
725
+ let filters = undefined;
726
+ if (!includeIdle) {
727
+ filters = [
728
+ {
729
+ memcmp: {
730
+ offset: 4350,
731
+ bytes: bs58.encode(Uint8Array.from([0])),
732
+ },
733
+ },
734
+ ];
735
+ }
736
+ return (await this.program.account.user.all(
737
+ filters
738
+ )) as ProgramAccount<UserAccount>[];
739
+ }
740
+
716
741
  public async getUserAccountsForDelegate(
717
742
  delegate: PublicKey
718
743
  ): Promise<UserAccount[]> {
@@ -2734,9 +2759,47 @@ export class DriftClient {
2734
2759
  });
2735
2760
  }
2736
2761
 
2762
+ public async updateUserInactive(
2763
+ userAccountPublicKey: PublicKey,
2764
+ user: UserAccount,
2765
+ txParams?: TxParams
2766
+ ): Promise<TransactionSignature> {
2767
+ const { txSig } = await this.txSender.send(
2768
+ wrapInTx(
2769
+ await this.getUpdateUserInactiveIx(userAccountPublicKey, user),
2770
+ txParams?.computeUnits,
2771
+ txParams?.computeUnitsPrice
2772
+ ),
2773
+ [],
2774
+ this.opts
2775
+ );
2776
+ return txSig;
2777
+ }
2778
+
2779
+ public async getUpdateUserInactiveIx(
2780
+ userAccountPublicKey: PublicKey,
2781
+ userAccount: UserAccount
2782
+ ): Promise<TransactionInstruction> {
2783
+ const fillerPublicKey = await this.getUserAccountPublicKey();
2784
+
2785
+ const remainingAccounts = this.getRemainingAccounts({
2786
+ userAccounts: [userAccount],
2787
+ });
2788
+
2789
+ return await this.program.instruction.updateUserInactive({
2790
+ accounts: {
2791
+ state: await this.getStatePublicKey(),
2792
+ filler: fillerPublicKey,
2793
+ user: userAccountPublicKey,
2794
+ authority: this.wallet.publicKey,
2795
+ },
2796
+ remainingAccounts,
2797
+ });
2798
+ }
2799
+
2737
2800
  public async placeAndTakePerpOrder(
2738
2801
  orderParams: OptionalOrderParams,
2739
- makerInfo?: MakerInfo,
2802
+ makerInfo?: MakerInfo | MakerInfo[],
2740
2803
  referrerInfo?: ReferrerInfo,
2741
2804
  txParams?: TxParams
2742
2805
  ): Promise<TransactionSignature> {
@@ -2759,54 +2822,64 @@ export class DriftClient {
2759
2822
 
2760
2823
  public async getPlaceAndTakePerpOrderIx(
2761
2824
  orderParams: OptionalOrderParams,
2762
- makerInfo?: MakerInfo,
2825
+ makerInfo?: MakerInfo | MakerInfo[],
2763
2826
  referrerInfo?: ReferrerInfo
2764
2827
  ): Promise<TransactionInstruction> {
2765
2828
  orderParams = this.getOrderParams(orderParams, MarketType.PERP);
2766
2829
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
2767
2830
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2768
2831
 
2832
+ makerInfo = Array.isArray(makerInfo)
2833
+ ? makerInfo
2834
+ : makerInfo
2835
+ ? [makerInfo]
2836
+ : [];
2837
+
2769
2838
  const userAccounts = [this.getUserAccount()];
2770
- if (makerInfo !== undefined) {
2771
- userAccounts.push(makerInfo.makerUserAccount);
2839
+ for (const maker of makerInfo) {
2840
+ userAccounts.push(maker.makerUserAccount);
2772
2841
  }
2842
+
2773
2843
  const remainingAccounts = this.getRemainingAccounts({
2774
2844
  userAccounts,
2775
2845
  useMarketLastSlotCache: true,
2776
2846
  writablePerpMarketIndexes: [orderParams.marketIndex],
2777
2847
  });
2778
2848
 
2779
- let makerOrderId = null;
2780
- if (makerInfo) {
2781
- makerOrderId = makerInfo.order.orderId;
2849
+ for (const maker of makerInfo) {
2782
2850
  remainingAccounts.push({
2783
- pubkey: makerInfo.maker,
2784
- isSigner: false,
2851
+ pubkey: maker.maker,
2785
2852
  isWritable: true,
2853
+ isSigner: false,
2786
2854
  });
2787
2855
  remainingAccounts.push({
2788
- pubkey: makerInfo.makerStats,
2789
- isSigner: false,
2856
+ pubkey: maker.makerStats,
2790
2857
  isWritable: true,
2858
+ isSigner: false,
2791
2859
  });
2792
2860
  }
2793
2861
 
2794
2862
  if (referrerInfo) {
2795
- remainingAccounts.push({
2796
- pubkey: referrerInfo.referrer,
2797
- isWritable: true,
2798
- isSigner: false,
2799
- });
2800
- remainingAccounts.push({
2801
- pubkey: referrerInfo.referrerStats,
2802
- isWritable: true,
2803
- isSigner: false,
2804
- });
2863
+ const referrerIsMaker =
2864
+ makerInfo.find((maker) => maker.maker.equals(referrerInfo.referrer)) !==
2865
+ undefined;
2866
+ if (!referrerIsMaker) {
2867
+ remainingAccounts.push({
2868
+ pubkey: referrerInfo.referrer,
2869
+ isWritable: true,
2870
+ isSigner: false,
2871
+ });
2872
+ remainingAccounts.push({
2873
+ pubkey: referrerInfo.referrerStats,
2874
+ isWritable: true,
2875
+ isSigner: false,
2876
+ });
2877
+ }
2805
2878
  }
2806
2879
 
2807
2880
  return await this.program.instruction.placeAndTakePerpOrder(
2808
2881
  orderParams,
2809
- makerOrderId,
2882
+ null,
2810
2883
  {
2811
2884
  accounts: {
2812
2885
  state: await this.getStatePublicKey(),
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.20.0-beta.3",
2
+ "version": "2.21.0-beta.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -4543,7 +4543,7 @@
4543
4543
  "type": "u64"
4544
4544
  },
4545
4545
  {
4546
- "name": "liquidationStartSlot",
4546
+ "name": "lastActiveSlot",
4547
4547
  "type": "u64"
4548
4548
  },
4549
4549
  {
@@ -4572,12 +4572,16 @@
4572
4572
  "name": "isMarginTradingEnabled",
4573
4573
  "type": "bool"
4574
4574
  },
4575
+ {
4576
+ "name": "idle",
4577
+ "type": "bool"
4578
+ },
4575
4579
  {
4576
4580
  "name": "padding",
4577
4581
  "type": {
4578
4582
  "array": [
4579
4583
  "u8",
4580
- 26
4584
+ 25
4581
4585
  ]
4582
4586
  }
4583
4587
  }
@@ -8733,6 +8737,11 @@
8733
8737
  "code": 6237,
8734
8738
  "name": "UnableToLoadUserStatsAccount",
8735
8739
  "msg": "UnableToLoadUserStatsAccount"
8740
+ },
8741
+ {
8742
+ "code": 6238,
8743
+ "name": "UserNotInactive",
8744
+ "msg": "User Not Inactive"
8736
8745
  }
8737
8746
  ]
8738
8747
  }
package/src/types.ts CHANGED
@@ -798,8 +798,9 @@ export type UserAccount = {
798
798
  totalSocialLoss: BN;
799
799
  cumulativePerpFunding: BN;
800
800
  liquidationMarginFreed: BN;
801
- liquidationStartSlot: BN;
801
+ lastActiveSlot: BN;
802
802
  isMarginTradingEnabled: boolean;
803
+ inactive: boolean;
803
804
  };
804
805
 
805
806
  export type SpotPosition = {
package/src/user.ts CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  isOneOfVariant,
13
13
  PerpMarketAccount,
14
14
  } from './types';
15
- import { calculateEntryPrice } from './math/position';
15
+ import { calculateEntryPrice, positionIsAvailable } from './math/position';
16
16
  import {
17
17
  PRICE_PRECISION,
18
18
  AMM_TO_QUOTE_PRECISION_RATIO,
@@ -2171,6 +2171,46 @@ export class User {
2171
2171
  };
2172
2172
  }
2173
2173
 
2174
+ public canMakeIdle(slot: BN, slotsBeforeIdle: BN): boolean {
2175
+ const userAccount = this.getUserAccount();
2176
+ if (userAccount.inactive) {
2177
+ return false;
2178
+ }
2179
+
2180
+ const userLastActiveSlot = userAccount.lastActiveSlot;
2181
+ if (userLastActiveSlot.lt(slotsBeforeIdle)) {
2182
+ return false;
2183
+ }
2184
+
2185
+ if (this.isBeingLiquidated()) {
2186
+ return false;
2187
+ }
2188
+
2189
+ for (const perpPosition of userAccount.perpPositions) {
2190
+ if (!positionIsAvailable(perpPosition)) {
2191
+ return false;
2192
+ }
2193
+ }
2194
+
2195
+ for (const spotPosition of userAccount.spotPositions) {
2196
+ if (isVariant(spotPosition.balanceType, 'borrow')) {
2197
+ return false;
2198
+ }
2199
+
2200
+ if (spotPosition.openOrders !== 0) {
2201
+ return false;
2202
+ }
2203
+ }
2204
+
2205
+ for (const order of userAccount.orders) {
2206
+ if (!isVariant(order.status, 'init')) {
2207
+ return false;
2208
+ }
2209
+ }
2210
+
2211
+ return true;
2212
+ }
2213
+
2174
2214
  /**
2175
2215
  * Get the total position value, excluding any position coming from the given target market
2176
2216
  * @param marketToIgnore
@@ -14,7 +14,6 @@ import {
14
14
  NewUserRecord,
15
15
  LPRecord,
16
16
  } from '..';
17
- import { ProgramAccount } from '@project-serum/anchor';
18
17
 
19
18
  import { PublicKey } from '@solana/web3.js';
20
19
 
@@ -42,12 +41,13 @@ export class UserMap implements UserMapInterface {
42
41
  this.accountSubscription = accountSubscription;
43
42
  }
44
43
 
45
- public async fetchAllUsers() {
44
+ public async fetchAllUsers(includeIdle = true) {
46
45
  const userArray: User[] = [];
47
46
  const userAccountArray: UserAccount[] = [];
48
47
 
49
- const programUserAccounts =
50
- (await this.driftClient.program.account.user.all()) as ProgramAccount<UserAccount>[];
48
+ const programUserAccounts = await this.driftClient.fetchAllUserAccounts(
49
+ includeIdle
50
+ );
51
51
  for (const programUserAccount of programUserAccounts) {
52
52
  if (this.userMap.has(programUserAccount.publicKey.toString())) {
53
53
  continue;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.assert = void 0;
4
- function assert(condition, error) {
5
- if (!condition) {
6
- throw new Error(error || 'Unspecified AssertionError');
7
- }
8
- }
9
- exports.assert = assert;
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseTokenAccount = void 0;
4
- const spl_token_1 = require("@solana/spl-token");
5
- const web3_js_1 = require("@solana/web3.js");
6
- function parseTokenAccount(data) {
7
- const accountInfo = spl_token_1.AccountLayout.decode(data);
8
- accountInfo.mint = new web3_js_1.PublicKey(accountInfo.mint);
9
- accountInfo.owner = new web3_js_1.PublicKey(accountInfo.owner);
10
- accountInfo.amount = spl_token_1.u64.fromBuffer(accountInfo.amount);
11
- if (accountInfo.delegateOption === 0) {
12
- accountInfo.delegate = null;
13
- // eslint-disable-next-line new-cap
14
- accountInfo.delegatedAmount = new spl_token_1.u64(0);
15
- }
16
- else {
17
- accountInfo.delegate = new web3_js_1.PublicKey(accountInfo.delegate);
18
- accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(accountInfo.delegatedAmount);
19
- }
20
- accountInfo.isInitialized = accountInfo.state !== 0;
21
- accountInfo.isFrozen = accountInfo.state === 2;
22
- if (accountInfo.isNativeOption === 1) {
23
- accountInfo.rentExemptReserve = spl_token_1.u64.fromBuffer(accountInfo.isNative);
24
- accountInfo.isNative = true;
25
- }
26
- else {
27
- accountInfo.rentExemptReserve = null;
28
- accountInfo.isNative = false;
29
- }
30
- if (accountInfo.closeAuthorityOption === 0) {
31
- accountInfo.closeAuthority = null;
32
- }
33
- else {
34
- accountInfo.closeAuthority = new web3_js_1.PublicKey(accountInfo.closeAuthority);
35
- }
36
- return accountInfo;
37
- }
38
- exports.parseTokenAccount = parseTokenAccount;
@@ -1,27 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.findComputeUnitConsumption = void 0;
13
- function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
14
- return __awaiter(this, void 0, void 0, function* () {
15
- const tx = yield connection.getTransaction(txSignature, { commitment });
16
- const computeUnits = [];
17
- const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of ([0-9]{0,7}) compute units`);
18
- tx.meta.logMessages.forEach((logMessage) => {
19
- const match = logMessage.match(regex);
20
- if (match && match[1]) {
21
- computeUnits.push(match[1]);
22
- }
23
- });
24
- return computeUnits;
25
- });
26
- }
27
- exports.findComputeUnitConsumption = findComputeUnitConsumption;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTokenAddress = void 0;
4
- const spl_token_1 = require("@solana/spl-token");
5
- const web3_js_1 = require("@solana/web3.js");
6
- const getTokenAddress = (mintAddress, userPubKey) => {
7
- return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, new web3_js_1.PublicKey(mintAddress), new web3_js_1.PublicKey(userPubKey));
8
- };
9
- exports.getTokenAddress = getTokenAddress;
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.promiseTimeout = void 0;
4
- function promiseTimeout(promise, timeoutMs) {
5
- let timeoutId;
6
- const timeoutPromise = new Promise((resolve) => {
7
- timeoutId = setTimeout(() => resolve(null), timeoutMs);
8
- });
9
- return Promise.race([promise, timeoutPromise]).then((result) => {
10
- clearTimeout(timeoutId);
11
- return result;
12
- });
13
- }
14
- exports.promiseTimeout = promiseTimeout;
package/src/util/tps.js DELETED
@@ -1,27 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.estimateTps = void 0;
13
- function estimateTps(programId, connection, failed) {
14
- return __awaiter(this, void 0, void 0, function* () {
15
- let signatures = yield connection.getSignaturesForAddress(programId, undefined, 'finalized');
16
- if (failed) {
17
- signatures = signatures.filter((signature) => signature.err);
18
- }
19
- const numberOfSignatures = signatures.length;
20
- if (numberOfSignatures === 0) {
21
- return 0;
22
- }
23
- return (numberOfSignatures /
24
- (signatures[0].blockTime - signatures[numberOfSignatures - 1].blockTime));
25
- });
26
- }
27
- exports.estimateTps = estimateTps;