@drift-labs/sdk 0.2.0-master.25 → 0.2.0-master.27
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/pollingClearingHouseAccountSubscriber.d.ts +14 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +30 -27
- package/lib/accounts/types.d.ts +9 -9
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +15 -14
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +38 -34
- package/lib/addresses/pda.d.ts +7 -6
- package/lib/addresses/pda.js +31 -27
- package/lib/admin.d.ts +13 -7
- package/lib/admin.js +111 -44
- package/lib/clearingHouse.d.ts +71 -42
- package/lib/clearingHouse.js +767 -278
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +24 -22
- package/lib/clearingHouseUser.js +273 -177
- package/lib/config.d.ts +7 -7
- package/lib/config.js +21 -21
- package/lib/constants/numericConstants.d.ts +12 -12
- package/lib/constants/numericConstants.js +13 -13
- package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
- package/lib/constants/{markets.js → perpMarkets.js} +4 -4
- package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
- package/lib/constants/{banks.js → spotMarkets.js} +16 -16
- package/lib/dlob/DLOB.d.ts +73 -0
- package/lib/dlob/DLOB.js +557 -0
- package/lib/dlob/DLOBNode.d.ts +52 -0
- package/lib/dlob/DLOBNode.js +82 -0
- package/lib/dlob/NodeList.d.ts +26 -0
- package/lib/dlob/NodeList.js +138 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/examples/makeTradeExample.js +7 -7
- package/lib/idl/clearing_house.json +1152 -503
- package/lib/index.d.ts +10 -3
- package/lib/index.js +10 -3
- package/lib/math/amm.d.ts +2 -2
- package/lib/math/amm.js +1 -1
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +2 -1
- package/lib/math/margin.d.ts +4 -4
- package/lib/math/margin.js +18 -11
- package/lib/math/market.d.ts +11 -10
- package/lib/math/market.js +30 -7
- package/lib/math/oracles.d.ts +2 -1
- package/lib/math/oracles.js +11 -1
- package/lib/math/orders.d.ts +6 -6
- package/lib/math/orders.js +31 -16
- package/lib/math/position.d.ts +13 -13
- package/lib/math/position.js +19 -19
- package/lib/math/spotBalance.d.ts +22 -0
- package/lib/math/spotBalance.js +193 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +6 -0
- package/lib/math/spotPosition.js +23 -0
- package/lib/math/state.js +2 -2
- package/lib/math/trade.d.ts +4 -4
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumSubscriber.d.ts +23 -0
- package/lib/serum/serumSubscriber.js +41 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/serum/types.js +2 -0
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +4 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +148 -57
- package/lib/types.js +39 -11
- package/lib/userMap/userMap.d.ts +25 -0
- package/lib/userMap/userMap.js +73 -0
- package/lib/userMap/userStatsMap.d.ts +19 -0
- package/lib/userMap/userStatsMap.js +68 -0
- package/package.json +6 -3
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +42 -38
- package/src/accounts/types.ts +12 -9
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +65 -52
- package/src/addresses/pda.ts +49 -44
- package/src/admin.ts +190 -55
- package/src/clearingHouse.ts +1092 -365
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.ts +518 -255
- package/src/config.ts +30 -30
- package/src/constants/numericConstants.ts +17 -15
- package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
- package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
- package/src/dlob/DLOB.ts +884 -0
- package/src/dlob/DLOBNode.ts +163 -0
- package/src/dlob/NodeList.ts +185 -0
- package/src/events/types.ts +3 -0
- package/src/examples/makeTradeExample.js +152 -75
- package/src/examples/makeTradeExample.ts +10 -8
- package/src/idl/clearing_house.json +1152 -503
- package/src/index.ts +10 -3
- package/src/math/amm.ts +6 -3
- package/src/math/funding.ts +7 -7
- package/src/math/margin.ts +34 -23
- package/src/math/market.ts +72 -20
- package/src/math/oracles.ts +18 -1
- package/src/math/orders.ts +33 -25
- package/src/math/position.ts +31 -31
- package/src/math/spotBalance.ts +316 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.ts +47 -0
- package/src/math/state.ts +2 -2
- package/src/math/trade.ts +4 -4
- package/src/orderParams.ts +16 -8
- package/src/serum/serumSubscriber.ts +80 -0
- package/src/serum/types.ts +13 -0
- package/src/tx/retryTxSender.ts +5 -2
- package/src/tx/types.ts +2 -1
- package/src/types.ts +135 -56
- package/src/userMap/userMap.ts +100 -0
- package/src/userMap/userStatsMap.ts +110 -0
- package/tests/bn/test.ts +2 -3
- package/tests/dlob/helpers.ts +322 -0
- package/tests/dlob/test.ts +2865 -0
- package/lib/math/bankBalance.d.ts +0 -15
- package/lib/math/bankBalance.js +0 -150
- package/src/constants/numericConstants.js +0 -41
- package/src/math/bankBalance.ts +0 -258
- package/src/math/oracles.js +0 -26
- package/src/math/state.js +0 -15
- package/src/orderParams.js +0 -20
- package/src/slot/SlotSubscriber.js +0 -39
- package/src/tokenFaucet.js +0 -189
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserStatsMap = void 0;
|
|
4
|
+
const __1 = require("..");
|
|
5
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
6
|
+
class UserStatsMap {
|
|
7
|
+
constructor(clearingHouse, accountSubscription) {
|
|
8
|
+
/**
|
|
9
|
+
* map from authority pubkey to ClearingHouseUserStats
|
|
10
|
+
*/
|
|
11
|
+
this.userStatsMap = new Map();
|
|
12
|
+
this.clearingHouse = clearingHouse;
|
|
13
|
+
this.accountSubscription = accountSubscription;
|
|
14
|
+
}
|
|
15
|
+
async fetchAllUserStats() {
|
|
16
|
+
const userStatArray = [];
|
|
17
|
+
const programUserAccounts = (await this.clearingHouse.program.account.userStats.all());
|
|
18
|
+
for (const programUserAccount of programUserAccounts) {
|
|
19
|
+
const userStat = programUserAccount.account;
|
|
20
|
+
if (this.userStatsMap.has(userStat.authority.toString())) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const chUserStat = new __1.ClearingHouseUserStats({
|
|
24
|
+
clearingHouse: this.clearingHouse,
|
|
25
|
+
userStatsAccountPublicKey: (0, __1.getUserStatsAccountPublicKey)(this.clearingHouse.program.programId, userStat.authority),
|
|
26
|
+
accountSubscription: this.accountSubscription,
|
|
27
|
+
});
|
|
28
|
+
userStatArray.push(chUserStat);
|
|
29
|
+
}
|
|
30
|
+
if (this.accountSubscription.type === 'polling') {
|
|
31
|
+
await (0, __1.bulkPollingUserStatsSubscribe)(userStatArray, this.accountSubscription.accountLoader);
|
|
32
|
+
}
|
|
33
|
+
for (const userStat of userStatArray) {
|
|
34
|
+
this.userStatsMap.set(userStat.getAccount().authority.toString(), userStat);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async addUserStat(authority) {
|
|
38
|
+
const userStat = new __1.ClearingHouseUserStats({
|
|
39
|
+
clearingHouse: this.clearingHouse,
|
|
40
|
+
userStatsAccountPublicKey: (0, __1.getUserStatsAccountPublicKey)(this.clearingHouse.program.programId, authority),
|
|
41
|
+
accountSubscription: this.accountSubscription,
|
|
42
|
+
});
|
|
43
|
+
await userStat.subscribe();
|
|
44
|
+
this.userStatsMap.set(authority.toString(), userStat);
|
|
45
|
+
}
|
|
46
|
+
async updateWithOrderRecord(record, userMap) {
|
|
47
|
+
if (!this.has(record.user.toString())) {
|
|
48
|
+
const takerUserAccount = await userMap.mustGet(record.user.toString());
|
|
49
|
+
this.addUserStat(takerUserAccount.getUserAccount().authority);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
has(authorityPublicKey) {
|
|
53
|
+
return this.userStatsMap.has(authorityPublicKey);
|
|
54
|
+
}
|
|
55
|
+
get(authorityPublicKey) {
|
|
56
|
+
return this.userStatsMap.get(authorityPublicKey);
|
|
57
|
+
}
|
|
58
|
+
async mustGet(authorityPublicKey) {
|
|
59
|
+
if (!this.has(authorityPublicKey)) {
|
|
60
|
+
await this.addUserStat(new web3_js_1.PublicKey(authorityPublicKey));
|
|
61
|
+
}
|
|
62
|
+
return this.get(authorityPublicKey);
|
|
63
|
+
}
|
|
64
|
+
values() {
|
|
65
|
+
return this.userStatsMap.values();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.UserStatsMap = UserStatsMap;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "0.2.0-master.
|
|
3
|
+
"version": "0.2.0-master.27",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
"build": "yarn clean && tsc",
|
|
15
15
|
"clean": "rm -rf lib",
|
|
16
16
|
"test": "mocha -r ts-node/register tests/**/*.ts",
|
|
17
|
-
"patch-and-pub": "npm version patch --force && npm publish"
|
|
17
|
+
"patch-and-pub": "npm version patch --force && npm publish",
|
|
18
|
+
"prettify": "prettier --check './src/***/*.ts'",
|
|
19
|
+
"prettify:fix": "prettier --write './{src,tests}/***/*.ts'"
|
|
18
20
|
},
|
|
19
21
|
"keywords": [
|
|
20
22
|
"drift-labs",
|
|
@@ -48,7 +50,8 @@
|
|
|
48
50
|
"eslint-config-prettier": "^8.3.0",
|
|
49
51
|
"eslint-plugin-prettier": "^3.4.0",
|
|
50
52
|
"mocha": "^10.0.0",
|
|
51
|
-
"ts-node": "^10.8.0"
|
|
53
|
+
"ts-node": "^10.8.0",
|
|
54
|
+
"prettier": "^2.4.1"
|
|
52
55
|
},
|
|
53
56
|
"description": "SDK for Drift Protocol v1",
|
|
54
57
|
"engines": {
|
|
@@ -10,14 +10,14 @@ import { BN, Program } from '@project-serum/anchor';
|
|
|
10
10
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
11
11
|
import { EventEmitter } from 'events';
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
SpotMarketAccount,
|
|
14
|
+
PerpMarketAccount,
|
|
15
15
|
StateAccount,
|
|
16
16
|
UserAccount,
|
|
17
17
|
} from '../types';
|
|
18
18
|
import {
|
|
19
19
|
getClearingHouseStateAccountPublicKey,
|
|
20
|
-
|
|
20
|
+
getSpotMarketPublicKey,
|
|
21
21
|
getMarketPublicKey,
|
|
22
22
|
} from '../addresses/pda';
|
|
23
23
|
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
@@ -32,8 +32,8 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
32
32
|
{
|
|
33
33
|
isSubscribed: boolean;
|
|
34
34
|
program: Program;
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
perpMarketIndexes: BN[];
|
|
36
|
+
spotMarketIndexes: BN[];
|
|
37
37
|
oracleInfos: OracleInfo[];
|
|
38
38
|
oracleClientCache = new OracleClientCache();
|
|
39
39
|
|
|
@@ -45,8 +45,8 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
45
45
|
errorCallbackId?: string;
|
|
46
46
|
|
|
47
47
|
state?: DataAndSlot<StateAccount>;
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
perpMarket = new Map<number, DataAndSlot<PerpMarketAccount>>();
|
|
49
|
+
spotMarket = new Map<number, DataAndSlot<SpotMarketAccount>>();
|
|
50
50
|
oracles = new Map<string, DataAndSlot<OraclePriceData>>();
|
|
51
51
|
user?: DataAndSlot<UserAccount>;
|
|
52
52
|
|
|
@@ -57,16 +57,16 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
57
57
|
public constructor(
|
|
58
58
|
program: Program,
|
|
59
59
|
accountLoader: BulkAccountLoader,
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
perpMarketIndexes: BN[],
|
|
61
|
+
spotMarketIndexes: BN[],
|
|
62
62
|
oracleInfos: OracleInfo[]
|
|
63
63
|
) {
|
|
64
64
|
this.isSubscribed = false;
|
|
65
65
|
this.program = program;
|
|
66
66
|
this.eventEmitter = new EventEmitter();
|
|
67
67
|
this.accountLoader = accountLoader;
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
68
|
+
this.perpMarketIndexes = perpMarketIndexes;
|
|
69
|
+
this.spotMarketIndexes = spotMarketIndexes;
|
|
70
70
|
this.oracleInfos = oracleInfos;
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -122,11 +122,11 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
122
122
|
});
|
|
123
123
|
|
|
124
124
|
await this.updateMarketAccountsToPoll();
|
|
125
|
-
await this.
|
|
125
|
+
await this.updateSpotMarketAccountsToPoll();
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
async updateMarketAccountsToPoll(): Promise<boolean> {
|
|
129
|
-
for (const marketIndex of this.
|
|
129
|
+
for (const marketIndex of this.perpMarketIndexes) {
|
|
130
130
|
await this.addMarketAccountToPoll(marketIndex);
|
|
131
131
|
}
|
|
132
132
|
return true;
|
|
@@ -139,34 +139,34 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
139
139
|
);
|
|
140
140
|
|
|
141
141
|
this.accountsToPoll.set(marketPublicKey.toString(), {
|
|
142
|
-
key: '
|
|
142
|
+
key: 'perpMarket',
|
|
143
143
|
publicKey: marketPublicKey,
|
|
144
|
-
eventType: '
|
|
144
|
+
eventType: 'perpMarketAccountUpdate',
|
|
145
145
|
mapKey: marketIndex.toNumber(),
|
|
146
146
|
});
|
|
147
147
|
|
|
148
148
|
return true;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
async
|
|
152
|
-
for (const
|
|
153
|
-
await this.
|
|
151
|
+
async updateSpotMarketAccountsToPoll(): Promise<boolean> {
|
|
152
|
+
for (const marketIndex of this.spotMarketIndexes) {
|
|
153
|
+
await this.addSpotMarketAccountToPoll(marketIndex);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
return true;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
async
|
|
160
|
-
const
|
|
159
|
+
async addSpotMarketAccountToPoll(marketIndex: BN): Promise<boolean> {
|
|
160
|
+
const marketPublicKey = await getSpotMarketPublicKey(
|
|
161
161
|
this.program.programId,
|
|
162
|
-
|
|
162
|
+
marketIndex
|
|
163
163
|
);
|
|
164
164
|
|
|
165
|
-
this.accountsToPoll.set(
|
|
166
|
-
key: '
|
|
167
|
-
publicKey:
|
|
168
|
-
eventType: '
|
|
169
|
-
mapKey:
|
|
165
|
+
this.accountsToPoll.set(marketPublicKey.toString(), {
|
|
166
|
+
key: 'spotMarket',
|
|
167
|
+
publicKey: marketPublicKey,
|
|
168
|
+
eventType: 'spotMarketAccountUpdate',
|
|
169
|
+
mapKey: marketIndex.toNumber(),
|
|
170
170
|
});
|
|
171
171
|
return true;
|
|
172
172
|
}
|
|
@@ -353,14 +353,14 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
353
353
|
this.isSubscribed = false;
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
async
|
|
357
|
-
await this.
|
|
358
|
-
const accountToPoll = this.accountsToPoll.get(
|
|
356
|
+
async addSpotMarket(marketIndex: BN): Promise<boolean> {
|
|
357
|
+
await this.addSpotMarketAccountToPoll(marketIndex);
|
|
358
|
+
const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
|
|
359
359
|
this.addAccountToAccountLoader(accountToPoll);
|
|
360
360
|
return true;
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
-
async
|
|
363
|
+
async addPerpMarket(marketIndex: BN): Promise<boolean> {
|
|
364
364
|
await this.addMarketAccountToPoll(marketIndex);
|
|
365
365
|
const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
|
|
366
366
|
this.addAccountToAccountLoader(accountToPoll);
|
|
@@ -395,18 +395,22 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
395
395
|
|
|
396
396
|
public getMarketAccountAndSlot(
|
|
397
397
|
marketIndex: BN
|
|
398
|
-
): DataAndSlot<
|
|
399
|
-
return this.
|
|
398
|
+
): DataAndSlot<PerpMarketAccount> | undefined {
|
|
399
|
+
return this.perpMarket.get(marketIndex.toNumber());
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
public getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[] {
|
|
403
|
+
return Array.from(this.perpMarket.values());
|
|
400
404
|
}
|
|
401
405
|
|
|
402
|
-
public
|
|
403
|
-
|
|
406
|
+
public getSpotMarketAccountAndSlot(
|
|
407
|
+
marketIndex: BN
|
|
408
|
+
): DataAndSlot<SpotMarketAccount> | undefined {
|
|
409
|
+
return this.spotMarket.get(marketIndex.toNumber());
|
|
404
410
|
}
|
|
405
411
|
|
|
406
|
-
public
|
|
407
|
-
|
|
408
|
-
): DataAndSlot<BankAccount> | undefined {
|
|
409
|
-
return this.bank.get(bankIndex.toNumber());
|
|
412
|
+
public getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[] {
|
|
413
|
+
return Array.from(this.spotMarket.values());
|
|
410
414
|
}
|
|
411
415
|
|
|
412
416
|
public getOraclePriceDataAndSlot(
|
package/src/accounts/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
SpotMarketAccount,
|
|
3
|
+
PerpMarketAccount,
|
|
4
4
|
OracleSource,
|
|
5
5
|
StateAccount,
|
|
6
6
|
UserAccount,
|
|
@@ -26,8 +26,8 @@ export class NotSubscribedError extends Error {
|
|
|
26
26
|
|
|
27
27
|
export interface ClearingHouseAccountEvents {
|
|
28
28
|
stateAccountUpdate: (payload: StateAccount) => void;
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
perpMarketAccountUpdate: (payload: PerpMarketAccount) => void;
|
|
30
|
+
spotMarketAccountUpdate: (payload: SpotMarketAccount) => void;
|
|
31
31
|
oraclePriceUpdate: (publicKey: PublicKey, data: OraclePriceData) => void;
|
|
32
32
|
userAccountUpdate: (payload: UserAccount) => void;
|
|
33
33
|
update: void;
|
|
@@ -42,16 +42,19 @@ export interface ClearingHouseAccountSubscriber {
|
|
|
42
42
|
fetch(): Promise<void>;
|
|
43
43
|
unsubscribe(): Promise<void>;
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
addPerpMarket(marketIndex: BN): Promise<boolean>;
|
|
46
|
+
addSpotMarket(marketIndex: BN): Promise<boolean>;
|
|
47
47
|
addOracle(oracleInfo: OracleInfo): Promise<boolean>;
|
|
48
48
|
|
|
49
49
|
getStateAccountAndSlot(): DataAndSlot<StateAccount>;
|
|
50
50
|
getMarketAccountAndSlot(
|
|
51
51
|
marketIndex: BN
|
|
52
|
-
): DataAndSlot<
|
|
53
|
-
getMarketAccountsAndSlots(): DataAndSlot<
|
|
54
|
-
|
|
52
|
+
): DataAndSlot<PerpMarketAccount> | undefined;
|
|
53
|
+
getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
|
|
54
|
+
getSpotMarketAccountAndSlot(
|
|
55
|
+
marketIndex: BN
|
|
56
|
+
): DataAndSlot<SpotMarketAccount> | undefined;
|
|
57
|
+
getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
|
|
55
58
|
getOraclePriceDataAndSlot(
|
|
56
59
|
oraclePublicKey: PublicKey
|
|
57
60
|
): DataAndSlot<OraclePriceData> | undefined;
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
DataAndSlot,
|
|
5
5
|
} from './types';
|
|
6
6
|
import { AccountSubscriber, NotSubscribedError } from './types';
|
|
7
|
-
import {
|
|
7
|
+
import { SpotMarketAccount, PerpMarketAccount, StateAccount } from '../types';
|
|
8
8
|
import { BN, Program } from '@project-serum/anchor';
|
|
9
9
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
10
10
|
import { EventEmitter } from 'events';
|
|
11
11
|
import {
|
|
12
12
|
getClearingHouseStateAccountPublicKey,
|
|
13
|
-
|
|
13
|
+
getSpotMarketPublicKey,
|
|
14
14
|
getMarketPublicKey,
|
|
15
15
|
} from '../addresses/pda';
|
|
16
16
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
@@ -25,18 +25,21 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
25
25
|
{
|
|
26
26
|
isSubscribed: boolean;
|
|
27
27
|
program: Program;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
perpMarketIndexes: BN[];
|
|
29
|
+
spotMarketIndexes: BN[];
|
|
30
30
|
oracleInfos: OracleInfo[];
|
|
31
31
|
oracleClientCache = new OracleClientCache();
|
|
32
32
|
|
|
33
33
|
eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
|
|
34
34
|
stateAccountSubscriber?: AccountSubscriber<StateAccount>;
|
|
35
|
-
|
|
35
|
+
perpMarketAccountSubscribers = new Map<
|
|
36
36
|
number,
|
|
37
|
-
AccountSubscriber<
|
|
37
|
+
AccountSubscriber<PerpMarketAccount>
|
|
38
|
+
>();
|
|
39
|
+
spotMarketAccountSubscribers = new Map<
|
|
40
|
+
number,
|
|
41
|
+
AccountSubscriber<SpotMarketAccount>
|
|
38
42
|
>();
|
|
39
|
-
bankAccountSubscribers = new Map<number, AccountSubscriber<BankAccount>>();
|
|
40
43
|
oracleSubscribers = new Map<string, AccountSubscriber<OraclePriceData>>();
|
|
41
44
|
|
|
42
45
|
private isSubscribing = false;
|
|
@@ -45,15 +48,15 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
45
48
|
|
|
46
49
|
public constructor(
|
|
47
50
|
program: Program,
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
perpMarketIndexes: BN[],
|
|
52
|
+
spotMarketIndexes: BN[],
|
|
50
53
|
oracleInfos: OracleInfo[]
|
|
51
54
|
) {
|
|
52
55
|
this.isSubscribed = false;
|
|
53
56
|
this.program = program;
|
|
54
57
|
this.eventEmitter = new EventEmitter();
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
58
|
+
this.perpMarketIndexes = perpMarketIndexes;
|
|
59
|
+
this.spotMarketIndexes = spotMarketIndexes;
|
|
57
60
|
this.oracleInfos = oracleInfos;
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -90,8 +93,8 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
90
93
|
// subscribe to market accounts
|
|
91
94
|
await this.subscribeToMarketAccounts();
|
|
92
95
|
|
|
93
|
-
// subscribe to
|
|
94
|
-
await this.
|
|
96
|
+
// subscribe to spot market accounts
|
|
97
|
+
await this.subscribeToSpotMarketAccounts();
|
|
95
98
|
|
|
96
99
|
// subscribe to oracles
|
|
97
100
|
await this.subscribeToOracles();
|
|
@@ -106,7 +109,7 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
async subscribeToMarketAccounts(): Promise<boolean> {
|
|
109
|
-
for (const marketIndex of this.
|
|
112
|
+
for (const marketIndex of this.perpMarketIndexes) {
|
|
110
113
|
await this.subscribeToMarketAccount(marketIndex);
|
|
111
114
|
}
|
|
112
115
|
return true;
|
|
@@ -117,44 +120,47 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
117
120
|
this.program.programId,
|
|
118
121
|
marketIndex
|
|
119
122
|
);
|
|
120
|
-
const accountSubscriber = new WebSocketAccountSubscriber<
|
|
121
|
-
'
|
|
123
|
+
const accountSubscriber = new WebSocketAccountSubscriber<PerpMarketAccount>(
|
|
124
|
+
'perpMarket',
|
|
122
125
|
this.program,
|
|
123
126
|
marketPublicKey
|
|
124
127
|
);
|
|
125
|
-
await accountSubscriber.subscribe((data:
|
|
126
|
-
this.eventEmitter.emit('
|
|
128
|
+
await accountSubscriber.subscribe((data: PerpMarketAccount) => {
|
|
129
|
+
this.eventEmitter.emit('perpMarketAccountUpdate', data);
|
|
127
130
|
this.eventEmitter.emit('update');
|
|
128
131
|
});
|
|
129
|
-
this.
|
|
132
|
+
this.perpMarketAccountSubscribers.set(
|
|
130
133
|
marketIndex.toNumber(),
|
|
131
134
|
accountSubscriber
|
|
132
135
|
);
|
|
133
136
|
return true;
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
async
|
|
137
|
-
for (const
|
|
138
|
-
await this.
|
|
139
|
+
async subscribeToSpotMarketAccounts(): Promise<boolean> {
|
|
140
|
+
for (const marketIndex of this.spotMarketIndexes) {
|
|
141
|
+
await this.subscribeToSpotMarketAccount(marketIndex);
|
|
139
142
|
}
|
|
140
143
|
return true;
|
|
141
144
|
}
|
|
142
145
|
|
|
143
|
-
async
|
|
144
|
-
const
|
|
146
|
+
async subscribeToSpotMarketAccount(marketIndex: BN): Promise<boolean> {
|
|
147
|
+
const marketPublicKey = await getSpotMarketPublicKey(
|
|
145
148
|
this.program.programId,
|
|
146
|
-
|
|
149
|
+
marketIndex
|
|
147
150
|
);
|
|
148
|
-
const accountSubscriber = new WebSocketAccountSubscriber<
|
|
149
|
-
'
|
|
151
|
+
const accountSubscriber = new WebSocketAccountSubscriber<SpotMarketAccount>(
|
|
152
|
+
'spotMarket',
|
|
150
153
|
this.program,
|
|
151
|
-
|
|
154
|
+
marketPublicKey
|
|
152
155
|
);
|
|
153
|
-
await accountSubscriber.subscribe((data:
|
|
154
|
-
this.eventEmitter.emit('
|
|
156
|
+
await accountSubscriber.subscribe((data: SpotMarketAccount) => {
|
|
157
|
+
this.eventEmitter.emit('spotMarketAccountUpdate', data);
|
|
155
158
|
this.eventEmitter.emit('update');
|
|
156
159
|
});
|
|
157
|
-
this.
|
|
160
|
+
this.spotMarketAccountSubscribers.set(
|
|
161
|
+
marketIndex.toNumber(),
|
|
162
|
+
accountSubscriber
|
|
163
|
+
);
|
|
158
164
|
return true;
|
|
159
165
|
}
|
|
160
166
|
|
|
@@ -195,13 +201,13 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
195
201
|
}
|
|
196
202
|
|
|
197
203
|
async unsubscribeFromMarketAccounts(): Promise<void> {
|
|
198
|
-
for (const accountSubscriber of this.
|
|
204
|
+
for (const accountSubscriber of this.perpMarketAccountSubscribers.values()) {
|
|
199
205
|
await accountSubscriber.unsubscribe();
|
|
200
206
|
}
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
async
|
|
204
|
-
for (const accountSubscriber of this.
|
|
209
|
+
async unsubscribeFromSpotMarketAccounts(): Promise<void> {
|
|
210
|
+
for (const accountSubscriber of this.spotMarketAccountSubscribers.values()) {
|
|
205
211
|
await accountSubscriber.unsubscribe();
|
|
206
212
|
}
|
|
207
213
|
}
|
|
@@ -219,13 +225,13 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
219
225
|
|
|
220
226
|
const promises = [this.stateAccountSubscriber.fetch()]
|
|
221
227
|
.concat(
|
|
222
|
-
Array.from(this.
|
|
223
|
-
subscriber.fetch()
|
|
228
|
+
Array.from(this.perpMarketAccountSubscribers.values()).map(
|
|
229
|
+
(subscriber) => subscriber.fetch()
|
|
224
230
|
)
|
|
225
231
|
)
|
|
226
232
|
.concat(
|
|
227
|
-
Array.from(this.
|
|
228
|
-
subscriber.fetch()
|
|
233
|
+
Array.from(this.spotMarketAccountSubscribers.values()).map(
|
|
234
|
+
(subscriber) => subscriber.fetch()
|
|
229
235
|
)
|
|
230
236
|
);
|
|
231
237
|
|
|
@@ -240,21 +246,21 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
240
246
|
await this.stateAccountSubscriber.unsubscribe();
|
|
241
247
|
|
|
242
248
|
await this.unsubscribeFromMarketAccounts();
|
|
243
|
-
await this.
|
|
249
|
+
await this.unsubscribeFromSpotMarketAccounts();
|
|
244
250
|
await this.unsubscribeFromOracles();
|
|
245
251
|
|
|
246
252
|
this.isSubscribed = false;
|
|
247
253
|
}
|
|
248
254
|
|
|
249
|
-
async
|
|
250
|
-
if (this.
|
|
255
|
+
async addSpotMarket(marketIndex: BN): Promise<boolean> {
|
|
256
|
+
if (this.spotMarketAccountSubscribers.has(marketIndex.toNumber())) {
|
|
251
257
|
return true;
|
|
252
258
|
}
|
|
253
|
-
return this.
|
|
259
|
+
return this.subscribeToSpotMarketAccount(marketIndex);
|
|
254
260
|
}
|
|
255
261
|
|
|
256
|
-
async
|
|
257
|
-
if (this.
|
|
262
|
+
async addPerpMarket(marketIndex: BN): Promise<boolean> {
|
|
263
|
+
if (this.perpMarketAccountSubscribers.has(marketIndex.toNumber())) {
|
|
258
264
|
return true;
|
|
259
265
|
}
|
|
260
266
|
return this.subscribeToMarketAccount(marketIndex);
|
|
@@ -287,23 +293,30 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
287
293
|
|
|
288
294
|
public getMarketAccountAndSlot(
|
|
289
295
|
marketIndex: BN
|
|
290
|
-
): DataAndSlot<
|
|
296
|
+
): DataAndSlot<PerpMarketAccount> | undefined {
|
|
291
297
|
this.assertIsSubscribed();
|
|
292
|
-
return this.
|
|
298
|
+
return this.perpMarketAccountSubscribers.get(marketIndex.toNumber())
|
|
293
299
|
.dataAndSlot;
|
|
294
300
|
}
|
|
295
301
|
|
|
296
|
-
public getMarketAccountsAndSlots(): DataAndSlot<
|
|
297
|
-
return Array.from(this.
|
|
302
|
+
public getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[] {
|
|
303
|
+
return Array.from(this.perpMarketAccountSubscribers.values()).map(
|
|
298
304
|
(subscriber) => subscriber.dataAndSlot
|
|
299
305
|
);
|
|
300
306
|
}
|
|
301
307
|
|
|
302
|
-
public
|
|
303
|
-
|
|
304
|
-
): DataAndSlot<
|
|
308
|
+
public getSpotMarketAccountAndSlot(
|
|
309
|
+
marketIndex: BN
|
|
310
|
+
): DataAndSlot<SpotMarketAccount> | undefined {
|
|
305
311
|
this.assertIsSubscribed();
|
|
306
|
-
return this.
|
|
312
|
+
return this.spotMarketAccountSubscribers.get(marketIndex.toNumber())
|
|
313
|
+
.dataAndSlot;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
public getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[] {
|
|
317
|
+
return Array.from(this.spotMarketAccountSubscribers.values()).map(
|
|
318
|
+
(subscriber) => subscriber.dataAndSlot
|
|
319
|
+
);
|
|
307
320
|
}
|
|
308
321
|
|
|
309
322
|
public getOraclePriceDataAndSlot(
|