@drift-labs/sdk 2.131.0-beta.0 → 2.131.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/bun.lock +96 -5
- package/lib/browser/accounts/grpcAccountSubscriber.d.ts +0 -1
- package/lib/browser/accounts/grpcAccountSubscriber.js +2 -18
- package/lib/browser/accounts/grpcProgramAccountSubscriber.d.ts +0 -1
- package/lib/browser/accounts/grpcProgramAccountSubscriber.js +2 -18
- package/lib/browser/accounts/webSocketAccountSubscriberV2.d.ts +36 -0
- package/lib/browser/accounts/webSocketAccountSubscriberV2.js +223 -0
- package/lib/browser/accounts/webSocketDriftClientAccountSubscriber.d.ts +6 -1
- package/lib/browser/accounts/webSocketDriftClientAccountSubscriber.js +4 -2
- package/lib/browser/accounts/webSocketProgramAccountSubscriberV2.d.ts +53 -0
- package/lib/browser/accounts/webSocketProgramAccountSubscriberV2.js +453 -0
- package/lib/browser/constants/index.d.ts +5 -0
- package/lib/browser/constants/index.js +21 -0
- package/lib/browser/constants/insuranceFund.d.ts +5 -0
- package/lib/browser/constants/insuranceFund.js +9 -0
- package/lib/browser/driftClient.js +3 -3
- package/lib/browser/driftClientConfig.d.ts +7 -2
- package/lib/browser/events/types.d.ts +1 -1
- package/lib/browser/idl/drift.json +29 -5
- package/lib/browser/index.d.ts +2 -4
- package/lib/browser/index.js +4 -5
- package/lib/browser/math/insurance.d.ts +2 -1
- package/lib/browser/math/insurance.js +7 -6
- package/lib/browser/math/oracles.d.ts +2 -2
- package/lib/browser/math/oracles.js +32 -32
- package/lib/browser/orderSubscriber/OrderSubscriber.js +4 -3
- package/lib/node/accounts/grpcAccountSubscriber.d.ts +0 -1
- package/lib/node/accounts/grpcAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcAccountSubscriber.js +2 -18
- package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts +0 -1
- package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcProgramAccountSubscriber.js +2 -18
- package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts +37 -0
- package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts.map +1 -0
- package/lib/node/accounts/webSocketAccountSubscriberV2.js +223 -0
- package/lib/node/accounts/webSocketDriftClientAccountSubscriber.d.ts +6 -1
- package/lib/node/accounts/webSocketDriftClientAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/webSocketDriftClientAccountSubscriber.js +4 -2
- package/lib/node/accounts/webSocketProgramAccountSubscriberV2.d.ts +54 -0
- package/lib/node/accounts/webSocketProgramAccountSubscriberV2.d.ts.map +1 -0
- package/lib/node/accounts/webSocketProgramAccountSubscriberV2.js +453 -0
- package/lib/node/constants/index.d.ts +6 -0
- package/lib/node/constants/index.d.ts.map +1 -0
- package/lib/node/constants/index.js +21 -0
- package/lib/node/constants/insuranceFund.d.ts +6 -0
- package/lib/node/constants/insuranceFund.d.ts.map +1 -0
- package/lib/node/constants/insuranceFund.js +9 -0
- package/lib/node/driftClient.d.ts.map +1 -1
- package/lib/node/driftClient.js +3 -3
- package/lib/node/driftClientConfig.d.ts +7 -2
- package/lib/node/driftClientConfig.d.ts.map +1 -1
- package/lib/node/events/types.d.ts +1 -1
- package/lib/node/idl/drift.json +29 -5
- package/lib/node/index.d.ts +2 -4
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +4 -5
- package/lib/node/math/insurance.d.ts +2 -1
- package/lib/node/math/insurance.d.ts.map +1 -1
- package/lib/node/math/insurance.js +7 -6
- package/lib/node/math/oracles.d.ts +2 -2
- package/lib/node/math/oracles.d.ts.map +1 -1
- package/lib/node/math/oracles.js +32 -32
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
- package/lib/node/orderSubscriber/OrderSubscriber.js +4 -3
- package/lib/node/orderSubscriber/WebsocketSubscription.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/accounts/README_WebSocketAccountSubscriberV2.md +54 -0
- package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +135 -0
- package/src/accounts/grpcAccountSubscriber.ts +2 -28
- package/src/accounts/grpcProgramAccountSubscriber.ts +2 -28
- package/src/accounts/webSocketAccountSubscriberV2.ts +315 -0
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +22 -2
- package/src/accounts/webSocketProgramAccountSubscriberV2.ts +596 -0
- package/src/constants/index.ts +5 -0
- package/src/constants/insuranceFund.ts +8 -0
- package/src/driftClient.ts +2 -1
- package/src/driftClientConfig.ts +16 -2
- package/src/events/types.ts +1 -1
- package/src/idl/drift.json +30 -6
- package/src/index.ts +2 -4
- package/src/math/insurance.ts +2 -1
- package/src/math/oracles.ts +9 -7
- package/src/orderSubscriber/OrderSubscriber.ts +2 -1
- package/src/orderSubscriber/WebsocketSubscription.ts +1 -1
- package/tests/bn/test.ts +2 -1
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataAndSlot,
|
|
3
|
+
AccountSubscriber,
|
|
4
|
+
ResubOpts,
|
|
5
|
+
BufferAndSlot,
|
|
6
|
+
} from './types';
|
|
7
|
+
import { AnchorProvider, Program } from '@coral-xyz/anchor';
|
|
8
|
+
import { capitalize } from './utils';
|
|
9
|
+
import {
|
|
10
|
+
AccountInfoBase,
|
|
11
|
+
AccountInfoWithBase58EncodedData,
|
|
12
|
+
AccountInfoWithBase64EncodedData,
|
|
13
|
+
createSolanaClient,
|
|
14
|
+
isAddress,
|
|
15
|
+
type Address,
|
|
16
|
+
type Commitment,
|
|
17
|
+
} from 'gill';
|
|
18
|
+
import { PublicKey } from '@solana/web3.js';
|
|
19
|
+
import bs58 from 'bs58';
|
|
20
|
+
|
|
21
|
+
export class WebSocketAccountSubscriberV2<T> implements AccountSubscriber<T> {
|
|
22
|
+
dataAndSlot?: DataAndSlot<T>;
|
|
23
|
+
bufferAndSlot?: BufferAndSlot;
|
|
24
|
+
accountName: string;
|
|
25
|
+
logAccountName: string;
|
|
26
|
+
program: Program;
|
|
27
|
+
accountPublicKey: PublicKey;
|
|
28
|
+
decodeBufferFn: (buffer: Buffer) => T;
|
|
29
|
+
onChange: (data: T) => void;
|
|
30
|
+
listenerId?: number;
|
|
31
|
+
|
|
32
|
+
resubOpts?: ResubOpts;
|
|
33
|
+
|
|
34
|
+
commitment?: Commitment;
|
|
35
|
+
isUnsubscribing = false;
|
|
36
|
+
|
|
37
|
+
timeoutId?: ReturnType<typeof setTimeout>;
|
|
38
|
+
|
|
39
|
+
receivingData: boolean;
|
|
40
|
+
|
|
41
|
+
// Gill client components
|
|
42
|
+
private rpc: ReturnType<typeof createSolanaClient>['rpc'];
|
|
43
|
+
private rpcSubscriptions: ReturnType<
|
|
44
|
+
typeof createSolanaClient
|
|
45
|
+
>['rpcSubscriptions'];
|
|
46
|
+
private abortController?: AbortController;
|
|
47
|
+
|
|
48
|
+
public constructor(
|
|
49
|
+
accountName: string,
|
|
50
|
+
program: Program,
|
|
51
|
+
accountPublicKey: PublicKey,
|
|
52
|
+
decodeBuffer?: (buffer: Buffer) => T,
|
|
53
|
+
resubOpts?: ResubOpts,
|
|
54
|
+
commitment?: Commitment
|
|
55
|
+
) {
|
|
56
|
+
this.accountName = accountName;
|
|
57
|
+
this.logAccountName = `${accountName}-${accountPublicKey.toBase58()}-ws-acct-subscriber-v2`;
|
|
58
|
+
this.program = program;
|
|
59
|
+
this.accountPublicKey = accountPublicKey;
|
|
60
|
+
this.decodeBufferFn = decodeBuffer;
|
|
61
|
+
this.resubOpts = resubOpts;
|
|
62
|
+
if (this.resubOpts?.resubTimeoutMs < 1000) {
|
|
63
|
+
console.log(
|
|
64
|
+
`resubTimeoutMs should be at least 1000ms to avoid spamming resub ${this.logAccountName}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
this.receivingData = false;
|
|
68
|
+
if (
|
|
69
|
+
['recent', 'single', 'singleGossip', 'root', 'max'].includes(
|
|
70
|
+
(this.program.provider as AnchorProvider).opts.commitment
|
|
71
|
+
)
|
|
72
|
+
) {
|
|
73
|
+
console.warn(
|
|
74
|
+
`using commitment ${
|
|
75
|
+
(this.program.provider as AnchorProvider).opts.commitment
|
|
76
|
+
} that is not supported by gill, this may cause issues`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
this.commitment =
|
|
80
|
+
commitment ??
|
|
81
|
+
((this.program.provider as AnchorProvider).opts.commitment as Commitment);
|
|
82
|
+
|
|
83
|
+
// Initialize gill client using the same RPC URL as the program provider
|
|
84
|
+
const rpcUrl = (this.program.provider as AnchorProvider).connection
|
|
85
|
+
.rpcEndpoint;
|
|
86
|
+
const { rpc, rpcSubscriptions } = createSolanaClient({
|
|
87
|
+
urlOrMoniker: rpcUrl,
|
|
88
|
+
});
|
|
89
|
+
this.rpc = rpc;
|
|
90
|
+
this.rpcSubscriptions = rpcSubscriptions;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private async handleNotificationLoop(subscription: AsyncIterable<any>) {
|
|
94
|
+
for await (const notification of subscription) {
|
|
95
|
+
if (this.resubOpts?.resubTimeoutMs) {
|
|
96
|
+
this.receivingData = true;
|
|
97
|
+
clearTimeout(this.timeoutId);
|
|
98
|
+
this.handleRpcResponse(notification.context, notification.value);
|
|
99
|
+
this.setTimeout();
|
|
100
|
+
} else {
|
|
101
|
+
this.handleRpcResponse(notification.context, notification.value);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async subscribe(onChange: (data: T) => void): Promise<void> {
|
|
107
|
+
if (this.listenerId != null || this.isUnsubscribing) {
|
|
108
|
+
if (this.resubOpts?.logResubMessages) {
|
|
109
|
+
console.log(
|
|
110
|
+
`[${this.logAccountName}] Subscribe returning early - listenerId=${this.listenerId}, isUnsubscribing=${this.isUnsubscribing}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.onChange = onChange;
|
|
117
|
+
if (!this.dataAndSlot) {
|
|
118
|
+
await this.fetch();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Create abort controller for proper cleanup
|
|
122
|
+
const abortController = new AbortController();
|
|
123
|
+
this.abortController = abortController;
|
|
124
|
+
|
|
125
|
+
this.listenerId = Math.random(); // Unique ID for logging purposes
|
|
126
|
+
|
|
127
|
+
if (this.resubOpts?.resubTimeoutMs) {
|
|
128
|
+
this.receivingData = true;
|
|
129
|
+
this.setTimeout();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Subscribe to account changes using gill's rpcSubscriptions
|
|
133
|
+
const pubkey = this.accountPublicKey.toBase58();
|
|
134
|
+
if (isAddress(pubkey)) {
|
|
135
|
+
const subscription = await this.rpcSubscriptions
|
|
136
|
+
.accountNotifications(pubkey, {
|
|
137
|
+
commitment: this.commitment,
|
|
138
|
+
encoding: 'base64',
|
|
139
|
+
})
|
|
140
|
+
.subscribe({
|
|
141
|
+
abortSignal: abortController.signal,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Start notification loop without awaiting
|
|
145
|
+
this.handleNotificationLoop(subscription);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
setData(data: T, slot?: number): void {
|
|
150
|
+
const newSlot = slot || 0;
|
|
151
|
+
if (this.dataAndSlot && this.dataAndSlot.slot > newSlot) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.dataAndSlot = {
|
|
156
|
+
data,
|
|
157
|
+
slot,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected setTimeout(): void {
|
|
162
|
+
if (!this.onChange) {
|
|
163
|
+
throw new Error('onChange callback function must be set');
|
|
164
|
+
}
|
|
165
|
+
this.timeoutId = setTimeout(
|
|
166
|
+
async () => {
|
|
167
|
+
if (this.isUnsubscribing) {
|
|
168
|
+
// If we are in the process of unsubscribing, do not attempt to resubscribe
|
|
169
|
+
if (this.resubOpts?.logResubMessages) {
|
|
170
|
+
console.log(
|
|
171
|
+
`[${this.logAccountName}] Timeout fired but isUnsubscribing=true, skipping resubscribe`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (this.receivingData) {
|
|
178
|
+
if (this.resubOpts?.logResubMessages) {
|
|
179
|
+
console.log(
|
|
180
|
+
`No ws data from ${this.logAccountName} in ${this.resubOpts.resubTimeoutMs}ms, resubscribing - listenerId=${this.listenerId}, isUnsubscribing=${this.isUnsubscribing}`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
await this.unsubscribe(true);
|
|
184
|
+
this.receivingData = false;
|
|
185
|
+
await this.subscribe(this.onChange);
|
|
186
|
+
if (this.resubOpts?.logResubMessages) {
|
|
187
|
+
console.log(
|
|
188
|
+
`[${this.logAccountName}] Resubscribe completed - receivingData=${this.receivingData}, listenerId=${this.listenerId}, isUnsubscribing=${this.isUnsubscribing}`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
if (this.resubOpts?.logResubMessages) {
|
|
193
|
+
console.log(
|
|
194
|
+
`[${this.logAccountName}] Timeout fired but receivingData=false, skipping resubscribe`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
this.resubOpts?.resubTimeoutMs
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async fetch(): Promise<void> {
|
|
204
|
+
// Use gill's rpc for fetching account info
|
|
205
|
+
const accountAddress = this.accountPublicKey.toBase58() as Address;
|
|
206
|
+
const rpcResponse = await this.rpc
|
|
207
|
+
.getAccountInfo(accountAddress, {
|
|
208
|
+
commitment: this.commitment,
|
|
209
|
+
encoding: 'base64',
|
|
210
|
+
})
|
|
211
|
+
.send();
|
|
212
|
+
|
|
213
|
+
// Convert gill response to match the expected format
|
|
214
|
+
const context = {
|
|
215
|
+
slot: Number(rpcResponse.context.slot),
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const accountInfo = rpcResponse.value;
|
|
219
|
+
|
|
220
|
+
this.handleRpcResponse({ slot: BigInt(context.slot) }, accountInfo);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
handleRpcResponse(
|
|
224
|
+
context: { slot: bigint },
|
|
225
|
+
accountInfo?: AccountInfoBase &
|
|
226
|
+
(AccountInfoWithBase58EncodedData | AccountInfoWithBase64EncodedData)
|
|
227
|
+
): void {
|
|
228
|
+
const newSlot = context.slot;
|
|
229
|
+
let newBuffer: Buffer | undefined = undefined;
|
|
230
|
+
|
|
231
|
+
if (accountInfo) {
|
|
232
|
+
// Extract data from gill response
|
|
233
|
+
if (accountInfo.data) {
|
|
234
|
+
// Handle different data formats from gill
|
|
235
|
+
if (Array.isArray(accountInfo.data)) {
|
|
236
|
+
// If it's a tuple [data, encoding]
|
|
237
|
+
const [data, encoding] = accountInfo.data;
|
|
238
|
+
|
|
239
|
+
if (encoding === 'base58') {
|
|
240
|
+
// we know encoding will be base58
|
|
241
|
+
// Convert base58 to buffer using bs58
|
|
242
|
+
newBuffer = Buffer.from(bs58.decode(data));
|
|
243
|
+
} else {
|
|
244
|
+
newBuffer = Buffer.from(data, 'base64');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!this.bufferAndSlot) {
|
|
251
|
+
this.bufferAndSlot = {
|
|
252
|
+
buffer: newBuffer,
|
|
253
|
+
slot: Number(newSlot),
|
|
254
|
+
};
|
|
255
|
+
if (newBuffer) {
|
|
256
|
+
const account = this.decodeBuffer(newBuffer);
|
|
257
|
+
this.dataAndSlot = {
|
|
258
|
+
data: account,
|
|
259
|
+
slot: Number(newSlot),
|
|
260
|
+
};
|
|
261
|
+
this.onChange(account);
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (Number(newSlot) < this.bufferAndSlot.slot) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const oldBuffer = this.bufferAndSlot.buffer;
|
|
271
|
+
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
272
|
+
this.bufferAndSlot = {
|
|
273
|
+
buffer: newBuffer,
|
|
274
|
+
slot: Number(newSlot),
|
|
275
|
+
};
|
|
276
|
+
const account = this.decodeBuffer(newBuffer);
|
|
277
|
+
this.dataAndSlot = {
|
|
278
|
+
data: account,
|
|
279
|
+
slot: Number(newSlot),
|
|
280
|
+
};
|
|
281
|
+
this.onChange(account);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
decodeBuffer(buffer: Buffer): T {
|
|
286
|
+
if (this.decodeBufferFn) {
|
|
287
|
+
return this.decodeBufferFn(buffer);
|
|
288
|
+
} else {
|
|
289
|
+
return this.program.account[this.accountName].coder.accounts.decode(
|
|
290
|
+
capitalize(this.accountName),
|
|
291
|
+
buffer
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
unsubscribe(onResub = false): Promise<void> {
|
|
297
|
+
if (!onResub && this.resubOpts) {
|
|
298
|
+
this.resubOpts.resubTimeoutMs = undefined;
|
|
299
|
+
}
|
|
300
|
+
this.isUnsubscribing = true;
|
|
301
|
+
clearTimeout(this.timeoutId);
|
|
302
|
+
this.timeoutId = undefined;
|
|
303
|
+
|
|
304
|
+
// Abort the WebSocket subscription
|
|
305
|
+
if (this.abortController) {
|
|
306
|
+
this.abortController.abort('unsubscribing');
|
|
307
|
+
this.abortController = undefined;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
this.listenerId = undefined;
|
|
311
|
+
this.isUnsubscribing = false;
|
|
312
|
+
|
|
313
|
+
return Promise.resolve();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -28,6 +28,7 @@ import { findAllMarketAndOracles } from '../config';
|
|
|
28
28
|
import { findDelistedPerpMarketsAndOracles } from './utils';
|
|
29
29
|
import { getOracleId } from '../oracles/oracleId';
|
|
30
30
|
import { OracleSource } from '../types';
|
|
31
|
+
import { WebSocketAccountSubscriberV2 } from './webSocketAccountSubscriberV2';
|
|
31
32
|
|
|
32
33
|
const ORACLE_DEFAULT_ID = getOracleId(
|
|
33
34
|
PublicKey.default,
|
|
@@ -68,6 +69,14 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
68
69
|
initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
|
|
69
70
|
initialSpotMarketAccountData: Map<number, SpotMarketAccount>;
|
|
70
71
|
initialOraclePriceData: Map<string, OraclePriceData>;
|
|
72
|
+
customPerpMarketAccountSubscriber?: new (
|
|
73
|
+
accountName: string,
|
|
74
|
+
program: Program,
|
|
75
|
+
accountPublicKey: PublicKey,
|
|
76
|
+
decodeBuffer?: (buffer: Buffer) => any,
|
|
77
|
+
resubOpts?: ResubOpts,
|
|
78
|
+
commitment?: Commitment
|
|
79
|
+
) => AccountSubscriber<any>;
|
|
71
80
|
|
|
72
81
|
protected isSubscribing = false;
|
|
73
82
|
protected subscriptionPromise: Promise<boolean>;
|
|
@@ -81,7 +90,15 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
81
90
|
shouldFindAllMarketsAndOracles: boolean,
|
|
82
91
|
delistedMarketSetting: DelistedMarketSetting,
|
|
83
92
|
resubOpts?: ResubOpts,
|
|
84
|
-
commitment?: Commitment
|
|
93
|
+
commitment?: Commitment,
|
|
94
|
+
customPerpMarketAccountSubscriber?: new (
|
|
95
|
+
accountName: string,
|
|
96
|
+
program: Program,
|
|
97
|
+
accountPublicKey: PublicKey,
|
|
98
|
+
decodeBuffer?: (buffer: Buffer) => any,
|
|
99
|
+
resubOpts?: ResubOpts,
|
|
100
|
+
commitment?: Commitment
|
|
101
|
+
) => WebSocketAccountSubscriberV2<any> | WebSocketAccountSubscriber<any>
|
|
85
102
|
) {
|
|
86
103
|
this.isSubscribed = false;
|
|
87
104
|
this.program = program;
|
|
@@ -93,6 +110,7 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
93
110
|
this.delistedMarketSetting = delistedMarketSetting;
|
|
94
111
|
this.resubOpts = resubOpts;
|
|
95
112
|
this.commitment = commitment;
|
|
113
|
+
this.customPerpMarketAccountSubscriber = customPerpMarketAccountSubscriber;
|
|
96
114
|
}
|
|
97
115
|
|
|
98
116
|
public async subscribe(): Promise<boolean> {
|
|
@@ -292,7 +310,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
292
310
|
this.program.programId,
|
|
293
311
|
marketIndex
|
|
294
312
|
);
|
|
295
|
-
const
|
|
313
|
+
const AccountSubscriberClass =
|
|
314
|
+
this.customPerpMarketAccountSubscriber || WebSocketAccountSubscriber;
|
|
315
|
+
const accountSubscriber = new AccountSubscriberClass<PerpMarketAccount>(
|
|
296
316
|
'perpMarket',
|
|
297
317
|
this.program,
|
|
298
318
|
perpMarketPublicKey,
|