@drift-labs/sdk 2.25.3 → 2.26.0-beta.0
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/lib/accounts/pollingUserAccountSubscriber.d.ts +5 -4
- package/lib/accounts/pollingUserAccountSubscriber.js +35 -48
- package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +4 -4
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +30 -47
- package/lib/accounts/types.d.ts +2 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +1 -1
- package/lib/accounts/webSocketAccountSubscriber.js +4 -3
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +1 -0
- package/lib/accounts/webSocketUserAccountSubscriber.js +9 -0
- package/lib/addresses/pda.d.ts +2 -0
- package/lib/addresses/pda.js +8 -1
- package/lib/adminClient.d.ts +2 -0
- package/lib/adminClient.js +20 -0
- package/lib/constants/numericConstants.d.ts +61 -59
- package/lib/constants/spotMarkets.d.ts +1 -0
- package/lib/dlob/DLOB.d.ts +1 -0
- package/lib/dlob/DLOBApiClient.d.ts +14 -0
- package/lib/dlob/DLOBApiClient.js +34 -0
- package/lib/dlob/DLOBNode.d.ts +1 -0
- package/lib/dlob/DLOBSubscriber.d.ts +19 -0
- package/lib/dlob/DLOBSubscriber.js +42 -0
- package/lib/dlob/NodeList.d.ts +1 -0
- package/lib/dlob/types.d.ts +16 -0
- package/lib/dlob/types.js +2 -0
- package/lib/driftClient.d.ts +14 -10
- package/lib/driftClient.js +124 -28
- package/lib/examples/loadDlob.js +2 -4
- package/lib/factory/bigNum.d.ts +8 -7
- package/lib/idl/drift.json +264 -82
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/math/amm.d.ts +2 -1
- package/lib/math/auction.d.ts +1 -0
- package/lib/math/conversion.d.ts +2 -1
- package/lib/math/funding.d.ts +1 -0
- package/lib/math/insurance.d.ts +1 -0
- package/lib/math/margin.d.ts +1 -0
- package/lib/math/market.d.ts +1 -0
- package/lib/math/oracles.d.ts +1 -0
- package/lib/math/orders.d.ts +1 -0
- package/lib/math/position.d.ts +1 -0
- package/lib/math/repeg.d.ts +1 -0
- package/lib/math/spotBalance.d.ts +1 -0
- package/lib/math/spotMarket.d.ts +1 -0
- package/lib/math/spotPosition.d.ts +1 -0
- package/lib/math/trade.d.ts +1 -0
- package/lib/math/utils.d.ts +1 -0
- package/lib/oracles/pythClient.d.ts +2 -1
- package/lib/oracles/types.d.ts +1 -0
- package/lib/orderParams.d.ts +1 -0
- package/lib/serum/serumSubscriber.d.ts +1 -0
- package/lib/slot/SlotSubscriber.js +3 -0
- package/lib/tokenFaucet.d.ts +1 -0
- package/lib/tx/retryTxSender.d.ts +2 -1
- package/lib/tx/retryTxSender.js +5 -1
- package/lib/tx/types.d.ts +4 -1
- package/lib/types.d.ts +12 -0
- package/lib/user.d.ts +1 -0
- package/lib/userMap/userMap.d.ts +17 -6
- package/lib/userMap/userMap.js +74 -46
- package/lib/userMap/userStatsMap.d.ts +6 -3
- package/lib/userMap/userStatsMap.js +30 -30
- package/package.json +2 -1
- package/src/accounts/pollingUserAccountSubscriber.ts +51 -63
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +46 -62
- package/src/accounts/types.ts +2 -1
- package/src/accounts/webSocketAccountSubscriber.ts +4 -3
- package/src/accounts/webSocketUserAccountSubscriber.ts +10 -0
- package/src/addresses/pda.ts +13 -0
- package/src/adminClient.ts +34 -0
- package/src/dlob/DLOBApiClient.ts +37 -0
- package/src/dlob/DLOBSubscriber.ts +57 -0
- package/src/dlob/types.ts +20 -0
- package/src/driftClient.ts +216 -59
- package/src/examples/loadDlob.ts +2 -4
- package/src/idl/drift.json +264 -82
- package/src/index.ts +2 -0
- package/src/slot/SlotSubscriber.ts +4 -0
- package/src/tx/retryTxSender.ts +19 -2
- package/src/tx/types.ts +13 -0
- package/src/types.ts +12 -0
- package/src/userMap/userMap.ts +111 -60
- package/src/userMap/userStatsMap.ts +43 -44
- package/tests/dlob/helpers.ts +3 -1
- package/src/assert/assert.js +0 -9
- package/src/token/index.js +0 -38
- package/src/util/computeUnits.js +0 -27
- package/src/util/getTokenAddress.js +0 -9
- package/src/util/promiseTimeout.js +0 -14
- package/src/util/tps.js +0 -27
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DataAndSlot,
|
|
3
|
-
AccountToPoll,
|
|
4
3
|
NotSubscribedError,
|
|
5
4
|
UserStatsAccountSubscriber,
|
|
6
5
|
UserStatsAccountEvents,
|
|
@@ -11,7 +10,6 @@ import { EventEmitter } from 'events';
|
|
|
11
10
|
import { PublicKey } from '@solana/web3.js';
|
|
12
11
|
import { UserStatsAccount } from '../types';
|
|
13
12
|
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
14
|
-
import { capitalize } from './utils';
|
|
15
13
|
|
|
16
14
|
export class PollingUserStatsAccountSubscriber
|
|
17
15
|
implements UserStatsAccountSubscriber
|
|
@@ -22,7 +20,7 @@ export class PollingUserStatsAccountSubscriber
|
|
|
22
20
|
userStatsAccountPublicKey: PublicKey;
|
|
23
21
|
|
|
24
22
|
accountLoader: BulkAccountLoader;
|
|
25
|
-
|
|
23
|
+
callbackId?: string;
|
|
26
24
|
errorCallbackId?: string;
|
|
27
25
|
|
|
28
26
|
userStats?: DataAndSlot<UserStatsAccount>;
|
|
@@ -39,16 +37,20 @@ export class PollingUserStatsAccountSubscriber
|
|
|
39
37
|
this.userStatsAccountPublicKey = userStatsAccountPublicKey;
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
async subscribe(): Promise<boolean> {
|
|
40
|
+
async subscribe(userStatsAccount?: UserStatsAccount): Promise<boolean> {
|
|
43
41
|
if (this.isSubscribed) {
|
|
44
42
|
return true;
|
|
45
43
|
}
|
|
46
44
|
|
|
45
|
+
if (userStatsAccount) {
|
|
46
|
+
this.userStats = { data: userStatsAccount, slot: undefined };
|
|
47
|
+
}
|
|
48
|
+
|
|
47
49
|
await this.addToAccountLoader();
|
|
48
50
|
|
|
49
51
|
await this.fetchIfUnloaded();
|
|
50
52
|
|
|
51
|
-
if (this.
|
|
53
|
+
if (this.doesAccountExist()) {
|
|
52
54
|
this.eventEmitter.emit('update');
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -57,34 +59,30 @@ export class PollingUserStatsAccountSubscriber
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
async addToAccountLoader(): Promise<void> {
|
|
60
|
-
if (this.
|
|
62
|
+
if (this.callbackId !== undefined) {
|
|
61
63
|
return;
|
|
62
64
|
}
|
|
63
65
|
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
this.callbackId = await this.accountLoader.addAccount(
|
|
67
|
+
this.userStatsAccountPublicKey,
|
|
68
|
+
(buffer, slot: number) => {
|
|
69
|
+
if (!buffer) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
accountToPoll.publicKey,
|
|
73
|
-
(buffer, slot) => {
|
|
74
|
-
if (!buffer) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const account = this.program.account[
|
|
79
|
-
accountToPoll.key
|
|
80
|
-
].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
|
|
81
|
-
this[accountToPoll.key] = { data: account, slot };
|
|
82
|
-
// @ts-ignore
|
|
83
|
-
this.eventEmitter.emit(accountToPoll.eventType, account);
|
|
84
|
-
this.eventEmitter.emit('update');
|
|
73
|
+
if (this.userStats && this.userStats.slot > slot) {
|
|
74
|
+
return;
|
|
85
75
|
}
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
|
|
77
|
+
const account = this.program.account.userStats.coder.accounts.decode(
|
|
78
|
+
'UserStats',
|
|
79
|
+
buffer
|
|
80
|
+
);
|
|
81
|
+
this.userStats = { data: account, slot };
|
|
82
|
+
this.eventEmitter.emit('userStatsAccountUpdate', account);
|
|
83
|
+
this.eventEmitter.emit('update');
|
|
84
|
+
}
|
|
85
|
+
);
|
|
88
86
|
|
|
89
87
|
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
90
88
|
this.eventEmitter.emit('error', error);
|
|
@@ -92,58 +90,44 @@ export class PollingUserStatsAccountSubscriber
|
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
async fetchIfUnloaded(): Promise<void> {
|
|
95
|
-
|
|
96
|
-
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
97
|
-
if (this[accountToPoll.key] === undefined) {
|
|
98
|
-
shouldFetch = true;
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (shouldFetch) {
|
|
93
|
+
if (this.userStats === undefined) {
|
|
104
94
|
await this.fetch();
|
|
105
95
|
}
|
|
106
96
|
}
|
|
107
97
|
|
|
108
98
|
async fetch(): Promise<void> {
|
|
109
99
|
await this.accountLoader.load();
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
const { buffer, slot } = this.accountLoader.getBufferAndSlot(
|
|
101
|
+
this.userStatsAccountPublicKey
|
|
102
|
+
);
|
|
103
|
+
const currentSlot = this.userStats?.slot ?? 0;
|
|
104
|
+
if (buffer && slot > currentSlot) {
|
|
105
|
+
const account = this.program.account.userStats.coder.accounts.decode(
|
|
106
|
+
'UserStats',
|
|
107
|
+
buffer
|
|
113
108
|
);
|
|
114
|
-
|
|
115
|
-
const account = this.program.account[
|
|
116
|
-
accountToPoll.key
|
|
117
|
-
].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
|
|
118
|
-
this[accountToPoll.key] = { data: account, slot };
|
|
119
|
-
}
|
|
109
|
+
this.userStats = { data: account, slot };
|
|
120
110
|
}
|
|
121
111
|
}
|
|
122
112
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
126
|
-
if (!this[accountToPoll.key]) {
|
|
127
|
-
success = false;
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return success;
|
|
113
|
+
doesAccountExist(): boolean {
|
|
114
|
+
return this.userStats !== undefined;
|
|
132
115
|
}
|
|
133
116
|
|
|
134
117
|
async unsubscribe(): Promise<void> {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
accountToPoll.publicKey,
|
|
138
|
-
accountToPoll.callbackId
|
|
139
|
-
);
|
|
118
|
+
if (!this.isSubscribed) {
|
|
119
|
+
return;
|
|
140
120
|
}
|
|
141
121
|
|
|
122
|
+
this.accountLoader.removeAccount(
|
|
123
|
+
this.userStatsAccountPublicKey,
|
|
124
|
+
this.callbackId
|
|
125
|
+
);
|
|
126
|
+
this.callbackId = undefined;
|
|
127
|
+
|
|
142
128
|
this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
|
|
143
129
|
this.errorCallbackId = undefined;
|
|
144
130
|
|
|
145
|
-
this.accountsToPoll.clear();
|
|
146
|
-
|
|
147
131
|
this.isSubscribed = false;
|
|
148
132
|
}
|
|
149
133
|
|
package/src/accounts/types.ts
CHANGED
|
@@ -18,7 +18,7 @@ export interface AccountSubscriber<T> {
|
|
|
18
18
|
fetch(): Promise<void>;
|
|
19
19
|
unsubscribe(): Promise<void>;
|
|
20
20
|
|
|
21
|
-
setData(userAccount: T): void;
|
|
21
|
+
setData(userAccount: T, slot?: number): void;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export class NotSubscribedError extends Error {
|
|
@@ -73,6 +73,7 @@ export interface UserAccountSubscriber {
|
|
|
73
73
|
|
|
74
74
|
subscribe(userAccount?: UserAccount): Promise<boolean>;
|
|
75
75
|
fetch(): Promise<void>;
|
|
76
|
+
updateData(userAccount: UserAccount, slot: number): void;
|
|
76
77
|
unsubscribe(): Promise<void>;
|
|
77
78
|
|
|
78
79
|
getUserAccountAndSlot(): DataAndSlot<UserAccount>;
|
|
@@ -45,14 +45,15 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
setData(data: T): void {
|
|
49
|
-
|
|
48
|
+
setData(data: T, slot?: number): void {
|
|
49
|
+
const newSlot = slot || 0;
|
|
50
|
+
if (this.dataAndSlot && this.dataAndSlot.slot > newSlot) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
this.dataAndSlot = {
|
|
54
55
|
data,
|
|
55
|
-
slot
|
|
56
|
+
slot,
|
|
56
57
|
};
|
|
57
58
|
}
|
|
58
59
|
|
|
@@ -78,4 +78,14 @@ export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
78
78
|
this.assertIsSubscribed();
|
|
79
79
|
return this.userDataAccountSubscriber.dataAndSlot;
|
|
80
80
|
}
|
|
81
|
+
|
|
82
|
+
public updateData(userAccount: UserAccount, slot: number) {
|
|
83
|
+
const currentDataSlot =
|
|
84
|
+
this.userDataAccountSubscriber.dataAndSlot?.slot || 0;
|
|
85
|
+
if (currentDataSlot < slot) {
|
|
86
|
+
this.userDataAccountSubscriber.setData(userAccount, slot);
|
|
87
|
+
this.eventEmitter.emit('userAccountUpdate', userAccount);
|
|
88
|
+
this.eventEmitter.emit('update');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
81
91
|
}
|
package/src/addresses/pda.ts
CHANGED
|
@@ -189,6 +189,19 @@ export function getSerumFulfillmentConfigPublicKey(
|
|
|
189
189
|
)[0];
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
export function getPhoenixFulfillmentConfigPublicKey(
|
|
193
|
+
programId: PublicKey,
|
|
194
|
+
market: PublicKey
|
|
195
|
+
): PublicKey {
|
|
196
|
+
return PublicKey.findProgramAddressSync(
|
|
197
|
+
[
|
|
198
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('phoenix_fulfillment_config')),
|
|
199
|
+
market.toBuffer(),
|
|
200
|
+
],
|
|
201
|
+
programId
|
|
202
|
+
)[0];
|
|
203
|
+
}
|
|
204
|
+
|
|
192
205
|
export function getReferrerNamePublicKeySync(
|
|
193
206
|
programId: PublicKey,
|
|
194
207
|
nameBuffer: number[]
|
package/src/adminClient.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
getInsuranceFundVaultPublicKey,
|
|
25
25
|
getSerumOpenOrdersPublicKey,
|
|
26
26
|
getSerumFulfillmentConfigPublicKey,
|
|
27
|
+
getPhoenixFulfillmentConfigPublicKey,
|
|
27
28
|
} from './addresses/pda';
|
|
28
29
|
import { squareRootBN } from './math/utils';
|
|
29
30
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
@@ -31,6 +32,7 @@ import { DriftClient } from './driftClient';
|
|
|
31
32
|
import { PEG_PRECISION } from './constants/numericConstants';
|
|
32
33
|
import { calculateTargetPriceTrade } from './math/trade';
|
|
33
34
|
import { calculateAmmReservesAfterSwap, getSwapDirection } from './math/amm';
|
|
35
|
+
import { PROGRAM_ID as PHOENIX_PROGRAM_ID } from '@ellipsis-labs/phoenix-sdk';
|
|
34
36
|
|
|
35
37
|
export class AdminClient extends DriftClient {
|
|
36
38
|
public async initialize(
|
|
@@ -181,6 +183,38 @@ export class AdminClient extends DriftClient {
|
|
|
181
183
|
return txSig;
|
|
182
184
|
}
|
|
183
185
|
|
|
186
|
+
public async initializePhoenixFulfillmentConfig(
|
|
187
|
+
marketIndex: number,
|
|
188
|
+
phoenixMarket: PublicKey
|
|
189
|
+
): Promise<TransactionSignature> {
|
|
190
|
+
const phoenixFulfillmentConfig = getPhoenixFulfillmentConfigPublicKey(
|
|
191
|
+
this.program.programId,
|
|
192
|
+
phoenixMarket
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const tx =
|
|
196
|
+
await this.program.transaction.initializePhoenixFulfillmentConfig(
|
|
197
|
+
marketIndex,
|
|
198
|
+
{
|
|
199
|
+
accounts: {
|
|
200
|
+
admin: this.wallet.publicKey,
|
|
201
|
+
state: await this.getStatePublicKey(),
|
|
202
|
+
baseSpotMarket: this.getSpotMarketAccount(marketIndex).pubkey,
|
|
203
|
+
quoteSpotMarket: this.getQuoteSpotMarketAccount().pubkey,
|
|
204
|
+
driftSigner: this.getSignerPublicKey(),
|
|
205
|
+
phoenixMarket: phoenixMarket,
|
|
206
|
+
phoenixProgram: PHOENIX_PROGRAM_ID,
|
|
207
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
208
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
209
|
+
phoenixFulfillmentConfig,
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
215
|
+
return txSig;
|
|
216
|
+
}
|
|
217
|
+
|
|
184
218
|
public async initializePerpMarket(
|
|
185
219
|
marketIndex: number,
|
|
186
220
|
priceOracle: PublicKey,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fetch from 'node-fetch';
|
|
2
|
+
import { DLOBOrdersCoder } from './DLOBOrders';
|
|
3
|
+
import { DLOB } from './DLOB';
|
|
4
|
+
|
|
5
|
+
type DLOBApiClientConfig = {
|
|
6
|
+
url: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export class DLOBApiClient {
|
|
10
|
+
url: string;
|
|
11
|
+
dlobCoder = DLOBOrdersCoder.create();
|
|
12
|
+
lastSeenDLOB: DLOB;
|
|
13
|
+
lastSeenSlot = 0;
|
|
14
|
+
|
|
15
|
+
constructor(config: DLOBApiClientConfig) {
|
|
16
|
+
this.url = config.url;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public async getDLOB(slot: number): Promise<DLOB> {
|
|
20
|
+
const r = await fetch(this.url);
|
|
21
|
+
if (!r.ok) {
|
|
22
|
+
throw new Error(`Failed to fetch DLOB from ${this.url}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const resp = await r.json();
|
|
26
|
+
const responseSlot = resp['slot'];
|
|
27
|
+
if (responseSlot > this.lastSeenSlot) {
|
|
28
|
+
const dlobOrdersBuffer = Buffer.from(resp['data'], 'base64');
|
|
29
|
+
const dlobOrders = this.dlobCoder.decode(Buffer.from(dlobOrdersBuffer));
|
|
30
|
+
const dlob = new DLOB();
|
|
31
|
+
dlob.initFromOrders(dlobOrders, slot);
|
|
32
|
+
this.lastSeenDLOB = dlob;
|
|
33
|
+
this.lastSeenSlot = responseSlot;
|
|
34
|
+
}
|
|
35
|
+
return this.lastSeenDLOB;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DLOB } from './DLOB';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
4
|
+
import {
|
|
5
|
+
DLOBSource,
|
|
6
|
+
DLOBSubscriberEvents,
|
|
7
|
+
DLOBSubscriptionConfig,
|
|
8
|
+
SlotSource,
|
|
9
|
+
} from './types';
|
|
10
|
+
|
|
11
|
+
export class DLOBSubscriber {
|
|
12
|
+
dlobSource: DLOBSource;
|
|
13
|
+
slotSource: SlotSource;
|
|
14
|
+
updateFrequency: number;
|
|
15
|
+
intervalId?: NodeJS.Timeout;
|
|
16
|
+
dlob = new DLOB();
|
|
17
|
+
public eventEmitter: StrictEventEmitter<EventEmitter, DLOBSubscriberEvents>;
|
|
18
|
+
|
|
19
|
+
constructor(config: DLOBSubscriptionConfig) {
|
|
20
|
+
this.dlobSource = config.dlobSource;
|
|
21
|
+
this.slotSource = config.slotSource;
|
|
22
|
+
this.updateFrequency = config.updateFrequency;
|
|
23
|
+
this.eventEmitter = new EventEmitter();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public async subscribe(): Promise<void> {
|
|
27
|
+
if (this.intervalId) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await this.updateDLOB();
|
|
32
|
+
|
|
33
|
+
this.intervalId = setInterval(async () => {
|
|
34
|
+
try {
|
|
35
|
+
await this.updateDLOB();
|
|
36
|
+
this.eventEmitter.emit('update', this.dlob);
|
|
37
|
+
} catch (e) {
|
|
38
|
+
this.eventEmitter.emit('error', e);
|
|
39
|
+
}
|
|
40
|
+
}, this.updateFrequency);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async updateDLOB(): Promise<void> {
|
|
44
|
+
this.dlob = await this.dlobSource.getDLOB(this.slotSource.getSlot());
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public getDLOB(): DLOB {
|
|
48
|
+
return this.dlob;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public async unsubscribe(): Promise<void> {
|
|
52
|
+
if (this.intervalId) {
|
|
53
|
+
clearInterval(this.intervalId);
|
|
54
|
+
this.intervalId = undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DLOB } from './DLOB';
|
|
2
|
+
|
|
3
|
+
export type DLOBSubscriptionConfig = {
|
|
4
|
+
dlobSource: DLOBSource;
|
|
5
|
+
slotSource: SlotSource;
|
|
6
|
+
updateFrequency: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export interface DLOBSubscriberEvents {
|
|
10
|
+
update: (dlob: DLOB) => void;
|
|
11
|
+
error: (e: Error) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface DLOBSource {
|
|
15
|
+
getDLOB(slot: number): Promise<DLOB>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface SlotSource {
|
|
19
|
+
getSlot(): number;
|
|
20
|
+
}
|