@drift-labs/sdk 2.21.0-beta.0 → 2.21.0-beta.1

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.
@@ -14,8 +14,9 @@ export declare class PollingUserAccountSubscriber implements UserAccountSubscrib
14
14
  accountLoader: BulkAccountLoader;
15
15
  accountsToPoll: Map<string, AccountToPoll>;
16
16
  errorCallbackId?: string;
17
+ lazyDecode: boolean;
17
18
  user?: DataAndSlot<UserAccount>;
18
- constructor(program: Program, userAccountPublicKey: PublicKey, accountLoader: BulkAccountLoader);
19
+ constructor(program: Program, userAccountPublicKey: PublicKey, accountLoader: BulkAccountLoader, lazyDecode?: boolean);
19
20
  subscribe(): Promise<boolean>;
20
21
  addToAccountLoader(): Promise<void>;
21
22
  fetchIfUnloaded(): Promise<void>;
@@ -5,13 +5,14 @@ const types_1 = require("./types");
5
5
  const events_1 = require("events");
6
6
  const utils_1 = require("./utils");
7
7
  class PollingUserAccountSubscriber {
8
- constructor(program, userAccountPublicKey, accountLoader) {
8
+ constructor(program, userAccountPublicKey, accountLoader, lazyDecode = false) {
9
9
  this.accountsToPoll = new Map();
10
10
  this.isSubscribed = false;
11
11
  this.program = program;
12
12
  this.accountLoader = accountLoader;
13
13
  this.eventEmitter = new events_1.EventEmitter();
14
14
  this.userAccountPublicKey = userAccountPublicKey;
15
+ this.lazyDecode = lazyDecode;
15
16
  }
16
17
  async subscribe() {
17
18
  if (this.isSubscribed) {
@@ -40,7 +41,9 @@ class PollingUserAccountSubscriber {
40
41
  return;
41
42
  }
42
43
  const account = this.program.account[accountToPoll.key].coder.accounts.decode((0, utils_1.capitalize)(accountToPoll.key), buffer);
43
- this[accountToPoll.key] = { data: account, slot };
44
+ if (!this.lazyDecode) {
45
+ this[accountToPoll.key] = { data: account, slot };
46
+ }
44
47
  // @ts-ignore
45
48
  this.eventEmitter.emit(accountToPoll.eventType, account);
46
49
  this.eventEmitter.emit('update');
@@ -53,7 +56,12 @@ class PollingUserAccountSubscriber {
53
56
  async fetchIfUnloaded() {
54
57
  let shouldFetch = false;
55
58
  for (const [_, accountToPoll] of this.accountsToPoll) {
56
- if (this[accountToPoll.key] === undefined) {
59
+ if (!this.lazyDecode && this[accountToPoll.key] === undefined) {
60
+ shouldFetch = true;
61
+ break;
62
+ }
63
+ else if (this.lazyDecode &&
64
+ this.accountLoader.bufferAndSlotMap.has(accountToPoll.publicKey.toString())) {
57
65
  shouldFetch = true;
58
66
  break;
59
67
  }
@@ -66,7 +74,7 @@ class PollingUserAccountSubscriber {
66
74
  await this.accountLoader.load();
67
75
  for (const [_, accountToPoll] of this.accountsToPoll) {
68
76
  const { buffer, slot } = this.accountLoader.getBufferAndSlot(accountToPoll.publicKey);
69
- if (buffer) {
77
+ if (buffer && !this.lazyDecode) {
70
78
  const account = this.program.account[accountToPoll.key].coder.accounts.decode((0, utils_1.capitalize)(accountToPoll.key), buffer);
71
79
  this[accountToPoll.key] = { data: account, slot };
72
80
  }
@@ -75,7 +83,7 @@ class PollingUserAccountSubscriber {
75
83
  doAccountsExist() {
76
84
  let success = true;
77
85
  for (const [_, accountToPoll] of this.accountsToPoll) {
78
- if (!this[accountToPoll.key]) {
86
+ if (!this.accountLoader.bufferAndSlotMap.has(accountToPoll.publicKey.toString())) {
79
87
  success = false;
80
88
  break;
81
89
  }
@@ -101,7 +109,14 @@ class PollingUserAccountSubscriber {
101
109
  }
102
110
  getUserAccountAndSlot() {
103
111
  this.assertIsSubscribed();
104
- return this.user;
112
+ if (!this.lazyDecode) {
113
+ return this.user;
114
+ }
115
+ else {
116
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(this.userAccountPublicKey);
117
+ const account = this.program.account.user.coder.accounts.decode('User', buffer);
118
+ return { data: account, slot };
119
+ }
105
120
  }
106
121
  }
107
122
  exports.PollingUserAccountSubscriber = PollingUserAccountSubscriber;
@@ -191,6 +191,7 @@ export declare class DriftClient {
191
191
  getCancelOrdersIx(marketType: MarketType | null, marketIndex: number | null, direction: PositionDirection | null): Promise<TransactionInstruction>;
192
192
  fillPerpOrder(userAccountPublicKey: PublicKey, user: UserAccount, order?: Pick<Order, 'marketIndex' | 'orderId'>, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
193
193
  getFillPerpOrderIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, order: Pick<Order, 'marketIndex' | 'orderId'>, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo): Promise<TransactionInstruction>;
194
+ getRevertFillIx(): Promise<TransactionInstruction>;
194
195
  placeSpotOrder(orderParams: OptionalOrderParams, txParams?: TxParams): Promise<TransactionSignature>;
195
196
  getPlaceSpotOrderIx(orderParams: OptionalOrderParams): Promise<TransactionInstruction>;
196
197
  fillSpotOrder(userAccountPublicKey: PublicKey, user: UserAccount, order?: Order, fulfillmentConfig?: SerumV3FulfillmentConfigAccount, makerInfo?: MakerInfo, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
@@ -201,8 +202,8 @@ export declare class DriftClient {
201
202
  getTriggerOrderIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, order: Order): Promise<TransactionInstruction>;
202
203
  forceCancelOrders(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
203
204
  getForceCancelOrdersIx(userAccountPublicKey: PublicKey, userAccount: UserAccount): Promise<TransactionInstruction>;
204
- updateUserInactive(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
205
- getUpdateUserInactiveIx(userAccountPublicKey: PublicKey, userAccount: UserAccount): Promise<TransactionInstruction>;
205
+ updateUserIdle(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
206
+ getUpdateUserIdleIx(userAccountPublicKey: PublicKey, userAccount: UserAccount): Promise<TransactionInstruction>;
206
207
  placeAndTakePerpOrder(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
207
208
  getPlaceAndTakePerpOrderIx(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo): Promise<TransactionInstruction>;
208
209
  placeAndMakePerpOrder(orderParams: OptionalOrderParams, takerInfo: TakerInfo, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<TransactionSignature>;
@@ -79,6 +79,7 @@ class DriftClient {
79
79
  ? {
80
80
  type: 'polling',
81
81
  accountLoader: config.accountSubscription.accountLoader,
82
+ lazyDecode: config.accountSubscription.lazyDecode,
82
83
  }
83
84
  : {
84
85
  type: 'websocket',
@@ -1357,6 +1358,18 @@ class DriftClient {
1357
1358
  remainingAccounts,
1358
1359
  });
1359
1360
  }
1361
+ async getRevertFillIx() {
1362
+ const fillerPublicKey = await this.getUserAccountPublicKey();
1363
+ const fillerStatsPublicKey = this.getUserStatsAccountPublicKey();
1364
+ return this.program.instruction.revertFill({
1365
+ accounts: {
1366
+ state: await this.getStatePublicKey(),
1367
+ filler: fillerPublicKey,
1368
+ fillerStats: fillerStatsPublicKey,
1369
+ authority: this.wallet.publicKey,
1370
+ },
1371
+ });
1372
+ }
1360
1373
  async placeSpotOrder(orderParams, txParams) {
1361
1374
  const { txSig, slot } = await this.sendTransaction((0, utils_1.wrapInTx)(await this.getPlaceSpotOrderIx(orderParams), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1362
1375
  this.spotMarketLastSlotCache.set(orderParams.marketIndex, slot);
@@ -1592,16 +1605,16 @@ class DriftClient {
1592
1605
  remainingAccounts,
1593
1606
  });
1594
1607
  }
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);
1608
+ async updateUserIdle(userAccountPublicKey, user, txParams) {
1609
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateUserIdleIx(userAccountPublicKey, user), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1597
1610
  return txSig;
1598
1611
  }
1599
- async getUpdateUserInactiveIx(userAccountPublicKey, userAccount) {
1612
+ async getUpdateUserIdleIx(userAccountPublicKey, userAccount) {
1600
1613
  const fillerPublicKey = await this.getUserAccountPublicKey();
1601
1614
  const remainingAccounts = this.getRemainingAccounts({
1602
1615
  userAccounts: [userAccount],
1603
1616
  });
1604
- return await this.program.instruction.updateUserInactive({
1617
+ return await this.program.instruction.updateUserIdle({
1605
1618
  accounts: {
1606
1619
  state: await this.getStatePublicKey(),
1607
1620
  filler: fillerPublicKey,
@@ -25,6 +25,7 @@ export type DriftClientSubscriptionConfig = {
25
25
  } | {
26
26
  type: 'polling';
27
27
  accountLoader: BulkAccountLoader;
28
+ lazyDecode?: boolean;
28
29
  };
29
30
  type TxSenderConfig = {
30
31
  type: 'retry';
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.21.0-beta.0",
2
+ "version": "2.21.0-beta.1",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -909,6 +909,32 @@
909
909
  }
910
910
  ]
911
911
  },
912
+ {
913
+ "name": "revertFill",
914
+ "accounts": [
915
+ {
916
+ "name": "state",
917
+ "isMut": false,
918
+ "isSigner": false
919
+ },
920
+ {
921
+ "name": "authority",
922
+ "isMut": false,
923
+ "isSigner": true
924
+ },
925
+ {
926
+ "name": "filler",
927
+ "isMut": true,
928
+ "isSigner": false
929
+ },
930
+ {
931
+ "name": "fillerStats",
932
+ "isMut": true,
933
+ "isSigner": false
934
+ }
935
+ ],
936
+ "args": []
937
+ },
912
938
  {
913
939
  "name": "fillSpotOrder",
914
940
  "accounts": [
@@ -1023,6 +1049,32 @@
1023
1049
  ],
1024
1050
  "args": []
1025
1051
  },
1052
+ {
1053
+ "name": "updateUserIdle",
1054
+ "accounts": [
1055
+ {
1056
+ "name": "state",
1057
+ "isMut": false,
1058
+ "isSigner": false
1059
+ },
1060
+ {
1061
+ "name": "authority",
1062
+ "isMut": false,
1063
+ "isSigner": true
1064
+ },
1065
+ {
1066
+ "name": "filler",
1067
+ "isMut": true,
1068
+ "isSigner": false
1069
+ },
1070
+ {
1071
+ "name": "user",
1072
+ "isMut": true,
1073
+ "isSigner": false
1074
+ }
1075
+ ],
1076
+ "args": []
1077
+ },
1026
1078
  {
1027
1079
  "name": "settlePnl",
1028
1080
  "accounts": [
@@ -8742,6 +8794,11 @@
8742
8794
  "code": 6238,
8743
8795
  "name": "UserNotInactive",
8744
8796
  "msg": "User Not Inactive"
8797
+ },
8798
+ {
8799
+ "code": 6239,
8800
+ "name": "RevertFill",
8801
+ "msg": "RevertFill"
8745
8802
  }
8746
8803
  ]
8747
8804
  }
@@ -31,12 +31,12 @@ class RetryTxSender {
31
31
  async prepareTx(tx, additionalSigners, opts) {
32
32
  tx.feePayer = this.provider.wallet.publicKey;
33
33
  tx.recentBlockhash = (await this.provider.connection.getRecentBlockhash(opts.preflightCommitment)).blockhash;
34
- const signedTx = await this.provider.wallet.signTransaction(tx);
35
34
  additionalSigners
36
35
  .filter((s) => s !== undefined)
37
36
  .forEach((kp) => {
38
- signedTx.partialSign(kp);
37
+ tx.partialSign(kp);
39
38
  });
39
+ const signedTx = await this.provider.wallet.signTransaction(tx);
40
40
  return signedTx;
41
41
  }
42
42
  async sendVersionedTransaction(ixs, lookupTableAccounts, additionalSigners, opts) {
package/lib/types.d.ts CHANGED
@@ -847,7 +847,7 @@ export type UserAccount = {
847
847
  liquidationMarginFreed: BN;
848
848
  lastActiveSlot: BN;
849
849
  isMarginTradingEnabled: boolean;
850
- inactive: boolean;
850
+ idle: boolean;
851
851
  };
852
852
  export type SpotPosition = {
853
853
  marketIndex: number;
package/lib/user.js CHANGED
@@ -25,7 +25,7 @@ class User {
25
25
  this.driftClient = config.driftClient;
26
26
  this.userAccountPublicKey = config.userAccountPublicKey;
27
27
  if (((_a = config.accountSubscription) === null || _a === void 0 ? void 0 : _a.type) === 'polling') {
28
- this.accountSubscriber = new pollingUserAccountSubscriber_1.PollingUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey, config.accountSubscription.accountLoader);
28
+ this.accountSubscriber = new pollingUserAccountSubscriber_1.PollingUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey, config.accountSubscription.accountLoader, config.accountSubscription.lazyDecode);
29
29
  }
30
30
  else {
31
31
  this.accountSubscriber = new webSocketUserAccountSubscriber_1.WebSocketUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey);
@@ -1214,7 +1214,7 @@ class User {
1214
1214
  }
1215
1215
  canMakeIdle(slot, slotsBeforeIdle) {
1216
1216
  const userAccount = this.getUserAccount();
1217
- if (userAccount.inactive) {
1217
+ if (userAccount.idle) {
1218
1218
  return false;
1219
1219
  }
1220
1220
  const userLastActiveSlot = userAccount.lastActiveSlot;
@@ -11,4 +11,5 @@ export type UserSubscriptionConfig = {
11
11
  } | {
12
12
  type: 'polling';
13
13
  accountLoader: BulkAccountLoader;
14
+ lazyDecode?: boolean;
14
15
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.21.0-beta.0",
3
+ "version": "2.21.0-beta.1",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -23,18 +23,22 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
23
23
  accountsToPoll = new Map<string, AccountToPoll>();
24
24
  errorCallbackId?: string;
25
25
 
26
+ lazyDecode: boolean;
27
+
26
28
  user?: DataAndSlot<UserAccount>;
27
29
 
28
30
  public constructor(
29
31
  program: Program,
30
32
  userAccountPublicKey: PublicKey,
31
- accountLoader: BulkAccountLoader
33
+ accountLoader: BulkAccountLoader,
34
+ lazyDecode = false
32
35
  ) {
33
36
  this.isSubscribed = false;
34
37
  this.program = program;
35
38
  this.accountLoader = accountLoader;
36
39
  this.eventEmitter = new EventEmitter();
37
40
  this.userAccountPublicKey = userAccountPublicKey;
41
+ this.lazyDecode = lazyDecode;
38
42
  }
39
43
 
40
44
  async subscribe(): Promise<boolean> {
@@ -75,7 +79,9 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
75
79
  const account = this.program.account[
76
80
  accountToPoll.key
77
81
  ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
78
- this[accountToPoll.key] = { data: account, slot };
82
+ if (!this.lazyDecode) {
83
+ this[accountToPoll.key] = { data: account, slot };
84
+ }
79
85
  // @ts-ignore
80
86
  this.eventEmitter.emit(accountToPoll.eventType, account);
81
87
  this.eventEmitter.emit('update');
@@ -91,7 +97,15 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
91
97
  async fetchIfUnloaded(): Promise<void> {
92
98
  let shouldFetch = false;
93
99
  for (const [_, accountToPoll] of this.accountsToPoll) {
94
- if (this[accountToPoll.key] === undefined) {
100
+ if (!this.lazyDecode && this[accountToPoll.key] === undefined) {
101
+ shouldFetch = true;
102
+ break;
103
+ } else if (
104
+ this.lazyDecode &&
105
+ this.accountLoader.bufferAndSlotMap.has(
106
+ accountToPoll.publicKey.toString()
107
+ )
108
+ ) {
95
109
  shouldFetch = true;
96
110
  break;
97
111
  }
@@ -108,7 +122,7 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
108
122
  const { buffer, slot } = this.accountLoader.getBufferAndSlot(
109
123
  accountToPoll.publicKey
110
124
  );
111
- if (buffer) {
125
+ if (buffer && !this.lazyDecode) {
112
126
  const account = this.program.account[
113
127
  accountToPoll.key
114
128
  ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
@@ -120,7 +134,11 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
120
134
  doAccountsExist(): boolean {
121
135
  let success = true;
122
136
  for (const [_, accountToPoll] of this.accountsToPoll) {
123
- if (!this[accountToPoll.key]) {
137
+ if (
138
+ !this.accountLoader.bufferAndSlotMap.has(
139
+ accountToPoll.publicKey.toString()
140
+ )
141
+ ) {
124
142
  success = false;
125
143
  break;
126
144
  }
@@ -158,6 +176,17 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
158
176
 
159
177
  public getUserAccountAndSlot(): DataAndSlot<UserAccount> {
160
178
  this.assertIsSubscribed();
161
- return this.user;
179
+ if (!this.lazyDecode) {
180
+ return this.user;
181
+ } else {
182
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(
183
+ this.userAccountPublicKey
184
+ );
185
+ const account = this.program.account.user.coder.accounts.decode(
186
+ 'User',
187
+ buffer
188
+ );
189
+ return { data: account, slot };
190
+ }
162
191
  }
163
192
  }
@@ -0,0 +1,9 @@
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;
@@ -160,6 +160,7 @@ export class DriftClient {
160
160
  ? {
161
161
  type: 'polling',
162
162
  accountLoader: config.accountSubscription.accountLoader,
163
+ lazyDecode: config.accountSubscription.lazyDecode,
163
164
  }
164
165
  : {
165
166
  type: 'websocket',
@@ -2394,6 +2395,20 @@ export class DriftClient {
2394
2395
  });
2395
2396
  }
2396
2397
 
2398
+ public async getRevertFillIx(): Promise<TransactionInstruction> {
2399
+ const fillerPublicKey = await this.getUserAccountPublicKey();
2400
+ const fillerStatsPublicKey = this.getUserStatsAccountPublicKey();
2401
+
2402
+ return this.program.instruction.revertFill({
2403
+ accounts: {
2404
+ state: await this.getStatePublicKey(),
2405
+ filler: fillerPublicKey,
2406
+ fillerStats: fillerStatsPublicKey,
2407
+ authority: this.wallet.publicKey,
2408
+ },
2409
+ });
2410
+ }
2411
+
2397
2412
  public async placeSpotOrder(
2398
2413
  orderParams: OptionalOrderParams,
2399
2414
  txParams?: TxParams
@@ -2759,14 +2774,14 @@ export class DriftClient {
2759
2774
  });
2760
2775
  }
2761
2776
 
2762
- public async updateUserInactive(
2777
+ public async updateUserIdle(
2763
2778
  userAccountPublicKey: PublicKey,
2764
2779
  user: UserAccount,
2765
2780
  txParams?: TxParams
2766
2781
  ): Promise<TransactionSignature> {
2767
2782
  const { txSig } = await this.txSender.send(
2768
2783
  wrapInTx(
2769
- await this.getUpdateUserInactiveIx(userAccountPublicKey, user),
2784
+ await this.getUpdateUserIdleIx(userAccountPublicKey, user),
2770
2785
  txParams?.computeUnits,
2771
2786
  txParams?.computeUnitsPrice
2772
2787
  ),
@@ -2776,7 +2791,7 @@ export class DriftClient {
2776
2791
  return txSig;
2777
2792
  }
2778
2793
 
2779
- public async getUpdateUserInactiveIx(
2794
+ public async getUpdateUserIdleIx(
2780
2795
  userAccountPublicKey: PublicKey,
2781
2796
  userAccount: UserAccount
2782
2797
  ): Promise<TransactionInstruction> {
@@ -2786,7 +2801,7 @@ export class DriftClient {
2786
2801
  userAccounts: [userAccount],
2787
2802
  });
2788
2803
 
2789
- return await this.program.instruction.updateUserInactive({
2804
+ return await this.program.instruction.updateUserIdle({
2790
2805
  accounts: {
2791
2806
  state: await this.getStatePublicKey(),
2792
2807
  filler: fillerPublicKey,
@@ -29,6 +29,7 @@ export type DriftClientSubscriptionConfig =
29
29
  | {
30
30
  type: 'polling';
31
31
  accountLoader: BulkAccountLoader;
32
+ lazyDecode?: boolean;
32
33
  };
33
34
 
34
35
  type TxSenderConfig = {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.21.0-beta.0",
2
+ "version": "2.21.0-beta.1",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -909,6 +909,32 @@
909
909
  }
910
910
  ]
911
911
  },
912
+ {
913
+ "name": "revertFill",
914
+ "accounts": [
915
+ {
916
+ "name": "state",
917
+ "isMut": false,
918
+ "isSigner": false
919
+ },
920
+ {
921
+ "name": "authority",
922
+ "isMut": false,
923
+ "isSigner": true
924
+ },
925
+ {
926
+ "name": "filler",
927
+ "isMut": true,
928
+ "isSigner": false
929
+ },
930
+ {
931
+ "name": "fillerStats",
932
+ "isMut": true,
933
+ "isSigner": false
934
+ }
935
+ ],
936
+ "args": []
937
+ },
912
938
  {
913
939
  "name": "fillSpotOrder",
914
940
  "accounts": [
@@ -1023,6 +1049,32 @@
1023
1049
  ],
1024
1050
  "args": []
1025
1051
  },
1052
+ {
1053
+ "name": "updateUserIdle",
1054
+ "accounts": [
1055
+ {
1056
+ "name": "state",
1057
+ "isMut": false,
1058
+ "isSigner": false
1059
+ },
1060
+ {
1061
+ "name": "authority",
1062
+ "isMut": false,
1063
+ "isSigner": true
1064
+ },
1065
+ {
1066
+ "name": "filler",
1067
+ "isMut": true,
1068
+ "isSigner": false
1069
+ },
1070
+ {
1071
+ "name": "user",
1072
+ "isMut": true,
1073
+ "isSigner": false
1074
+ }
1075
+ ],
1076
+ "args": []
1077
+ },
1026
1078
  {
1027
1079
  "name": "settlePnl",
1028
1080
  "accounts": [
@@ -8742,6 +8794,11 @@
8742
8794
  "code": 6238,
8743
8795
  "name": "UserNotInactive",
8744
8796
  "msg": "User Not Inactive"
8797
+ },
8798
+ {
8799
+ "code": 6239,
8800
+ "name": "RevertFill",
8801
+ "msg": "RevertFill"
8745
8802
  }
8746
8803
  ]
8747
8804
  }
@@ -0,0 +1,38 @@
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;
@@ -75,13 +75,14 @@ export class RetryTxSender implements TxSender {
75
75
  )
76
76
  ).blockhash;
77
77
 
78
- const signedTx = await this.provider.wallet.signTransaction(tx);
79
78
  additionalSigners
80
79
  .filter((s): s is Signer => s !== undefined)
81
80
  .forEach((kp) => {
82
- signedTx.partialSign(kp);
81
+ tx.partialSign(kp);
83
82
  });
84
83
 
84
+ const signedTx = await this.provider.wallet.signTransaction(tx);
85
+
85
86
  return signedTx;
86
87
  }
87
88
 
package/src/types.ts CHANGED
@@ -800,7 +800,7 @@ export type UserAccount = {
800
800
  liquidationMarginFreed: BN;
801
801
  lastActiveSlot: BN;
802
802
  isMarginTradingEnabled: boolean;
803
- inactive: boolean;
803
+ idle: boolean;
804
804
  };
805
805
 
806
806
  export type SpotPosition = {
package/src/user.ts CHANGED
@@ -95,7 +95,8 @@ export class User {
95
95
  this.accountSubscriber = new PollingUserAccountSubscriber(
96
96
  config.driftClient.program,
97
97
  config.userAccountPublicKey,
98
- config.accountSubscription.accountLoader
98
+ config.accountSubscription.accountLoader,
99
+ config.accountSubscription.lazyDecode
99
100
  );
100
101
  } else {
101
102
  this.accountSubscriber = new WebSocketUserAccountSubscriber(
@@ -2173,7 +2174,7 @@ export class User {
2173
2174
 
2174
2175
  public canMakeIdle(slot: BN, slotsBeforeIdle: BN): boolean {
2175
2176
  const userAccount = this.getUserAccount();
2176
- if (userAccount.inactive) {
2177
+ if (userAccount.idle) {
2177
2178
  return false;
2178
2179
  }
2179
2180
 
package/src/userConfig.ts CHANGED
@@ -15,4 +15,5 @@ export type UserSubscriptionConfig =
15
15
  | {
16
16
  type: 'polling';
17
17
  accountLoader: BulkAccountLoader;
18
+ lazyDecode?: boolean;
18
19
  };
@@ -0,0 +1,27 @@
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;
@@ -0,0 +1,9 @@
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;
@@ -0,0 +1,14 @@
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;
@@ -0,0 +1,27 @@
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;