@drift-labs/sdk 2.48.0-beta.2 → 2.48.0-beta.21
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/lib/accounts/bulkAccountLoader.js +1 -1
- package/lib/accounts/pollingUserAccountSubscriber.js +14 -7
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +14 -7
- package/lib/accounts/webSocketAccountSubscriber.js +1 -1
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +3 -2
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +6 -5
- package/lib/accounts/webSocketProgramAccountSubscriber.js +1 -1
- package/lib/accounts/webSocketUserAccountSubscriber.js +1 -1
- package/lib/constants/spotMarkets.js +10 -0
- package/lib/dlob/orderBookLevels.js +1 -1
- package/lib/driftClient.js +4 -4
- package/lib/events/eventSubscriber.js +23 -2
- package/lib/events/pollingLogProvider.d.ts +1 -1
- package/lib/events/pollingLogProvider.js +1 -1
- package/lib/events/types.d.ts +9 -2
- package/lib/events/webSocketLogProvider.d.ts +15 -3
- package/lib/events/webSocketLogProvider.js +66 -7
- package/lib/orderSubscriber/OrderSubscriber.d.ts +5 -1
- package/lib/orderSubscriber/OrderSubscriber.js +24 -7
- package/lib/orderSubscriber/WebsocketSubscription.d.ts +4 -1
- package/lib/orderSubscriber/WebsocketSubscription.js +4 -3
- package/lib/orderSubscriber/types.d.ts +3 -1
- package/lib/slot/SlotSubscriber.js +4 -2
- package/lib/user.js +3 -3
- package/lib/userMap/userMap.d.ts +16 -4
- package/lib/userMap/userMap.js +83 -41
- package/lib/userMap/userStatsMap.d.ts +29 -8
- package/lib/userMap/userStatsMap.js +46 -41
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +1 -1
- package/src/accounts/pollingUserAccountSubscriber.ts +19 -11
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +20 -12
- package/src/accounts/webSocketAccountSubscriber.ts +1 -1
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +13 -6
- package/src/accounts/webSocketProgramAccountSubscriber.ts +1 -1
- package/src/accounts/webSocketUserAccountSubscriber.ts +1 -1
- package/src/constants/spotMarkets.ts +10 -0
- package/src/dlob/orderBookLevels.ts +1 -1
- package/src/driftClient.ts +3 -2
- package/src/events/eventSubscriber.ts +46 -2
- package/src/events/pollingLogProvider.ts +2 -2
- package/src/events/types.ts +11 -2
- package/src/events/webSocketLogProvider.ts +78 -8
- package/src/orderSubscriber/OrderSubscriber.ts +39 -15
- package/src/orderSubscriber/WebsocketSubscription.ts +7 -2
- package/src/orderSubscriber/types.ts +3 -1
- package/src/slot/SlotSubscriber.ts +4 -2
- package/src/user.ts +3 -3
- package/src/userMap/userMap.ts +139 -66
- package/src/userMap/userStatsMap.ts +64 -69
- package/tests/amm/test.ts +3 -2
- package/tests/dlob/test.ts +8 -5
package/src/userMap/userMap.ts
CHANGED
|
@@ -32,33 +32,59 @@ export interface UserMapInterface {
|
|
|
32
32
|
values(): IterableIterator<User>;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
// filter users that meet these criteria when passing into syncCallback
|
|
36
|
+
export type SyncCallbackCriteria = {
|
|
37
|
+
// only sync users that have open orders
|
|
38
|
+
hasOpenOrders: boolean;
|
|
39
|
+
};
|
|
40
|
+
|
|
35
41
|
export class UserMap implements UserMapInterface {
|
|
36
42
|
private userMap = new Map<string, User>();
|
|
37
43
|
private driftClient: DriftClient;
|
|
38
44
|
private accountSubscription: UserSubscriptionConfig;
|
|
39
45
|
private includeIdle: boolean;
|
|
40
46
|
private lastNumberOfSubAccounts;
|
|
41
|
-
private
|
|
47
|
+
private stateAccountUpdateCallback = async (state: StateAccount) => {
|
|
42
48
|
if (state.numberOfSubAccounts !== this.lastNumberOfSubAccounts) {
|
|
43
49
|
await this.sync();
|
|
44
50
|
this.lastNumberOfSubAccounts = state.numberOfSubAccounts;
|
|
45
51
|
}
|
|
46
52
|
};
|
|
53
|
+
private syncCallback: (authorities: PublicKey[]) => Promise<void>;
|
|
54
|
+
private syncCallbackCriteria: SyncCallbackCriteria;
|
|
55
|
+
|
|
56
|
+
private syncPromise?: Promise<void>;
|
|
57
|
+
private syncPromiseResolver: () => void;
|
|
47
58
|
|
|
48
59
|
/**
|
|
60
|
+
* Constructs a new UserMap instance.
|
|
49
61
|
*
|
|
50
|
-
* @param driftClient
|
|
51
|
-
* @param accountSubscription
|
|
52
|
-
* @param includeIdle
|
|
62
|
+
* @param {DriftClient} driftClient - The DriftClient instance.
|
|
63
|
+
* @param {UserSubscriptionConfig} accountSubscription - The UserSubscriptionConfig instance.
|
|
64
|
+
* @param {boolean} includeIdle - Whether idle users are subscribed to. Defaults to false to decrease # of user subscriptions.
|
|
65
|
+
* @param {(authorities: PublicKey[]) => Promise<void>} syncCallback - Called after `sync` completes, will pas in unique list of authorities. Useful for using it to sync UserStatsMap.
|
|
66
|
+
* @param {SyncCallbackCriteria} syncCallbackCriteria - The criteria for the sync callback. Defaults to having no filters
|
|
53
67
|
*/
|
|
54
68
|
constructor(
|
|
55
69
|
driftClient: DriftClient,
|
|
56
70
|
accountSubscription: UserSubscriptionConfig,
|
|
57
|
-
includeIdle = false
|
|
71
|
+
includeIdle = false,
|
|
72
|
+
syncCallback?: (authorities: PublicKey[]) => Promise<void>,
|
|
73
|
+
syncCallbackCriteria: SyncCallbackCriteria = { hasOpenOrders: false }
|
|
58
74
|
) {
|
|
59
75
|
this.driftClient = driftClient;
|
|
60
76
|
this.accountSubscription = accountSubscription;
|
|
61
77
|
this.includeIdle = includeIdle;
|
|
78
|
+
this.syncCallback = syncCallback;
|
|
79
|
+
this.syncCallbackCriteria = syncCallbackCriteria;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public addSyncCallback(
|
|
83
|
+
syncCallback?: (authorities: PublicKey[]) => Promise<void>,
|
|
84
|
+
syncCallbackCriteria: SyncCallbackCriteria = { hasOpenOrders: false }
|
|
85
|
+
) {
|
|
86
|
+
this.syncCallback = syncCallback;
|
|
87
|
+
this.syncCallbackCriteria = syncCallbackCriteria;
|
|
62
88
|
}
|
|
63
89
|
|
|
64
90
|
public async subscribe() {
|
|
@@ -69,7 +95,10 @@ export class UserMap implements UserMapInterface {
|
|
|
69
95
|
await this.driftClient.subscribe();
|
|
70
96
|
this.lastNumberOfSubAccounts =
|
|
71
97
|
this.driftClient.getStateAccount().numberOfSubAccounts;
|
|
72
|
-
this.driftClient.eventEmitter.on(
|
|
98
|
+
this.driftClient.eventEmitter.on(
|
|
99
|
+
'stateAccountUpdate',
|
|
100
|
+
this.stateAccountUpdateCallback
|
|
101
|
+
);
|
|
73
102
|
|
|
74
103
|
await this.sync();
|
|
75
104
|
}
|
|
@@ -187,74 +216,118 @@ export class UserMap implements UserMapInterface {
|
|
|
187
216
|
return this.userMap.size;
|
|
188
217
|
}
|
|
189
218
|
|
|
219
|
+
public getUniqueAuthorities(useSyncCallbackCriteria = true): PublicKey[] {
|
|
220
|
+
const usersMeetingCriteria = Array.from(this.userMap.values()).filter(
|
|
221
|
+
(user) => {
|
|
222
|
+
let pass = true;
|
|
223
|
+
if (
|
|
224
|
+
useSyncCallbackCriteria &&
|
|
225
|
+
this.syncCallbackCriteria.hasOpenOrders
|
|
226
|
+
) {
|
|
227
|
+
pass = pass && user.getUserAccount().hasOpenOrder;
|
|
228
|
+
}
|
|
229
|
+
return pass;
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
const userAuths = new Set(
|
|
233
|
+
usersMeetingCriteria.map((user) =>
|
|
234
|
+
user.getUserAccount().authority.toBase58()
|
|
235
|
+
)
|
|
236
|
+
);
|
|
237
|
+
const userAuthKeys = Array.from(userAuths).map(
|
|
238
|
+
(userAuth) => new PublicKey(userAuth)
|
|
239
|
+
);
|
|
240
|
+
return userAuthKeys;
|
|
241
|
+
}
|
|
242
|
+
|
|
190
243
|
public async sync() {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
filters.push(getNonIdleUserFilter());
|
|
244
|
+
if (this.syncPromise) {
|
|
245
|
+
return this.syncPromise;
|
|
194
246
|
}
|
|
247
|
+
this.syncPromise = new Promise((resolver) => {
|
|
248
|
+
this.syncPromiseResolver = resolver;
|
|
249
|
+
});
|
|
195
250
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
{
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
encoding: 'base64',
|
|
202
|
-
withContext: true,
|
|
203
|
-
},
|
|
204
|
-
];
|
|
205
|
-
|
|
206
|
-
// @ts-ignore
|
|
207
|
-
const rpcJSONResponse: any = await this.driftClient.connection._rpcRequest(
|
|
208
|
-
'getProgramAccounts',
|
|
209
|
-
rpcRequestArgs
|
|
210
|
-
);
|
|
251
|
+
try {
|
|
252
|
+
const filters = [getUserFilter()];
|
|
253
|
+
if (!this.includeIdle) {
|
|
254
|
+
filters.push(getNonIdleUserFilter());
|
|
255
|
+
}
|
|
211
256
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const programAccountBufferMap = new Map<string, Buffer>();
|
|
224
|
-
for (const programAccount of rpcResponseAndContext.value) {
|
|
225
|
-
programAccountBufferMap.set(
|
|
226
|
-
programAccount.pubkey.toString(),
|
|
257
|
+
const rpcRequestArgs = [
|
|
258
|
+
this.driftClient.program.programId.toBase58(),
|
|
259
|
+
{
|
|
260
|
+
commitment: this.driftClient.connection.commitment,
|
|
261
|
+
filters,
|
|
262
|
+
encoding: 'base64',
|
|
263
|
+
withContext: true,
|
|
264
|
+
},
|
|
265
|
+
];
|
|
266
|
+
|
|
267
|
+
const rpcJSONResponse: any =
|
|
227
268
|
// @ts-ignore
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
|
|
269
|
+
await this.driftClient.connection._rpcRequest(
|
|
270
|
+
'getProgramAccounts',
|
|
271
|
+
rpcRequestArgs
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
const rpcResponseAndContext: RpcResponseAndContext<
|
|
275
|
+
Array<{
|
|
276
|
+
pubkey: PublicKey;
|
|
277
|
+
account: {
|
|
278
|
+
data: [string, string];
|
|
279
|
+
};
|
|
280
|
+
}>
|
|
281
|
+
> = rpcJSONResponse.result;
|
|
282
|
+
|
|
283
|
+
const slot = rpcResponseAndContext.context.slot;
|
|
234
284
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
285
|
+
const programAccountBufferMap = new Map<string, Buffer>();
|
|
286
|
+
for (const programAccount of rpcResponseAndContext.value) {
|
|
287
|
+
programAccountBufferMap.set(
|
|
288
|
+
programAccount.pubkey.toString(),
|
|
289
|
+
// @ts-ignore
|
|
290
|
+
Buffer.from(
|
|
291
|
+
programAccount.account.data[0],
|
|
292
|
+
programAccount.account.data[1]
|
|
293
|
+
)
|
|
294
|
+
);
|
|
243
295
|
}
|
|
244
|
-
}
|
|
245
296
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
297
|
+
for (const [key, buffer] of programAccountBufferMap.entries()) {
|
|
298
|
+
if (!this.has(key)) {
|
|
299
|
+
const userAccount =
|
|
300
|
+
this.driftClient.program.account.user.coder.accounts.decode(
|
|
301
|
+
'User',
|
|
302
|
+
buffer
|
|
303
|
+
);
|
|
304
|
+
await this.addPubkey(new PublicKey(key), userAccount);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
for (const [key, user] of this.userMap.entries()) {
|
|
309
|
+
if (!programAccountBufferMap.has(key)) {
|
|
310
|
+
await user.unsubscribe();
|
|
311
|
+
this.userMap.delete(key);
|
|
312
|
+
} else {
|
|
313
|
+
const userAccount =
|
|
314
|
+
this.driftClient.program.account.user.coder.accounts.decode(
|
|
315
|
+
'User',
|
|
316
|
+
programAccountBufferMap.get(key)
|
|
317
|
+
);
|
|
318
|
+
user.accountSubscriber.updateData(userAccount, slot);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (this.syncCallback) {
|
|
323
|
+
await this.syncCallback(this.getUniqueAuthorities());
|
|
257
324
|
}
|
|
325
|
+
} catch (e) {
|
|
326
|
+
console.error(`Error in UserMap.sync()`);
|
|
327
|
+
console.error(e);
|
|
328
|
+
} finally {
|
|
329
|
+
this.syncPromiseResolver();
|
|
330
|
+
this.syncPromise = undefined;
|
|
258
331
|
}
|
|
259
332
|
}
|
|
260
333
|
|
|
@@ -267,7 +340,7 @@ export class UserMap implements UserMapInterface {
|
|
|
267
340
|
if (this.lastNumberOfSubAccounts) {
|
|
268
341
|
this.driftClient.eventEmitter.removeListener(
|
|
269
342
|
'stateAccountUpdate',
|
|
270
|
-
this.
|
|
343
|
+
this.stateAccountUpdateCallback
|
|
271
344
|
);
|
|
272
345
|
this.lastNumberOfSubAccounts = undefined;
|
|
273
346
|
}
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
OrderRecord,
|
|
5
5
|
UserStatsAccount,
|
|
6
6
|
UserStats,
|
|
7
|
-
UserStatsSubscriptionConfig,
|
|
8
7
|
WrappedEvent,
|
|
9
8
|
DepositRecord,
|
|
10
9
|
FundingPaymentRecord,
|
|
@@ -14,12 +13,12 @@ import {
|
|
|
14
13
|
NewUserRecord,
|
|
15
14
|
LPRecord,
|
|
16
15
|
InsuranceFundStakeRecord,
|
|
17
|
-
|
|
16
|
+
BulkAccountLoader,
|
|
17
|
+
PollingUserStatsAccountSubscriber,
|
|
18
18
|
} from '..';
|
|
19
|
-
import {
|
|
19
|
+
import { PublicKey } from '@solana/web3.js';
|
|
20
20
|
|
|
21
21
|
import { UserMap } from './userMap';
|
|
22
|
-
import { Buffer } from 'buffer';
|
|
23
22
|
|
|
24
23
|
export class UserStatsMap {
|
|
25
24
|
/**
|
|
@@ -27,39 +26,45 @@ export class UserStatsMap {
|
|
|
27
26
|
*/
|
|
28
27
|
private userStatsMap = new Map<string, UserStats>();
|
|
29
28
|
private driftClient: DriftClient;
|
|
30
|
-
private
|
|
31
|
-
private lastNumberOfAuthorities;
|
|
32
|
-
private syncCallback = async (state: StateAccount) => {
|
|
33
|
-
if (state.numberOfAuthorities !== this.lastNumberOfAuthorities) {
|
|
34
|
-
await this.sync();
|
|
35
|
-
this.lastNumberOfAuthorities = state.numberOfAuthorities;
|
|
36
|
-
}
|
|
37
|
-
};
|
|
29
|
+
private bulkAccountLoader: BulkAccountLoader;
|
|
38
30
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new UserStatsMap instance.
|
|
33
|
+
*
|
|
34
|
+
* @param {DriftClient} driftClient - The DriftClient instance.
|
|
35
|
+
* @param {BulkAccountLoader} [bulkAccountLoader] - If not provided, a new BulkAccountLoader with polling disabled will be created.
|
|
36
|
+
*/
|
|
37
|
+
constructor(driftClient: DriftClient, bulkAccountLoader?: BulkAccountLoader) {
|
|
43
38
|
this.driftClient = driftClient;
|
|
44
|
-
|
|
39
|
+
if (!bulkAccountLoader) {
|
|
40
|
+
bulkAccountLoader = new BulkAccountLoader(
|
|
41
|
+
driftClient.connection,
|
|
42
|
+
driftClient.opts.commitment,
|
|
43
|
+
0
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
this.bulkAccountLoader = bulkAccountLoader;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
public async subscribe() {
|
|
49
|
+
public async subscribe(authorities: PublicKey[]) {
|
|
48
50
|
if (this.size() > 0) {
|
|
49
51
|
return;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
await this.driftClient.subscribe();
|
|
53
|
-
this.
|
|
54
|
-
this.driftClient.getStateAccount().numberOfAuthorities;
|
|
55
|
-
this.driftClient.eventEmitter.on('stateAccountUpdate', this.syncCallback);
|
|
56
|
-
|
|
57
|
-
await this.sync();
|
|
55
|
+
await this.sync(authorities);
|
|
58
56
|
}
|
|
59
57
|
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @param authority that owns the UserStatsAccount
|
|
61
|
+
* @param userStatsAccount optional UserStatsAccount to subscribe to, if undefined will be fetched later
|
|
62
|
+
* @param skipFetch if true, will not immediately fetch the UserStatsAccount
|
|
63
|
+
*/
|
|
60
64
|
public async addUserStat(
|
|
61
65
|
authority: PublicKey,
|
|
62
|
-
userStatsAccount?: UserStatsAccount
|
|
66
|
+
userStatsAccount?: UserStatsAccount,
|
|
67
|
+
skipFetch?: boolean
|
|
63
68
|
) {
|
|
64
69
|
const userStat = new UserStats({
|
|
65
70
|
driftClient: this.driftClient,
|
|
@@ -67,9 +72,18 @@ export class UserStatsMap {
|
|
|
67
72
|
this.driftClient.program.programId,
|
|
68
73
|
authority
|
|
69
74
|
),
|
|
70
|
-
accountSubscription:
|
|
75
|
+
accountSubscription: {
|
|
76
|
+
type: 'polling',
|
|
77
|
+
accountLoader: this.bulkAccountLoader,
|
|
78
|
+
},
|
|
71
79
|
});
|
|
72
|
-
|
|
80
|
+
if (skipFetch) {
|
|
81
|
+
await (
|
|
82
|
+
userStat.accountSubscriber as PollingUserStatsAccountSubscriber
|
|
83
|
+
).addToAccountLoader();
|
|
84
|
+
} else {
|
|
85
|
+
await userStat.subscribe(userStatsAccount);
|
|
86
|
+
}
|
|
73
87
|
|
|
74
88
|
this.userStatsMap.set(authority.toString(), userStat);
|
|
75
89
|
}
|
|
@@ -77,7 +91,7 @@ export class UserStatsMap {
|
|
|
77
91
|
public async updateWithOrderRecord(record: OrderRecord, userMap: UserMap) {
|
|
78
92
|
const user = await userMap.mustGet(record.user.toString());
|
|
79
93
|
if (!this.has(user.getUserAccount().authority.toString())) {
|
|
80
|
-
await this.addUserStat(user.getUserAccount().authority);
|
|
94
|
+
await this.addUserStat(user.getUserAccount().authority, undefined, false);
|
|
81
95
|
}
|
|
82
96
|
}
|
|
83
97
|
|
|
@@ -156,9 +170,19 @@ export class UserStatsMap {
|
|
|
156
170
|
return this.userStatsMap.get(authorityPublicKey);
|
|
157
171
|
}
|
|
158
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Enforce that a UserStats will exist for the given authorityPublicKey,
|
|
175
|
+
* reading one from the blockchain if necessary.
|
|
176
|
+
* @param authorityPublicKey
|
|
177
|
+
* @returns
|
|
178
|
+
*/
|
|
159
179
|
public async mustGet(authorityPublicKey: string): Promise<UserStats> {
|
|
160
180
|
if (!this.has(authorityPublicKey)) {
|
|
161
|
-
await this.addUserStat(
|
|
181
|
+
await this.addUserStat(
|
|
182
|
+
new PublicKey(authorityPublicKey),
|
|
183
|
+
undefined,
|
|
184
|
+
false
|
|
185
|
+
);
|
|
162
186
|
}
|
|
163
187
|
return this.get(authorityPublicKey);
|
|
164
188
|
}
|
|
@@ -171,39 +195,18 @@ export class UserStatsMap {
|
|
|
171
195
|
return this.userStatsMap.size;
|
|
172
196
|
}
|
|
173
197
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
const programAccountMap = new Map<string, AccountInfo<Buffer>>();
|
|
190
|
-
for (const programAccount of programAccounts) {
|
|
191
|
-
programAccountMap.set(
|
|
192
|
-
new PublicKey(programAccount.account.data.slice(8, 40)).toString(),
|
|
193
|
-
programAccount.account
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
for (const key of programAccountMap.keys()) {
|
|
198
|
-
if (!this.has(key)) {
|
|
199
|
-
const userStatsAccount =
|
|
200
|
-
this.driftClient.program.account.userStats.coder.accounts.decode(
|
|
201
|
-
'UserStats',
|
|
202
|
-
programAccountMap.get(key).data
|
|
203
|
-
);
|
|
204
|
-
await this.addUserStat(new PublicKey(key), userStatsAccount);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
198
|
+
/**
|
|
199
|
+
* Sync the UserStatsMap
|
|
200
|
+
* @param authorities list of authorities to derive UserStatsAccount public keys from.
|
|
201
|
+
* You may want to get this list from UserMap in order to filter out idle users
|
|
202
|
+
*/
|
|
203
|
+
public async sync(authorities: PublicKey[]) {
|
|
204
|
+
await Promise.all(
|
|
205
|
+
authorities.map((authority) =>
|
|
206
|
+
this.addUserStat(authority, undefined, true)
|
|
207
|
+
)
|
|
208
|
+
);
|
|
209
|
+
await this.bulkAccountLoader.load();
|
|
207
210
|
}
|
|
208
211
|
|
|
209
212
|
public async unsubscribe() {
|
|
@@ -211,13 +214,5 @@ export class UserStatsMap {
|
|
|
211
214
|
await userStats.unsubscribe();
|
|
212
215
|
this.userStatsMap.delete(key);
|
|
213
216
|
}
|
|
214
|
-
|
|
215
|
-
if (this.lastNumberOfAuthorities) {
|
|
216
|
-
this.driftClient.eventEmitter.removeListener(
|
|
217
|
-
'stateAccountUpdate',
|
|
218
|
-
this.syncCallback
|
|
219
|
-
);
|
|
220
|
-
this.lastNumberOfAuthorities = undefined;
|
|
221
|
-
}
|
|
222
217
|
}
|
|
223
218
|
}
|
package/tests/amm/test.ts
CHANGED
|
@@ -967,8 +967,9 @@ describe('AMM Tests', () => {
|
|
|
967
967
|
mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(
|
|
968
968
|
new BN(9)
|
|
969
969
|
);
|
|
970
|
-
mockMarket1.amm.minBaseAssetReserve =
|
|
971
|
-
|
|
970
|
+
mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.sub(
|
|
971
|
+
new BN(9)
|
|
972
|
+
);
|
|
972
973
|
mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
973
974
|
mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
|
|
974
975
|
mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
|
package/tests/dlob/test.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
|
|
28
28
|
import { mockPerpMarkets, mockSpotMarkets, mockStateAccount } from './helpers';
|
|
29
29
|
import { DLOBOrdersCoder } from '../../src/dlob/DLOBOrders';
|
|
30
|
-
import {isAuctionComplete, isRestingLimitOrder} from
|
|
30
|
+
import { isAuctionComplete, isRestingLimitOrder } from '../../lib';
|
|
31
31
|
|
|
32
32
|
function insertOrderToDLOB(
|
|
33
33
|
dlob: DLOB,
|
|
@@ -2537,18 +2537,21 @@ describe('DLOB Perp Tests', () => {
|
|
|
2537
2537
|
OrderTriggerCondition.TRIGGERED_ABOVE, // triggerCondition: OrderTriggerCondition,
|
|
2538
2538
|
vBid,
|
|
2539
2539
|
vAsk,
|
|
2540
|
-
new BN(1)
|
|
2540
|
+
new BN(1) // slot
|
|
2541
2541
|
);
|
|
2542
2542
|
|
|
2543
|
-
const restingLimitBids = Array.from(
|
|
2543
|
+
const restingLimitBids = Array.from(
|
|
2544
|
+
dlob.getRestingLimitBids(marketIndex, slot, MarketType.PERP, oracle)
|
|
2545
|
+
);
|
|
2544
2546
|
expect(restingLimitBids.length).to.equal(0);
|
|
2545
2547
|
|
|
2546
|
-
const takingBids = Array.from(
|
|
2548
|
+
const takingBids = Array.from(
|
|
2549
|
+
dlob.getTakingBids(marketIndex, MarketType.PERP, slot, oracle)
|
|
2550
|
+
);
|
|
2547
2551
|
expect(takingBids.length).to.equal(1);
|
|
2548
2552
|
const triggerLimitBid = takingBids[0];
|
|
2549
2553
|
expect(isAuctionComplete(triggerLimitBid.order, slot)).to.equal(true);
|
|
2550
2554
|
expect(isRestingLimitOrder(triggerLimitBid.order, slot)).to.equal(false);
|
|
2551
|
-
|
|
2552
2555
|
});
|
|
2553
2556
|
|
|
2554
2557
|
it('Test will return expired market orders to fill', () => {
|