@drift-labs/sdk 0.2.0-master.4 → 0.2.0-master.41
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/README.md +27 -27
- package/lib/accounts/bulkAccountLoader.d.ts +2 -0
- package/lib/accounts/bulkAccountLoader.js +36 -29
- package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
- package/lib/accounts/bulkUserStatsSubscription.js +21 -0
- package/lib/accounts/bulkUserSubscription.d.ts +2 -2
- package/lib/accounts/bulkUserSubscription.js +0 -1
- package/lib/accounts/fetch.d.ts +2 -1
- package/lib/accounts/fetch.js +9 -1
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.d.ts → pollingDriftClientAccountSubscriber.d.ts} +20 -25
- package/lib/accounts/{pollingClearingHouseAccountSubscriber.js → pollingDriftClientAccountSubscriber.js} +45 -49
- package/lib/accounts/{pollingOracleSubscriber.d.ts → pollingOracleAccountSubscriber.d.ts} +2 -2
- package/lib/accounts/{pollingOracleSubscriber.js → pollingOracleAccountSubscriber.js} +3 -3
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +1 -1
- package/lib/accounts/pollingUserAccountSubscriber.js +5 -11
- package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +107 -0
- package/lib/accounts/types.d.ts +26 -15
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +49 -0
- package/lib/accounts/{webSocketClearingHouseAccountSubscriber.js → webSocketDriftClientAccountSubscriber.js} +47 -45
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
- package/lib/addresses/marketAddresses.d.ts +1 -3
- package/lib/addresses/marketAddresses.js +1 -1
- package/lib/addresses/pda.d.ts +15 -9
- package/lib/addresses/pda.js +73 -35
- package/lib/adminClient.d.ts +65 -0
- package/lib/adminClient.js +637 -0
- package/lib/config.d.ts +9 -9
- package/lib/config.js +25 -21
- package/lib/constants/numericConstants.d.ts +30 -12
- package/lib/constants/numericConstants.js +41 -21
- package/lib/constants/perpMarkets.d.ts +18 -0
- package/lib/constants/{markets.js → perpMarkets.js} +7 -7
- package/lib/constants/spotMarkets.d.ts +19 -0
- package/lib/constants/spotMarkets.js +53 -0
- package/lib/dlob/DLOB.d.ts +82 -0
- package/lib/dlob/DLOB.js +694 -0
- package/lib/dlob/DLOBNode.d.ts +54 -0
- package/lib/dlob/DLOBNode.js +77 -0
- package/lib/dlob/NodeList.d.ts +27 -0
- package/lib/dlob/NodeList.js +144 -0
- package/lib/driftClient.d.ts +234 -0
- package/lib/driftClient.js +2108 -0
- package/lib/{clearingHouseConfig.d.ts → driftClientConfig.d.ts} +9 -9
- package/lib/{clearingHouseConfig.js → driftClientConfig.js} +0 -0
- package/lib/events/eventList.js +3 -0
- package/lib/events/eventSubscriber.d.ts +5 -2
- package/lib/events/eventSubscriber.js +25 -11
- package/lib/events/fetchLogs.d.ts +13 -2
- package/lib/events/fetchLogs.js +40 -12
- package/lib/events/pollingLogProvider.d.ts +2 -1
- package/lib/events/pollingLogProvider.js +7 -3
- package/lib/events/sort.js +8 -11
- package/lib/events/types.d.ts +11 -3
- package/lib/events/types.js +8 -0
- package/lib/events/webSocketLogProvider.js +1 -1
- package/lib/examples/makeTradeExample.js +30 -18
- package/lib/factory/bigNum.d.ts +8 -4
- package/lib/factory/bigNum.js +109 -19
- package/lib/idl/drift.json +8386 -0
- package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/lib/index.d.ts +30 -13
- package/lib/index.js +30 -13
- package/lib/math/amm.d.ts +9 -6
- package/lib/math/amm.js +91 -38
- package/lib/math/conversion.js +1 -1
- package/lib/math/exchangeStatus.d.ts +4 -0
- package/lib/math/exchangeStatus.js +18 -0
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +23 -21
- package/lib/math/insurance.d.ts +4 -0
- package/lib/math/insurance.js +27 -0
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +82 -0
- package/lib/math/market.d.ts +14 -9
- package/lib/math/market.js +70 -10
- package/lib/math/oracles.d.ts +4 -0
- package/lib/math/oracles.js +36 -8
- package/lib/math/orders.d.ts +16 -6
- package/lib/math/orders.js +97 -17
- package/lib/math/position.d.ts +27 -13
- package/lib/math/position.js +92 -36
- package/lib/math/repeg.js +17 -8
- package/lib/math/spotBalance.d.ts +22 -0
- package/lib/math/spotBalance.js +192 -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/trade.d.ts +10 -10
- package/lib/math/trade.js +27 -31
- package/lib/oracles/pythClient.js +1 -1
- package/lib/oracles/quoteAssetOracleClient.js +1 -1
- package/lib/oracles/switchboardClient.js +1 -1
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
- package/lib/serum/serumFulfillmentConfigMap.js +17 -0
- package/lib/serum/serumSubscriber.d.ts +27 -0
- package/lib/serum/serumSubscriber.js +56 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/{clearingHouseUserConfig.js → serum/types.js} +0 -0
- package/lib/slot/SlotSubscriber.d.ts +7 -0
- package/lib/slot/SlotSubscriber.js +3 -0
- package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
- package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +13 -4
- package/lib/tx/types.d.ts +1 -1
- package/lib/tx/utils.js +1 -1
- package/lib/types.d.ts +688 -216
- package/lib/types.js +153 -24
- package/lib/user.d.ts +228 -0
- package/lib/user.js +959 -0
- package/lib/userConfig.d.ts +14 -0
- package/lib/userConfig.js +2 -0
- package/lib/userMap/userMap.d.ts +41 -0
- package/lib/userMap/userMap.js +85 -0
- package/lib/userMap/userStatsMap.d.ts +19 -0
- package/lib/userMap/userStatsMap.js +68 -0
- package/lib/userName.d.ts +1 -0
- package/lib/userName.js +3 -2
- package/lib/userStats.d.ts +18 -0
- package/lib/userStats.js +49 -0
- package/lib/userStatsConfig.d.ts +14 -0
- package/lib/userStatsConfig.js +2 -0
- package/lib/util/computeUnits.js +1 -1
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +11 -4
- package/src/accounts/bulkAccountLoader.ts +44 -34
- package/src/accounts/bulkUserStatsSubscription.ts +33 -0
- package/src/accounts/bulkUserSubscription.ts +2 -3
- package/src/accounts/fetch.ts +27 -2
- package/src/accounts/{pollingClearingHouseAccountSubscriber.ts → pollingDriftClientAccountSubscriber.ts} +65 -75
- package/src/accounts/{pollingOracleSubscriber.ts → pollingOracleAccountSubscriber.ts} +2 -2
- package/src/accounts/pollingUserAccountSubscriber.ts +5 -12
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +166 -0
- package/src/accounts/types.ts +35 -15
- package/src/accounts/{webSocketClearingHouseAccountSubscriber.ts → webSocketDriftClientAccountSubscriber.ts} +78 -73
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
- package/src/addresses/marketAddresses.ts +3 -4
- package/src/addresses/pda.ts +105 -33
- package/src/adminClient.ts +1207 -0
- package/src/assert/assert.js +9 -0
- package/src/config.ts +37 -31
- package/src/constants/numericConstants.ts +58 -24
- package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
- package/src/constants/spotMarkets.ts +73 -0
- package/src/dlob/DLOB.ts +1120 -0
- package/src/dlob/DLOBNode.ts +155 -0
- package/src/dlob/NodeList.ts +195 -0
- package/src/driftClient.ts +3594 -0
- package/src/{clearingHouseConfig.ts → driftClientConfig.ts} +9 -8
- package/src/events/eventList.js +77 -0
- package/src/events/eventList.ts +3 -0
- package/src/events/eventSubscriber.ts +36 -14
- package/src/events/fetchLogs.ts +55 -13
- package/src/events/pollingLogProvider.ts +11 -3
- package/src/events/sort.ts +11 -15
- package/src/events/types.ts +27 -2
- package/src/events/webSocketLogProvider.ts +1 -1
- package/src/examples/makeTradeExample.js +157 -0
- package/src/examples/makeTradeExample.ts +44 -28
- package/src/factory/bigNum.ts +150 -22
- package/src/idl/drift.json +8386 -0
- package/src/idl/pyth.json +98 -2
- package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/src/index.ts +30 -13
- package/src/math/amm.ts +161 -48
- package/src/math/conversion.ts +2 -2
- package/src/math/exchangeStatus.ts +31 -0
- package/src/math/funding.ts +41 -31
- package/src/math/insurance.ts +35 -0
- package/src/math/margin.ts +133 -0
- package/src/math/market.ts +143 -14
- package/src/math/oracles.ts +63 -9
- package/src/math/orders.ts +168 -26
- package/src/math/position.ts +136 -58
- package/src/math/repeg.ts +19 -9
- package/src/math/spotBalance.ts +319 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.ts +47 -0
- package/src/math/trade.ts +33 -37
- package/src/oracles/pythClient.ts +2 -2
- package/src/oracles/quoteAssetOracleClient.ts +2 -2
- package/src/oracles/switchboardClient.ts +2 -2
- package/src/orderParams.ts +16 -8
- package/src/serum/serumFulfillmentConfigMap.ts +26 -0
- package/src/serum/serumSubscriber.ts +99 -0
- package/src/serum/types.ts +13 -0
- package/src/slot/SlotSubscriber.ts +11 -1
- package/src/token/index.js +38 -0
- package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
- package/src/tx/retryTxSender.ts +16 -5
- package/src/tx/types.js +2 -0
- package/src/tx/types.ts +2 -1
- package/src/tx/utils.js +17 -0
- package/src/tx/utils.ts +1 -1
- package/src/types.ts +650 -189
- package/src/user.ts +1599 -0
- package/src/{clearingHouseUserConfig.ts → userConfig.ts} +5 -5
- package/src/userMap/userMap.ts +124 -0
- package/src/userMap/userStatsMap.ts +108 -0
- package/src/userName.ts +2 -1
- package/src/userStats.ts +75 -0
- package/src/userStatsConfig.ts +18 -0
- package/src/util/computeUnits.js +21 -11
- package/src/util/computeUnits.ts +1 -1
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/tests/bn/test.ts +46 -11
- package/tests/dlob/helpers.ts +620 -0
- package/tests/dlob/test.ts +4586 -0
- package/yarn-error.log +3160 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +0 -49
- package/lib/admin.d.ts +0 -44
- package/lib/admin.js +0 -433
- package/lib/clearingHouse.d.ts +0 -133
- package/lib/clearingHouse.js +0 -931
- package/lib/clearingHouseUser.d.ts +0 -187
- package/lib/clearingHouseUser.js +0 -643
- package/lib/clearingHouseUserConfig.d.ts +0 -14
- package/lib/constants/banks.d.ts +0 -16
- package/lib/constants/banks.js +0 -34
- package/lib/constants/markets.d.ts +0 -19
- package/lib/idl/clearing_house.json +0 -3998
- package/lib/math/bankBalance.d.ts +0 -9
- package/lib/math/bankBalance.js +0 -75
- package/lib/math/state.d.ts +0 -8
- package/lib/math/state.js +0 -15
- package/lib/orders.d.ts +0 -8
- package/lib/orders.js +0 -134
- package/src/admin.ts +0 -722
- package/src/clearingHouse.ts +0 -1451
- package/src/clearingHouseUser.ts +0 -989
- package/src/constants/banks.ts +0 -43
- package/src/idl/clearing_house.json +0 -3998
- package/src/math/bankBalance.ts +0 -112
- package/src/math/state.ts +0 -14
- package/src/math/utils.js +0 -27
- package/src/math/utils.js.map +0 -1
- package/src/orders.ts +0 -244
- package/src/util/computeUnits.js.map +0 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
DriftClientAccountSubscriber,
|
|
3
|
+
DriftClientAccountEvents,
|
|
4
4
|
DataAndSlot,
|
|
5
5
|
} from './types';
|
|
6
6
|
import { AccountSubscriber, NotSubscribedError } from './types';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { SpotMarketAccount, PerpMarketAccount, StateAccount } from '../types';
|
|
8
|
+
import { Program } from '@project-serum/anchor';
|
|
9
9
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
10
10
|
import { EventEmitter } from 'events';
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
getDriftStateAccountPublicKey,
|
|
13
|
+
getSpotMarketPublicKey,
|
|
14
|
+
getPerpMarketPublicKey,
|
|
15
15
|
} from '../addresses/pda';
|
|
16
16
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
17
17
|
import { PublicKey } from '@solana/web3.js';
|
|
@@ -20,23 +20,26 @@ import { OracleClientCache } from '../oracles/oracleClientCache';
|
|
|
20
20
|
import * as Buffer from 'buffer';
|
|
21
21
|
import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
|
|
22
22
|
|
|
23
|
-
export class
|
|
24
|
-
implements
|
|
23
|
+
export class WebSocketDriftClientAccountSubscriber
|
|
24
|
+
implements DriftClientAccountSubscriber
|
|
25
25
|
{
|
|
26
26
|
isSubscribed: boolean;
|
|
27
27
|
program: Program;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
perpMarketIndexes: number[];
|
|
29
|
+
spotMarketIndexes: number[];
|
|
30
30
|
oracleInfos: OracleInfo[];
|
|
31
31
|
oracleClientCache = new OracleClientCache();
|
|
32
32
|
|
|
33
|
-
eventEmitter: StrictEventEmitter<EventEmitter,
|
|
33
|
+
eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
|
|
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: number[],
|
|
52
|
+
spotMarketIndexes: number[],
|
|
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
|
|
|
@@ -72,7 +75,7 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
72
75
|
this.subscriptionPromiseResolver = res;
|
|
73
76
|
});
|
|
74
77
|
|
|
75
|
-
const statePublicKey = await
|
|
78
|
+
const statePublicKey = await getDriftStateAccountPublicKey(
|
|
76
79
|
this.program.programId
|
|
77
80
|
);
|
|
78
81
|
|
|
@@ -88,10 +91,10 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
88
91
|
});
|
|
89
92
|
|
|
90
93
|
// subscribe to market accounts
|
|
91
|
-
await this.
|
|
94
|
+
await this.subscribeToPerpMarketAccounts();
|
|
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();
|
|
@@ -105,56 +108,53 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
105
108
|
return true;
|
|
106
109
|
}
|
|
107
110
|
|
|
108
|
-
async
|
|
109
|
-
for (const marketIndex of this.
|
|
110
|
-
await this.
|
|
111
|
+
async subscribeToPerpMarketAccounts(): Promise<boolean> {
|
|
112
|
+
for (const marketIndex of this.perpMarketIndexes) {
|
|
113
|
+
await this.subscribeToPerpMarketAccount(marketIndex);
|
|
111
114
|
}
|
|
112
115
|
return true;
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
async
|
|
116
|
-
const
|
|
118
|
+
async subscribeToPerpMarketAccount(marketIndex: number): Promise<boolean> {
|
|
119
|
+
const perpMarketPublicKey = await getPerpMarketPublicKey(
|
|
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
|
+
perpMarketPublicKey
|
|
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.
|
|
130
|
-
marketIndex.toNumber(),
|
|
131
|
-
accountSubscriber
|
|
132
|
-
);
|
|
132
|
+
this.perpMarketAccountSubscribers.set(marketIndex, accountSubscriber);
|
|
133
133
|
return true;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
async
|
|
137
|
-
for (const
|
|
138
|
-
await this.
|
|
136
|
+
async subscribeToSpotMarketAccounts(): Promise<boolean> {
|
|
137
|
+
for (const marketIndex of this.spotMarketIndexes) {
|
|
138
|
+
await this.subscribeToSpotMarketAccount(marketIndex);
|
|
139
139
|
}
|
|
140
140
|
return true;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
async
|
|
144
|
-
const
|
|
143
|
+
async subscribeToSpotMarketAccount(marketIndex: number): Promise<boolean> {
|
|
144
|
+
const marketPublicKey = await getSpotMarketPublicKey(
|
|
145
145
|
this.program.programId,
|
|
146
|
-
|
|
146
|
+
marketIndex
|
|
147
147
|
);
|
|
148
|
-
const accountSubscriber = new WebSocketAccountSubscriber<
|
|
149
|
-
'
|
|
148
|
+
const accountSubscriber = new WebSocketAccountSubscriber<SpotMarketAccount>(
|
|
149
|
+
'spotMarket',
|
|
150
150
|
this.program,
|
|
151
|
-
|
|
151
|
+
marketPublicKey
|
|
152
152
|
);
|
|
153
|
-
await accountSubscriber.subscribe((data:
|
|
154
|
-
this.eventEmitter.emit('
|
|
153
|
+
await accountSubscriber.subscribe((data: SpotMarketAccount) => {
|
|
154
|
+
this.eventEmitter.emit('spotMarketAccountUpdate', data);
|
|
155
155
|
this.eventEmitter.emit('update');
|
|
156
156
|
});
|
|
157
|
-
this.
|
|
157
|
+
this.spotMarketAccountSubscribers.set(marketIndex, accountSubscriber);
|
|
158
158
|
return true;
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -195,13 +195,13 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
async unsubscribeFromMarketAccounts(): Promise<void> {
|
|
198
|
-
for (const accountSubscriber of this.
|
|
198
|
+
for (const accountSubscriber of this.perpMarketAccountSubscribers.values()) {
|
|
199
199
|
await accountSubscriber.unsubscribe();
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
async
|
|
204
|
-
for (const accountSubscriber of this.
|
|
203
|
+
async unsubscribeFromSpotMarketAccounts(): Promise<void> {
|
|
204
|
+
for (const accountSubscriber of this.spotMarketAccountSubscribers.values()) {
|
|
205
205
|
await accountSubscriber.unsubscribe();
|
|
206
206
|
}
|
|
207
207
|
}
|
|
@@ -219,13 +219,13 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
219
219
|
|
|
220
220
|
const promises = [this.stateAccountSubscriber.fetch()]
|
|
221
221
|
.concat(
|
|
222
|
-
Array.from(this.
|
|
223
|
-
subscriber.fetch()
|
|
222
|
+
Array.from(this.perpMarketAccountSubscribers.values()).map(
|
|
223
|
+
(subscriber) => subscriber.fetch()
|
|
224
224
|
)
|
|
225
225
|
)
|
|
226
226
|
.concat(
|
|
227
|
-
Array.from(this.
|
|
228
|
-
subscriber.fetch()
|
|
227
|
+
Array.from(this.spotMarketAccountSubscribers.values()).map(
|
|
228
|
+
(subscriber) => subscriber.fetch()
|
|
229
229
|
)
|
|
230
230
|
);
|
|
231
231
|
|
|
@@ -240,24 +240,24 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
240
240
|
await this.stateAccountSubscriber.unsubscribe();
|
|
241
241
|
|
|
242
242
|
await this.unsubscribeFromMarketAccounts();
|
|
243
|
-
await this.
|
|
243
|
+
await this.unsubscribeFromSpotMarketAccounts();
|
|
244
244
|
await this.unsubscribeFromOracles();
|
|
245
245
|
|
|
246
246
|
this.isSubscribed = false;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
async
|
|
250
|
-
if (this.
|
|
249
|
+
async addSpotMarket(marketIndex: number): Promise<boolean> {
|
|
250
|
+
if (this.spotMarketAccountSubscribers.has(marketIndex)) {
|
|
251
251
|
return true;
|
|
252
252
|
}
|
|
253
|
-
return this.
|
|
253
|
+
return this.subscribeToSpotMarketAccount(marketIndex);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
async
|
|
257
|
-
if (this.
|
|
256
|
+
async addPerpMarket(marketIndex: number): Promise<boolean> {
|
|
257
|
+
if (this.perpMarketAccountSubscribers.has(marketIndex)) {
|
|
258
258
|
return true;
|
|
259
259
|
}
|
|
260
|
-
return this.
|
|
260
|
+
return this.subscribeToPerpMarketAccount(marketIndex);
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
async addOracle(oracleInfo: OracleInfo): Promise<boolean> {
|
|
@@ -286,24 +286,29 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
public getMarketAccountAndSlot(
|
|
289
|
-
marketIndex:
|
|
290
|
-
): DataAndSlot<
|
|
289
|
+
marketIndex: number
|
|
290
|
+
): DataAndSlot<PerpMarketAccount> | undefined {
|
|
291
291
|
this.assertIsSubscribed();
|
|
292
|
-
return this.
|
|
293
|
-
.dataAndSlot;
|
|
292
|
+
return this.perpMarketAccountSubscribers.get(marketIndex).dataAndSlot;
|
|
294
293
|
}
|
|
295
294
|
|
|
296
|
-
public getMarketAccountsAndSlots(): DataAndSlot<
|
|
297
|
-
return Array.from(this.
|
|
295
|
+
public getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[] {
|
|
296
|
+
return Array.from(this.perpMarketAccountSubscribers.values()).map(
|
|
298
297
|
(subscriber) => subscriber.dataAndSlot
|
|
299
298
|
);
|
|
300
299
|
}
|
|
301
300
|
|
|
302
|
-
public
|
|
303
|
-
|
|
304
|
-
): DataAndSlot<
|
|
301
|
+
public getSpotMarketAccountAndSlot(
|
|
302
|
+
marketIndex: number
|
|
303
|
+
): DataAndSlot<SpotMarketAccount> | undefined {
|
|
305
304
|
this.assertIsSubscribed();
|
|
306
|
-
return this.
|
|
305
|
+
return this.spotMarketAccountSubscribers.get(marketIndex).dataAndSlot;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
public getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[] {
|
|
309
|
+
return Array.from(this.spotMarketAccountSubscribers.values()).map(
|
|
310
|
+
(subscriber) => subscriber.dataAndSlot
|
|
311
|
+
);
|
|
307
312
|
}
|
|
308
313
|
|
|
309
314
|
public getOraclePriceDataAndSlot(
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataAndSlot,
|
|
3
|
+
AccountSubscriber,
|
|
4
|
+
NotSubscribedError,
|
|
5
|
+
UserStatsAccountSubscriber,
|
|
6
|
+
UserStatsAccountEvents,
|
|
7
|
+
} from './types';
|
|
8
|
+
import { Program } from '@project-serum/anchor';
|
|
9
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
import { PublicKey } from '@solana/web3.js';
|
|
12
|
+
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
13
|
+
import { UserStatsAccount } from '../types';
|
|
14
|
+
|
|
15
|
+
export class WebSocketUserStatsAccountSubscriber
|
|
16
|
+
implements UserStatsAccountSubscriber
|
|
17
|
+
{
|
|
18
|
+
isSubscribed: boolean;
|
|
19
|
+
program: Program;
|
|
20
|
+
eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
|
|
21
|
+
userStatsAccountPublicKey: PublicKey;
|
|
22
|
+
|
|
23
|
+
userStatsAccountSubscriber: AccountSubscriber<UserStatsAccount>;
|
|
24
|
+
|
|
25
|
+
public constructor(program: Program, userStatsAccountPublicKey: PublicKey) {
|
|
26
|
+
this.isSubscribed = false;
|
|
27
|
+
this.program = program;
|
|
28
|
+
this.userStatsAccountPublicKey = userStatsAccountPublicKey;
|
|
29
|
+
this.eventEmitter = new EventEmitter();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async subscribe(): Promise<boolean> {
|
|
33
|
+
if (this.isSubscribed) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.userStatsAccountSubscriber = new WebSocketAccountSubscriber(
|
|
38
|
+
'userStats',
|
|
39
|
+
this.program,
|
|
40
|
+
this.userStatsAccountPublicKey
|
|
41
|
+
);
|
|
42
|
+
await this.userStatsAccountSubscriber.subscribe(
|
|
43
|
+
(data: UserStatsAccount) => {
|
|
44
|
+
this.eventEmitter.emit('userStatsAccountUpdate', data);
|
|
45
|
+
this.eventEmitter.emit('update');
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
this.eventEmitter.emit('update');
|
|
50
|
+
this.isSubscribed = true;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async fetch(): Promise<void> {
|
|
55
|
+
await Promise.all([this.userStatsAccountSubscriber.fetch()]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async unsubscribe(): Promise<void> {
|
|
59
|
+
if (!this.isSubscribed) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await Promise.all([this.userStatsAccountSubscriber.unsubscribe()]);
|
|
64
|
+
|
|
65
|
+
this.isSubscribed = false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
assertIsSubscribed(): void {
|
|
69
|
+
if (!this.isSubscribed) {
|
|
70
|
+
throw new NotSubscribedError(
|
|
71
|
+
'You must call `subscribe` before using this function'
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public getUserStatsAccountAndSlot(): DataAndSlot<UserStatsAccount> {
|
|
77
|
+
this.assertIsSubscribed();
|
|
78
|
+
return this.userStatsAccountSubscriber.dataAndSlot;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
|
-
import {
|
|
3
|
-
import { getMarketPublicKey } from './pda';
|
|
2
|
+
import { getPerpMarketPublicKey } from './pda';
|
|
4
3
|
|
|
5
4
|
const CACHE = new Map<string, PublicKey>();
|
|
6
5
|
export async function getMarketAddress(
|
|
7
6
|
programId: PublicKey,
|
|
8
|
-
marketIndex:
|
|
7
|
+
marketIndex: number
|
|
9
8
|
): Promise<PublicKey> {
|
|
10
9
|
const cacheKey = `${programId.toString()}-${marketIndex.toString()}`;
|
|
11
10
|
if (CACHE.has(cacheKey)) {
|
|
12
11
|
return CACHE.get(cacheKey);
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
const publicKey = await
|
|
14
|
+
const publicKey = await getPerpMarketPublicKey(programId, marketIndex);
|
|
16
15
|
CACHE.set(cacheKey, publicKey);
|
|
17
16
|
return publicKey;
|
|
18
17
|
}
|
package/src/addresses/pda.ts
CHANGED
|
@@ -2,31 +2,31 @@ import { PublicKey } from '@solana/web3.js';
|
|
|
2
2
|
import * as anchor from '@project-serum/anchor';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
4
|
|
|
5
|
-
export async function
|
|
5
|
+
export async function getDriftStateAccountPublicKeyAndNonce(
|
|
6
6
|
programId: PublicKey
|
|
7
7
|
): Promise<[PublicKey, number]> {
|
|
8
|
-
return
|
|
9
|
-
[Buffer.from(anchor.utils.bytes.utf8.encode('
|
|
8
|
+
return PublicKey.findProgramAddress(
|
|
9
|
+
[Buffer.from(anchor.utils.bytes.utf8.encode('drift_state'))],
|
|
10
10
|
programId
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export async function
|
|
14
|
+
export async function getDriftStateAccountPublicKey(
|
|
15
15
|
programId: PublicKey
|
|
16
16
|
): Promise<PublicKey> {
|
|
17
|
-
return (await
|
|
17
|
+
return (await getDriftStateAccountPublicKeyAndNonce(programId))[0];
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export async function getUserAccountPublicKeyAndNonce(
|
|
21
21
|
programId: PublicKey,
|
|
22
22
|
authority: PublicKey,
|
|
23
|
-
|
|
23
|
+
subAccountId = 0
|
|
24
24
|
): Promise<[PublicKey, number]> {
|
|
25
|
-
return
|
|
25
|
+
return PublicKey.findProgramAddress(
|
|
26
26
|
[
|
|
27
27
|
Buffer.from(anchor.utils.bytes.utf8.encode('user')),
|
|
28
28
|
authority.toBuffer(),
|
|
29
|
-
|
|
29
|
+
new anchor.BN(subAccountId).toArrayLike(Buffer, 'le', 2),
|
|
30
30
|
],
|
|
31
31
|
programId
|
|
32
32
|
);
|
|
@@ -35,84 +35,156 @@ export async function getUserAccountPublicKeyAndNonce(
|
|
|
35
35
|
export async function getUserAccountPublicKey(
|
|
36
36
|
programId: PublicKey,
|
|
37
37
|
authority: PublicKey,
|
|
38
|
-
|
|
38
|
+
subAccountId = 0
|
|
39
39
|
): Promise<PublicKey> {
|
|
40
40
|
return (
|
|
41
|
-
await getUserAccountPublicKeyAndNonce(programId, authority,
|
|
41
|
+
await getUserAccountPublicKeyAndNonce(programId, authority, subAccountId)
|
|
42
42
|
)[0];
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export function getUserAccountPublicKeySync(
|
|
46
46
|
programId: PublicKey,
|
|
47
47
|
authority: PublicKey,
|
|
48
|
-
|
|
48
|
+
subAccountId = 0
|
|
49
49
|
): PublicKey {
|
|
50
|
-
return
|
|
50
|
+
return PublicKey.findProgramAddressSync(
|
|
51
51
|
[
|
|
52
52
|
Buffer.from(anchor.utils.bytes.utf8.encode('user')),
|
|
53
53
|
authority.toBuffer(),
|
|
54
|
-
|
|
54
|
+
new anchor.BN(subAccountId).toArrayLike(Buffer, 'le', 2),
|
|
55
55
|
],
|
|
56
56
|
programId
|
|
57
57
|
)[0];
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export
|
|
60
|
+
export function getUserStatsAccountPublicKey(
|
|
61
61
|
programId: PublicKey,
|
|
62
|
-
|
|
62
|
+
authority: PublicKey
|
|
63
|
+
): PublicKey {
|
|
64
|
+
return PublicKey.findProgramAddressSync(
|
|
65
|
+
[
|
|
66
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('user_stats')),
|
|
67
|
+
authority.toBuffer(),
|
|
68
|
+
],
|
|
69
|
+
programId
|
|
70
|
+
)[0];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function getPerpMarketPublicKey(
|
|
74
|
+
programId: PublicKey,
|
|
75
|
+
marketIndex: number
|
|
63
76
|
): Promise<PublicKey> {
|
|
64
77
|
return (
|
|
65
|
-
await
|
|
78
|
+
await PublicKey.findProgramAddress(
|
|
66
79
|
[
|
|
67
|
-
Buffer.from(anchor.utils.bytes.utf8.encode('
|
|
68
|
-
marketIndex.toArrayLike(Buffer, 'le',
|
|
80
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('perp_market')),
|
|
81
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
69
82
|
],
|
|
70
83
|
programId
|
|
71
84
|
)
|
|
72
85
|
)[0];
|
|
73
86
|
}
|
|
74
87
|
|
|
75
|
-
export async function
|
|
88
|
+
export async function getSpotMarketPublicKey(
|
|
76
89
|
programId: PublicKey,
|
|
77
|
-
|
|
90
|
+
marketIndex: number
|
|
78
91
|
): Promise<PublicKey> {
|
|
79
92
|
return (
|
|
80
|
-
await
|
|
93
|
+
await PublicKey.findProgramAddress(
|
|
81
94
|
[
|
|
82
|
-
Buffer.from(anchor.utils.bytes.utf8.encode('
|
|
83
|
-
|
|
95
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('spot_market')),
|
|
96
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
84
97
|
],
|
|
85
98
|
programId
|
|
86
99
|
)
|
|
87
100
|
)[0];
|
|
88
101
|
}
|
|
89
102
|
|
|
90
|
-
export async function
|
|
103
|
+
export async function getSpotMarketVaultPublicKey(
|
|
91
104
|
programId: PublicKey,
|
|
92
|
-
|
|
105
|
+
marketIndex: number
|
|
93
106
|
): Promise<PublicKey> {
|
|
94
107
|
return (
|
|
95
|
-
await
|
|
108
|
+
await PublicKey.findProgramAddress(
|
|
96
109
|
[
|
|
97
|
-
Buffer.from(anchor.utils.bytes.utf8.encode('
|
|
98
|
-
|
|
110
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('spot_market_vault')),
|
|
111
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
99
112
|
],
|
|
100
113
|
programId
|
|
101
114
|
)
|
|
102
115
|
)[0];
|
|
103
116
|
}
|
|
104
117
|
|
|
105
|
-
export async function
|
|
118
|
+
export async function getInsuranceFundVaultPublicKey(
|
|
106
119
|
programId: PublicKey,
|
|
107
|
-
|
|
120
|
+
marketIndex: number
|
|
108
121
|
): Promise<PublicKey> {
|
|
109
122
|
return (
|
|
110
|
-
await
|
|
123
|
+
await PublicKey.findProgramAddress(
|
|
111
124
|
[
|
|
112
|
-
Buffer.from(anchor.utils.bytes.utf8.encode('
|
|
113
|
-
|
|
125
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('insurance_fund_vault')),
|
|
126
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
114
127
|
],
|
|
115
128
|
programId
|
|
116
129
|
)
|
|
117
130
|
)[0];
|
|
118
131
|
}
|
|
132
|
+
|
|
133
|
+
export function getInsuranceFundStakeAccountPublicKey(
|
|
134
|
+
programId: PublicKey,
|
|
135
|
+
authority: PublicKey,
|
|
136
|
+
marketIndex: number
|
|
137
|
+
): PublicKey {
|
|
138
|
+
return PublicKey.findProgramAddressSync(
|
|
139
|
+
[
|
|
140
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('insurance_fund_stake')),
|
|
141
|
+
authority.toBuffer(),
|
|
142
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
143
|
+
],
|
|
144
|
+
programId
|
|
145
|
+
)[0];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function getDriftSignerPublicKey(programId: PublicKey): PublicKey {
|
|
149
|
+
return PublicKey.findProgramAddressSync(
|
|
150
|
+
[Buffer.from(anchor.utils.bytes.utf8.encode('drift_signer'))],
|
|
151
|
+
programId
|
|
152
|
+
)[0];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function getSerumOpenOrdersPublicKey(
|
|
156
|
+
programId: PublicKey,
|
|
157
|
+
market: PublicKey
|
|
158
|
+
): PublicKey {
|
|
159
|
+
return PublicKey.findProgramAddressSync(
|
|
160
|
+
[
|
|
161
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('serum_open_orders')),
|
|
162
|
+
market.toBuffer(),
|
|
163
|
+
],
|
|
164
|
+
programId
|
|
165
|
+
)[0];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function getSerumSignerPublicKey(
|
|
169
|
+
programId: PublicKey,
|
|
170
|
+
market: PublicKey,
|
|
171
|
+
nonce: BN
|
|
172
|
+
): PublicKey {
|
|
173
|
+
return anchor.web3.PublicKey.createProgramAddressSync(
|
|
174
|
+
[market.toBuffer(), nonce.toArrayLike(Buffer, 'le', 8)],
|
|
175
|
+
programId
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function getSerumFulfillmentConfigPublicKey(
|
|
180
|
+
programId: PublicKey,
|
|
181
|
+
market: PublicKey
|
|
182
|
+
): PublicKey {
|
|
183
|
+
return PublicKey.findProgramAddressSync(
|
|
184
|
+
[
|
|
185
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('serum_fulfillment_config')),
|
|
186
|
+
market.toBuffer(),
|
|
187
|
+
],
|
|
188
|
+
programId
|
|
189
|
+
)[0];
|
|
190
|
+
}
|