@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.2
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/bulkAccountLoader.d.ts +6 -6
- package/lib/accounts/bulkAccountLoader.js +81 -95
- package/lib/accounts/bulkUserSubscription.js +13 -57
- package/lib/accounts/fetch.d.ts +4 -0
- package/lib/accounts/fetch.js +18 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
- package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
- package/lib/accounts/pollingOracleSubscriber.js +37 -49
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
- package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
- package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
- package/lib/accounts/types.d.ts +34 -41
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
- package/lib/accounts/webSocketAccountSubscriber.js +39 -35
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
- package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
- package/lib/addresses/marketAddresses.d.ts +4 -0
- package/lib/addresses/marketAddresses.js +15 -0
- package/lib/addresses/pda.d.ts +12 -0
- package/lib/addresses/pda.js +83 -0
- package/lib/admin.d.ts +9 -17
- package/lib/admin.js +375 -558
- package/lib/clearingHouse.d.ts +86 -109
- package/lib/clearingHouse.js +828 -895
- package/lib/clearingHouseConfig.d.ts +34 -0
- package/lib/clearingHouseConfig.js +2 -0
- package/lib/clearingHouseUser.d.ts +19 -22
- package/lib/clearingHouseUser.js +155 -141
- package/lib/clearingHouseUserConfig.d.ts +14 -0
- package/lib/clearingHouseUserConfig.js +2 -0
- package/lib/config.d.ts +12 -0
- package/lib/config.js +35 -4
- package/lib/constants/banks.d.ts +16 -0
- package/lib/constants/banks.js +34 -0
- package/lib/constants/markets.d.ts +8 -3
- package/lib/constants/markets.js +13 -206
- package/lib/constants/numericConstants.d.ts +17 -0
- package/lib/constants/numericConstants.js +23 -6
- package/lib/events/eventList.d.ts +22 -0
- package/lib/events/eventList.js +77 -0
- package/lib/events/eventSubscriber.d.ts +34 -0
- package/lib/events/eventSubscriber.js +126 -0
- package/lib/events/fetchLogs.d.ts +13 -0
- package/lib/events/fetchLogs.js +39 -0
- package/lib/events/pollingLogProvider.d.ts +15 -0
- package/lib/events/pollingLogProvider.js +53 -0
- package/lib/events/sort.d.ts +2 -0
- package/lib/events/sort.js +44 -0
- package/lib/events/txEventCache.d.ts +24 -0
- package/lib/events/txEventCache.js +71 -0
- package/lib/events/types.d.ts +49 -0
- package/lib/events/types.js +20 -0
- package/lib/events/webSocketLogProvider.d.ts +12 -0
- package/lib/events/webSocketLogProvider.js +30 -0
- package/lib/examples/makeTradeExample.js +26 -27
- package/lib/factory/bigNum.d.ts +118 -0
- package/lib/factory/bigNum.js +364 -0
- package/lib/factory/oracleClient.d.ts +1 -2
- package/lib/factory/oracleClient.js +6 -2
- package/lib/idl/clearing_house.json +2287 -2938
- package/lib/index.d.ts +12 -4
- package/lib/index.js +12 -4
- package/lib/math/amm.d.ts +24 -29
- package/lib/math/amm.js +239 -178
- package/lib/math/auction.d.ts +5 -0
- package/lib/math/auction.js +39 -0
- package/lib/math/bankBalance.d.ts +9 -0
- package/lib/math/bankBalance.js +75 -0
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/conversion.js +1 -5
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +158 -175
- package/lib/math/market.d.ts +6 -6
- package/lib/math/market.js +10 -9
- package/lib/math/orders.d.ts +5 -0
- package/lib/math/orders.js +31 -1
- package/lib/math/position.d.ts +7 -5
- package/lib/math/position.js +27 -27
- package/lib/math/repeg.d.ts +22 -0
- package/lib/math/repeg.js +128 -0
- package/lib/math/trade.d.ts +5 -4
- package/lib/math/trade.js +29 -21
- package/lib/mockUSDCFaucet.js +87 -116
- package/lib/oracles/oracleClientCache.d.ts +8 -0
- package/lib/oracles/oracleClientCache.js +19 -0
- package/lib/oracles/pythClient.d.ts +3 -5
- package/lib/oracles/pythClient.js +12 -31
- package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
- package/lib/oracles/quoteAssetOracleClient.js +21 -0
- package/lib/oracles/switchboardClient.d.ts +3 -5
- package/lib/oracles/switchboardClient.js +29 -50
- package/lib/oracles/types.d.ts +6 -1
- package/lib/orders.d.ts +6 -7
- package/lib/orders.js +10 -80
- package/lib/slot/SlotSubscriber.d.ts +12 -0
- package/lib/slot/SlotSubscriber.js +23 -0
- package/lib/tx/retryTxSender.d.ts +2 -2
- package/lib/tx/retryTxSender.js +108 -123
- package/lib/tx/types.d.ts +5 -1
- package/lib/tx/utils.d.ts +1 -1
- package/lib/tx/utils.js +11 -2
- package/lib/types.d.ts +110 -109
- package/lib/types.js +14 -1
- package/lib/userName.d.ts +4 -0
- package/lib/userName.js +20 -0
- package/lib/util/computeUnits.js +10 -21
- package/lib/util/tps.js +11 -22
- package/lib/wallet.js +7 -20
- package/package.json +11 -4
- package/src/accounts/bulkAccountLoader.ts +21 -15
- package/src/accounts/bulkUserSubscription.ts +1 -45
- package/src/accounts/fetch.ts +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
- package/src/accounts/pollingOracleSubscriber.ts +16 -8
- package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
- package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
- package/src/accounts/types.ts +41 -70
- package/src/accounts/webSocketAccountSubscriber.ts +33 -16
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
- package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
- package/src/addresses/marketAddresses.ts +18 -0
- package/src/addresses/pda.ts +118 -0
- package/src/admin.ts +218 -346
- package/src/clearingHouse.ts +983 -952
- package/src/clearingHouseConfig.ts +37 -0
- package/src/clearingHouseUser.ts +275 -185
- package/src/clearingHouseUserConfig.ts +18 -0
- package/src/config.ts +54 -1
- package/src/constants/banks.ts +43 -0
- package/src/constants/markets.ts +16 -207
- package/src/constants/numericConstants.ts +34 -5
- package/src/events/eventList.ts +94 -0
- package/src/events/eventSubscriber.ts +194 -0
- package/src/events/fetchLogs.ts +80 -0
- package/src/events/pollingLogProvider.ts +79 -0
- package/src/events/sort.ts +65 -0
- package/src/events/txEventCache.ts +74 -0
- package/src/events/types.ts +98 -0
- package/src/events/webSocketLogProvider.ts +38 -0
- package/src/examples/makeTradeExample.ts +20 -11
- package/src/factory/bigNum.ts +524 -0
- package/src/factory/oracleClient.ts +7 -4
- package/src/idl/clearing_house.json +2287 -2938
- package/src/index.ts +12 -4
- package/src/math/amm.ts +414 -245
- package/src/math/auction.ts +39 -0
- package/src/math/bankBalance.ts +112 -0
- package/src/math/conversion.ts +1 -11
- package/src/math/funding.ts +12 -9
- package/src/math/market.ts +37 -30
- package/src/math/orders.ts +38 -0
- package/src/math/position.ts +48 -35
- package/src/math/repeg.ts +176 -0
- package/src/math/trade.ts +45 -35
- package/src/math/utils.js +27 -0
- package/src/math/utils.js.map +1 -0
- package/src/oracles/oracleClientCache.ts +20 -0
- package/src/oracles/pythClient.ts +4 -11
- package/src/oracles/quoteAssetOracleClient.ts +25 -0
- package/src/oracles/switchboardClient.ts +11 -24
- package/src/oracles/types.ts +7 -1
- package/src/orders.ts +24 -126
- package/src/slot/SlotSubscriber.ts +32 -0
- package/src/tx/retryTxSender.ts +6 -4
- package/src/tx/types.ts +6 -1
- package/src/tx/utils.ts +22 -3
- package/src/types.ts +111 -122
- package/src/userName.ts +20 -0
- package/src/util/computeUnits.js +17 -0
- package/src/util/computeUnits.js.map +1 -0
- package/tests/bn/test.ts +255 -0
- package/tsconfig.json +12 -12
- package/lib/addresses.d.ts +0 -10
- package/lib/addresses.js +0 -93
- package/lib/constants/accounts.d.ts +0 -15
- package/lib/constants/accounts.js +0 -18
- package/lib/factory/clearingHouse.d.ts +0 -35
- package/lib/factory/clearingHouse.js +0 -81
- package/lib/factory/clearingHouseUser.d.ts +0 -19
- package/lib/factory/clearingHouseUser.js +0 -34
- package/lib/math/insuranceFund.d.ts +0 -15
- package/lib/math/insuranceFund.js +0 -33
- package/lib/settlement.d.ts +0 -4
- package/lib/settlement.js +0 -10
- package/lib/tx/defaultTxSender.d.ts +0 -8
- package/lib/tx/defaultTxSender.js +0 -12
- package/src/addresses.ts +0 -82
- package/src/constants/accounts.ts +0 -26
- package/src/factory/clearingHouse.ts +0 -173
- package/src/factory/clearingHouseUser.ts +0 -73
- package/src/math/insuranceFund.ts +0 -29
- package/src/settlement.ts +0 -9
- package/src/tx/defaultTxSender.ts +0 -24
|
@@ -1,62 +1,63 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClearingHouseAccountSubscriber,
|
|
3
3
|
ClearingHouseAccountEvents,
|
|
4
|
-
|
|
4
|
+
DataAndSlot,
|
|
5
5
|
} from './types';
|
|
6
6
|
import { AccountSubscriber, NotSubscribedError } from './types';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
ExtendedCurveHistoryAccount,
|
|
10
|
-
FundingPaymentHistoryAccount,
|
|
11
|
-
FundingRateHistoryAccount,
|
|
12
|
-
LiquidationHistoryAccount,
|
|
13
|
-
MarketsAccount,
|
|
14
|
-
OrderHistoryAccount,
|
|
15
|
-
OrderStateAccount,
|
|
16
|
-
StateAccount,
|
|
17
|
-
TradeHistoryAccount,
|
|
18
|
-
} from '../types';
|
|
19
|
-
import { Program } from '@project-serum/anchor';
|
|
7
|
+
import { BankAccount, MarketAccount, StateAccount } from '../types';
|
|
8
|
+
import { BN, Program } from '@project-serum/anchor';
|
|
20
9
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
21
10
|
import { EventEmitter } from 'events';
|
|
22
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
getClearingHouseStateAccountPublicKey,
|
|
13
|
+
getBankPublicKey,
|
|
14
|
+
getMarketPublicKey,
|
|
15
|
+
} from '../addresses/pda';
|
|
23
16
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
24
|
-
import {
|
|
17
|
+
import { PublicKey } from '@solana/web3.js';
|
|
18
|
+
import { OracleInfo, OraclePriceData } from '../oracles/types';
|
|
19
|
+
import { OracleClientCache } from '../oracles/oracleClientCache';
|
|
20
|
+
import * as Buffer from 'buffer';
|
|
21
|
+
import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
|
|
25
22
|
|
|
26
23
|
export class WebSocketClearingHouseAccountSubscriber
|
|
27
24
|
implements ClearingHouseAccountSubscriber
|
|
28
25
|
{
|
|
29
26
|
isSubscribed: boolean;
|
|
30
27
|
program: Program;
|
|
28
|
+
marketIndexes: BN[];
|
|
29
|
+
bankIndexes: BN[];
|
|
30
|
+
oracleInfos: OracleInfo[];
|
|
31
|
+
oracleClientCache = new OracleClientCache();
|
|
32
|
+
|
|
31
33
|
eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
|
|
32
34
|
stateAccountSubscriber?: AccountSubscriber<StateAccount>;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
liquidationHistoryAccountSubscriber?: AccountSubscriber<LiquidationHistoryAccount>;
|
|
40
|
-
orderStateAccountSubscriber?: AccountSubscriber<OrderStateAccount>;
|
|
41
|
-
orderHistoryAccountSubscriber?: AccountSubscriber<OrderHistoryAccount>;
|
|
42
|
-
|
|
43
|
-
optionalExtraSubscriptions: ClearingHouseAccountTypes[] = [];
|
|
44
|
-
|
|
45
|
-
type: ClearingHouseConfigType = 'websocket';
|
|
35
|
+
marketAccountSubscribers = new Map<
|
|
36
|
+
number,
|
|
37
|
+
AccountSubscriber<MarketAccount>
|
|
38
|
+
>();
|
|
39
|
+
bankAccountSubscribers = new Map<number, AccountSubscriber<BankAccount>>();
|
|
40
|
+
oracleSubscribers = new Map<string, AccountSubscriber<OraclePriceData>>();
|
|
46
41
|
|
|
47
42
|
private isSubscribing = false;
|
|
48
43
|
private subscriptionPromise: Promise<boolean>;
|
|
49
44
|
private subscriptionPromiseResolver: (val: boolean) => void;
|
|
50
45
|
|
|
51
|
-
public constructor(
|
|
46
|
+
public constructor(
|
|
47
|
+
program: Program,
|
|
48
|
+
marketIndexes: BN[],
|
|
49
|
+
bankIndexes: BN[],
|
|
50
|
+
oracleInfos: OracleInfo[]
|
|
51
|
+
) {
|
|
52
52
|
this.isSubscribed = false;
|
|
53
53
|
this.program = program;
|
|
54
54
|
this.eventEmitter = new EventEmitter();
|
|
55
|
+
this.marketIndexes = marketIndexes;
|
|
56
|
+
this.bankIndexes = bankIndexes;
|
|
57
|
+
this.oracleInfos = oracleInfos;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
public async subscribe(
|
|
58
|
-
optionalSubscriptions?: ClearingHouseAccountTypes[]
|
|
59
|
-
): Promise<boolean> {
|
|
60
|
+
public async subscribe(): Promise<boolean> {
|
|
60
61
|
if (this.isSubscribed) {
|
|
61
62
|
return true;
|
|
62
63
|
}
|
|
@@ -86,146 +87,129 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
86
87
|
this.eventEmitter.emit('update');
|
|
87
88
|
});
|
|
88
89
|
|
|
89
|
-
|
|
90
|
+
// subscribe to market accounts
|
|
91
|
+
await this.subscribeToMarketAccounts();
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
this.program,
|
|
94
|
-
state.markets
|
|
95
|
-
);
|
|
93
|
+
// subscribe to bank accounts
|
|
94
|
+
await this.subscribeToBankAccounts();
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.eventEmitter.emit('update');
|
|
100
|
-
});
|
|
96
|
+
// subscribe to oracles
|
|
97
|
+
await this.subscribeToOracles();
|
|
101
98
|
|
|
102
|
-
this.
|
|
103
|
-
'orderState',
|
|
104
|
-
this.program,
|
|
105
|
-
state.orderState
|
|
106
|
-
);
|
|
99
|
+
this.eventEmitter.emit('update');
|
|
107
100
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.eventEmitter.emit('update');
|
|
112
|
-
}
|
|
113
|
-
);
|
|
101
|
+
this.isSubscribing = false;
|
|
102
|
+
this.isSubscribed = true;
|
|
103
|
+
this.subscriptionPromiseResolver(true);
|
|
114
104
|
|
|
115
|
-
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
116
107
|
|
|
117
|
-
|
|
108
|
+
async subscribeToMarketAccounts(): Promise<boolean> {
|
|
109
|
+
for (const marketIndex of this.marketIndexes) {
|
|
110
|
+
await this.subscribeToMarketAccount(marketIndex);
|
|
111
|
+
}
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
118
114
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
this.program,
|
|
122
|
-
|
|
115
|
+
async subscribeToMarketAccount(marketIndex: BN): Promise<boolean> {
|
|
116
|
+
const marketPublicKey = await getMarketPublicKey(
|
|
117
|
+
this.program.programId,
|
|
118
|
+
marketIndex
|
|
123
119
|
);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
'depositHistory',
|
|
120
|
+
const accountSubscriber = new WebSocketAccountSubscriber<MarketAccount>(
|
|
121
|
+
'market',
|
|
127
122
|
this.program,
|
|
128
|
-
|
|
123
|
+
marketPublicKey
|
|
124
|
+
);
|
|
125
|
+
await accountSubscriber.subscribe((data: MarketAccount) => {
|
|
126
|
+
this.eventEmitter.emit('marketAccountUpdate', data);
|
|
127
|
+
this.eventEmitter.emit('update');
|
|
128
|
+
});
|
|
129
|
+
this.marketAccountSubscribers.set(
|
|
130
|
+
marketIndex.toNumber(),
|
|
131
|
+
accountSubscriber
|
|
129
132
|
);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
130
135
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
async subscribeToBankAccounts(): Promise<boolean> {
|
|
137
|
+
for (const bankIndex of this.bankIndexes) {
|
|
138
|
+
await this.subscribeToBankAccount(bankIndex);
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
137
142
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
this.program,
|
|
141
|
-
|
|
143
|
+
async subscribeToBankAccount(bankIndex: BN): Promise<boolean> {
|
|
144
|
+
const bankPublicKey = await getBankPublicKey(
|
|
145
|
+
this.program.programId,
|
|
146
|
+
bankIndex
|
|
142
147
|
);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
'liquidationHistory',
|
|
148
|
+
const accountSubscriber = new WebSocketAccountSubscriber<BankAccount>(
|
|
149
|
+
'bank',
|
|
146
150
|
this.program,
|
|
147
|
-
|
|
151
|
+
bankPublicKey
|
|
148
152
|
);
|
|
153
|
+
await accountSubscriber.subscribe((data: BankAccount) => {
|
|
154
|
+
this.eventEmitter.emit('bankAccountUpdate', data);
|
|
155
|
+
this.eventEmitter.emit('update');
|
|
156
|
+
});
|
|
157
|
+
this.bankAccountSubscribers.set(bankIndex.toNumber(), accountSubscriber);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
149
160
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
161
|
+
async subscribeToOracles(): Promise<boolean> {
|
|
162
|
+
for (const oracleInfo of this.oracleInfos) {
|
|
163
|
+
if (!oracleInfo.publicKey.equals(PublicKey.default)) {
|
|
164
|
+
await this.subscribeToOracle(oracleInfo);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
155
167
|
|
|
156
|
-
|
|
157
|
-
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async subscribeToOracle(oracleInfo: OracleInfo): Promise<boolean> {
|
|
172
|
+
const client = this.oracleClientCache.get(
|
|
173
|
+
oracleInfo.source,
|
|
174
|
+
this.program.provider.connection
|
|
175
|
+
);
|
|
176
|
+
const accountSubscriber = new WebSocketAccountSubscriber<OraclePriceData>(
|
|
177
|
+
'oracle',
|
|
158
178
|
this.program,
|
|
159
|
-
|
|
179
|
+
oracleInfo.publicKey,
|
|
180
|
+
(buffer: Buffer) => {
|
|
181
|
+
return client.getOraclePriceDataFromBuffer(buffer);
|
|
182
|
+
}
|
|
160
183
|
);
|
|
161
184
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
eventType: 'tradeHistoryAccountUpdate',
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
if (optionalSubscriptions?.includes('depositHistoryAccount'))
|
|
174
|
-
extraSusbcribersToUse.push({
|
|
175
|
-
subscriber: this.depositHistoryAccountSubscriber,
|
|
176
|
-
eventType: 'depositHistoryAccountUpdate',
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
if (optionalSubscriptions?.includes('fundingPaymentHistoryAccount'))
|
|
180
|
-
extraSusbcribersToUse.push({
|
|
181
|
-
subscriber: this.fundingPaymentHistoryAccountSubscriber,
|
|
182
|
-
eventType: 'fundingPaymentHistoryAccountUpdate',
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
if (optionalSubscriptions?.includes('fundingRateHistoryAccount'))
|
|
186
|
-
extraSusbcribersToUse.push({
|
|
187
|
-
subscriber: this.fundingRateHistoryAccountSubscriber,
|
|
188
|
-
eventType: 'fundingRateHistoryAccountUpdate',
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
if (optionalSubscriptions?.includes('liquidationHistoryAccount'))
|
|
192
|
-
extraSusbcribersToUse.push({
|
|
193
|
-
subscriber: this.liquidationHistoryAccountSubscriber,
|
|
194
|
-
eventType: 'liquidationHistoryAccountUpdate',
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
if (optionalSubscriptions?.includes('curveHistoryAccount'))
|
|
198
|
-
extraSusbcribersToUse.push({
|
|
199
|
-
subscriber: this.curveHistoryAccountSubscriber,
|
|
200
|
-
eventType: 'curveHistoryAccountUpdate',
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
if (optionalSubscriptions?.includes('orderHistoryAccount'))
|
|
204
|
-
extraSusbcribersToUse.push({
|
|
205
|
-
subscriber: this.orderHistoryAccountSubscriber,
|
|
206
|
-
eventType: 'orderHistoryAccountUpdate',
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
this.optionalExtraSubscriptions = optionalSubscriptions ?? [];
|
|
210
|
-
|
|
211
|
-
// await all subcriptions in parallel to boost performance
|
|
212
|
-
//// the state account subscription above can't happen in here, because some of these susbcriptions are dependent on clearing house state being available
|
|
213
|
-
await Promise.all(
|
|
214
|
-
extraSusbcribersToUse.map(({ subscriber, eventType }) =>
|
|
215
|
-
subscriber.subscribe((data) => {
|
|
216
|
-
this.eventEmitter.emit(eventType, data);
|
|
217
|
-
this.eventEmitter.emit('update');
|
|
218
|
-
})
|
|
219
|
-
)
|
|
185
|
+
await accountSubscriber.subscribe((data: OraclePriceData) => {
|
|
186
|
+
this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
|
|
187
|
+
this.eventEmitter.emit('update');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
this.oracleSubscribers.set(
|
|
191
|
+
oracleInfo.publicKey.toString(),
|
|
192
|
+
accountSubscriber
|
|
220
193
|
);
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
221
196
|
|
|
222
|
-
|
|
197
|
+
async unsubscribeFromMarketAccounts(): Promise<void> {
|
|
198
|
+
for (const accountSubscriber of this.marketAccountSubscribers.values()) {
|
|
199
|
+
await accountSubscriber.unsubscribe();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
223
202
|
|
|
224
|
-
|
|
225
|
-
this.
|
|
226
|
-
|
|
203
|
+
async unsubscribeFromBankAccounts(): Promise<void> {
|
|
204
|
+
for (const accountSubscriber of this.bankAccountSubscribers.values()) {
|
|
205
|
+
await accountSubscriber.unsubscribe();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
227
208
|
|
|
228
|
-
|
|
209
|
+
async unsubscribeFromOracles(): Promise<void> {
|
|
210
|
+
for (const accountSubscriber of this.oracleSubscribers.values()) {
|
|
211
|
+
await accountSubscriber.unsubscribe();
|
|
212
|
+
}
|
|
229
213
|
}
|
|
230
214
|
|
|
231
215
|
public async fetch(): Promise<void> {
|
|
@@ -233,15 +217,17 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
233
217
|
return;
|
|
234
218
|
}
|
|
235
219
|
|
|
236
|
-
const promises = this.
|
|
237
|
-
.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.
|
|
244
|
-
|
|
220
|
+
const promises = [this.stateAccountSubscriber.fetch()]
|
|
221
|
+
.concat(
|
|
222
|
+
Array.from(this.marketAccountSubscribers.values()).map((subscriber) =>
|
|
223
|
+
subscriber.fetch()
|
|
224
|
+
)
|
|
225
|
+
)
|
|
226
|
+
.concat(
|
|
227
|
+
Array.from(this.bankAccountSubscribers.values()).map((subscriber) =>
|
|
228
|
+
subscriber.fetch()
|
|
229
|
+
)
|
|
230
|
+
);
|
|
245
231
|
|
|
246
232
|
await Promise.all(promises);
|
|
247
233
|
}
|
|
@@ -252,40 +238,38 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
252
238
|
}
|
|
253
239
|
|
|
254
240
|
await this.stateAccountSubscriber.unsubscribe();
|
|
255
|
-
await this.marketsAccountSubscriber.unsubscribe();
|
|
256
|
-
await this.orderStateAccountSubscriber.unsubscribe();
|
|
257
241
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
242
|
+
await this.unsubscribeFromMarketAccounts();
|
|
243
|
+
await this.unsubscribeFromBankAccounts();
|
|
244
|
+
await this.unsubscribeFromOracles();
|
|
261
245
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (
|
|
267
|
-
this.optionalExtraSubscriptions.includes('fundingPaymentHistoryAccount')
|
|
268
|
-
) {
|
|
269
|
-
await this.fundingPaymentHistoryAccountSubscriber.unsubscribe();
|
|
270
|
-
}
|
|
246
|
+
this.isSubscribed = false;
|
|
247
|
+
}
|
|
271
248
|
|
|
272
|
-
|
|
273
|
-
|
|
249
|
+
async addBank(bankIndex: BN): Promise<boolean> {
|
|
250
|
+
if (this.bankAccountSubscribers.has(bankIndex.toNumber())) {
|
|
251
|
+
return true;
|
|
274
252
|
}
|
|
253
|
+
return this.subscribeToBankAccount(bankIndex);
|
|
254
|
+
}
|
|
275
255
|
|
|
276
|
-
|
|
277
|
-
|
|
256
|
+
async addMarket(marketIndex: BN): Promise<boolean> {
|
|
257
|
+
if (this.marketAccountSubscribers.has(marketIndex.toNumber())) {
|
|
258
|
+
return true;
|
|
278
259
|
}
|
|
260
|
+
return this.subscribeToMarketAccount(marketIndex);
|
|
261
|
+
}
|
|
279
262
|
|
|
280
|
-
|
|
281
|
-
|
|
263
|
+
async addOracle(oracleInfo: OracleInfo): Promise<boolean> {
|
|
264
|
+
if (this.oracleSubscribers.has(oracleInfo.publicKey.toString())) {
|
|
265
|
+
return true;
|
|
282
266
|
}
|
|
283
267
|
|
|
284
|
-
if (
|
|
285
|
-
|
|
268
|
+
if (oracleInfo.publicKey.equals(PublicKey.default)) {
|
|
269
|
+
return true;
|
|
286
270
|
}
|
|
287
271
|
|
|
288
|
-
this.
|
|
272
|
+
return this.subscribeToOracle(oracleInfo);
|
|
289
273
|
}
|
|
290
274
|
|
|
291
275
|
assertIsSubscribed(): void {
|
|
@@ -296,76 +280,42 @@ export class WebSocketClearingHouseAccountSubscriber
|
|
|
296
280
|
}
|
|
297
281
|
}
|
|
298
282
|
|
|
299
|
-
|
|
300
|
-
optionalSubscription: ClearingHouseAccountTypes
|
|
301
|
-
): void {
|
|
302
|
-
if (!this.isSubscribed) {
|
|
303
|
-
throw new NotSubscribedError(
|
|
304
|
-
'You must call `subscribe` before using this function'
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (!this.optionalExtraSubscriptions.includes(optionalSubscription)) {
|
|
309
|
-
throw new NotSubscribedError(
|
|
310
|
-
`You need to subscribe to the optional Clearing House account "${optionalSubscription}" to use this method`
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
public getStateAccount(): StateAccount {
|
|
283
|
+
public getStateAccountAndSlot(): DataAndSlot<StateAccount> {
|
|
316
284
|
this.assertIsSubscribed();
|
|
317
|
-
return this.stateAccountSubscriber.
|
|
285
|
+
return this.stateAccountSubscriber.dataAndSlot;
|
|
318
286
|
}
|
|
319
287
|
|
|
320
|
-
public
|
|
288
|
+
public getMarketAccountAndSlot(
|
|
289
|
+
marketIndex: BN
|
|
290
|
+
): DataAndSlot<MarketAccount> | undefined {
|
|
321
291
|
this.assertIsSubscribed();
|
|
322
|
-
return this.
|
|
292
|
+
return this.marketAccountSubscribers.get(marketIndex.toNumber())
|
|
293
|
+
.dataAndSlot;
|
|
323
294
|
}
|
|
324
295
|
|
|
325
|
-
public
|
|
326
|
-
this.
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
public getDepositHistoryAccount(): DepositHistoryAccount {
|
|
332
|
-
this.assertIsSubscribed();
|
|
333
|
-
this.assertOptionalIsSubscribed('depositHistoryAccount');
|
|
334
|
-
return this.depositHistoryAccountSubscriber.data;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
public getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount {
|
|
338
|
-
this.assertIsSubscribed();
|
|
339
|
-
this.assertOptionalIsSubscribed('fundingPaymentHistoryAccount');
|
|
340
|
-
return this.fundingPaymentHistoryAccountSubscriber.data;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
public getFundingRateHistoryAccount(): FundingRateHistoryAccount {
|
|
344
|
-
this.assertIsSubscribed();
|
|
345
|
-
this.assertOptionalIsSubscribed('fundingRateHistoryAccount');
|
|
346
|
-
return this.fundingRateHistoryAccountSubscriber.data;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
public getCurveHistoryAccount(): ExtendedCurveHistoryAccount {
|
|
350
|
-
this.assertIsSubscribed();
|
|
351
|
-
this.assertOptionalIsSubscribed('curveHistoryAccount');
|
|
352
|
-
return this.curveHistoryAccountSubscriber.data;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
public getLiquidationHistoryAccount(): LiquidationHistoryAccount {
|
|
356
|
-
this.assertIsSubscribed();
|
|
357
|
-
this.assertOptionalIsSubscribed('liquidationHistoryAccount');
|
|
358
|
-
return this.liquidationHistoryAccountSubscriber.data;
|
|
296
|
+
public getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[] {
|
|
297
|
+
return Array.from(this.marketAccountSubscribers.values()).map(
|
|
298
|
+
(subscriber) => subscriber.dataAndSlot
|
|
299
|
+
);
|
|
359
300
|
}
|
|
360
301
|
|
|
361
|
-
public
|
|
302
|
+
public getBankAccountAndSlot(
|
|
303
|
+
bankIndex: BN
|
|
304
|
+
): DataAndSlot<BankAccount> | undefined {
|
|
362
305
|
this.assertIsSubscribed();
|
|
363
|
-
this.
|
|
364
|
-
return this.orderHistoryAccountSubscriber.data;
|
|
306
|
+
return this.bankAccountSubscribers.get(bankIndex.toNumber()).dataAndSlot;
|
|
365
307
|
}
|
|
366
308
|
|
|
367
|
-
public
|
|
309
|
+
public getOraclePriceDataAndSlot(
|
|
310
|
+
oraclePublicKey: PublicKey
|
|
311
|
+
): DataAndSlot<OraclePriceData> | undefined {
|
|
368
312
|
this.assertIsSubscribed();
|
|
369
|
-
|
|
313
|
+
if (oraclePublicKey.equals(PublicKey.default)) {
|
|
314
|
+
return {
|
|
315
|
+
data: QUOTE_ORACLE_PRICE_DATA,
|
|
316
|
+
slot: 0,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
|
|
370
320
|
}
|
|
371
321
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DataAndSlot,
|
|
2
3
|
AccountSubscriber,
|
|
3
4
|
NotSubscribedError,
|
|
4
5
|
UserAccountEvents,
|
|
@@ -8,30 +9,21 @@ import { Program } from '@project-serum/anchor';
|
|
|
8
9
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
9
10
|
import { EventEmitter } from 'events';
|
|
10
11
|
import { PublicKey } from '@solana/web3.js';
|
|
11
|
-
import {
|
|
12
|
-
getUserAccountPublicKey,
|
|
13
|
-
getUserOrdersAccountPublicKey,
|
|
14
|
-
} from '../addresses';
|
|
15
12
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
16
|
-
import { UserAccount
|
|
17
|
-
import { ClearingHouseConfigType } from '../factory/clearingHouse';
|
|
13
|
+
import { UserAccount } from '../types';
|
|
18
14
|
|
|
19
15
|
export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
20
16
|
isSubscribed: boolean;
|
|
21
17
|
program: Program;
|
|
22
18
|
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
23
|
-
|
|
19
|
+
userAccountPublicKey: PublicKey;
|
|
24
20
|
|
|
25
21
|
userDataAccountSubscriber: AccountSubscriber<UserAccount>;
|
|
26
|
-
userPositionsAccountSubscriber: AccountSubscriber<UserPositionsAccount>;
|
|
27
|
-
userOrdersAccountSubscriber: AccountSubscriber<UserOrdersAccount>;
|
|
28
|
-
|
|
29
|
-
type: ClearingHouseConfigType = 'websocket';
|
|
30
22
|
|
|
31
|
-
public constructor(program: Program,
|
|
23
|
+
public constructor(program: Program, userAccountPublicKey: PublicKey) {
|
|
32
24
|
this.isSubscribed = false;
|
|
33
25
|
this.program = program;
|
|
34
|
-
this.
|
|
26
|
+
this.userAccountPublicKey = userAccountPublicKey;
|
|
35
27
|
this.eventEmitter = new EventEmitter();
|
|
36
28
|
}
|
|
37
29
|
|
|
@@ -40,62 +32,23 @@ export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
40
32
|
return true;
|
|
41
33
|
}
|
|
42
34
|
|
|
43
|
-
const userPublicKey = await getUserAccountPublicKey(
|
|
44
|
-
this.program.programId,
|
|
45
|
-
this.authority
|
|
46
|
-
);
|
|
47
35
|
this.userDataAccountSubscriber = new WebSocketAccountSubscriber(
|
|
48
36
|
'user',
|
|
49
37
|
this.program,
|
|
50
|
-
|
|
38
|
+
this.userAccountPublicKey
|
|
51
39
|
);
|
|
52
40
|
await this.userDataAccountSubscriber.subscribe((data: UserAccount) => {
|
|
53
|
-
this.eventEmitter.emit('
|
|
41
|
+
this.eventEmitter.emit('userAccountUpdate', data);
|
|
54
42
|
this.eventEmitter.emit('update');
|
|
55
43
|
});
|
|
56
44
|
|
|
57
|
-
const userAccountData = this.userDataAccountSubscriber.data;
|
|
58
|
-
this.userPositionsAccountSubscriber = new WebSocketAccountSubscriber(
|
|
59
|
-
'userPositions',
|
|
60
|
-
this.program,
|
|
61
|
-
userAccountData.positions
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
await this.userPositionsAccountSubscriber.subscribe(
|
|
65
|
-
(data: UserPositionsAccount) => {
|
|
66
|
-
this.eventEmitter.emit('userPositionsData', data);
|
|
67
|
-
this.eventEmitter.emit('update');
|
|
68
|
-
}
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
const userOrdersPublicKey = await getUserOrdersAccountPublicKey(
|
|
72
|
-
this.program.programId,
|
|
73
|
-
userPublicKey
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
this.userOrdersAccountSubscriber = new WebSocketAccountSubscriber(
|
|
77
|
-
'userOrders',
|
|
78
|
-
this.program,
|
|
79
|
-
userOrdersPublicKey
|
|
80
|
-
);
|
|
81
|
-
await this.userOrdersAccountSubscriber.subscribe(
|
|
82
|
-
(data: UserOrdersAccount) => {
|
|
83
|
-
this.eventEmitter.emit('userOrdersData', data);
|
|
84
|
-
this.eventEmitter.emit('update');
|
|
85
|
-
}
|
|
86
|
-
);
|
|
87
|
-
|
|
88
45
|
this.eventEmitter.emit('update');
|
|
89
46
|
this.isSubscribed = true;
|
|
90
47
|
return true;
|
|
91
48
|
}
|
|
92
49
|
|
|
93
50
|
async fetch(): Promise<void> {
|
|
94
|
-
await Promise.all([
|
|
95
|
-
this.userDataAccountSubscriber.fetch(),
|
|
96
|
-
this.userPositionsAccountSubscriber.fetch(),
|
|
97
|
-
this.userOrdersAccountSubscriber.fetch(),
|
|
98
|
-
]);
|
|
51
|
+
await Promise.all([this.userDataAccountSubscriber.fetch()]);
|
|
99
52
|
}
|
|
100
53
|
|
|
101
54
|
async unsubscribe(): Promise<void> {
|
|
@@ -103,11 +56,7 @@ export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
103
56
|
return;
|
|
104
57
|
}
|
|
105
58
|
|
|
106
|
-
await Promise.all([
|
|
107
|
-
this.userDataAccountSubscriber.unsubscribe(),
|
|
108
|
-
this.userPositionsAccountSubscriber.unsubscribe(),
|
|
109
|
-
await this.userOrdersAccountSubscriber.unsubscribe(),
|
|
110
|
-
]);
|
|
59
|
+
await Promise.all([this.userDataAccountSubscriber.unsubscribe()]);
|
|
111
60
|
|
|
112
61
|
this.isSubscribed = false;
|
|
113
62
|
}
|
|
@@ -120,17 +69,8 @@ export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
120
69
|
}
|
|
121
70
|
}
|
|
122
71
|
|
|
123
|
-
public
|
|
72
|
+
public getUserAccountAndSlot(): DataAndSlot<UserAccount> {
|
|
124
73
|
this.assertIsSubscribed();
|
|
125
|
-
return this.userDataAccountSubscriber.
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
public getUserPositionsAccount(): UserPositionsAccount {
|
|
129
|
-
this.assertIsSubscribed();
|
|
130
|
-
return this.userPositionsAccountSubscriber.data;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
public getUserOrdersAccount(): UserOrdersAccount {
|
|
134
|
-
return this.userOrdersAccountSubscriber.data;
|
|
74
|
+
return this.userDataAccountSubscriber.dataAndSlot;
|
|
135
75
|
}
|
|
136
76
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { BN } from '@project-serum/anchor';
|
|
3
|
+
import { getMarketPublicKey } from './pda';
|
|
4
|
+
|
|
5
|
+
const CACHE = new Map<string, PublicKey>();
|
|
6
|
+
export async function getMarketAddress(
|
|
7
|
+
programId: PublicKey,
|
|
8
|
+
marketIndex: BN
|
|
9
|
+
): Promise<PublicKey> {
|
|
10
|
+
const cacheKey = `${programId.toString()}-${marketIndex.toString()}`;
|
|
11
|
+
if (CACHE.has(cacheKey)) {
|
|
12
|
+
return CACHE.get(cacheKey);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const publicKey = await getMarketPublicKey(programId, marketIndex);
|
|
16
|
+
CACHE.set(cacheKey, publicKey);
|
|
17
|
+
return publicKey;
|
|
18
|
+
}
|