@drift-labs/sdk 2.98.0-beta.10 → 2.98.0-beta.12

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.98.0-beta.10
1
+ 2.98.0-beta.12
@@ -0,0 +1,29 @@
1
+ /// <reference types="node" />
2
+ import { DataAndSlot, HighLeverageModeConfigAccountEvents, HighLeverageModeConfigAccountSubscriber } from './types';
3
+ import { Program } from '@coral-xyz/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { PublicKey } from '@solana/web3.js';
7
+ import { BulkAccountLoader } from './bulkAccountLoader';
8
+ import { HighLeverageModeConfig } from '../types';
9
+ export declare class PollingHighLeverageModeConfigAccountSubscriber implements HighLeverageModeConfigAccountSubscriber {
10
+ isSubscribed: boolean;
11
+ program: Program;
12
+ eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
13
+ highLeverageModeConfigAccountPublicKey: PublicKey;
14
+ accountLoader: BulkAccountLoader;
15
+ callbackId?: string;
16
+ errorCallbackId?: string;
17
+ highLeverageModeConfigAccountAndSlot?: DataAndSlot<HighLeverageModeConfig>;
18
+ constructor(program: Program, publicKey: PublicKey, accountLoader: BulkAccountLoader);
19
+ subscribe(highLeverageModeConfig?: HighLeverageModeConfig): Promise<boolean>;
20
+ addToAccountLoader(): Promise<void>;
21
+ fetchIfUnloaded(): Promise<void>;
22
+ fetch(): Promise<void>;
23
+ doesAccountExist(): boolean;
24
+ unsubscribe(): Promise<void>;
25
+ assertIsSubscribed(): void;
26
+ getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
27
+ didSubscriptionSucceed(): boolean;
28
+ updateData(highLeverageModeConfig: HighLeverageModeConfig, slot: number): void;
29
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PollingHighLeverageModeConfigAccountSubscriber = void 0;
4
+ const types_1 = require("./types");
5
+ const events_1 = require("events");
6
+ class PollingHighLeverageModeConfigAccountSubscriber {
7
+ constructor(program, publicKey, accountLoader) {
8
+ this.isSubscribed = false;
9
+ this.program = program;
10
+ this.highLeverageModeConfigAccountPublicKey = publicKey;
11
+ this.accountLoader = accountLoader;
12
+ this.eventEmitter = new events_1.EventEmitter();
13
+ }
14
+ async subscribe(highLeverageModeConfig) {
15
+ if (this.isSubscribed) {
16
+ return true;
17
+ }
18
+ if (highLeverageModeConfig) {
19
+ this.highLeverageModeConfigAccountAndSlot = {
20
+ data: highLeverageModeConfig,
21
+ slot: undefined,
22
+ };
23
+ }
24
+ await this.addToAccountLoader();
25
+ await this.fetchIfUnloaded();
26
+ if (this.doesAccountExist()) {
27
+ this.eventEmitter.emit('update');
28
+ }
29
+ this.isSubscribed = true;
30
+ return true;
31
+ }
32
+ async addToAccountLoader() {
33
+ if (this.callbackId) {
34
+ return;
35
+ }
36
+ this.callbackId = await this.accountLoader.addAccount(this.highLeverageModeConfigAccountPublicKey, (buffer, slot) => {
37
+ if (!buffer) {
38
+ return;
39
+ }
40
+ if (this.highLeverageModeConfigAccountAndSlot &&
41
+ this.highLeverageModeConfigAccountAndSlot.slot > slot) {
42
+ return;
43
+ }
44
+ const account = this.program.account.user.coder.accounts.decode('HighLeverageModeConfig', buffer);
45
+ this.highLeverageModeConfigAccountAndSlot = { data: account, slot };
46
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', account);
47
+ this.eventEmitter.emit('update');
48
+ });
49
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
50
+ this.eventEmitter.emit('error', error);
51
+ });
52
+ }
53
+ async fetchIfUnloaded() {
54
+ if (this.highLeverageModeConfigAccountAndSlot === undefined) {
55
+ await this.fetch();
56
+ }
57
+ }
58
+ async fetch() {
59
+ var _a, _b;
60
+ try {
61
+ const dataAndContext = await this.program.account.highLeverageModeConfig.fetchAndContext(this.highLeverageModeConfigAccountPublicKey, this.accountLoader.commitment);
62
+ if (dataAndContext.context.slot >
63
+ ((_b = (_a = this.highLeverageModeConfigAccountAndSlot) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0)) {
64
+ this.highLeverageModeConfigAccountAndSlot = {
65
+ data: dataAndContext.data,
66
+ slot: dataAndContext.context.slot,
67
+ };
68
+ }
69
+ }
70
+ catch (e) {
71
+ console.log(`PollingHighLeverageModeConfigAccountSubscriber.fetch() HighLeverageModeConfig does not exist: ${e.message}`);
72
+ }
73
+ }
74
+ doesAccountExist() {
75
+ return this.highLeverageModeConfigAccountAndSlot !== undefined;
76
+ }
77
+ async unsubscribe() {
78
+ if (!this.isSubscribed) {
79
+ return;
80
+ }
81
+ this.accountLoader.removeAccount(this.highLeverageModeConfigAccountPublicKey, this.callbackId);
82
+ this.callbackId = undefined;
83
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
84
+ this.errorCallbackId = undefined;
85
+ this.isSubscribed = false;
86
+ }
87
+ assertIsSubscribed() {
88
+ if (!this.isSubscribed) {
89
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
90
+ }
91
+ }
92
+ getHighLeverageModeConfigAccountAndSlot() {
93
+ this.assertIsSubscribed();
94
+ return this.highLeverageModeConfigAccountAndSlot;
95
+ }
96
+ didSubscriptionSucceed() {
97
+ return !!this.highLeverageModeConfigAccountAndSlot;
98
+ }
99
+ updateData(highLeverageModeConfig, slot) {
100
+ if (!this.highLeverageModeConfigAccountAndSlot ||
101
+ this.highLeverageModeConfigAccountAndSlot.slot < slot) {
102
+ this.highLeverageModeConfigAccountAndSlot = {
103
+ data: highLeverageModeConfig,
104
+ slot,
105
+ };
106
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', highLeverageModeConfig);
107
+ this.eventEmitter.emit('update');
108
+ }
109
+ }
110
+ }
111
+ exports.PollingHighLeverageModeConfigAccountSubscriber = PollingHighLeverageModeConfigAccountSubscriber;
@@ -6,7 +6,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
6
6
  import { EventEmitter } from 'events';
7
7
  import { Context, PublicKey } from '@solana/web3.js';
8
8
  import { Account } from '@solana/spl-token';
9
- import { OracleInfo, OraclePriceData } from '..';
9
+ import { HighLeverageModeConfig, OracleInfo, OraclePriceData } from '..';
10
10
  import { ChannelOptions, CommitmentLevel } from '../isomorphic/grpc';
11
11
  export interface AccountSubscriber<T> {
12
12
  dataAndSlot?: DataAndSlot<T>;
@@ -153,3 +153,16 @@ export type GrpcConfigs = {
153
153
  commitmentLevel?: CommitmentLevel;
154
154
  channelOptions?: ChannelOptions;
155
155
  };
156
+ export interface HighLeverageModeConfigAccountSubscriber {
157
+ eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
158
+ isSubscribed: boolean;
159
+ subscribe(highLeverageModeConfigAccount?: HighLeverageModeConfig): Promise<boolean>;
160
+ fetch(): Promise<void>;
161
+ unsubscribe(): Promise<void>;
162
+ getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
163
+ }
164
+ export interface HighLeverageModeConfigAccountEvents {
165
+ highLeverageModeConfigAccountUpdate: (payload: HighLeverageModeConfig) => void;
166
+ update: void;
167
+ error: (e: Error) => void;
168
+ }
@@ -0,0 +1,23 @@
1
+ /// <reference types="node" />
2
+ import { DataAndSlot, AccountSubscriber, HighLeverageModeConfigAccountEvents, HighLeverageModeConfigAccountSubscriber } from './types';
3
+ import { Program } from '@coral-xyz/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { Commitment, PublicKey } from '@solana/web3.js';
7
+ import { HighLeverageModeConfig } from '../types';
8
+ export declare class WebSocketHighLeverageModeConfigAccountSubscriber implements HighLeverageModeConfigAccountSubscriber {
9
+ isSubscribed: boolean;
10
+ resubTimeoutMs?: number;
11
+ commitment?: Commitment;
12
+ program: Program;
13
+ eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
14
+ highLeverageModeConfigAccountPublicKey: PublicKey;
15
+ highLeverageModeConfigDataAccountSubscriber: AccountSubscriber<HighLeverageModeConfig>;
16
+ constructor(program: Program, highLeverageModeConfigAccountPublicKey: PublicKey, resubTimeoutMs?: number, commitment?: Commitment);
17
+ subscribe(highLeverageModeConfigAccount?: HighLeverageModeConfig): Promise<boolean>;
18
+ fetch(): Promise<void>;
19
+ unsubscribe(): Promise<void>;
20
+ assertIsSubscribed(): void;
21
+ getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
22
+ updateData(highLeverageModeConfig: HighLeverageModeConfig, slot: number): void;
23
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocketHighLeverageModeConfigAccountSubscriber = void 0;
4
+ const types_1 = require("./types");
5
+ const events_1 = require("events");
6
+ const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
7
+ class WebSocketHighLeverageModeConfigAccountSubscriber {
8
+ constructor(program, highLeverageModeConfigAccountPublicKey, resubTimeoutMs, commitment) {
9
+ this.isSubscribed = false;
10
+ this.program = program;
11
+ this.highLeverageModeConfigAccountPublicKey =
12
+ highLeverageModeConfigAccountPublicKey;
13
+ this.eventEmitter = new events_1.EventEmitter();
14
+ this.resubTimeoutMs = resubTimeoutMs;
15
+ this.commitment = commitment;
16
+ }
17
+ async subscribe(highLeverageModeConfigAccount) {
18
+ if (this.isSubscribed) {
19
+ return true;
20
+ }
21
+ this.highLeverageModeConfigDataAccountSubscriber =
22
+ new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('highLeverageModeConfig', this.program, this.highLeverageModeConfigAccountPublicKey, undefined, {
23
+ resubTimeoutMs: this.resubTimeoutMs,
24
+ }, this.commitment);
25
+ if (highLeverageModeConfigAccount) {
26
+ this.highLeverageModeConfigDataAccountSubscriber.setData(highLeverageModeConfigAccount);
27
+ }
28
+ await this.highLeverageModeConfigDataAccountSubscriber.subscribe((data) => {
29
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', data);
30
+ this.eventEmitter.emit('update');
31
+ });
32
+ this.eventEmitter.emit('update');
33
+ this.isSubscribed = true;
34
+ return true;
35
+ }
36
+ async fetch() {
37
+ await Promise.all([
38
+ this.highLeverageModeConfigDataAccountSubscriber.fetch(),
39
+ ]);
40
+ }
41
+ async unsubscribe() {
42
+ if (!this.isSubscribed) {
43
+ return;
44
+ }
45
+ await Promise.all([
46
+ this.highLeverageModeConfigDataAccountSubscriber.unsubscribe(),
47
+ ]);
48
+ this.isSubscribed = false;
49
+ }
50
+ assertIsSubscribed() {
51
+ if (!this.isSubscribed) {
52
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
53
+ }
54
+ }
55
+ getHighLeverageModeConfigAccountAndSlot() {
56
+ this.assertIsSubscribed();
57
+ return this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot;
58
+ }
59
+ updateData(highLeverageModeConfig, slot) {
60
+ var _a;
61
+ const currentDataSlot = ((_a = this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot) === null || _a === void 0 ? void 0 : _a.slot) || 0;
62
+ if (currentDataSlot <= slot) {
63
+ this.highLeverageModeConfigDataAccountSubscriber.setData(highLeverageModeConfig, slot);
64
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', highLeverageModeConfig);
65
+ this.eventEmitter.emit('update');
66
+ }
67
+ }
68
+ }
69
+ exports.WebSocketHighLeverageModeConfigAccountSubscriber = WebSocketHighLeverageModeConfigAccountSubscriber;
@@ -3880,6 +3880,9 @@ class DriftClient {
3880
3880
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
3881
3881
  const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
3882
3882
  const createWSOLTokenAccount = isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
3883
+ // create associated token account because it may not exist
3884
+ const associatedTokenAccountPublicKey = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarketAccount.mint, this.wallet.publicKey, true);
3885
+ addIfStakeIxs.push(await (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(this.wallet.publicKey, associatedTokenAccountPublicKey, this.wallet.publicKey, spotMarketAccount.mint));
3883
3886
  let tokenAccount;
3884
3887
  if (!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))) {
3885
3888
  addIfStakeIxs.push(await this.getInitializeUserStatsIx());
@@ -10,6 +10,7 @@ export * from './constants/perpMarkets';
10
10
  export * from './accounts/fetch';
11
11
  export * from './accounts/webSocketDriftClientAccountSubscriber';
12
12
  export * from './accounts/webSocketInsuranceFundStakeAccountSubscriber';
13
+ export * from './accounts/webSocketHighLeverageModeConfigAccountSubscriber';
13
14
  export * from './accounts/bulkAccountLoader';
14
15
  export * from './accounts/bulkUserSubscription';
15
16
  export * from './accounts/bulkUserStatsSubscription';
@@ -19,6 +20,7 @@ export * from './accounts/pollingTokenAccountSubscriber';
19
20
  export * from './accounts/pollingUserAccountSubscriber';
20
21
  export * from './accounts/pollingUserStatsAccountSubscriber';
21
22
  export * from './accounts/pollingInsuranceFundStakeAccountSubscriber';
23
+ export * from './accounts/pollingHighLeverageModeConfigAccountSubscriber';
22
24
  export * from './accounts/basicUserAccountSubscriber';
23
25
  export * from './accounts/oneShotUserAccountSubscriber';
24
26
  export * from './accounts/types';
@@ -33,6 +33,7 @@ __exportStar(require("./constants/perpMarkets"), exports);
33
33
  __exportStar(require("./accounts/fetch"), exports);
34
34
  __exportStar(require("./accounts/webSocketDriftClientAccountSubscriber"), exports);
35
35
  __exportStar(require("./accounts/webSocketInsuranceFundStakeAccountSubscriber"), exports);
36
+ __exportStar(require("./accounts/webSocketHighLeverageModeConfigAccountSubscriber"), exports);
36
37
  __exportStar(require("./accounts/bulkAccountLoader"), exports);
37
38
  __exportStar(require("./accounts/bulkUserSubscription"), exports);
38
39
  __exportStar(require("./accounts/bulkUserStatsSubscription"), exports);
@@ -42,6 +43,7 @@ __exportStar(require("./accounts/pollingTokenAccountSubscriber"), exports);
42
43
  __exportStar(require("./accounts/pollingUserAccountSubscriber"), exports);
43
44
  __exportStar(require("./accounts/pollingUserStatsAccountSubscriber"), exports);
44
45
  __exportStar(require("./accounts/pollingInsuranceFundStakeAccountSubscriber"), exports);
46
+ __exportStar(require("./accounts/pollingHighLeverageModeConfigAccountSubscriber"), exports);
45
47
  __exportStar(require("./accounts/basicUserAccountSubscriber"), exports);
46
48
  __exportStar(require("./accounts/oneShotUserAccountSubscriber"), exports);
47
49
  __exportStar(require("./accounts/types"), exports);
@@ -0,0 +1,29 @@
1
+ /// <reference types="node" />
2
+ import { DataAndSlot, HighLeverageModeConfigAccountEvents, HighLeverageModeConfigAccountSubscriber } from './types';
3
+ import { Program } from '@coral-xyz/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { PublicKey } from '@solana/web3.js';
7
+ import { BulkAccountLoader } from './bulkAccountLoader';
8
+ import { HighLeverageModeConfig } from '../types';
9
+ export declare class PollingHighLeverageModeConfigAccountSubscriber implements HighLeverageModeConfigAccountSubscriber {
10
+ isSubscribed: boolean;
11
+ program: Program;
12
+ eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
13
+ highLeverageModeConfigAccountPublicKey: PublicKey;
14
+ accountLoader: BulkAccountLoader;
15
+ callbackId?: string;
16
+ errorCallbackId?: string;
17
+ highLeverageModeConfigAccountAndSlot?: DataAndSlot<HighLeverageModeConfig>;
18
+ constructor(program: Program, publicKey: PublicKey, accountLoader: BulkAccountLoader);
19
+ subscribe(highLeverageModeConfig?: HighLeverageModeConfig): Promise<boolean>;
20
+ addToAccountLoader(): Promise<void>;
21
+ fetchIfUnloaded(): Promise<void>;
22
+ fetch(): Promise<void>;
23
+ doesAccountExist(): boolean;
24
+ unsubscribe(): Promise<void>;
25
+ assertIsSubscribed(): void;
26
+ getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
27
+ didSubscriptionSucceed(): boolean;
28
+ updateData(highLeverageModeConfig: HighLeverageModeConfig, slot: number): void;
29
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PollingHighLeverageModeConfigAccountSubscriber = void 0;
4
+ const types_1 = require("./types");
5
+ const events_1 = require("events");
6
+ class PollingHighLeverageModeConfigAccountSubscriber {
7
+ constructor(program, publicKey, accountLoader) {
8
+ this.isSubscribed = false;
9
+ this.program = program;
10
+ this.highLeverageModeConfigAccountPublicKey = publicKey;
11
+ this.accountLoader = accountLoader;
12
+ this.eventEmitter = new events_1.EventEmitter();
13
+ }
14
+ async subscribe(highLeverageModeConfig) {
15
+ if (this.isSubscribed) {
16
+ return true;
17
+ }
18
+ if (highLeverageModeConfig) {
19
+ this.highLeverageModeConfigAccountAndSlot = {
20
+ data: highLeverageModeConfig,
21
+ slot: undefined,
22
+ };
23
+ }
24
+ await this.addToAccountLoader();
25
+ await this.fetchIfUnloaded();
26
+ if (this.doesAccountExist()) {
27
+ this.eventEmitter.emit('update');
28
+ }
29
+ this.isSubscribed = true;
30
+ return true;
31
+ }
32
+ async addToAccountLoader() {
33
+ if (this.callbackId) {
34
+ return;
35
+ }
36
+ this.callbackId = await this.accountLoader.addAccount(this.highLeverageModeConfigAccountPublicKey, (buffer, slot) => {
37
+ if (!buffer) {
38
+ return;
39
+ }
40
+ if (this.highLeverageModeConfigAccountAndSlot &&
41
+ this.highLeverageModeConfigAccountAndSlot.slot > slot) {
42
+ return;
43
+ }
44
+ const account = this.program.account.user.coder.accounts.decode('HighLeverageModeConfig', buffer);
45
+ this.highLeverageModeConfigAccountAndSlot = { data: account, slot };
46
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', account);
47
+ this.eventEmitter.emit('update');
48
+ });
49
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
50
+ this.eventEmitter.emit('error', error);
51
+ });
52
+ }
53
+ async fetchIfUnloaded() {
54
+ if (this.highLeverageModeConfigAccountAndSlot === undefined) {
55
+ await this.fetch();
56
+ }
57
+ }
58
+ async fetch() {
59
+ var _a, _b;
60
+ try {
61
+ const dataAndContext = await this.program.account.highLeverageModeConfig.fetchAndContext(this.highLeverageModeConfigAccountPublicKey, this.accountLoader.commitment);
62
+ if (dataAndContext.context.slot >
63
+ ((_b = (_a = this.highLeverageModeConfigAccountAndSlot) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0)) {
64
+ this.highLeverageModeConfigAccountAndSlot = {
65
+ data: dataAndContext.data,
66
+ slot: dataAndContext.context.slot,
67
+ };
68
+ }
69
+ }
70
+ catch (e) {
71
+ console.log(`PollingHighLeverageModeConfigAccountSubscriber.fetch() HighLeverageModeConfig does not exist: ${e.message}`);
72
+ }
73
+ }
74
+ doesAccountExist() {
75
+ return this.highLeverageModeConfigAccountAndSlot !== undefined;
76
+ }
77
+ async unsubscribe() {
78
+ if (!this.isSubscribed) {
79
+ return;
80
+ }
81
+ this.accountLoader.removeAccount(this.highLeverageModeConfigAccountPublicKey, this.callbackId);
82
+ this.callbackId = undefined;
83
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
84
+ this.errorCallbackId = undefined;
85
+ this.isSubscribed = false;
86
+ }
87
+ assertIsSubscribed() {
88
+ if (!this.isSubscribed) {
89
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
90
+ }
91
+ }
92
+ getHighLeverageModeConfigAccountAndSlot() {
93
+ this.assertIsSubscribed();
94
+ return this.highLeverageModeConfigAccountAndSlot;
95
+ }
96
+ didSubscriptionSucceed() {
97
+ return !!this.highLeverageModeConfigAccountAndSlot;
98
+ }
99
+ updateData(highLeverageModeConfig, slot) {
100
+ if (!this.highLeverageModeConfigAccountAndSlot ||
101
+ this.highLeverageModeConfigAccountAndSlot.slot < slot) {
102
+ this.highLeverageModeConfigAccountAndSlot = {
103
+ data: highLeverageModeConfig,
104
+ slot,
105
+ };
106
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', highLeverageModeConfig);
107
+ this.eventEmitter.emit('update');
108
+ }
109
+ }
110
+ }
111
+ exports.PollingHighLeverageModeConfigAccountSubscriber = PollingHighLeverageModeConfigAccountSubscriber;
@@ -6,7 +6,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
6
6
  import { EventEmitter } from 'events';
7
7
  import { Context, PublicKey } from '@solana/web3.js';
8
8
  import { Account } from '@solana/spl-token';
9
- import { OracleInfo, OraclePriceData } from '..';
9
+ import { HighLeverageModeConfig, OracleInfo, OraclePriceData } from '..';
10
10
  import { ChannelOptions, CommitmentLevel } from '../isomorphic/grpc';
11
11
  export interface AccountSubscriber<T> {
12
12
  dataAndSlot?: DataAndSlot<T>;
@@ -153,3 +153,16 @@ export type GrpcConfigs = {
153
153
  commitmentLevel?: CommitmentLevel;
154
154
  channelOptions?: ChannelOptions;
155
155
  };
156
+ export interface HighLeverageModeConfigAccountSubscriber {
157
+ eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
158
+ isSubscribed: boolean;
159
+ subscribe(highLeverageModeConfigAccount?: HighLeverageModeConfig): Promise<boolean>;
160
+ fetch(): Promise<void>;
161
+ unsubscribe(): Promise<void>;
162
+ getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
163
+ }
164
+ export interface HighLeverageModeConfigAccountEvents {
165
+ highLeverageModeConfigAccountUpdate: (payload: HighLeverageModeConfig) => void;
166
+ update: void;
167
+ error: (e: Error) => void;
168
+ }
@@ -0,0 +1,23 @@
1
+ /// <reference types="node" />
2
+ import { DataAndSlot, AccountSubscriber, HighLeverageModeConfigAccountEvents, HighLeverageModeConfigAccountSubscriber } from './types';
3
+ import { Program } from '@coral-xyz/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { Commitment, PublicKey } from '@solana/web3.js';
7
+ import { HighLeverageModeConfig } from '../types';
8
+ export declare class WebSocketHighLeverageModeConfigAccountSubscriber implements HighLeverageModeConfigAccountSubscriber {
9
+ isSubscribed: boolean;
10
+ resubTimeoutMs?: number;
11
+ commitment?: Commitment;
12
+ program: Program;
13
+ eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
14
+ highLeverageModeConfigAccountPublicKey: PublicKey;
15
+ highLeverageModeConfigDataAccountSubscriber: AccountSubscriber<HighLeverageModeConfig>;
16
+ constructor(program: Program, highLeverageModeConfigAccountPublicKey: PublicKey, resubTimeoutMs?: number, commitment?: Commitment);
17
+ subscribe(highLeverageModeConfigAccount?: HighLeverageModeConfig): Promise<boolean>;
18
+ fetch(): Promise<void>;
19
+ unsubscribe(): Promise<void>;
20
+ assertIsSubscribed(): void;
21
+ getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
22
+ updateData(highLeverageModeConfig: HighLeverageModeConfig, slot: number): void;
23
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocketHighLeverageModeConfigAccountSubscriber = void 0;
4
+ const types_1 = require("./types");
5
+ const events_1 = require("events");
6
+ const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
7
+ class WebSocketHighLeverageModeConfigAccountSubscriber {
8
+ constructor(program, highLeverageModeConfigAccountPublicKey, resubTimeoutMs, commitment) {
9
+ this.isSubscribed = false;
10
+ this.program = program;
11
+ this.highLeverageModeConfigAccountPublicKey =
12
+ highLeverageModeConfigAccountPublicKey;
13
+ this.eventEmitter = new events_1.EventEmitter();
14
+ this.resubTimeoutMs = resubTimeoutMs;
15
+ this.commitment = commitment;
16
+ }
17
+ async subscribe(highLeverageModeConfigAccount) {
18
+ if (this.isSubscribed) {
19
+ return true;
20
+ }
21
+ this.highLeverageModeConfigDataAccountSubscriber =
22
+ new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('highLeverageModeConfig', this.program, this.highLeverageModeConfigAccountPublicKey, undefined, {
23
+ resubTimeoutMs: this.resubTimeoutMs,
24
+ }, this.commitment);
25
+ if (highLeverageModeConfigAccount) {
26
+ this.highLeverageModeConfigDataAccountSubscriber.setData(highLeverageModeConfigAccount);
27
+ }
28
+ await this.highLeverageModeConfigDataAccountSubscriber.subscribe((data) => {
29
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', data);
30
+ this.eventEmitter.emit('update');
31
+ });
32
+ this.eventEmitter.emit('update');
33
+ this.isSubscribed = true;
34
+ return true;
35
+ }
36
+ async fetch() {
37
+ await Promise.all([
38
+ this.highLeverageModeConfigDataAccountSubscriber.fetch(),
39
+ ]);
40
+ }
41
+ async unsubscribe() {
42
+ if (!this.isSubscribed) {
43
+ return;
44
+ }
45
+ await Promise.all([
46
+ this.highLeverageModeConfigDataAccountSubscriber.unsubscribe(),
47
+ ]);
48
+ this.isSubscribed = false;
49
+ }
50
+ assertIsSubscribed() {
51
+ if (!this.isSubscribed) {
52
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
53
+ }
54
+ }
55
+ getHighLeverageModeConfigAccountAndSlot() {
56
+ this.assertIsSubscribed();
57
+ return this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot;
58
+ }
59
+ updateData(highLeverageModeConfig, slot) {
60
+ var _a;
61
+ const currentDataSlot = ((_a = this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot) === null || _a === void 0 ? void 0 : _a.slot) || 0;
62
+ if (currentDataSlot <= slot) {
63
+ this.highLeverageModeConfigDataAccountSubscriber.setData(highLeverageModeConfig, slot);
64
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', highLeverageModeConfig);
65
+ this.eventEmitter.emit('update');
66
+ }
67
+ }
68
+ }
69
+ exports.WebSocketHighLeverageModeConfigAccountSubscriber = WebSocketHighLeverageModeConfigAccountSubscriber;
@@ -3880,6 +3880,9 @@ class DriftClient {
3880
3880
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
3881
3881
  const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
3882
3882
  const createWSOLTokenAccount = isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
3883
+ // create associated token account because it may not exist
3884
+ const associatedTokenAccountPublicKey = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarketAccount.mint, this.wallet.publicKey, true);
3885
+ addIfStakeIxs.push(await (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(this.wallet.publicKey, associatedTokenAccountPublicKey, this.wallet.publicKey, spotMarketAccount.mint));
3883
3886
  let tokenAccount;
3884
3887
  if (!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))) {
3885
3888
  addIfStakeIxs.push(await this.getInitializeUserStatsIx());
@@ -10,6 +10,7 @@ export * from './constants/perpMarkets';
10
10
  export * from './accounts/fetch';
11
11
  export * from './accounts/webSocketDriftClientAccountSubscriber';
12
12
  export * from './accounts/webSocketInsuranceFundStakeAccountSubscriber';
13
+ export * from './accounts/webSocketHighLeverageModeConfigAccountSubscriber';
13
14
  export * from './accounts/bulkAccountLoader';
14
15
  export * from './accounts/bulkUserSubscription';
15
16
  export * from './accounts/bulkUserStatsSubscription';
@@ -19,6 +20,7 @@ export * from './accounts/pollingTokenAccountSubscriber';
19
20
  export * from './accounts/pollingUserAccountSubscriber';
20
21
  export * from './accounts/pollingUserStatsAccountSubscriber';
21
22
  export * from './accounts/pollingInsuranceFundStakeAccountSubscriber';
23
+ export * from './accounts/pollingHighLeverageModeConfigAccountSubscriber';
22
24
  export * from './accounts/basicUserAccountSubscriber';
23
25
  export * from './accounts/oneShotUserAccountSubscriber';
24
26
  export * from './accounts/types';
package/lib/node/index.js CHANGED
@@ -33,6 +33,7 @@ __exportStar(require("./constants/perpMarkets"), exports);
33
33
  __exportStar(require("./accounts/fetch"), exports);
34
34
  __exportStar(require("./accounts/webSocketDriftClientAccountSubscriber"), exports);
35
35
  __exportStar(require("./accounts/webSocketInsuranceFundStakeAccountSubscriber"), exports);
36
+ __exportStar(require("./accounts/webSocketHighLeverageModeConfigAccountSubscriber"), exports);
36
37
  __exportStar(require("./accounts/bulkAccountLoader"), exports);
37
38
  __exportStar(require("./accounts/bulkUserSubscription"), exports);
38
39
  __exportStar(require("./accounts/bulkUserStatsSubscription"), exports);
@@ -42,6 +43,7 @@ __exportStar(require("./accounts/pollingTokenAccountSubscriber"), exports);
42
43
  __exportStar(require("./accounts/pollingUserAccountSubscriber"), exports);
43
44
  __exportStar(require("./accounts/pollingUserStatsAccountSubscriber"), exports);
44
45
  __exportStar(require("./accounts/pollingInsuranceFundStakeAccountSubscriber"), exports);
46
+ __exportStar(require("./accounts/pollingHighLeverageModeConfigAccountSubscriber"), exports);
45
47
  __exportStar(require("./accounts/basicUserAccountSubscriber"), exports);
46
48
  __exportStar(require("./accounts/oneShotUserAccountSubscriber"), exports);
47
49
  __exportStar(require("./accounts/types"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.98.0-beta.10",
3
+ "version": "2.98.0-beta.12",
4
4
  "main": "lib/node/index.js",
5
5
  "types": "lib/node/index.d.ts",
6
6
  "browser": "./lib/browser/index.js",
@@ -0,0 +1,189 @@
1
+ import {
2
+ DataAndSlot,
3
+ NotSubscribedError,
4
+ HighLeverageModeConfigAccountEvents,
5
+ HighLeverageModeConfigAccountSubscriber,
6
+ } from './types';
7
+ import { Program } from '@coral-xyz/anchor';
8
+ import StrictEventEmitter from 'strict-event-emitter-types';
9
+ import { EventEmitter } from 'events';
10
+ import { PublicKey } from '@solana/web3.js';
11
+ import { BulkAccountLoader } from './bulkAccountLoader';
12
+ import { HighLeverageModeConfig } from '../types';
13
+
14
+ export class PollingHighLeverageModeConfigAccountSubscriber
15
+ implements HighLeverageModeConfigAccountSubscriber
16
+ {
17
+ isSubscribed: boolean;
18
+ program: Program;
19
+ eventEmitter: StrictEventEmitter<
20
+ EventEmitter,
21
+ HighLeverageModeConfigAccountEvents
22
+ >;
23
+ highLeverageModeConfigAccountPublicKey: PublicKey;
24
+
25
+ accountLoader: BulkAccountLoader;
26
+ callbackId?: string;
27
+ errorCallbackId?: string;
28
+
29
+ highLeverageModeConfigAccountAndSlot?: DataAndSlot<HighLeverageModeConfig>;
30
+
31
+ public constructor(
32
+ program: Program,
33
+ publicKey: PublicKey,
34
+ accountLoader: BulkAccountLoader
35
+ ) {
36
+ this.isSubscribed = false;
37
+ this.program = program;
38
+ this.highLeverageModeConfigAccountPublicKey = publicKey;
39
+ this.accountLoader = accountLoader;
40
+ this.eventEmitter = new EventEmitter();
41
+ }
42
+
43
+ async subscribe(
44
+ highLeverageModeConfig?: HighLeverageModeConfig
45
+ ): Promise<boolean> {
46
+ if (this.isSubscribed) {
47
+ return true;
48
+ }
49
+
50
+ if (highLeverageModeConfig) {
51
+ this.highLeverageModeConfigAccountAndSlot = {
52
+ data: highLeverageModeConfig,
53
+ slot: undefined,
54
+ };
55
+ }
56
+
57
+ await this.addToAccountLoader();
58
+
59
+ await this.fetchIfUnloaded();
60
+
61
+ if (this.doesAccountExist()) {
62
+ this.eventEmitter.emit('update');
63
+ }
64
+
65
+ this.isSubscribed = true;
66
+ return true;
67
+ }
68
+
69
+ async addToAccountLoader(): Promise<void> {
70
+ if (this.callbackId) {
71
+ return;
72
+ }
73
+
74
+ this.callbackId = await this.accountLoader.addAccount(
75
+ this.highLeverageModeConfigAccountPublicKey,
76
+ (buffer, slot: number) => {
77
+ if (!buffer) {
78
+ return;
79
+ }
80
+
81
+ if (
82
+ this.highLeverageModeConfigAccountAndSlot &&
83
+ this.highLeverageModeConfigAccountAndSlot.slot > slot
84
+ ) {
85
+ return;
86
+ }
87
+
88
+ const account = this.program.account.user.coder.accounts.decode(
89
+ 'HighLeverageModeConfig',
90
+ buffer
91
+ );
92
+ this.highLeverageModeConfigAccountAndSlot = { data: account, slot };
93
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', account);
94
+ this.eventEmitter.emit('update');
95
+ }
96
+ );
97
+
98
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
99
+ this.eventEmitter.emit('error', error);
100
+ });
101
+ }
102
+
103
+ async fetchIfUnloaded(): Promise<void> {
104
+ if (this.highLeverageModeConfigAccountAndSlot === undefined) {
105
+ await this.fetch();
106
+ }
107
+ }
108
+
109
+ async fetch(): Promise<void> {
110
+ try {
111
+ const dataAndContext =
112
+ await this.program.account.highLeverageModeConfig.fetchAndContext(
113
+ this.highLeverageModeConfigAccountPublicKey,
114
+ this.accountLoader.commitment
115
+ );
116
+ if (
117
+ dataAndContext.context.slot >
118
+ (this.highLeverageModeConfigAccountAndSlot?.slot ?? 0)
119
+ ) {
120
+ this.highLeverageModeConfigAccountAndSlot = {
121
+ data: dataAndContext.data as HighLeverageModeConfig,
122
+ slot: dataAndContext.context.slot,
123
+ };
124
+ }
125
+ } catch (e) {
126
+ console.log(
127
+ `PollingHighLeverageModeConfigAccountSubscriber.fetch() HighLeverageModeConfig does not exist: ${e.message}`
128
+ );
129
+ }
130
+ }
131
+
132
+ doesAccountExist(): boolean {
133
+ return this.highLeverageModeConfigAccountAndSlot !== undefined;
134
+ }
135
+
136
+ async unsubscribe(): Promise<void> {
137
+ if (!this.isSubscribed) {
138
+ return;
139
+ }
140
+
141
+ this.accountLoader.removeAccount(
142
+ this.highLeverageModeConfigAccountPublicKey,
143
+ this.callbackId
144
+ );
145
+ this.callbackId = undefined;
146
+
147
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
148
+ this.errorCallbackId = undefined;
149
+
150
+ this.isSubscribed = false;
151
+ }
152
+
153
+ assertIsSubscribed(): void {
154
+ if (!this.isSubscribed) {
155
+ throw new NotSubscribedError(
156
+ 'You must call `subscribe` before using this function'
157
+ );
158
+ }
159
+ }
160
+
161
+ public getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig> {
162
+ this.assertIsSubscribed();
163
+ return this.highLeverageModeConfigAccountAndSlot;
164
+ }
165
+
166
+ didSubscriptionSucceed(): boolean {
167
+ return !!this.highLeverageModeConfigAccountAndSlot;
168
+ }
169
+
170
+ public updateData(
171
+ highLeverageModeConfig: HighLeverageModeConfig,
172
+ slot: number
173
+ ): void {
174
+ if (
175
+ !this.highLeverageModeConfigAccountAndSlot ||
176
+ this.highLeverageModeConfigAccountAndSlot.slot < slot
177
+ ) {
178
+ this.highLeverageModeConfigAccountAndSlot = {
179
+ data: highLeverageModeConfig,
180
+ slot,
181
+ };
182
+ this.eventEmitter.emit(
183
+ 'highLeverageModeConfigAccountUpdate',
184
+ highLeverageModeConfig
185
+ );
186
+ this.eventEmitter.emit('update');
187
+ }
188
+ }
189
+ }
@@ -11,7 +11,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
11
11
  import { EventEmitter } from 'events';
12
12
  import { Context, PublicKey } from '@solana/web3.js';
13
13
  import { Account } from '@solana/spl-token';
14
- import { OracleInfo, OraclePriceData } from '..';
14
+ import { HighLeverageModeConfig, OracleInfo, OraclePriceData } from '..';
15
15
  import { ChannelOptions, CommitmentLevel } from '../isomorphic/grpc';
16
16
 
17
17
  export interface AccountSubscriber<T> {
@@ -215,3 +215,27 @@ export type GrpcConfigs = {
215
215
  commitmentLevel?: CommitmentLevel;
216
216
  channelOptions?: ChannelOptions;
217
217
  };
218
+
219
+ export interface HighLeverageModeConfigAccountSubscriber {
220
+ eventEmitter: StrictEventEmitter<
221
+ EventEmitter,
222
+ HighLeverageModeConfigAccountEvents
223
+ >;
224
+ isSubscribed: boolean;
225
+
226
+ subscribe(
227
+ highLeverageModeConfigAccount?: HighLeverageModeConfig
228
+ ): Promise<boolean>;
229
+ fetch(): Promise<void>;
230
+ unsubscribe(): Promise<void>;
231
+
232
+ getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
233
+ }
234
+
235
+ export interface HighLeverageModeConfigAccountEvents {
236
+ highLeverageModeConfigAccountUpdate: (
237
+ payload: HighLeverageModeConfig
238
+ ) => void;
239
+ update: void;
240
+ error: (e: Error) => void;
241
+ }
@@ -0,0 +1,131 @@
1
+ import {
2
+ DataAndSlot,
3
+ AccountSubscriber,
4
+ NotSubscribedError,
5
+ HighLeverageModeConfigAccountEvents,
6
+ HighLeverageModeConfigAccountSubscriber,
7
+ } from './types';
8
+ import { Program } from '@coral-xyz/anchor';
9
+ import StrictEventEmitter from 'strict-event-emitter-types';
10
+ import { EventEmitter } from 'events';
11
+ import { Commitment, PublicKey } from '@solana/web3.js';
12
+ import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
13
+ import { HighLeverageModeConfig } from '../types';
14
+
15
+ export class WebSocketHighLeverageModeConfigAccountSubscriber
16
+ implements HighLeverageModeConfigAccountSubscriber
17
+ {
18
+ isSubscribed: boolean;
19
+ resubTimeoutMs?: number;
20
+ commitment?: Commitment;
21
+ program: Program;
22
+ eventEmitter: StrictEventEmitter<
23
+ EventEmitter,
24
+ HighLeverageModeConfigAccountEvents
25
+ >;
26
+ highLeverageModeConfigAccountPublicKey: PublicKey;
27
+
28
+ highLeverageModeConfigDataAccountSubscriber: AccountSubscriber<HighLeverageModeConfig>;
29
+
30
+ public constructor(
31
+ program: Program,
32
+ highLeverageModeConfigAccountPublicKey: PublicKey,
33
+ resubTimeoutMs?: number,
34
+ commitment?: Commitment
35
+ ) {
36
+ this.isSubscribed = false;
37
+ this.program = program;
38
+ this.highLeverageModeConfigAccountPublicKey =
39
+ highLeverageModeConfigAccountPublicKey;
40
+ this.eventEmitter = new EventEmitter();
41
+ this.resubTimeoutMs = resubTimeoutMs;
42
+ this.commitment = commitment;
43
+ }
44
+
45
+ async subscribe(
46
+ highLeverageModeConfigAccount?: HighLeverageModeConfig
47
+ ): Promise<boolean> {
48
+ if (this.isSubscribed) {
49
+ return true;
50
+ }
51
+
52
+ this.highLeverageModeConfigDataAccountSubscriber =
53
+ new WebSocketAccountSubscriber(
54
+ 'highLeverageModeConfig',
55
+ this.program,
56
+ this.highLeverageModeConfigAccountPublicKey,
57
+ undefined,
58
+ {
59
+ resubTimeoutMs: this.resubTimeoutMs,
60
+ },
61
+ this.commitment
62
+ );
63
+
64
+ if (highLeverageModeConfigAccount) {
65
+ this.highLeverageModeConfigDataAccountSubscriber.setData(
66
+ highLeverageModeConfigAccount
67
+ );
68
+ }
69
+
70
+ await this.highLeverageModeConfigDataAccountSubscriber.subscribe(
71
+ (data: HighLeverageModeConfig) => {
72
+ this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', data);
73
+ this.eventEmitter.emit('update');
74
+ }
75
+ );
76
+
77
+ this.eventEmitter.emit('update');
78
+ this.isSubscribed = true;
79
+ return true;
80
+ }
81
+
82
+ async fetch(): Promise<void> {
83
+ await Promise.all([
84
+ this.highLeverageModeConfigDataAccountSubscriber.fetch(),
85
+ ]);
86
+ }
87
+
88
+ async unsubscribe(): Promise<void> {
89
+ if (!this.isSubscribed) {
90
+ return;
91
+ }
92
+
93
+ await Promise.all([
94
+ this.highLeverageModeConfigDataAccountSubscriber.unsubscribe(),
95
+ ]);
96
+
97
+ this.isSubscribed = false;
98
+ }
99
+
100
+ assertIsSubscribed(): void {
101
+ if (!this.isSubscribed) {
102
+ throw new NotSubscribedError(
103
+ 'You must call `subscribe` before using this function'
104
+ );
105
+ }
106
+ }
107
+
108
+ public getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig> {
109
+ this.assertIsSubscribed();
110
+ return this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot;
111
+ }
112
+
113
+ public updateData(
114
+ highLeverageModeConfig: HighLeverageModeConfig,
115
+ slot: number
116
+ ): void {
117
+ const currentDataSlot =
118
+ this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot?.slot || 0;
119
+ if (currentDataSlot <= slot) {
120
+ this.highLeverageModeConfigDataAccountSubscriber.setData(
121
+ highLeverageModeConfig,
122
+ slot
123
+ );
124
+ this.eventEmitter.emit(
125
+ 'highLeverageModeConfigAccountUpdate',
126
+ highLeverageModeConfig
127
+ );
128
+ this.eventEmitter.emit('update');
129
+ }
130
+ }
131
+ }
@@ -11,11 +11,13 @@ import bs58 from 'bs58';
11
11
  import {
12
12
  ASSOCIATED_TOKEN_PROGRAM_ID,
13
13
  createAssociatedTokenAccountInstruction,
14
+ createAssociatedTokenAccountIdempotentInstruction,
14
15
  createCloseAccountInstruction,
15
16
  createInitializeAccountInstruction,
16
17
  getAssociatedTokenAddress,
17
18
  TOKEN_2022_PROGRAM_ID,
18
19
  TOKEN_PROGRAM_ID,
20
+ getAssociatedTokenAddressSync,
19
21
  } from '@solana/spl-token';
20
22
  import {
21
23
  DriftClientMetricsEvents,
@@ -7407,6 +7409,22 @@ export class DriftClient {
7407
7409
  const createWSOLTokenAccount =
7408
7410
  isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
7409
7411
 
7412
+ // create associated token account because it may not exist
7413
+ const associatedTokenAccountPublicKey = getAssociatedTokenAddressSync(
7414
+ spotMarketAccount.mint,
7415
+ this.wallet.publicKey,
7416
+ true
7417
+ );
7418
+
7419
+ addIfStakeIxs.push(
7420
+ await createAssociatedTokenAccountIdempotentInstruction(
7421
+ this.wallet.publicKey,
7422
+ associatedTokenAccountPublicKey,
7423
+ this.wallet.publicKey,
7424
+ spotMarketAccount.mint
7425
+ )
7426
+ );
7427
+
7410
7428
  let tokenAccount;
7411
7429
 
7412
7430
  if (
package/src/index.ts CHANGED
@@ -11,6 +11,7 @@ export * from './constants/perpMarkets';
11
11
  export * from './accounts/fetch';
12
12
  export * from './accounts/webSocketDriftClientAccountSubscriber';
13
13
  export * from './accounts/webSocketInsuranceFundStakeAccountSubscriber';
14
+ export * from './accounts/webSocketHighLeverageModeConfigAccountSubscriber';
14
15
  export * from './accounts/bulkAccountLoader';
15
16
  export * from './accounts/bulkUserSubscription';
16
17
  export * from './accounts/bulkUserStatsSubscription';
@@ -20,6 +21,7 @@ export * from './accounts/pollingTokenAccountSubscriber';
20
21
  export * from './accounts/pollingUserAccountSubscriber';
21
22
  export * from './accounts/pollingUserStatsAccountSubscriber';
22
23
  export * from './accounts/pollingInsuranceFundStakeAccountSubscriber';
24
+ export * from './accounts/pollingHighLeverageModeConfigAccountSubscriber';
23
25
  export * from './accounts/basicUserAccountSubscriber';
24
26
  export * from './accounts/oneShotUserAccountSubscriber';
25
27
  export * from './accounts/types';