@velocity-exchange/sdk 0.4.0 → 0.6.0

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 (323) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +35 -0
  3. package/lib/browser/adminClient.js +65 -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 +146 -3
  9. package/lib/browser/idl/velocity.json +147 -4
  10. package/lib/browser/orderSubscriber/OrderSubscriber.js +3 -0
  11. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  12. package/lib/browser/types.d.ts +4 -0
  13. package/lib/browser/user.d.ts +15 -0
  14. package/lib/browser/user.js +37 -1
  15. package/lib/browser/velocityClient.d.ts +46 -10
  16. package/lib/browser/velocityClient.js +107 -35
  17. package/lib/node/adminClient.d.ts +35 -0
  18. package/lib/node/adminClient.d.ts.map +1 -1
  19. package/lib/node/adminClient.js +65 -0
  20. package/lib/node/config.d.ts.map +1 -1
  21. package/lib/node/config.js +6 -7
  22. package/lib/node/constants/numericConstants.d.ts +1 -1
  23. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  24. package/lib/node/constants/numericConstants.js +1 -1
  25. package/lib/node/decode/user.d.ts.map +1 -1
  26. package/lib/node/decode/user.js +5 -1
  27. package/lib/node/idl/velocity.d.ts +146 -3
  28. package/lib/node/idl/velocity.d.ts.map +1 -1
  29. package/lib/node/idl/velocity.json +147 -4
  30. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  31. package/lib/node/orderSubscriber/OrderSubscriber.js +3 -0
  32. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  33. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  34. package/lib/node/types.d.ts +4 -0
  35. package/lib/node/types.d.ts.map +1 -1
  36. package/lib/node/user.d.ts +15 -0
  37. package/lib/node/user.d.ts.map +1 -1
  38. package/lib/node/user.js +37 -1
  39. package/lib/node/velocityClient.d.ts +46 -10
  40. package/lib/node/velocityClient.d.ts.map +1 -1
  41. package/lib/node/velocityClient.js +107 -35
  42. package/package.json +7 -3
  43. package/.prettierignore +0 -1
  44. package/CHANGELOG.md +0 -132
  45. package/build-browser.js +0 -58
  46. package/bunfig.toml +0 -3
  47. package/esbuild-shims.js +0 -12
  48. package/scripts/deposit-isolated-positions.ts +0 -110
  49. package/scripts/find-flagged-users.ts +0 -213
  50. package/scripts/grpc-client-test-comparison.ts +0 -372
  51. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  52. package/scripts/postbuild.js +0 -95
  53. package/scripts/single-grpc-client-test.ts +0 -284
  54. package/scripts/withdraw-isolated-positions.ts +0 -174
  55. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  56. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  57. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  58. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  59. package/src/accounts/bulkAccountLoader.ts +0 -358
  60. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  61. package/src/accounts/bulkUserSubscription.ts +0 -39
  62. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  63. package/src/accounts/fetch.ts +0 -200
  64. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  65. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  66. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  67. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  68. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  69. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  70. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  71. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  72. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  73. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  74. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  75. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  76. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  77. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  78. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  79. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  80. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  81. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  82. package/src/accounts/testBulkAccountLoader.ts +0 -59
  83. package/src/accounts/types.ts +0 -428
  84. package/src/accounts/utils.ts +0 -90
  85. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  86. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  87. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  88. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  89. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  90. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  91. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  92. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  93. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  94. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  95. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  96. package/src/addresses/marketAddresses.ts +0 -28
  97. package/src/addresses/pda.ts +0 -620
  98. package/src/adminClient.ts +0 -8136
  99. package/src/assert/assert.ts +0 -5
  100. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  101. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  102. package/src/auctionSubscriber/index.ts +0 -9
  103. package/src/auctionSubscriber/types.ts +0 -30
  104. package/src/bankrun/bankrunConnection.ts +0 -630
  105. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  106. package/src/blockhashSubscriber/index.ts +0 -6
  107. package/src/blockhashSubscriber/types.ts +0 -13
  108. package/src/clock/clockSubscriber.ts +0 -146
  109. package/src/config.ts +0 -312
  110. package/src/constants/index.ts +0 -9
  111. package/src/constants/numericConstants.ts +0 -194
  112. package/src/constants/perpMarkets.ts +0 -127
  113. package/src/constants/spotMarkets.ts +0 -104
  114. package/src/constants/txConstants.ts +0 -2
  115. package/src/constituentMap/constituentMap.ts +0 -305
  116. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  117. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  118. package/src/core/VelocityCore.ts +0 -606
  119. package/src/core/index.ts +0 -12
  120. package/src/core/instructions/deposit.ts +0 -64
  121. package/src/core/instructions/fill.ts +0 -51
  122. package/src/core/instructions/funding.ts +0 -33
  123. package/src/core/instructions/liquidation.ts +0 -55
  124. package/src/core/instructions/orders.ts +0 -84
  125. package/src/core/instructions/perpOrders.ts +0 -312
  126. package/src/core/instructions/settlement.ts +0 -40
  127. package/src/core/instructions/trigger.ts +0 -41
  128. package/src/core/instructions/withdraw.ts +0 -65
  129. package/src/core/remainingAccounts.ts +0 -320
  130. package/src/core/signedMsg.ts +0 -109
  131. package/src/decode/customCoder.ts +0 -148
  132. package/src/decode/user.ts +0 -401
  133. package/src/dlob/DLOB.ts +0 -2793
  134. package/src/dlob/DLOBNode.ts +0 -305
  135. package/src/dlob/DLOBSubscriber.ts +0 -269
  136. package/src/dlob/NodeList.ts +0 -244
  137. package/src/dlob/orderBookLevels.ts +0 -695
  138. package/src/dlob/types.ts +0 -37
  139. package/src/events/eventList.ts +0 -114
  140. package/src/events/eventSubscriber.ts +0 -521
  141. package/src/events/eventsServerLogProvider.ts +0 -189
  142. package/src/events/fetchLogs.ts +0 -219
  143. package/src/events/parse.ts +0 -271
  144. package/src/events/pollingLogProvider.ts +0 -113
  145. package/src/events/sort.ts +0 -51
  146. package/src/events/txEventCache.ts +0 -92
  147. package/src/events/types.ts +0 -337
  148. package/src/events/webSocketLogProvider.ts +0 -152
  149. package/src/factory/bigNum.ts +0 -709
  150. package/src/factory/oracleClient.ts +0 -73
  151. package/src/idl/pyth.json +0 -142
  152. package/src/idl/pyth.ts +0 -97
  153. package/src/idl/pyth_solana_receiver.json +0 -628
  154. package/src/idl/token_faucet.json +0 -229
  155. package/src/idl/token_faucet.ts +0 -197
  156. package/src/idl/velocity.json +0 -23974
  157. package/src/idl/velocity.ts +0 -23980
  158. package/src/index.ts +0 -150
  159. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  160. package/src/isomorphic/README.md +0 -19
  161. package/src/isomorphic/anchor.browser.ts +0 -44
  162. package/src/isomorphic/anchor.node.ts +0 -1
  163. package/src/isomorphic/anchor.ts +0 -1
  164. package/src/isomorphic/anchor29.browser.ts +0 -24
  165. package/src/isomorphic/anchor29.node.ts +0 -1
  166. package/src/isomorphic/anchor29.ts +0 -1
  167. package/src/isomorphic/grpc.browser.ts +0 -4
  168. package/src/isomorphic/grpc.node.ts +0 -130
  169. package/src/isomorphic/grpc.ts +0 -1
  170. package/src/jupiter/jupiterClient.ts +0 -502
  171. package/src/keypair.ts +0 -32
  172. package/src/margin/README.md +0 -138
  173. package/src/marginCalculation.ts +0 -407
  174. package/src/marinade/idl/idl.json +0 -1962
  175. package/src/marinade/index.ts +0 -73
  176. package/src/marinade/types.ts +0 -3925
  177. package/src/math/amm.ts +0 -1758
  178. package/src/math/auction.ts +0 -480
  179. package/src/math/bankruptcy.ts +0 -138
  180. package/src/math/builder.ts +0 -130
  181. package/src/math/conversion.ts +0 -45
  182. package/src/math/exchangeStatus.ts +0 -261
  183. package/src/math/funding.ts +0 -498
  184. package/src/math/insurance.ts +0 -171
  185. package/src/math/liquidation.ts +0 -433
  186. package/src/math/margin.ts +0 -327
  187. package/src/math/market.ts +0 -487
  188. package/src/math/oracles.ts +0 -477
  189. package/src/math/orders.ts +0 -500
  190. package/src/math/position.ts +0 -381
  191. package/src/math/repeg.ts +0 -223
  192. package/src/math/spotBalance.ts +0 -996
  193. package/src/math/spotMarket.ts +0 -115
  194. package/src/math/spotPosition.ts +0 -263
  195. package/src/math/state.ts +0 -71
  196. package/src/math/superStake.ts +0 -602
  197. package/src/math/tiers.ts +0 -73
  198. package/src/math/trade.ts +0 -879
  199. package/src/math/utils.ts +0 -183
  200. package/src/memcmp.ts +0 -279
  201. package/src/oracles/oracleClientCache.ts +0 -41
  202. package/src/oracles/oracleId.ts +0 -99
  203. package/src/oracles/prelaunchOracleClient.ts +0 -63
  204. package/src/oracles/pythClient.ts +0 -125
  205. package/src/oracles/pythLazerClient.ts +0 -141
  206. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  207. package/src/oracles/strictOraclePrice.ts +0 -40
  208. package/src/oracles/types.ts +0 -82
  209. package/src/oracles/utils.ts +0 -45
  210. package/src/orderParams.ts +0 -117
  211. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  212. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  213. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  214. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  215. package/src/orderSubscriber/index.ts +0 -7
  216. package/src/orderSubscriber/types.ts +0 -64
  217. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  218. package/src/priorityFee/averageStrategy.ts +0 -13
  219. package/src/priorityFee/ewmaStrategy.ts +0 -51
  220. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  221. package/src/priorityFee/index.ts +0 -16
  222. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  223. package/src/priorityFee/maxStrategy.ts +0 -8
  224. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  225. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  226. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  227. package/src/priorityFee/types.ts +0 -82
  228. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  229. package/src/pyth/constants.ts +0 -9
  230. package/src/pyth/index.ts +0 -15
  231. package/src/pyth/pythLazerSubscriber.ts +0 -365
  232. package/src/pyth/types.ts +0 -4451
  233. package/src/pyth/utils.ts +0 -13
  234. package/src/slot/SlotSubscriber.ts +0 -126
  235. package/src/slot/SlothashSubscriber.ts +0 -163
  236. package/src/swap/UnifiedSwapClient.ts +0 -315
  237. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  238. package/src/swift/index.ts +0 -10
  239. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  240. package/src/swift/swiftOrderSubscriber.ts +0 -351
  241. package/src/testClient.ts +0 -42
  242. package/src/titan/titanClient.ts +0 -438
  243. package/src/token/index.ts +0 -13
  244. package/src/tokenFaucet.ts +0 -296
  245. package/src/tx/baseTxSender.ts +0 -651
  246. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  247. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  248. package/src/tx/blockhashFetcher/types.ts +0 -9
  249. package/src/tx/fastSingleTxSender.ts +0 -200
  250. package/src/tx/forwardOnlyTxSender.ts +0 -193
  251. package/src/tx/priorityFeeCalculator.ts +0 -117
  252. package/src/tx/reportTransactionError.ts +0 -176
  253. package/src/tx/retryTxSender.ts +0 -177
  254. package/src/tx/txHandler.ts +0 -1009
  255. package/src/tx/txParamProcessor.ts +0 -225
  256. package/src/tx/types.ts +0 -117
  257. package/src/tx/utils.ts +0 -133
  258. package/src/tx/whileValidTxSender.ts +0 -377
  259. package/src/types.ts +0 -2575
  260. package/src/user.ts +0 -5316
  261. package/src/userConfig.ts +0 -38
  262. package/src/userMap/PollingSubscription.ts +0 -61
  263. package/src/userMap/WebsocketSubscription.ts +0 -93
  264. package/src/userMap/grpcSubscription.ts +0 -93
  265. package/src/userMap/referrerMap.ts +0 -360
  266. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  267. package/src/userMap/userMap.ts +0 -784
  268. package/src/userMap/userMapConfig.ts +0 -82
  269. package/src/userMap/userStatsMap.ts +0 -393
  270. package/src/userName.ts +0 -37
  271. package/src/userStats.ts +0 -159
  272. package/src/userStatsConfig.ts +0 -35
  273. package/src/util/TransactionConfirmationManager.ts +0 -333
  274. package/src/util/chainClock.ts +0 -65
  275. package/src/util/computeUnits.ts +0 -101
  276. package/src/util/digest.ts +0 -33
  277. package/src/util/ed25519Utils.ts +0 -95
  278. package/src/util/promiseTimeout.ts +0 -23
  279. package/src/velocityClient.ts +0 -14802
  280. package/src/velocityClientConfig.ts +0 -119
  281. package/src/wallet.ts +0 -91
  282. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  283. package/tests/VelocityCore/decode.test.ts +0 -16
  284. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  285. package/tests/VelocityCore/instructions.test.ts +0 -46
  286. package/tests/VelocityCore/pdas.test.ts +0 -30
  287. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  288. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  289. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  290. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  291. package/tests/amm/test.ts +0 -2402
  292. package/tests/auctions/test.ts +0 -81
  293. package/tests/bn/test.ts +0 -355
  294. package/tests/builder/builderFee.test.ts +0 -42
  295. package/tests/ci/verifyConstants.ts +0 -393
  296. package/tests/decode/test.ts +0 -262
  297. package/tests/decode/userAccountBufferStrings.ts +0 -102
  298. package/tests/dlob/helpers.ts +0 -748
  299. package/tests/dlob/test.ts +0 -6969
  300. package/tests/dlob/tickSizeStandardization.ts +0 -545
  301. package/tests/events/parseLogsForCuUsage.ts +0 -139
  302. package/tests/exchangeStatus/test.ts +0 -45
  303. package/tests/insurance/test.ts +0 -40
  304. package/tests/liquidation/test.ts +0 -125
  305. package/tests/oracles/mmOracleGate.test.ts +0 -379
  306. package/tests/oracles/pythPegSnap.test.ts +0 -76
  307. package/tests/sdkParity/enumParity.test.ts +0 -84
  308. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  309. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  310. package/tests/spot/test.ts +0 -281
  311. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  312. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  313. package/tests/tx/priorityFeeCalculator.ts +0 -77
  314. package/tests/tx/priorityFeeStrategy.ts +0 -95
  315. package/tests/user/bankruptcy.ts +0 -165
  316. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  317. package/tests/user/getMarginCalculation.ts +0 -586
  318. package/tests/user/helpers.ts +0 -184
  319. package/tests/user/liquidations.ts +0 -129
  320. package/tests/user/marginCalculations.test.ts +0 -321
  321. package/tests/user/test.ts +0 -833
  322. package/tsconfig.browser.json +0 -18
  323. 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
- }