@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,305 +0,0 @@
1
- import { BN } from '../isomorphic/anchor';
2
- import {
3
- AMM_RESERVE_PRECISION,
4
- PRICE_PRECISION,
5
- ZERO,
6
- } from '../constants/numericConstants';
7
- import { getLimitPrice } from '../math/orders';
8
- import { isVariant, MarketTypeStr, Order } from '../types';
9
- import { MMOraclePriceData, OraclePriceData } from '../oracles/types';
10
- import { convertToNumber } from '../math/conversion';
11
- import { getOrderSignature } from './NodeList';
12
-
13
- /**
14
- * Picks the oracle price data shape a `DLOBNode` needs to compute its limit price for a given
15
- * market type: `OraclePriceData` for spot markets, `MMOraclePriceData` (which layers in the
16
- * market-maker oracle) for perp markets.
17
- */
18
- export type NodeOraclePriceData<T extends MarketTypeStr = MarketTypeStr> =
19
- T extends 'spot' ? OraclePriceData : MMOraclePriceData;
20
-
21
- /**
22
- * A single order sitting in the DLOB, indexed by one of the sorted `NodeList`s. Wraps one
23
- * on-chain `Order` plus DLOB-local bookkeeping (fill progress, sort key) used by
24
- * `DLOB`'s crossing/fill-finding and L2/L3 book construction.
25
- */
26
- export interface DLOBNode {
27
- /**
28
- * Computes the node's current limit price, or `undefined` if it has none right now (e.g. a
29
- * market/auction order still mid-auction with no fallback price, or an unset oracle-offset
30
- * order below the tick floor). Callers that can tolerate "no price" (market orders crossing
31
- * on a taker/maker basis, fallback-liquidity checks) should use this; callers that require a
32
- * price to proceed should use `getPriceOrThrow` instead.
33
- *
34
- * @param oraclePriceData current oracle price data for the node's market (price in
35
- * PRICE_PRECISION, 1e6)
36
- * @param slot current slot, used to resolve auction/oracle-offset pricing
37
- * @param tickSize market's order tick size, PRICE_PRECISION (1e6); when omitted this
38
- * effectively rounds to the smallest price unit (no meaningful rounding) — pass the
39
- * market's `orderTickSize` to match on-chain price standardization
40
- * @returns limit price, PRICE_PRECISION (1e6), or `undefined` if the node has no price yet
41
- */
42
- getPrice<T extends MarketTypeStr>(
43
- oraclePriceData: NodeOraclePriceData<T>,
44
- slot: number,
45
- tickSize?: BN
46
- ): BN | undefined;
47
- /**
48
- * Same as `getPrice`, but throws instead of returning `undefined` when the node has no limit
49
- * price. Use this wherever a missing price would be a bug (e.g. iterating resting limit
50
- * orders, which always have a determinable price once the auction is complete).
51
- *
52
- * @param oraclePriceData current oracle price data for the node's market (price in
53
- * PRICE_PRECISION, 1e6)
54
- * @param slot current slot, used to resolve auction/oracle-offset pricing
55
- * @param tickSize market's order tick size, PRICE_PRECISION (1e6); defaults to no rounding
56
- * if omitted
57
- * @returns limit price, PRICE_PRECISION (1e6)
58
- * @throws if the underlying order has no limit price at this slot
59
- */
60
- getPriceOrThrow<T extends MarketTypeStr>(
61
- oraclePriceData: NodeOraclePriceData<T>,
62
- slot: number,
63
- tickSize?: BN
64
- ): BN;
65
- /** True for synthetic vAMM liquidity nodes (not backed by an on-chain `Order`); always `false` for `OrderNode` subclasses. */
66
- isVammNode(): boolean;
67
- /** The on-chain order this node mirrors, or `undefined` for non-order (e.g. vAMM) nodes. */
68
- order: Order | undefined;
69
- /** True once `order.baseAssetAmountFilled` equals `order.baseAssetAmount` (fully filled). */
70
- isBaseFilled(): boolean;
71
- /** DLOB-local flag set by crossing/fill-finding once this node has been matched in the current pass, so it isn't matched twice. */
72
- haveFilled: boolean;
73
- /** Base58 pubkey string of the `User` account that owns this order, or `undefined` if not applicable. */
74
- userAccount: string | undefined;
75
- /** True if this order arrived as an off-chain signed message (not yet landed on-chain) rather than a resting on-chain order. */
76
- isSignedMsg: boolean | undefined;
77
- /** Remaining base asset amount tracked by this node, BASE_PRECISION (1e9); defaults to `order.baseAssetAmount` if not overridden at insert time. */
78
- baseAssetAmount: BN;
79
- }
80
-
81
- /**
82
- * Base class for all order-backed DLOB nodes. Holds a defensive copy of the on-chain `Order`
83
- * plus a `sortValue` (the field each `NodeList` sorts on) computed by the concrete subclass's
84
- * `getSortValue`. Concrete subclasses (`RestingLimitOrderNode`, `TakingLimitOrderNode`, etc.)
85
- * only differ in which `Order` field they sort by and which `NodeList` bucket they belong to.
86
- */
87
- export abstract class OrderNode implements DLOBNode {
88
- order: Order;
89
- userAccount: string;
90
- /** The value this node is sorted by within its `NodeList`; set from `getSortValue(order)` at construction and not auto-updated on order changes. */
91
- sortValue: BN;
92
- haveFilled = false;
93
- haveTrigger = false;
94
- baseAssetAmount: BN;
95
- isSignedMsg: boolean;
96
-
97
- /**
98
- * @param order on-chain order to wrap; a shallow copy is stored so DLOB mutations don't alias the caller's object
99
- * @param userAccount base58 pubkey string of the order's owner
100
- * @param baseAssetAmount remaining base amount to track, BASE_PRECISION (1e9); defaults to `order.baseAssetAmount` (used for reduce-only orders where the fillable amount is smaller than the order's stated size)
101
- * @param isSignedMsg whether this node represents an off-chain signed-message order rather than a resting on-chain order; defaults to `false`
102
- */
103
- constructor(
104
- order: Order,
105
- userAccount: string,
106
- baseAssetAmount?: BN,
107
- isSignedMsg = false
108
- ) {
109
- // Copy the order over to the node
110
- this.order = { ...order };
111
- this.userAccount = userAccount;
112
- this.sortValue = this.getSortValue(order);
113
- this.baseAssetAmount = baseAssetAmount ?? order.baseAssetAmount;
114
- this.isSignedMsg = isSignedMsg;
115
- }
116
-
117
- /** Returns the field of `order` this node type sorts on within its `NodeList` (e.g. price, slot, trigger price, or oracle offset). */
118
- abstract getSortValue(order: Order): BN;
119
-
120
- /** Builds a one-line human-readable summary of the order (id, side, size, price, trigger) for `NodeList.print`/`printTop` debugging output. */
121
- public getLabel(): string {
122
- let msg = `Order ${getOrderSignature(
123
- this.order.orderId,
124
- this.userAccount
125
- )}`;
126
- msg += ` ${isVariant(this.order.direction, 'long') ? 'LONG' : 'SHORT'} `;
127
- msg += `${convertToNumber(
128
- this.order.baseAssetAmount,
129
- AMM_RESERVE_PRECISION
130
- ).toFixed(3)}`;
131
- if (this.order.price.gt(ZERO)) {
132
- msg += ` @ ${convertToNumber(this.order.price, PRICE_PRECISION).toFixed(
133
- 3
134
- )}`;
135
- }
136
- if (this.order.triggerPrice.gt(ZERO)) {
137
- msg += ` ${
138
- isVariant(this.order.triggerCondition, 'below') ? 'BELOW' : 'ABOVE'
139
- }`;
140
- msg += ` ${convertToNumber(
141
- this.order.triggerPrice,
142
- PRICE_PRECISION
143
- ).toFixed(3)}`;
144
- }
145
- return msg;
146
- }
147
-
148
- /** See `DLOBNode.getPrice`. Delegates to `getLimitPrice`, which resolves auction, oracle-offset, and fixed-price orders in that priority. */
149
- getPrice<T extends MarketTypeStr>(
150
- oraclePriceData: NodeOraclePriceData<T>,
151
- slot: number,
152
- tickSize?: BN
153
- ): BN | undefined {
154
- return getLimitPrice<T>(
155
- this.order,
156
- oraclePriceData,
157
- slot,
158
- undefined,
159
- tickSize
160
- );
161
- }
162
-
163
- /** See `DLOBNode.getPriceOrThrow`. @throws if `getPrice` returns `undefined` for this order. */
164
- getPriceOrThrow<T extends MarketTypeStr>(
165
- oraclePriceData: NodeOraclePriceData<T>,
166
- slot: number,
167
- tickSize?: BN
168
- ): BN {
169
- const price = this.getPrice<T>(oraclePriceData, slot, tickSize);
170
- if (price === undefined) {
171
- throw new Error(
172
- `OrderNode.getPrice: order ${this.order.orderId} has no limit price`
173
- );
174
- }
175
- return price;
176
- }
177
-
178
- /** True once the wrapped order's `baseAssetAmountFilled` equals its `baseAssetAmount` (BASE_PRECISION, 1e9). */
179
- isBaseFilled(): boolean {
180
- return this.order.baseAssetAmountFilled.eq(this.order.baseAssetAmount);
181
- }
182
-
183
- /** Always `false` — order-backed nodes are never vAMM nodes. */
184
- isVammNode(): boolean {
185
- return false;
186
- }
187
- }
188
-
189
- /** A limit order whose auction has not yet completed (still crossable as a taker); sorted ascending by `order.slot` (arrival order) within its `NodeList`. Promoted to a `RestingLimitOrderNode` once its auction completes or it settles as post-only, via `DLOB.updateRestingLimitOrders`. */
190
- export class TakingLimitOrderNode extends OrderNode {
191
- next?: TakingLimitOrderNode;
192
- previous?: TakingLimitOrderNode;
193
-
194
- getSortValue(order: Order): BN {
195
- return order.slot;
196
- }
197
- }
198
-
199
- /** A limit order with a fixed (non-oracle-relative) price whose auction has completed, or that is post-only; sorted by `order.price` (PRICE_PRECISION, 1e6) — ascending for asks, descending for bids. This is the DLOB's standard resting maker order. */
200
- export class RestingLimitOrderNode extends OrderNode {
201
- next?: RestingLimitOrderNode;
202
- previous?: RestingLimitOrderNode;
203
-
204
- getSortValue(order: Order): BN {
205
- return order.price;
206
- }
207
- }
208
-
209
- /** A resting limit order priced relative to the oracle (`oraclePriceOffset != 0`); sorted by `order.oraclePriceOffset` (PRICE_PRECISION, 1e6, signed) rather than an absolute price, since its effective price moves with the oracle. */
210
- export class FloatingLimitOrderNode extends OrderNode {
211
- next?: FloatingLimitOrderNode;
212
- previous?: FloatingLimitOrderNode;
213
-
214
- getSortValue(order: Order): BN {
215
- return order.oraclePriceOffset;
216
- }
217
- }
218
-
219
- /** A market order (or an order otherwise treated as market/oracle-priced); sorted ascending by `order.slot` (arrival order) since market orders have no fixed price to sort by. */
220
- export class MarketOrderNode extends OrderNode {
221
- next?: MarketOrderNode;
222
- previous?: MarketOrderNode;
223
-
224
- getSortValue(order: Order): BN {
225
- return order.slot;
226
- }
227
- }
228
-
229
- /** A trigger (stop-loss/take-profit) order that has not yet fired; sorted by `order.triggerPrice` (PRICE_PRECISION, 1e6) — ascending in the "above" list, descending in the "below" list — so `DLOB.findNodesToTrigger` can stop scanning as soon as the trigger price is no longer crossed. */
230
- export class TriggerOrderNode extends OrderNode {
231
- next?: TriggerOrderNode;
232
- previous?: TriggerOrderNode;
233
-
234
- getSortValue(order: Order): BN {
235
- return order.triggerPrice;
236
- }
237
- }
238
-
239
- // We'll use the signedMsg uuid for the order id since it's not yet on-chain
240
- /** An order that arrived as an off-chain signed message and has not yet landed on-chain; always constructed with `isSignedMsg = true`. Sorted ascending by `order.slot`. */
241
- export class SignedMsgOrderNode extends OrderNode {
242
- next?: SignedMsgOrderNode;
243
- previous?: SignedMsgOrderNode;
244
-
245
- constructor(order: Order, userAccount: string, baseAssetAmount?: BN) {
246
- super(order, userAccount, baseAssetAmount, true);
247
- }
248
-
249
- getSortValue(order: Order): BN {
250
- return order.slot;
251
- }
252
- }
253
-
254
- /** Maps each `DLOBNodeType` key to its concrete `OrderNode` subclass; used to type `NodeList<T>` and `createNode`'s return value. */
255
- export type DLOBNodeMap = {
256
- restingLimit: RestingLimitOrderNode;
257
- takingLimit: TakingLimitOrderNode;
258
- floatingLimit: FloatingLimitOrderNode;
259
- market: MarketOrderNode;
260
- trigger: TriggerOrderNode;
261
- signedMsg: SignedMsgOrderNode;
262
- };
263
-
264
- /** The discriminant used to pick which `NodeList` (and thus sort order) an order belongs in. */
265
- export type DLOBNodeType =
266
- | 'signedMsg'
267
- | 'restingLimit'
268
- | 'takingLimit'
269
- | 'floatingLimit'
270
- | 'market'
271
- | ('trigger' & keyof DLOBNodeMap);
272
-
273
- /**
274
- * Constructs the concrete `OrderNode` subclass for a given `DLOBNodeType`.
275
- *
276
- * @param nodeType which node subclass to build; determines the node's sort key (see `DLOBNodeMap`)
277
- * @param order on-chain order to wrap (copied, not mutated)
278
- * @param userAccount base58 pubkey string of the order's owner
279
- * @param baseAssetAmount remaining base amount to track, BASE_PRECISION (1e9); defaults to `order.baseAssetAmount`
280
- * @returns a new node instance of the type matching `nodeType`
281
- * @throws if `nodeType` is not one of the known `DLOBNodeType` values
282
- */
283
- export function createNode<T extends DLOBNodeType>(
284
- nodeType: T,
285
- order: Order,
286
- userAccount: string,
287
- baseAssetAmount?: BN
288
- ): DLOBNodeMap[T] {
289
- switch (nodeType) {
290
- case 'floatingLimit':
291
- return new FloatingLimitOrderNode(order, userAccount, baseAssetAmount);
292
- case 'restingLimit':
293
- return new RestingLimitOrderNode(order, userAccount, baseAssetAmount);
294
- case 'takingLimit':
295
- return new TakingLimitOrderNode(order, userAccount, baseAssetAmount);
296
- case 'market':
297
- return new MarketOrderNode(order, userAccount, baseAssetAmount);
298
- case 'trigger':
299
- return new TriggerOrderNode(order, userAccount, baseAssetAmount);
300
- case 'signedMsg':
301
- return new SignedMsgOrderNode(order, userAccount, baseAssetAmount);
302
- default:
303
- throw Error(`Unknown DLOBNode type ${nodeType}`);
304
- }
305
- }
@@ -1,269 +0,0 @@
1
- import { DLOB } from './DLOB';
2
- import { EventEmitter } from 'events';
3
- import StrictEventEmitter from 'strict-event-emitter-types';
4
- import {
5
- DLOBSource,
6
- DLOBSubscriberEvents,
7
- DLOBSubscriptionConfig,
8
- SlotSource,
9
- } from './types';
10
- import { VelocityClient } from '../velocityClient';
11
- import { isVariant, MarketType } from '../types';
12
- import {
13
- DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS,
14
- MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS,
15
- getVammL2Generator,
16
- L2OrderBook,
17
- L2OrderBookGenerator,
18
- L3OrderBook,
19
- } from './orderBookLevels';
20
- import { BN } from '../isomorphic/anchor';
21
-
22
- /**
23
- * Keeps a `DLOB` snapshot fresh on a timer and exposes convenience `getL2`/`getL3` accessors that
24
- * resolve market name/index/type and oracle price data via `velocityClient` so callers don't have
25
- * to. Until `subscribe()` resolves at least once, `getDLOB()`/`getL2`/`getL3` operate on an empty
26
- * `DLOB`.
27
- */
28
- export class DLOBSubscriber {
29
- velocityClient: VelocityClient;
30
- dlobSource: DLOBSource;
31
- slotSource: SlotSource;
32
- /** Polling interval in milliseconds between `DLOB` refreshes. */
33
- updateFrequency: number;
34
- /** Handle of the active polling timer, or `undefined` before `subscribe()`/after `unsubscribe()`. */
35
- intervalId?: ReturnType<typeof setTimeout>;
36
- /** The current `DLOB` snapshot; replaced wholesale on each refresh rather than mutated. */
37
- dlob: DLOB;
38
- /** Emits `'update'` after each successful refresh and `'error'` if a refresh throws. */
39
- public eventEmitter: StrictEventEmitter<EventEmitter, DLOBSubscriberEvents>;
40
- /** @throws if `config.velocityClient` is not provided. */
41
- constructor(config: DLOBSubscriptionConfig) {
42
- const velocityClient = config.velocityClient;
43
- if (!velocityClient) {
44
- throw new Error('DLOBSubscriber: velocityClient must be provided');
45
- }
46
- this.velocityClient = velocityClient;
47
- this.dlobSource = config.dlobSource;
48
- this.slotSource = config.slotSource;
49
- this.updateFrequency = config.updateFrequency;
50
- this.dlob = new DLOB();
51
- this.eventEmitter = new EventEmitter();
52
- }
53
-
54
- /**
55
- * Fetches an initial `DLOB` snapshot (awaited before returning) and then starts a timer that
56
- * refreshes it every `updateFrequency` ms, emitting `'update'` on success or `'error'` if the
57
- * fetch throws. No-ops if already subscribed.
58
- */
59
- public async subscribe(): Promise<void> {
60
- if (this.intervalId) {
61
- return;
62
- }
63
-
64
- await this.updateDLOB();
65
-
66
- this.intervalId = setInterval(async () => {
67
- try {
68
- await this.updateDLOB();
69
- this.eventEmitter.emit('update', this.dlob);
70
- } catch (e) {
71
- this.eventEmitter.emit(
72
- 'error',
73
- e instanceof Error ? e : new Error(String(e))
74
- );
75
- }
76
- }, this.updateFrequency);
77
- }
78
-
79
- /** Fetches a new `DLOB` snapshot at the current slot (from `slotSource`) via `dlobSource.getDLOB` and replaces `this.dlob`. */
80
- async updateDLOB(): Promise<void> {
81
- this.dlob = await this.dlobSource.getDLOB(this.slotSource.getSlot());
82
- }
83
-
84
- /** @returns the most recently fetched `DLOB` snapshot (empty until the first successful `subscribe()`/`updateDLOB()`). */
85
- public getDLOB(): DLOB {
86
- return this.dlob;
87
- }
88
-
89
- /**
90
- * Get the L2 (aggregated price/size) order book for a given market, using the current
91
- * `DLOB` snapshot and the current slot from `slotSource`.
92
- *
93
- * @param marketName e.g. "SOL-PERP" or "SOL". If not provided, `marketIndex` and `marketType` must both be provided.
94
- * @param marketIndex market index; ignored if `marketName` is provided
95
- * @param marketType market type; ignored if `marketName` is provided
96
- * @param depth number of price levels to include per side; defaults to 10
97
- * @param includeVamm whether to synthesize and merge in vAMM liquidity (perp markets only) via `getVammL2Generator`; defaults to `false`. Throws if `true` and `fallbackL2Generators` is non-empty.
98
- * @param numVammOrders number of vAMM levels to generate per side when `includeVamm` is true; defaults to `depth`
99
- * @param fallbackL2Generators additional non-DLOB liquidity sources to merge in, e.g. `getVammL2Generator`'s output; defaults to `[]`
100
- * @param latestSlot latest observed slot (e.g. from a `SlotSubscriber`), used for more accurate vAMM spread-reserve quotes when `includeVamm` is true; optional
101
- * @returns the merged `L2OrderBook` (bids/asks with sizes, BASE_PRECISION 1e9, and prices, PRICE_PRECISION 1e6)
102
- * @throws if `marketName` doesn't resolve to a known market, if neither `marketName` nor both `marketIndex`/`marketType` are given, or if `includeVamm` is combined with a non-empty `fallbackL2Generators`
103
- */
104
- public getL2({
105
- marketName,
106
- marketIndex,
107
- marketType,
108
- depth = 10,
109
- includeVamm = false,
110
- numVammOrders,
111
- fallbackL2Generators = [],
112
- latestSlot,
113
- }: {
114
- marketName?: string;
115
- marketIndex?: number;
116
- marketType?: MarketType;
117
- depth?: number;
118
- includeVamm?: boolean;
119
- numVammOrders?: number;
120
- fallbackL2Generators?: L2OrderBookGenerator[];
121
- latestSlot?: BN;
122
- }): L2OrderBook {
123
- if (marketName) {
124
- const derivedMarketInfo =
125
- this.velocityClient.getMarketIndexAndType(marketName);
126
- if (!derivedMarketInfo) {
127
- throw new Error(`Market ${marketName} not found`);
128
- }
129
- marketIndex = derivedMarketInfo.marketIndex;
130
- marketType = derivedMarketInfo.marketType;
131
- } else {
132
- if (marketIndex === undefined || marketType === undefined) {
133
- throw new Error(
134
- 'Either marketName or marketIndex and marketType must be provided'
135
- );
136
- }
137
- }
138
-
139
- const isPerp = isVariant(marketType, 'perp');
140
- if (isPerp) {
141
- const perpMarketAccount =
142
- this.velocityClient.getPerpMarketAccountOrThrow(marketIndex);
143
- const oraclePriceData = this.velocityClient.getMMOracleDataForPerpMarket(
144
- perpMarketAccount.marketIndex
145
- );
146
-
147
- if (includeVamm) {
148
- if (fallbackL2Generators.length > 0) {
149
- throw new Error(
150
- 'includeVamm can only be used if fallbackL2Generators is empty'
151
- );
152
- }
153
-
154
- fallbackL2Generators = [
155
- getVammL2Generator({
156
- marketAccount: perpMarketAccount,
157
- mmOraclePriceData:
158
- this.velocityClient.getMMOracleDataForPerpMarket(marketIndex),
159
- numOrders: numVammOrders ?? depth,
160
- topOfBookQuoteAmounts:
161
- marketIndex < 3
162
- ? MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS
163
- : DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS,
164
- latestSlot,
165
- }),
166
- ];
167
- }
168
-
169
- return this.dlob.getL2({
170
- marketIndex,
171
- marketType: MarketType.PERP,
172
- depth,
173
- oraclePriceData,
174
- slot: this.slotSource.getSlot(),
175
- fallbackL2Generators: fallbackL2Generators,
176
- tickSize: perpMarketAccount.orderTickSize,
177
- });
178
- }
179
-
180
- const oraclePriceData =
181
- this.velocityClient.getOracleDataForSpotMarket(marketIndex);
182
- const spotMarketAccount =
183
- this.velocityClient.getSpotMarketAccountOrThrow(marketIndex);
184
-
185
- return this.dlob.getL2({
186
- marketIndex,
187
- marketType: MarketType.SPOT,
188
- depth,
189
- oraclePriceData,
190
- slot: this.slotSource.getSlot(),
191
- fallbackL2Generators: fallbackL2Generators,
192
- tickSize: spotMarketAccount.orderTickSize,
193
- });
194
- }
195
-
196
- /**
197
- * Get the L3 (individual resting order) book for a given market, using the current `DLOB`
198
- * snapshot and the current slot from `slotSource`. Does not include fallback (e.g. vAMM)
199
- * liquidity.
200
- *
201
- * @param marketName e.g. "SOL-PERP" or "SOL". If not provided, `marketIndex` and `marketType` must both be provided.
202
- * @param marketIndex market index; ignored if `marketName` is provided
203
- * @param marketType market type; ignored if `marketName` is provided
204
- * @returns the `L3OrderBook` (per-order price/size/maker/orderId, prices PRICE_PRECISION 1e6, sizes BASE_PRECISION 1e9)
205
- * @throws if `marketName` doesn't resolve to a known market, or if neither `marketName` nor both `marketIndex`/`marketType` are given
206
- */
207
- public getL3({
208
- marketName,
209
- marketIndex,
210
- marketType,
211
- }: {
212
- marketName?: string;
213
- marketIndex?: number;
214
- marketType?: MarketType;
215
- }): L3OrderBook {
216
- if (marketName) {
217
- const derivedMarketInfo =
218
- this.velocityClient.getMarketIndexAndType(marketName);
219
- if (!derivedMarketInfo) {
220
- throw new Error(`Market ${marketName} not found`);
221
- }
222
- marketIndex = derivedMarketInfo.marketIndex;
223
- marketType = derivedMarketInfo.marketType;
224
- } else {
225
- if (marketIndex === undefined || marketType === undefined) {
226
- throw new Error(
227
- 'Either marketName or marketIndex and marketType must be provided'
228
- );
229
- }
230
- }
231
-
232
- const isPerp = isVariant(marketType, 'perp');
233
- if (isPerp) {
234
- const oraclePriceData =
235
- this.velocityClient.getMMOracleDataForPerpMarket(marketIndex);
236
- const perpMarketAccount =
237
- this.velocityClient.getPerpMarketAccountOrThrow(marketIndex);
238
-
239
- return this.dlob.getL3({
240
- marketIndex,
241
- marketType: MarketType.PERP,
242
- oraclePriceData,
243
- slot: this.slotSource.getSlot(),
244
- tickSize: perpMarketAccount.orderTickSize,
245
- });
246
- }
247
-
248
- const oraclePriceData =
249
- this.velocityClient.getOracleDataForSpotMarket(marketIndex);
250
- const spotMarketAccount =
251
- this.velocityClient.getSpotMarketAccountOrThrow(marketIndex);
252
-
253
- return this.dlob.getL3({
254
- marketIndex,
255
- marketType: MarketType.SPOT,
256
- oraclePriceData,
257
- slot: this.slotSource.getSlot(),
258
- tickSize: spotMarketAccount.orderTickSize,
259
- });
260
- }
261
-
262
- /** Stops the periodic refresh timer, if running. Safe to call when not subscribed. */
263
- public async unsubscribe(): Promise<void> {
264
- if (this.intervalId) {
265
- clearInterval(this.intervalId);
266
- this.intervalId = undefined;
267
- }
268
- }
269
- }