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

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/VERSION CHANGED
@@ -1 +1 @@
1
- 2.31.1-beta.1
1
+ 2.31.1-beta.3
@@ -0,0 +1,23 @@
1
+ /// <reference types="node" />
2
+ import { DataAndSlot, UserAccountEvents, UserAccountSubscriber } from './types';
3
+ import { PublicKey } from '@solana/web3.js';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { UserAccount } from '../types';
7
+ export declare class MockUserAccountSubscriber implements UserAccountSubscriber {
8
+ isSubscribed: boolean;
9
+ eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
10
+ userAccountPublicKey: PublicKey;
11
+ callbackId?: string;
12
+ errorCallbackId?: string;
13
+ user: DataAndSlot<UserAccount>;
14
+ constructor(userAccountPublicKey: PublicKey, data: UserAccount, slot: number);
15
+ subscribe(_userAccount?: UserAccount): Promise<boolean>;
16
+ addToAccountLoader(): Promise<void>;
17
+ fetch(): Promise<void>;
18
+ doesAccountExist(): boolean;
19
+ unsubscribe(): Promise<void>;
20
+ assertIsSubscribed(): void;
21
+ getUserAccountAndSlot(): DataAndSlot<UserAccount>;
22
+ updateData(userAccount: UserAccount, slot: number): void;
23
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MockUserAccountSubscriber = void 0;
4
+ const events_1 = require("events");
5
+ class MockUserAccountSubscriber {
6
+ constructor(userAccountPublicKey, data, slot) {
7
+ this.isSubscribed = true;
8
+ this.eventEmitter = new events_1.EventEmitter();
9
+ this.userAccountPublicKey = userAccountPublicKey;
10
+ this.user = { data, slot };
11
+ }
12
+ async subscribe(_userAccount) {
13
+ return true;
14
+ }
15
+ async addToAccountLoader() { }
16
+ async fetch() { }
17
+ doesAccountExist() {
18
+ return this.user !== undefined;
19
+ }
20
+ async unsubscribe() { }
21
+ assertIsSubscribed() { }
22
+ getUserAccountAndSlot() {
23
+ return this.user;
24
+ }
25
+ updateData(userAccount, slot) {
26
+ this.user = { data: userAccount, slot };
27
+ this.eventEmitter.emit('userAccountUpdate', userAccount);
28
+ this.eventEmitter.emit('update');
29
+ }
30
+ }
31
+ exports.MockUserAccountSubscriber = MockUserAccountSubscriber;
@@ -14,6 +14,7 @@ import { User } from './user';
14
14
  import { UserSubscriptionConfig } from './userConfig';
15
15
  import { UserStats } from './userStats';
16
16
  import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
17
+ import { UserStatsSubscriptionConfig } from './userStatsConfig';
17
18
  type RemainingAccountParams = {
18
19
  userAccounts: UserAccount[];
19
20
  writablePerpMarketIndexes?: number[];
@@ -36,6 +37,7 @@ export declare class DriftClient {
36
37
  userStats?: UserStats;
37
38
  activeSubAccountId: number;
38
39
  userAccountSubscriptionConfig: UserSubscriptionConfig;
40
+ userStatsAccountSubscriptionConfig: UserStatsSubscriptionConfig;
39
41
  accountSubscriber: DriftClientAccountSubscriber;
40
42
  eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
41
43
  _isSubscribed: boolean;
@@ -64,7 +64,7 @@ class DriftClient {
64
64
  this._isSubscribed = val;
65
65
  }
66
66
  constructor(config) {
67
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
67
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
68
68
  this.users = new Map();
69
69
  this._isSubscribed = false;
70
70
  this.perpMarketLastSlotCache = new Map();
@@ -93,15 +93,24 @@ class DriftClient {
93
93
  ? new Map([[this.authority.toString(), config.subAccountIds]])
94
94
  : new Map();
95
95
  this.includeDelegates = (_f = config.includeDelegates) !== null && _f !== void 0 ? _f : false;
96
- this.userAccountSubscriptionConfig =
97
- ((_g = config.accountSubscription) === null || _g === void 0 ? void 0 : _g.type) === 'polling'
98
- ? {
99
- type: 'polling',
100
- accountLoader: config.accountSubscription.accountLoader,
101
- }
102
- : {
103
- type: 'websocket',
104
- };
96
+ if (((_g = config.accountSubscription) === null || _g === void 0 ? void 0 : _g.type) === 'polling') {
97
+ this.userAccountSubscriptionConfig = {
98
+ type: 'polling',
99
+ accountLoader: config.accountSubscription.accountLoader,
100
+ };
101
+ this.userStatsAccountSubscriptionConfig = {
102
+ type: 'polling',
103
+ accountLoader: config.accountSubscription.accountLoader,
104
+ };
105
+ }
106
+ else {
107
+ this.userAccountSubscriptionConfig = {
108
+ type: 'websocket',
109
+ };
110
+ this.userStatsAccountSubscriptionConfig = {
111
+ type: 'websocket',
112
+ };
113
+ }
105
114
  if (config.userStats) {
106
115
  this.userStats = new userStats_1.UserStats({
107
116
  driftClient: this,
@@ -123,7 +132,7 @@ class DriftClient {
123
132
  this.accountSubscriber = new webSocketDriftClientAccountSubscriber_1.WebSocketDriftClientAccountSubscriber(this.program, (_m = config.perpMarketIndexes) !== null && _m !== void 0 ? _m : [], (_o = config.spotMarketIndexes) !== null && _o !== void 0 ? _o : [], (_p = config.oracleInfos) !== null && _p !== void 0 ? _p : [], noMarketsAndOraclesSpecified);
124
133
  }
125
134
  this.eventEmitter = this.accountSubscriber.eventEmitter;
126
- this.txSender = new retryTxSender_1.RetryTxSender(this.provider, (_q = config.txSenderConfig) === null || _q === void 0 ? void 0 : _q.timeout, (_r = config.txSenderConfig) === null || _r === void 0 ? void 0 : _r.retrySleep, (_s = config.txSenderConfig) === null || _s === void 0 ? void 0 : _s.additionalConnections);
135
+ this.txSender = (_q = config.txSender) !== null && _q !== void 0 ? _q : new retryTxSender_1.RetryTxSender(this.provider);
127
136
  }
128
137
  getUserMapKey(subAccountId, authority) {
129
138
  return `${subAccountId}_${authority.toString()}`;
@@ -304,7 +313,7 @@ class DriftClient {
304
313
  this.userStats = new userStats_1.UserStats({
305
314
  driftClient: this,
306
315
  userStatsAccountPublicKey: this.getUserStatsAccountPublicKey(),
307
- accountSubscription: this.userAccountSubscriptionConfig,
316
+ accountSubscription: this.userStatsAccountSubscriptionConfig,
308
317
  });
309
318
  await this.userStats.subscribe();
310
319
  }
@@ -3,6 +3,7 @@ import { IWallet } from './types';
3
3
  import { OracleInfo } from './oracles/types';
4
4
  import { BulkAccountLoader } from './accounts/bulkAccountLoader';
5
5
  import { DriftEnv } from './config';
6
+ import { TxSender } from './tx/types';
6
7
  export type DriftClientConfig = {
7
8
  connection: Connection;
8
9
  wallet: IWallet;
@@ -10,7 +11,7 @@ export type DriftClientConfig = {
10
11
  programID?: PublicKey;
11
12
  accountSubscription?: DriftClientSubscriptionConfig;
12
13
  opts?: ConfirmOptions;
13
- txSenderConfig?: TxSenderConfig;
14
+ txSender?: TxSender;
14
15
  subAccountIds?: number[];
15
16
  activeSubAccountId?: number;
16
17
  perpMarketIndexes?: number[];
@@ -30,10 +31,3 @@ export type DriftClientSubscriptionConfig = {
30
31
  type: 'polling';
31
32
  accountLoader: BulkAccountLoader;
32
33
  };
33
- type TxSenderConfig = {
34
- type: 'retry';
35
- timeout?: number;
36
- retrySleep?: number;
37
- additionalConnections?: Connection[];
38
- };
39
- export {};
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.31.1-beta.0",
2
+ "version": "2.31.1-beta.2",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -10,6 +10,7 @@ export declare class RetryTxSender implements TxSender {
10
10
  timeout: number;
11
11
  retrySleep: number;
12
12
  additionalConnections: Connection[];
13
+ timoutCount: number;
13
14
  constructor(provider: AnchorProvider, timeout?: number, retrySleep?: number, additionalConnections?: Connection[]);
14
15
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
15
16
  prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions): Promise<Transaction>;
@@ -22,5 +23,6 @@ export declare class RetryTxSender implements TxSender {
22
23
  promiseTimeout<T>(promises: Promise<T>[], timeoutMs: number): Promise<T | null>;
23
24
  sendToAdditionalConnections(rawTx: Buffer | Uint8Array, opts: ConfirmOptions): void;
24
25
  addAdditionalConnection(newConnection: Connection): void;
26
+ getTimeoutCount(): number;
25
27
  }
26
28
  export {};
@@ -11,6 +11,7 @@ const DEFAULT_TIMEOUT = 35000;
11
11
  const DEFAULT_RETRY = 8000;
12
12
  class RetryTxSender {
13
13
  constructor(provider, timeout, retrySleep, additionalConnections = new Array()) {
14
+ this.timoutCount = 0;
14
15
  this.provider = provider;
15
16
  this.timeout = timeout !== null && timeout !== void 0 ? timeout : DEFAULT_TIMEOUT;
16
17
  this.retrySleep = retrySleep !== null && retrySleep !== void 0 ? retrySleep : DEFAULT_RETRY;
@@ -174,6 +175,7 @@ class RetryTxSender {
174
175
  }
175
176
  }
176
177
  if (response === null) {
178
+ this.timoutCount += 1;
177
179
  const duration = (Date.now() - start) / 1000;
178
180
  throw new Error(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
179
181
  }
@@ -217,5 +219,8 @@ class RetryTxSender {
217
219
  this.additionalConnections.push(newConnection);
218
220
  }
219
221
  }
222
+ getTimeoutCount() {
223
+ return this.timoutCount;
224
+ }
220
225
  }
221
226
  exports.RetryTxSender = RetryTxSender;
package/lib/tx/types.d.ts CHANGED
@@ -11,4 +11,5 @@ export interface TxSender {
11
11
  sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
12
12
  getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<VersionedTransaction>;
13
13
  sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
14
+ getTimeoutCount(): number;
14
15
  }
package/lib/user.js CHANGED
@@ -20,13 +20,16 @@ class User {
20
20
  this._isSubscribed = val;
21
21
  }
22
22
  constructor(config) {
23
- var _a;
23
+ var _a, _b;
24
24
  this._isSubscribed = false;
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
28
  this.accountSubscriber = new pollingUserAccountSubscriber_1.PollingUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey, config.accountSubscription.accountLoader);
29
29
  }
30
+ else if (((_b = config.accountSubscription) === null || _b === void 0 ? void 0 : _b.type) === 'custom') {
31
+ this.accountSubscriber = config.accountSubscription.userAccountSubscriber;
32
+ }
30
33
  else {
31
34
  this.accountSubscriber = new webSocketUserAccountSubscriber_1.WebSocketUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey);
32
35
  }
@@ -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/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.3",
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
+ }
@@ -115,6 +115,7 @@ import { fetchUserStatsAccount } from './accounts/fetch';
115
115
  import { castNumberToSpotPrecision } from './math/spotMarket';
116
116
  import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
117
117
  import { getNonIdleUserFilter } from './memcmp';
118
+ import { UserStatsSubscriptionConfig } from './userStatsConfig';
118
119
 
119
120
  type RemainingAccountParams = {
120
121
  userAccounts: UserAccount[];
@@ -139,6 +140,7 @@ export class DriftClient {
139
140
  userStats?: UserStats;
140
141
  activeSubAccountId: number;
141
142
  userAccountSubscriptionConfig: UserSubscriptionConfig;
143
+ userStatsAccountSubscriptionConfig: UserStatsSubscriptionConfig;
142
144
  accountSubscriber: DriftClientAccountSubscriber;
143
145
  eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
144
146
  _isSubscribed = false;
@@ -206,15 +208,23 @@ export class DriftClient {
206
208
  : new Map<string, number[]>();
207
209
 
208
210
  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
- };
211
+ if (config.accountSubscription?.type === 'polling') {
212
+ this.userAccountSubscriptionConfig = {
213
+ type: 'polling',
214
+ accountLoader: config.accountSubscription.accountLoader,
215
+ };
216
+ this.userStatsAccountSubscriptionConfig = {
217
+ type: 'polling',
218
+ accountLoader: config.accountSubscription.accountLoader,
219
+ };
220
+ } else {
221
+ this.userAccountSubscriptionConfig = {
222
+ type: 'websocket',
223
+ };
224
+ this.userStatsAccountSubscriptionConfig = {
225
+ type: 'websocket',
226
+ };
227
+ }
218
228
 
219
229
  if (config.userStats) {
220
230
  this.userStats = new UserStats({
@@ -257,12 +267,7 @@ export class DriftClient {
257
267
  );
258
268
  }
259
269
  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
- );
270
+ this.txSender = config.txSender ?? new RetryTxSender(this.provider);
266
271
  }
267
272
 
268
273
  public getUserMapKey(subAccountId: number, authority: PublicKey): string {
@@ -547,7 +552,7 @@ export class DriftClient {
547
552
  this.userStats = new UserStats({
548
553
  driftClient: this,
549
554
  userStatsAccountPublicKey: this.getUserStatsAccountPublicKey(),
550
- accountSubscription: this.userAccountSubscriptionConfig,
555
+ accountSubscription: this.userStatsAccountSubscriptionConfig,
551
556
  });
552
557
 
553
558
  await this.userStats.subscribe();
@@ -8,6 +8,7 @@ import { IWallet } 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[];
@@ -39,10 +40,3 @@ export type DriftClientSubscriptionConfig =
39
40
  type: 'polling';
40
41
  accountLoader: BulkAccountLoader;
41
42
  };
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.3",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -30,6 +30,7 @@ export class RetryTxSender implements TxSender {
30
30
  timeout: number;
31
31
  retrySleep: number;
32
32
  additionalConnections: Connection[];
33
+ timoutCount = 0;
33
34
 
34
35
  public constructor(
35
36
  provider: AnchorProvider,
@@ -260,6 +261,7 @@ export class RetryTxSender implements TxSender {
260
261
  }
261
262
 
262
263
  if (response === null) {
264
+ this.timoutCount += 1;
263
265
  const duration = (Date.now() - start) / 1000;
264
266
  throw new Error(
265
267
  `Transaction was not confirmed in ${duration.toFixed(
@@ -325,4 +327,8 @@ export class RetryTxSender implements TxSender {
325
327
  this.additionalConnections.push(newConnection);
326
328
  }
327
329
  }
330
+
331
+ public getTimeoutCount(): number {
332
+ return this.timoutCount;
333
+ }
328
334
  }
package/src/tx/types.ts CHANGED
@@ -42,4 +42,6 @@ export interface TxSender {
42
42
  rawTransaction: Buffer | Uint8Array,
43
43
  opts: ConfirmOptions
44
44
  ): Promise<TxSigAndSlot>;
45
+
46
+ getTimeoutCount(): number;
45
47
  }
package/src/user.ts CHANGED
@@ -97,6 +97,8 @@ export class User {
97
97
  config.userAccountPublicKey,
98
98
  config.accountSubscription.accountLoader
99
99
  );
100
+ } else if (config.accountSubscription?.type === 'custom') {
101
+ this.accountSubscriber = config.accountSubscription.userAccountSubscriber;
100
102
  } else {
101
103
  this.accountSubscriber = new WebSocketUserAccountSubscriber(
102
104
  config.driftClient.program,
package/src/userConfig.ts CHANGED
@@ -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
 
5
6
  export type UserConfig = {
6
7
  accountSubscription?: UserSubscriptionConfig;
@@ -15,4 +16,8 @@ export type UserSubscriptionConfig =
15
16
  | {
16
17
  type: 'polling';
17
18
  accountLoader: BulkAccountLoader;
19
+ }
20
+ | {
21
+ type: 'custom';
22
+ userAccountSubscriber: UserAccountSubscriber;
18
23
  };