@velocity-exchange/sdk 0.4.0 → 0.6.1

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.
Files changed (325) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +52 -0
  3. package/lib/browser/adminClient.js +97 -0
  4. package/lib/browser/config.js +6 -7
  5. package/lib/browser/constants/numericConstants.d.ts +1 -1
  6. package/lib/browser/constants/numericConstants.js +1 -1
  7. package/lib/browser/decode/user.js +5 -1
  8. package/lib/browser/idl/velocity.d.ts +191 -15
  9. package/lib/browser/idl/velocity.json +192 -16
  10. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
  11. package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
  12. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  13. package/lib/browser/types.d.ts +6 -0
  14. package/lib/browser/user.d.ts +20 -3
  15. package/lib/browser/user.js +52 -4
  16. package/lib/browser/velocityClient.d.ts +46 -10
  17. package/lib/browser/velocityClient.js +107 -35
  18. package/lib/node/adminClient.d.ts +52 -0
  19. package/lib/node/adminClient.d.ts.map +1 -1
  20. package/lib/node/adminClient.js +97 -0
  21. package/lib/node/config.d.ts.map +1 -1
  22. package/lib/node/config.js +6 -7
  23. package/lib/node/constants/numericConstants.d.ts +1 -1
  24. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  25. package/lib/node/constants/numericConstants.js +1 -1
  26. package/lib/node/decode/user.d.ts.map +1 -1
  27. package/lib/node/decode/user.js +5 -1
  28. package/lib/node/idl/velocity.d.ts +191 -15
  29. package/lib/node/idl/velocity.d.ts.map +1 -1
  30. package/lib/node/idl/velocity.json +192 -16
  31. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
  32. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  33. package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
  34. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  35. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  36. package/lib/node/types.d.ts +6 -0
  37. package/lib/node/types.d.ts.map +1 -1
  38. package/lib/node/user.d.ts +20 -3
  39. package/lib/node/user.d.ts.map +1 -1
  40. package/lib/node/user.js +52 -4
  41. package/lib/node/velocityClient.d.ts +46 -10
  42. package/lib/node/velocityClient.d.ts.map +1 -1
  43. package/lib/node/velocityClient.js +107 -35
  44. package/package.json +7 -3
  45. package/.prettierignore +0 -1
  46. package/CHANGELOG.md +0 -132
  47. package/build-browser.js +0 -58
  48. package/bunfig.toml +0 -3
  49. package/esbuild-shims.js +0 -12
  50. package/scripts/deposit-isolated-positions.ts +0 -110
  51. package/scripts/find-flagged-users.ts +0 -213
  52. package/scripts/grpc-client-test-comparison.ts +0 -372
  53. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  54. package/scripts/postbuild.js +0 -95
  55. package/scripts/single-grpc-client-test.ts +0 -284
  56. package/scripts/withdraw-isolated-positions.ts +0 -174
  57. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  58. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  59. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  60. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  61. package/src/accounts/bulkAccountLoader.ts +0 -358
  62. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  63. package/src/accounts/bulkUserSubscription.ts +0 -39
  64. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  65. package/src/accounts/fetch.ts +0 -200
  66. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  67. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  68. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  69. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  70. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  71. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  72. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  73. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  74. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  75. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  76. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  77. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  78. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  79. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  80. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  81. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  82. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  83. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  84. package/src/accounts/testBulkAccountLoader.ts +0 -59
  85. package/src/accounts/types.ts +0 -428
  86. package/src/accounts/utils.ts +0 -90
  87. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  88. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  89. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  90. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  91. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  92. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  93. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  94. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  95. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  96. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  97. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  98. package/src/addresses/marketAddresses.ts +0 -28
  99. package/src/addresses/pda.ts +0 -620
  100. package/src/adminClient.ts +0 -8136
  101. package/src/assert/assert.ts +0 -5
  102. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  103. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  104. package/src/auctionSubscriber/index.ts +0 -9
  105. package/src/auctionSubscriber/types.ts +0 -30
  106. package/src/bankrun/bankrunConnection.ts +0 -630
  107. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  108. package/src/blockhashSubscriber/index.ts +0 -6
  109. package/src/blockhashSubscriber/types.ts +0 -13
  110. package/src/clock/clockSubscriber.ts +0 -146
  111. package/src/config.ts +0 -312
  112. package/src/constants/index.ts +0 -9
  113. package/src/constants/numericConstants.ts +0 -194
  114. package/src/constants/perpMarkets.ts +0 -127
  115. package/src/constants/spotMarkets.ts +0 -104
  116. package/src/constants/txConstants.ts +0 -2
  117. package/src/constituentMap/constituentMap.ts +0 -305
  118. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  119. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  120. package/src/core/VelocityCore.ts +0 -606
  121. package/src/core/index.ts +0 -12
  122. package/src/core/instructions/deposit.ts +0 -64
  123. package/src/core/instructions/fill.ts +0 -51
  124. package/src/core/instructions/funding.ts +0 -33
  125. package/src/core/instructions/liquidation.ts +0 -55
  126. package/src/core/instructions/orders.ts +0 -84
  127. package/src/core/instructions/perpOrders.ts +0 -312
  128. package/src/core/instructions/settlement.ts +0 -40
  129. package/src/core/instructions/trigger.ts +0 -41
  130. package/src/core/instructions/withdraw.ts +0 -65
  131. package/src/core/remainingAccounts.ts +0 -320
  132. package/src/core/signedMsg.ts +0 -109
  133. package/src/decode/customCoder.ts +0 -148
  134. package/src/decode/user.ts +0 -401
  135. package/src/dlob/DLOB.ts +0 -2793
  136. package/src/dlob/DLOBNode.ts +0 -305
  137. package/src/dlob/DLOBSubscriber.ts +0 -269
  138. package/src/dlob/NodeList.ts +0 -244
  139. package/src/dlob/orderBookLevels.ts +0 -695
  140. package/src/dlob/types.ts +0 -37
  141. package/src/events/eventList.ts +0 -114
  142. package/src/events/eventSubscriber.ts +0 -521
  143. package/src/events/eventsServerLogProvider.ts +0 -189
  144. package/src/events/fetchLogs.ts +0 -219
  145. package/src/events/parse.ts +0 -271
  146. package/src/events/pollingLogProvider.ts +0 -113
  147. package/src/events/sort.ts +0 -51
  148. package/src/events/txEventCache.ts +0 -92
  149. package/src/events/types.ts +0 -337
  150. package/src/events/webSocketLogProvider.ts +0 -152
  151. package/src/factory/bigNum.ts +0 -709
  152. package/src/factory/oracleClient.ts +0 -73
  153. package/src/idl/pyth.json +0 -142
  154. package/src/idl/pyth.ts +0 -97
  155. package/src/idl/pyth_solana_receiver.json +0 -628
  156. package/src/idl/token_faucet.json +0 -229
  157. package/src/idl/token_faucet.ts +0 -197
  158. package/src/idl/velocity.json +0 -23974
  159. package/src/idl/velocity.ts +0 -23980
  160. package/src/index.ts +0 -150
  161. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  162. package/src/isomorphic/README.md +0 -19
  163. package/src/isomorphic/anchor.browser.ts +0 -44
  164. package/src/isomorphic/anchor.node.ts +0 -1
  165. package/src/isomorphic/anchor.ts +0 -1
  166. package/src/isomorphic/anchor29.browser.ts +0 -24
  167. package/src/isomorphic/anchor29.node.ts +0 -1
  168. package/src/isomorphic/anchor29.ts +0 -1
  169. package/src/isomorphic/grpc.browser.ts +0 -4
  170. package/src/isomorphic/grpc.node.ts +0 -130
  171. package/src/isomorphic/grpc.ts +0 -1
  172. package/src/jupiter/jupiterClient.ts +0 -502
  173. package/src/keypair.ts +0 -32
  174. package/src/margin/README.md +0 -138
  175. package/src/marginCalculation.ts +0 -407
  176. package/src/marinade/idl/idl.json +0 -1962
  177. package/src/marinade/index.ts +0 -73
  178. package/src/marinade/types.ts +0 -3925
  179. package/src/math/amm.ts +0 -1758
  180. package/src/math/auction.ts +0 -480
  181. package/src/math/bankruptcy.ts +0 -138
  182. package/src/math/builder.ts +0 -130
  183. package/src/math/conversion.ts +0 -45
  184. package/src/math/exchangeStatus.ts +0 -261
  185. package/src/math/funding.ts +0 -498
  186. package/src/math/insurance.ts +0 -171
  187. package/src/math/liquidation.ts +0 -433
  188. package/src/math/margin.ts +0 -327
  189. package/src/math/market.ts +0 -487
  190. package/src/math/oracles.ts +0 -477
  191. package/src/math/orders.ts +0 -500
  192. package/src/math/position.ts +0 -381
  193. package/src/math/repeg.ts +0 -223
  194. package/src/math/spotBalance.ts +0 -996
  195. package/src/math/spotMarket.ts +0 -115
  196. package/src/math/spotPosition.ts +0 -263
  197. package/src/math/state.ts +0 -71
  198. package/src/math/superStake.ts +0 -602
  199. package/src/math/tiers.ts +0 -73
  200. package/src/math/trade.ts +0 -879
  201. package/src/math/utils.ts +0 -183
  202. package/src/memcmp.ts +0 -279
  203. package/src/oracles/oracleClientCache.ts +0 -41
  204. package/src/oracles/oracleId.ts +0 -99
  205. package/src/oracles/prelaunchOracleClient.ts +0 -63
  206. package/src/oracles/pythClient.ts +0 -125
  207. package/src/oracles/pythLazerClient.ts +0 -141
  208. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  209. package/src/oracles/strictOraclePrice.ts +0 -40
  210. package/src/oracles/types.ts +0 -82
  211. package/src/oracles/utils.ts +0 -45
  212. package/src/orderParams.ts +0 -117
  213. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  214. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  215. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  216. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  217. package/src/orderSubscriber/index.ts +0 -7
  218. package/src/orderSubscriber/types.ts +0 -64
  219. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  220. package/src/priorityFee/averageStrategy.ts +0 -13
  221. package/src/priorityFee/ewmaStrategy.ts +0 -51
  222. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  223. package/src/priorityFee/index.ts +0 -16
  224. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  225. package/src/priorityFee/maxStrategy.ts +0 -8
  226. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  227. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  228. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  229. package/src/priorityFee/types.ts +0 -82
  230. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  231. package/src/pyth/constants.ts +0 -9
  232. package/src/pyth/index.ts +0 -15
  233. package/src/pyth/pythLazerSubscriber.ts +0 -365
  234. package/src/pyth/types.ts +0 -4451
  235. package/src/pyth/utils.ts +0 -13
  236. package/src/slot/SlotSubscriber.ts +0 -126
  237. package/src/slot/SlothashSubscriber.ts +0 -163
  238. package/src/swap/UnifiedSwapClient.ts +0 -315
  239. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  240. package/src/swift/index.ts +0 -10
  241. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  242. package/src/swift/swiftOrderSubscriber.ts +0 -351
  243. package/src/testClient.ts +0 -42
  244. package/src/titan/titanClient.ts +0 -438
  245. package/src/token/index.ts +0 -13
  246. package/src/tokenFaucet.ts +0 -296
  247. package/src/tx/baseTxSender.ts +0 -651
  248. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  249. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  250. package/src/tx/blockhashFetcher/types.ts +0 -9
  251. package/src/tx/fastSingleTxSender.ts +0 -200
  252. package/src/tx/forwardOnlyTxSender.ts +0 -193
  253. package/src/tx/priorityFeeCalculator.ts +0 -117
  254. package/src/tx/reportTransactionError.ts +0 -176
  255. package/src/tx/retryTxSender.ts +0 -177
  256. package/src/tx/txHandler.ts +0 -1009
  257. package/src/tx/txParamProcessor.ts +0 -225
  258. package/src/tx/types.ts +0 -117
  259. package/src/tx/utils.ts +0 -133
  260. package/src/tx/whileValidTxSender.ts +0 -377
  261. package/src/types.ts +0 -2575
  262. package/src/user.ts +0 -5316
  263. package/src/userConfig.ts +0 -38
  264. package/src/userMap/PollingSubscription.ts +0 -61
  265. package/src/userMap/WebsocketSubscription.ts +0 -93
  266. package/src/userMap/grpcSubscription.ts +0 -93
  267. package/src/userMap/referrerMap.ts +0 -360
  268. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  269. package/src/userMap/userMap.ts +0 -784
  270. package/src/userMap/userMapConfig.ts +0 -82
  271. package/src/userMap/userStatsMap.ts +0 -393
  272. package/src/userName.ts +0 -37
  273. package/src/userStats.ts +0 -159
  274. package/src/userStatsConfig.ts +0 -35
  275. package/src/util/TransactionConfirmationManager.ts +0 -333
  276. package/src/util/chainClock.ts +0 -65
  277. package/src/util/computeUnits.ts +0 -101
  278. package/src/util/digest.ts +0 -33
  279. package/src/util/ed25519Utils.ts +0 -95
  280. package/src/util/promiseTimeout.ts +0 -23
  281. package/src/velocityClient.ts +0 -14802
  282. package/src/velocityClientConfig.ts +0 -119
  283. package/src/wallet.ts +0 -91
  284. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  285. package/tests/VelocityCore/decode.test.ts +0 -16
  286. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  287. package/tests/VelocityCore/instructions.test.ts +0 -46
  288. package/tests/VelocityCore/pdas.test.ts +0 -30
  289. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  290. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  291. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  292. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  293. package/tests/amm/test.ts +0 -2402
  294. package/tests/auctions/test.ts +0 -81
  295. package/tests/bn/test.ts +0 -355
  296. package/tests/builder/builderFee.test.ts +0 -42
  297. package/tests/ci/verifyConstants.ts +0 -393
  298. package/tests/decode/test.ts +0 -262
  299. package/tests/decode/userAccountBufferStrings.ts +0 -102
  300. package/tests/dlob/helpers.ts +0 -748
  301. package/tests/dlob/test.ts +0 -6969
  302. package/tests/dlob/tickSizeStandardization.ts +0 -545
  303. package/tests/events/parseLogsForCuUsage.ts +0 -139
  304. package/tests/exchangeStatus/test.ts +0 -45
  305. package/tests/insurance/test.ts +0 -40
  306. package/tests/liquidation/test.ts +0 -125
  307. package/tests/oracles/mmOracleGate.test.ts +0 -379
  308. package/tests/oracles/pythPegSnap.test.ts +0 -76
  309. package/tests/sdkParity/enumParity.test.ts +0 -84
  310. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  311. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  312. package/tests/spot/test.ts +0 -281
  313. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  314. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  315. package/tests/tx/priorityFeeCalculator.ts +0 -77
  316. package/tests/tx/priorityFeeStrategy.ts +0 -95
  317. package/tests/user/bankruptcy.ts +0 -165
  318. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  319. package/tests/user/getMarginCalculation.ts +0 -586
  320. package/tests/user/helpers.ts +0 -184
  321. package/tests/user/liquidations.ts +0 -129
  322. package/tests/user/marginCalculations.test.ts +0 -321
  323. package/tests/user/test.ts +0 -833
  324. package/tsconfig.browser.json +0 -18
  325. package/tsconfig.json +0 -36
@@ -1,774 +0,0 @@
1
- import {
2
- AccountToPoll,
3
- DataAndSlot,
4
- DelistedMarketSetting,
5
- VelocityClientAccountEvents,
6
- VelocityClientAccountSubscriber,
7
- NotSubscribedError,
8
- OraclesToPoll,
9
- } from './types';
10
- import StrictEventEmitter from 'strict-event-emitter-types';
11
- import { EventEmitter } from 'events';
12
- import {
13
- PerpMarketAccount,
14
- SpotMarketAccount,
15
- StateAccount,
16
- UserAccount,
17
- OracleSource,
18
- } from '../types';
19
- import {
20
- getVelocityStateAccountPublicKey,
21
- getPerpMarketPublicKey,
22
- getSpotMarketPublicKey,
23
- } from '../addresses/pda';
24
- import { BulkAccountLoader } from './bulkAccountLoader';
25
- import { findDelistedPerpMarketsAndOracles } from './utils';
26
- import { PublicKey } from '@solana/web3.js';
27
- import { OracleInfo, OraclePriceData } from '../oracles/types';
28
- import { OracleClientCache } from '../oracles/oracleClientCache';
29
- import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
30
- import { findAllMarketAndOracles, VelocityProgram } from '../config';
31
- import { getOracleId } from '../oracles/oracleId';
32
-
33
- const ORACLE_DEFAULT_ID = getOracleId(
34
- PublicKey.default,
35
- OracleSource.QUOTE_ASSET
36
- );
37
-
38
- /**
39
- * `VelocityClientAccountSubscriber` that batches the `State`, every tracked `PerpMarket`/
40
- * `SpotMarket`, and every tracked oracle behind a single `BulkAccountLoader` instead of one
41
- * WebSocket subscription per account. Cheaper on connection count at the cost of update latency
42
- * bounded by the loader's poll interval. `subscribe()` retries the initial load up to 5 times
43
- * before giving up (returning `false`) if the `State` account never appears — `didSubscriptionSucceed`
44
- * checks only for `state`, since market/oracle data can be added incrementally afterward via
45
- * `addPerpMarket`/`addSpotMarket`/`addOracle`.
46
- */
47
- export class PollingVelocityClientAccountSubscriber
48
- implements VelocityClientAccountSubscriber
49
- {
50
- isSubscribed: boolean;
51
- program: VelocityProgram;
52
- perpMarketIndexes: number[];
53
- spotMarketIndexes: number[];
54
- oracleInfos: OracleInfo[];
55
- oracleClientCache = new OracleClientCache();
56
-
57
- shouldFindAllMarketsAndOracles: boolean;
58
-
59
- eventEmitter: StrictEventEmitter<EventEmitter, VelocityClientAccountEvents>;
60
-
61
- accountLoader: BulkAccountLoader;
62
- accountsToPoll = new Map<string, AccountToPoll>();
63
- oraclesToPoll = new Map<string, OraclesToPoll>();
64
- errorCallbackId?: string;
65
-
66
- state?: DataAndSlot<StateAccount>;
67
- perpMarket = new Map<number, DataAndSlot<PerpMarketAccount>>();
68
- perpOracleMap = new Map<number, PublicKey>();
69
- perpOracleStringMap = new Map<number, string>();
70
- spotMarket = new Map<number, DataAndSlot<SpotMarketAccount>>();
71
- spotOracleMap = new Map<number, PublicKey>();
72
- spotOracleStringMap = new Map<number, string>();
73
- oracles = new Map<string, DataAndSlot<OraclePriceData>>();
74
- user?: DataAndSlot<UserAccount>;
75
- delistedMarketSetting: DelistedMarketSetting;
76
-
77
- private isSubscribing = false;
78
- private subscriptionPromiseResolver: (val: boolean) => void = () => {};
79
- private subscriptionPromise: Promise<boolean> = new Promise((res) => {
80
- this.subscriptionPromiseResolver = res;
81
- });
82
-
83
- /**
84
- * @param program Anchor program used to derive PDAs, decode accounts, and resolve oracle clients.
85
- * @param accountLoader Shared `BulkAccountLoader` all state/market/oracle accounts are registered with.
86
- * @param perpMarketIndexes Perp market indexes to track, if `shouldFindAllMarketsAndOracles` is false.
87
- * @param spotMarketIndexes Spot market indexes to track, if `shouldFindAllMarketsAndOracles` is false.
88
- * @param oracleInfos Oracles to track up front, if `shouldFindAllMarketsAndOracles` is false.
89
- * @param shouldFindAllMarketsAndOracles If true, `subscribe()` first discovers every market/oracle from on-chain state, ignoring the index/info args above.
90
- * @param delistedMarketSetting Behavior applied to delisted perp markets/oracles after subscribing; see `DelistedMarketSetting`.
91
- */
92
- public constructor(
93
- program: VelocityProgram,
94
- accountLoader: BulkAccountLoader,
95
- perpMarketIndexes: number[],
96
- spotMarketIndexes: number[],
97
- oracleInfos: OracleInfo[],
98
- shouldFindAllMarketsAndOracles: boolean,
99
- delistedMarketSetting: DelistedMarketSetting
100
- ) {
101
- this.isSubscribed = false;
102
- this.program = program;
103
- this.eventEmitter = new EventEmitter();
104
- this.accountLoader = accountLoader;
105
- this.perpMarketIndexes = perpMarketIndexes;
106
- this.spotMarketIndexes = spotMarketIndexes;
107
- this.oracleInfos = oracleInfos;
108
- this.shouldFindAllMarketsAndOracles = shouldFindAllMarketsAndOracles;
109
- this.delistedMarketSetting = delistedMarketSetting;
110
- }
111
-
112
- /**
113
- * Registers state/market/oracle accounts with the `BulkAccountLoader` and retries the initial
114
- * load up to 5 times until the `State` account has appeared. Idempotent: a no-op if already
115
- * subscribed, and concurrent calls while a subscribe is in flight share the same result via
116
- * `subscriptionPromise` rather than issuing duplicate loads.
117
- * @returns `true` if `State` account data loaded within the retry budget, `false` otherwise.
118
- */
119
- public async subscribe(): Promise<boolean> {
120
- if (this.isSubscribed) {
121
- return true;
122
- }
123
-
124
- if (this.isSubscribing) {
125
- return await this.subscriptionPromise;
126
- }
127
-
128
- this.isSubscribing = true;
129
-
130
- this.subscriptionPromise = new Promise((res) => {
131
- this.subscriptionPromiseResolver = res;
132
- });
133
-
134
- if (this.shouldFindAllMarketsAndOracles) {
135
- const { perpMarketIndexes, spotMarketIndexes, oracleInfos } =
136
- await findAllMarketAndOracles(this.program);
137
- this.perpMarketIndexes = perpMarketIndexes;
138
- this.spotMarketIndexes = spotMarketIndexes;
139
- this.oracleInfos = oracleInfos;
140
- }
141
-
142
- await this.updateAccountsToPoll();
143
- this.updateOraclesToPoll();
144
- await this.addToAccountLoader();
145
-
146
- let subscriptionSucceeded = false;
147
- let retries = 0;
148
- while (!subscriptionSucceeded && retries < 5) {
149
- await this.fetch();
150
- subscriptionSucceeded = this.didSubscriptionSucceed();
151
- retries++;
152
- }
153
-
154
- if (subscriptionSucceeded) {
155
- this.eventEmitter.emit('update');
156
- }
157
-
158
- this.handleDelistedMarkets();
159
-
160
- await Promise.all([this.setPerpOracleMap(), this.setSpotOracleMap()]);
161
-
162
- this.isSubscribing = false;
163
- this.isSubscribed = subscriptionSucceeded;
164
- this.subscriptionPromiseResolver(subscriptionSucceeded);
165
-
166
- return subscriptionSucceeded;
167
- }
168
-
169
- async updateAccountsToPoll(): Promise<void> {
170
- if (this.accountsToPoll.size > 0) {
171
- return;
172
- }
173
-
174
- const statePublicKey = await getVelocityStateAccountPublicKey(
175
- this.program.programId
176
- );
177
-
178
- this.accountsToPoll.set(statePublicKey.toString(), {
179
- key: 'state',
180
- publicKey: statePublicKey,
181
- eventType: 'stateAccountUpdate',
182
- });
183
-
184
- await Promise.all([
185
- this.updatePerpMarketAccountsToPoll(),
186
- this.updateSpotMarketAccountsToPoll(),
187
- ]);
188
- }
189
-
190
- async updatePerpMarketAccountsToPoll(): Promise<boolean> {
191
- await Promise.all(
192
- this.perpMarketIndexes.map((marketIndex) => {
193
- return this.addPerpMarketAccountToPoll(marketIndex);
194
- })
195
- );
196
- return true;
197
- }
198
-
199
- async addPerpMarketAccountToPoll(marketIndex: number): Promise<boolean> {
200
- const perpMarketPublicKey = await getPerpMarketPublicKey(
201
- this.program.programId,
202
- marketIndex
203
- );
204
-
205
- this.accountsToPoll.set(perpMarketPublicKey.toString(), {
206
- key: 'perpMarket',
207
- publicKey: perpMarketPublicKey,
208
- eventType: 'perpMarketAccountUpdate',
209
- mapKey: marketIndex,
210
- });
211
-
212
- return true;
213
- }
214
-
215
- async updateSpotMarketAccountsToPoll(): Promise<boolean> {
216
- await Promise.all(
217
- this.spotMarketIndexes.map(async (marketIndex) => {
218
- await this.addSpotMarketAccountToPoll(marketIndex);
219
- })
220
- );
221
-
222
- return true;
223
- }
224
-
225
- async addSpotMarketAccountToPoll(marketIndex: number): Promise<boolean> {
226
- const marketPublicKey = await getSpotMarketPublicKey(
227
- this.program.programId,
228
- marketIndex
229
- );
230
-
231
- this.accountsToPoll.set(marketPublicKey.toString(), {
232
- key: 'spotMarket',
233
- publicKey: marketPublicKey,
234
- eventType: 'spotMarketAccountUpdate',
235
- mapKey: marketIndex,
236
- });
237
- return true;
238
- }
239
-
240
- updateOraclesToPoll(): boolean {
241
- for (const oracleInfo of this.oracleInfos) {
242
- if (!oracleInfo.publicKey.equals(PublicKey.default)) {
243
- this.addOracleToPoll(oracleInfo);
244
- }
245
- }
246
-
247
- return true;
248
- }
249
-
250
- addOracleToPoll(oracleInfo: OracleInfo): boolean {
251
- this.oraclesToPoll.set(
252
- getOracleId(oracleInfo.publicKey, oracleInfo.source),
253
- {
254
- publicKey: oracleInfo.publicKey,
255
- source: oracleInfo.source,
256
- }
257
- );
258
-
259
- return true;
260
- }
261
- async addToAccountLoader(): Promise<void> {
262
- const accountPromises = [];
263
- for (const [_, accountToPoll] of this.accountsToPoll) {
264
- accountPromises.push(this.addAccountToAccountLoader(accountToPoll));
265
- }
266
-
267
- const oraclePromises = [];
268
- for (const [_, oracleToPoll] of this.oraclesToPoll) {
269
- oraclePromises.push(this.addOracleToAccountLoader(oracleToPoll));
270
- }
271
-
272
- await Promise.all([...accountPromises, ...oraclePromises]);
273
-
274
- this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
275
- this.eventEmitter.emit('error', error);
276
- });
277
- }
278
-
279
- /**
280
- * Routes a freshly-decoded account into the correct container based on
281
- * its poll key. Replaces dynamic `this[key]` indexing with explicit,
282
- * type-checked dispatch.
283
- */
284
- private storeDecodedAccount(
285
- accountToPoll: AccountToPoll,
286
- account: any,
287
- slot: number
288
- ): void {
289
- const dataAndSlot = { data: account, slot };
290
- switch (accountToPoll.key) {
291
- case 'perpMarket':
292
- if (accountToPoll.mapKey !== undefined) {
293
- this.perpMarket.set(accountToPoll.mapKey, dataAndSlot);
294
- }
295
- break;
296
- case 'spotMarket':
297
- if (accountToPoll.mapKey !== undefined) {
298
- this.spotMarket.set(accountToPoll.mapKey, dataAndSlot);
299
- }
300
- break;
301
- case 'state':
302
- this.state = dataAndSlot;
303
- break;
304
- default: {
305
- const _exhaustive: never = accountToPoll.key;
306
- throw new Error(`Unhandled account poll key: ${String(_exhaustive)}`);
307
- }
308
- }
309
- }
310
-
311
- async addAccountToAccountLoader(accountToPoll: AccountToPoll): Promise<void> {
312
- accountToPoll.callbackId = await this.accountLoader.addAccount(
313
- accountToPoll.publicKey,
314
- (buffer: Buffer, slot: number) => {
315
- if (!buffer) return;
316
-
317
- const account = this.program.coder.accounts.decodeUnchecked(
318
- accountToPoll.key,
319
- buffer
320
- );
321
- this.storeDecodedAccount(accountToPoll, account, slot);
322
-
323
- // @ts-ignore
324
- this.eventEmitter.emit(accountToPoll.eventType, account);
325
- this.eventEmitter.emit('update');
326
-
327
- if (!this.isSubscribed) {
328
- this.isSubscribed = this.didSubscriptionSucceed();
329
- }
330
- }
331
- );
332
- }
333
-
334
- async addOracleToAccountLoader(oracleToPoll: OraclesToPoll): Promise<void> {
335
- const oracleClient = this.oracleClientCache.get(
336
- oracleToPoll.source,
337
- this.program.provider.connection,
338
- this.program
339
- );
340
-
341
- const oracleId = getOracleId(oracleToPoll.publicKey, oracleToPoll.source);
342
-
343
- oracleToPoll.callbackId = await this.accountLoader.addAccount(
344
- oracleToPoll.publicKey,
345
- (buffer: Buffer, slot: number) => {
346
- if (!buffer) return;
347
- if (!oracleClient) return;
348
-
349
- const oraclePriceData =
350
- oracleClient.getOraclePriceDataFromBuffer(buffer);
351
- const dataAndSlot = {
352
- data: oraclePriceData,
353
- slot,
354
- };
355
-
356
- this.oracles.set(oracleId, dataAndSlot);
357
-
358
- this.eventEmitter.emit(
359
- 'oraclePriceUpdate',
360
- oracleToPoll.publicKey,
361
- oracleToPoll.source,
362
- oraclePriceData
363
- );
364
- this.eventEmitter.emit('update');
365
- }
366
- );
367
- }
368
-
369
- /** Forces the shared `BulkAccountLoader` to load, then re-decodes every tracked state/market/oracle account from the loader's cached buffers into this subscriber's maps. */
370
- public async fetch(): Promise<void> {
371
- await this.accountLoader.load();
372
- for (const [_, accountToPoll] of this.accountsToPoll) {
373
- const bufferAndSlot = this.accountLoader.getBufferAndSlot(
374
- accountToPoll.publicKey
375
- );
376
-
377
- if (!bufferAndSlot) {
378
- continue;
379
- }
380
-
381
- const { buffer, slot } = bufferAndSlot;
382
-
383
- if (buffer) {
384
- const account = this.program.coder.accounts.decodeUnchecked(
385
- accountToPoll.key,
386
- buffer
387
- );
388
- this.storeDecodedAccount(accountToPoll, account, slot);
389
- }
390
- }
391
-
392
- for (const [_, oracleToPoll] of this.oraclesToPoll) {
393
- const bufferAndSlot = this.accountLoader.getBufferAndSlot(
394
- oracleToPoll.publicKey
395
- );
396
-
397
- if (!bufferAndSlot) {
398
- continue;
399
- }
400
-
401
- const { buffer, slot } = bufferAndSlot;
402
-
403
- if (buffer) {
404
- const oracleClient = this.oracleClientCache.get(
405
- oracleToPoll.source,
406
- this.program.provider.connection,
407
- this.program
408
- );
409
- if (!oracleClient) {
410
- continue;
411
- }
412
- const oraclePriceData =
413
- oracleClient.getOraclePriceDataFromBuffer(buffer);
414
- this.oracles.set(
415
- getOracleId(oracleToPoll.publicKey, oracleToPoll.source),
416
- {
417
- data: oraclePriceData,
418
- slot,
419
- }
420
- );
421
- }
422
- }
423
- }
424
-
425
- /** True once the `State` account has loaded, independent of `isSubscribed`. Market/oracle data is not required. */
426
- didSubscriptionSucceed(): boolean {
427
- if (this.state) return true;
428
-
429
- return false;
430
- }
431
-
432
- /** Removes every tracked state/market/oracle account and the error callback from the `BulkAccountLoader`, then clears internal maps. */
433
- public async unsubscribe(): Promise<void> {
434
- for (const [_, accountToPoll] of this.accountsToPoll) {
435
- this.accountLoader.removeAccount(
436
- accountToPoll.publicKey,
437
- accountToPoll.callbackId
438
- );
439
- }
440
-
441
- for (const [_, oracleToPoll] of this.oraclesToPoll) {
442
- this.accountLoader.removeAccount(
443
- oracleToPoll.publicKey,
444
- oracleToPoll.callbackId
445
- );
446
- }
447
-
448
- this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
449
- this.errorCallbackId = undefined;
450
-
451
- this.accountsToPoll.clear();
452
- this.oraclesToPoll.clear();
453
- this.isSubscribed = false;
454
- }
455
-
456
- /**
457
- * Adds a spot market (and its oracle, via `setSpotOracleMap`) to be tracked, registering it
458
- * with the `BulkAccountLoader`. Idempotent: returns `true` immediately if already tracked.
459
- * @param marketIndex Spot market index to start tracking.
460
- */
461
- async addSpotMarket(marketIndex: number): Promise<boolean> {
462
- const marketPublicKey = await getSpotMarketPublicKey(
463
- this.program.programId,
464
- marketIndex
465
- );
466
-
467
- if (this.accountsToPoll.has(marketPublicKey.toString())) {
468
- return true;
469
- }
470
-
471
- await this.addSpotMarketAccountToPoll(marketIndex);
472
-
473
- const accountToPoll = this.accountsToPoll.get(marketPublicKey.toString());
474
- if (!accountToPoll) {
475
- return false;
476
- }
477
-
478
- await this.addAccountToAccountLoader(accountToPoll);
479
- await this.setSpotOracleMap();
480
- return true;
481
- }
482
-
483
- /**
484
- * Adds a perp market (and its oracle, via `setPerpOracleMap`) to be tracked, registering it
485
- * with the `BulkAccountLoader`. Idempotent: returns `true` immediately if already tracked.
486
- * @param marketIndex Perp market index to start tracking.
487
- */
488
- async addPerpMarket(marketIndex: number): Promise<boolean> {
489
- const marketPublicKey = await getPerpMarketPublicKey(
490
- this.program.programId,
491
- marketIndex
492
- );
493
-
494
- if (this.accountsToPoll.has(marketPublicKey.toString())) {
495
- return true;
496
- }
497
-
498
- await this.addPerpMarketAccountToPoll(marketIndex);
499
- const accountToPoll = this.accountsToPoll.get(marketPublicKey.toString());
500
- if (!accountToPoll) {
501
- return false;
502
- }
503
- await this.addAccountToAccountLoader(accountToPoll);
504
- await this.setPerpOracleMap();
505
- return true;
506
- }
507
-
508
- /**
509
- * Adds an oracle to be tracked, registering it with the `BulkAccountLoader` and waiting
510
- * (polling up to 3 times at `accountLoader.pollingFrequency` intervals) for it to appear in
511
- * the loader's buffer map before resolving. A no-op that resolves `true` immediately for the
512
- * `PublicKey.default` sentinel (quote-asset "no oracle") or an oracle already tracked.
513
- * @param oracleInfo Oracle pubkey and source to start tracking.
514
- */
515
- async addOracle(oracleInfo: OracleInfo): Promise<boolean> {
516
- const oracleId = getOracleId(oracleInfo.publicKey, oracleInfo.source);
517
- if (
518
- oracleInfo.publicKey.equals(PublicKey.default) ||
519
- this.oracles.has(oracleId)
520
- ) {
521
- return true;
522
- }
523
-
524
- // this func can be called multiple times before the first pauseForOracleToBeAdded finishes
525
- // avoid adding to oraclesToPoll multiple time
526
- if (!this.oraclesToPoll.has(oracleId)) {
527
- this.addOracleToPoll(oracleInfo);
528
- const oracleToPoll = this.oraclesToPoll.get(oracleId);
529
- if (oracleToPoll) {
530
- await this.addOracleToAccountLoader(oracleToPoll);
531
- }
532
- }
533
-
534
- await this.pauseForOracleToBeAdded(3, oracleInfo.publicKey.toBase58());
535
-
536
- return true;
537
- }
538
-
539
- private async pauseForOracleToBeAdded(
540
- tries: number,
541
- oracle: string
542
- ): Promise<void> {
543
- let i = 0;
544
- while (i < tries) {
545
- await new Promise((r) =>
546
- setTimeout(r, this.accountLoader.pollingFrequency)
547
- );
548
- if (this.accountLoader.bufferAndSlotMap.has(oracle)) {
549
- return;
550
- }
551
- i++;
552
- }
553
- console.log(`Pausing to find oracle ${oracle} failed`);
554
- }
555
-
556
- /** Rebuilds `perpOracleMap`/`perpOracleStringMap` from currently cached perp markets, calling `addOracle` for any oracle not yet tracked. */
557
- async setPerpOracleMap() {
558
- const perpMarkets = this.getMarketAccountsAndSlots();
559
- const oraclePromises = [];
560
- for (const perpMarket of perpMarkets) {
561
- const perpMarketAccount = perpMarket.data;
562
- const perpMarketIndex = perpMarketAccount.marketIndex;
563
- const oracle = perpMarketAccount.oracle;
564
- const oracleId = getOracleId(oracle, perpMarketAccount.oracleSource);
565
- if (!this.oracles.has(oracleId)) {
566
- oraclePromises.push(
567
- this.addOracle({
568
- publicKey: oracle,
569
- source: perpMarketAccount.oracleSource,
570
- })
571
- );
572
- }
573
- this.perpOracleMap.set(perpMarketIndex, oracle);
574
- this.perpOracleStringMap.set(perpMarketIndex, oracleId);
575
- }
576
- await Promise.all(oraclePromises);
577
- }
578
-
579
- /** Rebuilds `spotOracleMap`/`spotOracleStringMap` from currently cached spot markets, calling `addOracle` for any oracle not yet tracked. */
580
- async setSpotOracleMap() {
581
- const spotMarkets = this.getSpotMarketAccountsAndSlots();
582
- const oraclePromises = [];
583
- for (const spotMarket of spotMarkets) {
584
- const spotMarketAccount = spotMarket.data;
585
- const spotMarketIndex = spotMarketAccount.marketIndex;
586
- const oracle = spotMarketAccount.oracle;
587
- const oracleId = getOracleId(oracle, spotMarketAccount.oracleSource);
588
- if (!this.oracles.has(oracleId)) {
589
- oraclePromises.push(
590
- this.addOracle({
591
- publicKey: oracle,
592
- source: spotMarketAccount.oracleSource,
593
- })
594
- );
595
- }
596
- this.spotOracleMap.set(spotMarketIndex, oracle);
597
- this.spotOracleStringMap.set(spotMarketIndex, oracleId);
598
- }
599
- await Promise.all(oraclePromises);
600
- }
601
-
602
- /**
603
- * Applies `delistedMarketSetting` to any perp market currently `status: delisted` (and its
604
- * oracle, if not shared with a live spot market): removes the `BulkAccountLoader` registration,
605
- * and additionally drops the market/oracle from internal maps if the setting is `Discard`. A
606
- * no-op if the setting is `Subscribe`. Throws if internal bookkeeping is inconsistent (e.g. a
607
- * delisted market missing from `accountsToPoll`), which would indicate a bug rather than an
608
- * expected runtime condition.
609
- */
610
- handleDelistedMarkets(): void {
611
- if (this.delistedMarketSetting === DelistedMarketSetting.Subscribe) {
612
- return;
613
- }
614
-
615
- const { perpMarketIndexes, oracles } = findDelistedPerpMarketsAndOracles(
616
- this.getMarketAccountsAndSlots(),
617
- this.getSpotMarketAccountsAndSlots()
618
- );
619
-
620
- for (const perpMarketIndex of perpMarketIndexes) {
621
- const perpMarketData = this.perpMarket.get(perpMarketIndex);
622
- if (!perpMarketData) {
623
- throw new Error(
624
- `PollingVelocityClientAccountSubscriber: delisted perp market ${perpMarketIndex} not found in perpMarket map`
625
- );
626
- }
627
- const perpMarketPubkey = perpMarketData.data.pubkey;
628
- const accountToPoll = this.accountsToPoll.get(
629
- perpMarketPubkey.toBase58()
630
- );
631
- if (!accountToPoll) {
632
- throw new Error(
633
- `PollingVelocityClientAccountSubscriber: delisted perp market ${perpMarketIndex} not found in accountsToPoll map`
634
- );
635
- }
636
- const callbackId = accountToPoll.callbackId;
637
- this.accountLoader.removeAccount(perpMarketPubkey, callbackId);
638
- if (this.delistedMarketSetting === DelistedMarketSetting.Discard) {
639
- this.perpMarket.delete(perpMarketIndex);
640
- }
641
- }
642
-
643
- for (const oracle of oracles) {
644
- const oracleId = getOracleId(oracle.publicKey, oracle.source);
645
- const oracleToPoll = this.oraclesToPoll.get(oracleId);
646
- if (!oracleToPoll) {
647
- throw new Error(
648
- `PollingVelocityClientAccountSubscriber: delisted oracle ${oracleId} not found in oraclesToPoll map`
649
- );
650
- }
651
- const callbackId = oracleToPoll.callbackId;
652
- this.accountLoader.removeAccount(oracle.publicKey, callbackId);
653
- if (this.delistedMarketSetting === DelistedMarketSetting.Discard) {
654
- this.oracles.delete(oracleId);
655
- }
656
- }
657
- }
658
-
659
- /** Throws `NotSubscribedError` if `subscribe()` has not been called. */
660
- assertIsSubscribed(): void {
661
- if (!this.isSubscribed) {
662
- throw new NotSubscribedError(
663
- 'You must call `subscribe` before using this function'
664
- );
665
- }
666
- }
667
-
668
- /** Throws `NotSubscribedError` if not subscribed. */
669
- public getStateAccountAndSlot(): DataAndSlot<StateAccount> {
670
- this.assertIsSubscribed();
671
- return this.state!;
672
- }
673
-
674
- /** Returns the cached perp market, or undefined if `marketIndex` isn't tracked (or hasn't loaded yet). Does not throw `NotSubscribedError`. */
675
- public getMarketAccountAndSlot(
676
- marketIndex: number
677
- ): DataAndSlot<PerpMarketAccount> | undefined {
678
- return this.perpMarket.get(marketIndex);
679
- }
680
-
681
- /** Returns every currently cached perp market. Does not throw `NotSubscribedError`. */
682
- public getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[] {
683
- return Array.from(this.perpMarket.values());
684
- }
685
-
686
- /** Returns the cached spot market, or undefined if `marketIndex` isn't tracked (or hasn't loaded yet). Does not throw `NotSubscribedError`. */
687
- public getSpotMarketAccountAndSlot(
688
- marketIndex: number
689
- ): DataAndSlot<SpotMarketAccount> | undefined {
690
- return this.spotMarket.get(marketIndex);
691
- }
692
-
693
- /** Returns every currently cached spot market. Does not throw `NotSubscribedError`. */
694
- public getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[] {
695
- return Array.from(this.spotMarket.values());
696
- }
697
-
698
- /**
699
- * Looks up cached oracle price data by oracle id (see `getOracleId`). Special-cases the
700
- * quote-asset default oracle id, returning the constant `QUOTE_ORACLE_PRICE_DATA` at slot 0
701
- * rather than a map lookup, since that oracle is never actually subscribed to.
702
- * @param oracleId Oracle id string from `getOracleId(publicKey, source)`.
703
- * @returns Cached price data/slot, or undefined if not tracked. Throws `NotSubscribedError` if not subscribed.
704
- */
705
- public getOraclePriceDataAndSlot(
706
- oracleId: string
707
- ): DataAndSlot<OraclePriceData> | undefined {
708
- this.assertIsSubscribed();
709
- if (oracleId === ORACLE_DEFAULT_ID) {
710
- return {
711
- data: QUOTE_ORACLE_PRICE_DATA,
712
- slot: 0,
713
- };
714
- }
715
-
716
- return this.oracles.get(oracleId);
717
- }
718
-
719
- /**
720
- * Convenience lookup: resolves the oracle price data currently mapped to a perp market's
721
- * oracle. If the cached market's oracle pubkey has drifted from `perpOracleMap` (e.g. an admin
722
- * changed it on-chain), triggers a background `setPerpOracleMap()` refresh and still returns
723
- * the (possibly stale) mapping for this call.
724
- * @param marketIndex Perp market index whose oracle price to look up.
725
- */
726
- public getOraclePriceDataAndSlotForPerpMarket(
727
- marketIndex: number
728
- ): DataAndSlot<OraclePriceData> | undefined {
729
- const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
730
- const oracle = this.perpOracleMap.get(marketIndex);
731
- const oracleId = this.perpOracleStringMap.get(marketIndex);
732
-
733
- if (!perpMarketAccount || !oracle || !oracleId) {
734
- return undefined;
735
- }
736
-
737
- if (!perpMarketAccount.data.oracle.equals(oracle)) {
738
- // If the oracle has changed, we need to update the oracle map in background
739
- this.setPerpOracleMap();
740
- }
741
-
742
- return this.getOraclePriceDataAndSlot(oracleId);
743
- }
744
-
745
- /**
746
- * Convenience lookup: resolves the oracle price data currently mapped to a spot market's
747
- * oracle. If the cached market's oracle pubkey has drifted from `spotOracleMap`, triggers a
748
- * background `setSpotOracleMap()` refresh and still returns the (possibly stale) mapping for
749
- * this call.
750
- * @param marketIndex Spot market index whose oracle price to look up.
751
- */
752
- public getOraclePriceDataAndSlotForSpotMarket(
753
- marketIndex: number
754
- ): DataAndSlot<OraclePriceData> | undefined {
755
- const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
756
- const oracle = this.spotOracleMap.get(marketIndex);
757
- const oracleId = this.spotOracleStringMap.get(marketIndex);
758
- if (!spotMarketAccount || !oracle || !oracleId) {
759
- return undefined;
760
- }
761
-
762
- if (!spotMarketAccount.data.oracle.equals(oracle)) {
763
- // If the oracle has changed, we need to update the oracle map in background
764
- this.setSpotOracleMap();
765
- }
766
-
767
- return this.getOraclePriceDataAndSlot(oracleId);
768
- }
769
-
770
- /** Retunes the shared `BulkAccountLoader`'s poll interval (ms) for every account it batches (affects other subscribers sharing the same loader too). */
771
- public updateAccountLoaderPollingFrequency(pollingFrequency: number): void {
772
- this.accountLoader.updatePollingFrequency(pollingFrequency);
773
- }
774
- }