@drift-labs/common 1.0.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 (400) hide show
  1. package/lib/Config.d.ts +26 -0
  2. package/lib/Config.js +29 -0
  3. package/lib/Config.js.map +1 -0
  4. package/lib/EnvironmentConstants.d.ts +40 -0
  5. package/lib/EnvironmentConstants.js +64 -0
  6. package/lib/EnvironmentConstants.js.map +1 -0
  7. package/lib/actions/actionHelpers/accountDeletionHelpers.d.ts +16 -0
  8. package/lib/actions/actionHelpers/accountDeletionHelpers.js +151 -0
  9. package/lib/actions/actionHelpers/accountDeletionHelpers.js.map +1 -0
  10. package/lib/actions/actionHelpers/actionHelpers.d.ts +13 -0
  11. package/lib/actions/actionHelpers/actionHelpers.js +8 -0
  12. package/lib/actions/actionHelpers/actionHelpers.js.map +1 -0
  13. package/lib/chartConstants.d.ts +2 -0
  14. package/lib/chartConstants.js +14 -0
  15. package/lib/chartConstants.js.map +1 -0
  16. package/lib/clients/candleClient.d.ts +74 -0
  17. package/lib/clients/candleClient.js +364 -0
  18. package/lib/clients/candleClient.js.map +1 -0
  19. package/lib/clients/dataApiWsClient.d.ts +33 -0
  20. package/lib/clients/dataApiWsClient.js +118 -0
  21. package/lib/clients/dataApiWsClient.js.map +1 -0
  22. package/lib/clients/index.d.ts +1 -0
  23. package/lib/clients/index.js +19 -0
  24. package/lib/clients/index.js.map +1 -0
  25. package/lib/clients/marketDataFeed.d.ts +42 -0
  26. package/lib/clients/marketDataFeed.js +422 -0
  27. package/lib/clients/marketDataFeed.js.map +1 -0
  28. package/lib/clients/redisClient.d.ts +89 -0
  29. package/lib/clients/redisClient.js +647 -0
  30. package/lib/clients/redisClient.js.map +1 -0
  31. package/lib/clients/swiftClient.d.ts +57 -0
  32. package/lib/clients/swiftClient.js +289 -0
  33. package/lib/clients/swiftClient.js.map +1 -0
  34. package/lib/clients/tvFeed.d.ts +63 -0
  35. package/lib/clients/tvFeed.js +351 -0
  36. package/lib/clients/tvFeed.js.map +1 -0
  37. package/lib/common-ui-utils/commonUiUtils.d.ts +211 -0
  38. package/lib/common-ui-utils/commonUiUtils.js +624 -0
  39. package/lib/common-ui-utils/commonUiUtils.js.map +1 -0
  40. package/lib/common-ui-utils/index.d.ts +6 -0
  41. package/lib/common-ui-utils/index.js +23 -0
  42. package/lib/common-ui-utils/index.js.map +1 -0
  43. package/lib/common-ui-utils/market.d.ts +27 -0
  44. package/lib/common-ui-utils/market.js +80 -0
  45. package/lib/common-ui-utils/market.js.map +1 -0
  46. package/lib/common-ui-utils/order.d.ts +11 -0
  47. package/lib/common-ui-utils/order.js +161 -0
  48. package/lib/common-ui-utils/order.js.map +1 -0
  49. package/lib/common-ui-utils/settings/settings.d.ts +51 -0
  50. package/lib/common-ui-utils/settings/settings.js +84 -0
  51. package/lib/common-ui-utils/settings/settings.js.map +1 -0
  52. package/lib/common-ui-utils/trading.d.ts +56 -0
  53. package/lib/common-ui-utils/trading.js +200 -0
  54. package/lib/common-ui-utils/trading.js.map +1 -0
  55. package/lib/common-ui-utils/user.d.ts +13 -0
  56. package/lib/common-ui-utils/user.js +124 -0
  57. package/lib/common-ui-utils/user.js.map +1 -0
  58. package/lib/constants/autogenerated/driftErrors.json +1787 -0
  59. package/lib/constants/autogenerated/jup-v4-error-codes.json +67 -0
  60. package/lib/constants/autogenerated/jup-v6-error-codes.json +115 -0
  61. package/lib/constants/dev.d.ts +15 -0
  62. package/lib/constants/dev.js +19 -0
  63. package/lib/constants/dev.js.map +1 -0
  64. package/lib/constants/geoblockList.d.ts +4 -0
  65. package/lib/constants/geoblockList.js +32 -0
  66. package/lib/constants/geoblockList.js.map +1 -0
  67. package/lib/constants/index.d.ts +9 -0
  68. package/lib/constants/index.js +26 -0
  69. package/lib/constants/index.js.map +1 -0
  70. package/lib/constants/markets.d.ts +1 -0
  71. package/lib/constants/markets.js +5 -0
  72. package/lib/constants/markets.js.map +1 -0
  73. package/lib/constants/misc.d.ts +23 -0
  74. package/lib/constants/misc.js +27 -0
  75. package/lib/constants/misc.js.map +1 -0
  76. package/lib/constants/orders.d.ts +12 -0
  77. package/lib/constants/orders.js +79 -0
  78. package/lib/constants/orders.js.map +1 -0
  79. package/lib/constants/pools.d.ts +5 -0
  80. package/lib/constants/pools.js +9 -0
  81. package/lib/constants/pools.js.map +1 -0
  82. package/lib/constants/predictionMarket.d.ts +3 -0
  83. package/lib/constants/predictionMarket.js +7 -0
  84. package/lib/constants/predictionMarket.js.map +1 -0
  85. package/lib/constants/superstake.d.ts +22 -0
  86. package/lib/constants/superstake.js +45 -0
  87. package/lib/constants/superstake.js.map +1 -0
  88. package/lib/constants/trade.d.ts +2 -0
  89. package/lib/constants/trade.js +9 -0
  90. package/lib/constants/trade.js.map +1 -0
  91. package/lib/drift/Drift/clients/AuthorityDrift/DriftL2OrderbookManager.d.ts +68 -0
  92. package/lib/drift/Drift/clients/AuthorityDrift/DriftL2OrderbookManager.js +146 -0
  93. package/lib/drift/Drift/clients/AuthorityDrift/DriftL2OrderbookManager.js.map +1 -0
  94. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.d.ts +204 -0
  95. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js +530 -0
  96. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js.map +1 -0
  97. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/types.d.ts +90 -0
  98. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/types.js +3 -0
  99. package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/types.js.map +1 -0
  100. package/lib/drift/Drift/clients/AuthorityDrift/SubscriptionManager.d.ts +139 -0
  101. package/lib/drift/Drift/clients/AuthorityDrift/SubscriptionManager.js +287 -0
  102. package/lib/drift/Drift/clients/AuthorityDrift/SubscriptionManager.js.map +1 -0
  103. package/lib/drift/Drift/clients/AuthorityDrift/index.d.ts +242 -0
  104. package/lib/drift/Drift/clients/AuthorityDrift/index.js +503 -0
  105. package/lib/drift/Drift/clients/AuthorityDrift/index.js.map +1 -0
  106. package/lib/drift/Drift/clients/CentralServerDrift.d.ts +91 -0
  107. package/lib/drift/Drift/clients/CentralServerDrift.js +326 -0
  108. package/lib/drift/Drift/clients/CentralServerDrift.js.map +1 -0
  109. package/lib/drift/Drift/clients/index.d.ts +3 -0
  110. package/lib/drift/Drift/clients/index.js +20 -0
  111. package/lib/drift/Drift/clients/index.js.map +1 -0
  112. package/lib/drift/Drift/constants/blockchain.d.ts +24 -0
  113. package/lib/drift/Drift/constants/blockchain.js +32 -0
  114. package/lib/drift/Drift/constants/blockchain.js.map +1 -0
  115. package/lib/drift/Drift/constants/errors.d.ts +6 -0
  116. package/lib/drift/Drift/constants/errors.js +14 -0
  117. package/lib/drift/Drift/constants/errors.js.map +1 -0
  118. package/lib/drift/Drift/constants/index.d.ts +3 -0
  119. package/lib/drift/Drift/constants/index.js +20 -0
  120. package/lib/drift/Drift/constants/index.js.map +1 -0
  121. package/lib/drift/Drift/constants/orderbook.d.ts +7 -0
  122. package/lib/drift/Drift/constants/orderbook.js +10 -0
  123. package/lib/drift/Drift/constants/orderbook.js.map +1 -0
  124. package/lib/drift/Drift/data/PollingDlob.d.ts +154 -0
  125. package/lib/drift/Drift/data/PollingDlob.js +387 -0
  126. package/lib/drift/Drift/data/PollingDlob.js.map +1 -0
  127. package/lib/drift/Drift/data/index.d.ts +1 -0
  128. package/lib/drift/Drift/data/index.js +18 -0
  129. package/lib/drift/Drift/data/index.js.map +1 -0
  130. package/lib/drift/Drift/index.d.ts +4 -0
  131. package/lib/drift/Drift/index.js +21 -0
  132. package/lib/drift/Drift/index.js.map +1 -0
  133. package/lib/drift/Drift/stores/MarkPriceCache.d.ts +27 -0
  134. package/lib/drift/Drift/stores/MarkPriceCache.js +59 -0
  135. package/lib/drift/Drift/stores/MarkPriceCache.js.map +1 -0
  136. package/lib/drift/Drift/stores/OraclePriceCache.d.ts +21 -0
  137. package/lib/drift/Drift/stores/OraclePriceCache.js +57 -0
  138. package/lib/drift/Drift/stores/OraclePriceCache.js.map +1 -0
  139. package/lib/drift/Drift/stores/UserAccountCache.d.ts +49 -0
  140. package/lib/drift/Drift/stores/UserAccountCache.js +107 -0
  141. package/lib/drift/Drift/stores/UserAccountCache.js.map +1 -0
  142. package/lib/drift/Drift/stores/index.d.ts +3 -0
  143. package/lib/drift/Drift/stores/index.js +20 -0
  144. package/lib/drift/Drift/stores/index.js.map +1 -0
  145. package/lib/drift/base/actions/index.d.ts +4 -0
  146. package/lib/drift/base/actions/index.js +21 -0
  147. package/lib/drift/base/actions/index.js.map +1 -0
  148. package/lib/drift/base/actions/perp/index.d.ts +2 -0
  149. package/lib/drift/base/actions/perp/index.js +19 -0
  150. package/lib/drift/base/actions/perp/index.js.map +1 -0
  151. package/lib/drift/base/actions/perp/settleFunding.d.ts +25 -0
  152. package/lib/drift/base/actions/perp/settleFunding.js +41 -0
  153. package/lib/drift/base/actions/perp/settleFunding.js.map +1 -0
  154. package/lib/drift/base/actions/perp/settlePnl.d.ts +35 -0
  155. package/lib/drift/base/actions/perp/settlePnl.js +44 -0
  156. package/lib/drift/base/actions/perp/settlePnl.js.map +1 -0
  157. package/lib/drift/base/actions/spot/borrow.d.ts +1 -0
  158. package/lib/drift/base/actions/spot/borrow.js +8 -0
  159. package/lib/drift/base/actions/spot/borrow.js.map +1 -0
  160. package/lib/drift/base/actions/spot/deposit.d.ts +40 -0
  161. package/lib/drift/base/actions/spot/deposit.js +82 -0
  162. package/lib/drift/base/actions/spot/deposit.js.map +1 -0
  163. package/lib/drift/base/actions/spot/index.d.ts +3 -0
  164. package/lib/drift/base/actions/spot/index.js +20 -0
  165. package/lib/drift/base/actions/spot/index.js.map +1 -0
  166. package/lib/drift/base/actions/spot/withdraw.d.ts +16 -0
  167. package/lib/drift/base/actions/spot/withdraw.js +39 -0
  168. package/lib/drift/base/actions/spot/withdraw.js.map +1 -0
  169. package/lib/drift/base/actions/trade/cancelOrder.d.ts +47 -0
  170. package/lib/drift/base/actions/trade/cancelOrder.js +55 -0
  171. package/lib/drift/base/actions/trade/cancelOrder.js.map +1 -0
  172. package/lib/drift/base/actions/trade/editOrder.d.ts +55 -0
  173. package/lib/drift/base/actions/trade/editOrder.js +35 -0
  174. package/lib/drift/base/actions/trade/editOrder.js.map +1 -0
  175. package/lib/drift/base/actions/trade/index.d.ts +4 -0
  176. package/lib/drift/base/actions/trade/index.js +21 -0
  177. package/lib/drift/base/actions/trade/index.js.map +1 -0
  178. package/lib/drift/base/actions/trade/openPerpOrder/index.d.ts +3 -0
  179. package/lib/drift/base/actions/trade/openPerpOrder/index.js +20 -0
  180. package/lib/drift/base/actions/trade/openPerpOrder/index.js.map +1 -0
  181. package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.d.ts +84 -0
  182. package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js +293 -0
  183. package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js.map +1 -0
  184. package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.d.ts +19 -0
  185. package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js +161 -0
  186. package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js.map +1 -0
  187. package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.d.ts +166 -0
  188. package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js +156 -0
  189. package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js.map +1 -0
  190. package/lib/drift/base/actions/trade/swap.d.ts +62 -0
  191. package/lib/drift/base/actions/trade/swap.js +60 -0
  192. package/lib/drift/base/actions/trade/swap.js.map +1 -0
  193. package/lib/drift/base/actions/user/create.d.ts +75 -0
  194. package/lib/drift/base/actions/user/create.js +104 -0
  195. package/lib/drift/base/actions/user/create.js.map +1 -0
  196. package/lib/drift/base/actions/user/delete.d.ts +47 -0
  197. package/lib/drift/base/actions/user/delete.js +39 -0
  198. package/lib/drift/base/actions/user/delete.js.map +1 -0
  199. package/lib/drift/base/actions/user/index.d.ts +1 -0
  200. package/lib/drift/base/actions/user/index.js +18 -0
  201. package/lib/drift/base/actions/user/index.js.map +1 -0
  202. package/lib/drift/base/constants/accountNames.d.ts +1 -0
  203. package/lib/drift/base/constants/accountNames.js +13 -0
  204. package/lib/drift/base/constants/accountNames.js.map +1 -0
  205. package/lib/drift/base/details/index.d.ts +2 -0
  206. package/lib/drift/base/details/index.js +19 -0
  207. package/lib/drift/base/details/index.js.map +1 -0
  208. package/lib/drift/base/details/market/funding.d.ts +9 -0
  209. package/lib/drift/base/details/market/funding.js +50 -0
  210. package/lib/drift/base/details/market/funding.js.map +1 -0
  211. package/lib/drift/base/details/market/index.d.ts +2 -0
  212. package/lib/drift/base/details/market/index.js +19 -0
  213. package/lib/drift/base/details/market/index.js.map +1 -0
  214. package/lib/drift/base/details/market/openInterest.d.ts +5 -0
  215. package/lib/drift/base/details/market/openInterest.js +12 -0
  216. package/lib/drift/base/details/market/openInterest.js.map +1 -0
  217. package/lib/drift/base/details/user/balances.d.ts +40 -0
  218. package/lib/drift/base/details/user/balances.js +39 -0
  219. package/lib/drift/base/details/user/balances.js.map +1 -0
  220. package/lib/drift/base/details/user/index.d.ts +4 -0
  221. package/lib/drift/base/details/user/index.js +21 -0
  222. package/lib/drift/base/details/user/index.js.map +1 -0
  223. package/lib/drift/base/details/user/marginInfo.d.ts +29 -0
  224. package/lib/drift/base/details/user/marginInfo.js +49 -0
  225. package/lib/drift/base/details/user/marginInfo.js.map +1 -0
  226. package/lib/drift/base/details/user/orders.d.ts +3 -0
  227. package/lib/drift/base/details/user/orders.js +11 -0
  228. package/lib/drift/base/details/user/orders.js.map +1 -0
  229. package/lib/drift/base/details/user/positions.d.ts +70 -0
  230. package/lib/drift/base/details/user/positions.js +146 -0
  231. package/lib/drift/base/details/user/positions.js.map +1 -0
  232. package/lib/drift/cli.d.ts +25 -0
  233. package/lib/drift/cli.js +900 -0
  234. package/lib/drift/cli.js.map +1 -0
  235. package/lib/drift/constants/apiUrls.d.ts +27 -0
  236. package/lib/drift/constants/apiUrls.js +31 -0
  237. package/lib/drift/constants/apiUrls.js.map +1 -0
  238. package/lib/drift/example.d.ts +19 -0
  239. package/lib/drift/example.js +249 -0
  240. package/lib/drift/example.js.map +1 -0
  241. package/lib/drift/index.d.ts +3 -0
  242. package/lib/drift/index.js +20 -0
  243. package/lib/drift/index.js.map +1 -0
  244. package/lib/drift/utils/auctionParamsResponseMapper.d.ts +45 -0
  245. package/lib/drift/utils/auctionParamsResponseMapper.js +148 -0
  246. package/lib/drift/utils/auctionParamsResponseMapper.js.map +1 -0
  247. package/lib/drift/utils/funding.d.ts +2 -0
  248. package/lib/drift/utils/funding.js +9 -0
  249. package/lib/drift/utils/funding.js.map +1 -0
  250. package/lib/drift/utils/index.d.ts +3 -0
  251. package/lib/drift/utils/index.js +23 -0
  252. package/lib/drift/utils/index.js.map +1 -0
  253. package/lib/drift/utils/orderParams.d.ts +48 -0
  254. package/lib/drift/utils/orderParams.js +140 -0
  255. package/lib/drift/utils/orderParams.js.map +1 -0
  256. package/lib/index.d.ts +45 -0
  257. package/lib/index.js +68 -0
  258. package/lib/index.js.map +1 -0
  259. package/lib/serializableTypes.d.ts +961 -0
  260. package/lib/serializableTypes.js +3887 -0
  261. package/lib/serializableTypes.js.map +1 -0
  262. package/lib/types/MarketId.d.ts +26 -0
  263. package/lib/types/MarketId.js +64 -0
  264. package/lib/types/MarketId.js.map +1 -0
  265. package/lib/types/Superstake.d.ts +7 -0
  266. package/lib/types/Superstake.js +3 -0
  267. package/lib/types/Superstake.js.map +1 -0
  268. package/lib/types/UIEnv.d.ts +26 -0
  269. package/lib/types/UIEnv.js +49 -0
  270. package/lib/types/UIEnv.js.map +1 -0
  271. package/lib/types/UIMarket.d.ts +94 -0
  272. package/lib/types/UIMarket.js +224 -0
  273. package/lib/types/UIMarket.js.map +1 -0
  274. package/lib/types/candles.d.ts +4 -0
  275. package/lib/types/candles.js +9 -0
  276. package/lib/types/candles.js.map +1 -0
  277. package/lib/types/dataServer.d.ts +53 -0
  278. package/lib/types/dataServer.js +3 -0
  279. package/lib/types/dataServer.js.map +1 -0
  280. package/lib/types/historyServer.d.ts +38 -0
  281. package/lib/types/historyServer.js +11 -0
  282. package/lib/types/historyServer.js.map +1 -0
  283. package/lib/types/index.d.ts +12 -0
  284. package/lib/types/index.js +29 -0
  285. package/lib/types/index.js.map +1 -0
  286. package/lib/types/leaderboard.d.ts +80 -0
  287. package/lib/types/leaderboard.js +11 -0
  288. package/lib/types/leaderboard.js.map +1 -0
  289. package/lib/types/remote-configs.d.ts +61 -0
  290. package/lib/types/remote-configs.js +3 -0
  291. package/lib/types/remote-configs.js.map +1 -0
  292. package/lib/types/trade.d.ts +18 -0
  293. package/lib/types/trade.js +3 -0
  294. package/lib/types/trade.js.map +1 -0
  295. package/lib/types/user.d.ts +40 -0
  296. package/lib/types/user.js +3 -0
  297. package/lib/types/user.js.map +1 -0
  298. package/lib/types/utility.d.ts +15 -0
  299. package/lib/types/utility.js +3 -0
  300. package/lib/types/utility.js.map +1 -0
  301. package/lib/utils/CircularBuffers/CircularBuffer.d.ts +22 -0
  302. package/lib/utils/CircularBuffers/CircularBuffer.js +73 -0
  303. package/lib/utils/CircularBuffers/CircularBuffer.js.map +1 -0
  304. package/lib/utils/CircularBuffers/UniqueCircularBuffer.d.ts +19 -0
  305. package/lib/utils/CircularBuffers/UniqueCircularBuffer.js +78 -0
  306. package/lib/utils/CircularBuffers/UniqueCircularBuffer.js.map +1 -0
  307. package/lib/utils/CircularBuffers/index.d.ts +2 -0
  308. package/lib/utils/CircularBuffers/index.js +19 -0
  309. package/lib/utils/CircularBuffers/index.js.map +1 -0
  310. package/lib/utils/MultiplexWebSocket.d.ts +95 -0
  311. package/lib/utils/MultiplexWebSocket.js +416 -0
  312. package/lib/utils/MultiplexWebSocket.js.map +1 -0
  313. package/lib/utils/NumLib.d.ts +106 -0
  314. package/lib/utils/NumLib.js +300 -0
  315. package/lib/utils/NumLib.js.map +1 -0
  316. package/lib/utils/SharedInterval.d.ts +21 -0
  317. package/lib/utils/SharedInterval.js +47 -0
  318. package/lib/utils/SharedInterval.js.map +1 -0
  319. package/lib/utils/SlotBasedResultValidator.d.ts +9 -0
  320. package/lib/utils/SlotBasedResultValidator.js +27 -0
  321. package/lib/utils/SlotBasedResultValidator.js.map +1 -0
  322. package/lib/utils/Stopwatch.d.ts +15 -0
  323. package/lib/utils/Stopwatch.js +31 -0
  324. package/lib/utils/Stopwatch.js.map +1 -0
  325. package/lib/utils/StrictEventEmitter.d.ts +15 -0
  326. package/lib/utils/StrictEventEmitter.js +55 -0
  327. package/lib/utils/StrictEventEmitter.js.map +1 -0
  328. package/lib/utils/WalletConnectionState.d.ts +31 -0
  329. package/lib/utils/WalletConnectionState.js +83 -0
  330. package/lib/utils/WalletConnectionState.js.map +1 -0
  331. package/lib/utils/assert.d.ts +1 -0
  332. package/lib/utils/assert.js +10 -0
  333. package/lib/utils/assert.js.map +1 -0
  334. package/lib/utils/candles/Candle.d.ts +94 -0
  335. package/lib/utils/candles/Candle.js +580 -0
  336. package/lib/utils/candles/Candle.js.map +1 -0
  337. package/lib/utils/candles/types.d.ts +8 -0
  338. package/lib/utils/candles/types.js +3 -0
  339. package/lib/utils/candles/types.js.map +1 -0
  340. package/lib/utils/dlob-server/DlobServerWebsocketUtils.d.ts +57 -0
  341. package/lib/utils/dlob-server/DlobServerWebsocketUtils.js +137 -0
  342. package/lib/utils/dlob-server/DlobServerWebsocketUtils.js.map +1 -0
  343. package/lib/utils/driftEvents.d.ts +10 -0
  344. package/lib/utils/driftEvents.js +123 -0
  345. package/lib/utils/driftEvents.js.map +1 -0
  346. package/lib/utils/equalityChecks.d.ts +12 -0
  347. package/lib/utils/equalityChecks.js +71 -0
  348. package/lib/utils/equalityChecks.js.map +1 -0
  349. package/lib/utils/featureFlags.d.ts +3 -0
  350. package/lib/utils/featureFlags.js +7 -0
  351. package/lib/utils/featureFlags.js.map +1 -0
  352. package/lib/utils/geoblock/index.d.ts +4 -0
  353. package/lib/utils/geoblock/index.js +20 -0
  354. package/lib/utils/geoblock/index.js.map +1 -0
  355. package/lib/utils/index.d.ts +181 -0
  356. package/lib/utils/index.js +608 -0
  357. package/lib/utils/index.js.map +1 -0
  358. package/lib/utils/insuranceFund.d.ts +15 -0
  359. package/lib/utils/insuranceFund.js +84 -0
  360. package/lib/utils/insuranceFund.js.map +1 -0
  361. package/lib/utils/logger.d.ts +5 -0
  362. package/lib/utils/logger.js +53 -0
  363. package/lib/utils/logger.js.map +1 -0
  364. package/lib/utils/math.d.ts +10 -0
  365. package/lib/utils/math.js +89 -0
  366. package/lib/utils/math.js.map +1 -0
  367. package/lib/utils/orderbook/index.d.ts +65 -0
  368. package/lib/utils/orderbook/index.js +80 -0
  369. package/lib/utils/orderbook/index.js.map +1 -0
  370. package/lib/utils/pollingSequenceGuard.d.ts +9 -0
  371. package/lib/utils/pollingSequenceGuard.js +24 -0
  372. package/lib/utils/pollingSequenceGuard.js.map +1 -0
  373. package/lib/utils/priority-fees/PriorityFeeCalculator.d.ts +24 -0
  374. package/lib/utils/priority-fees/PriorityFeeCalculator.js +53 -0
  375. package/lib/utils/priority-fees/PriorityFeeCalculator.js.map +1 -0
  376. package/lib/utils/priority-fees/PriorityFeeStrategies.d.ts +5 -0
  377. package/lib/utils/priority-fees/PriorityFeeStrategies.js +43 -0
  378. package/lib/utils/priority-fees/PriorityFeeStrategies.js.map +1 -0
  379. package/lib/utils/priority-fees/index.d.ts +2 -0
  380. package/lib/utils/priority-fees/index.js +19 -0
  381. package/lib/utils/priority-fees/index.js.map +1 -0
  382. package/lib/utils/priorityFees.d.ts +14 -0
  383. package/lib/utils/priorityFees.js +68 -0
  384. package/lib/utils/priorityFees.js.map +1 -0
  385. package/lib/utils/rpcLatency.d.ts +7 -0
  386. package/lib/utils/rpcLatency.js +49 -0
  387. package/lib/utils/rpcLatency.js.map +1 -0
  388. package/lib/utils/rxjs.d.ts +11 -0
  389. package/lib/utils/rxjs.js +24 -0
  390. package/lib/utils/rxjs.js.map +1 -0
  391. package/lib/utils/s3Buckets.d.ts +43 -0
  392. package/lib/utils/s3Buckets.js +108 -0
  393. package/lib/utils/s3Buckets.js.map +1 -0
  394. package/lib/utils/superstake.d.ts +86 -0
  395. package/lib/utils/superstake.js +224 -0
  396. package/lib/utils/superstake.js.map +1 -0
  397. package/lib/utils/token.d.ts +16 -0
  398. package/lib/utils/token.js +44 -0
  399. package/lib/utils/token.js.map +1 -0
  400. package/package.json +87 -0
@@ -0,0 +1,364 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CandleClient = void 0;
4
+ const sdk_1 = require("@drift-labs/sdk");
5
+ const Candle_1 = require("../utils/candles/Candle");
6
+ const StrictEventEmitter_1 = require("../utils/StrictEventEmitter");
7
+ const EnvironmentConstants_1 = require("../EnvironmentConstants");
8
+ const assert_1 = require("../utils/assert");
9
+ const marketDataFeed_1 = require("./marketDataFeed");
10
+ const getMarketSymbolForMarketId = (marketId, uiEnv) => {
11
+ const isPerp = marketId.isPerp;
12
+ const sdkEnv = uiEnv.sdkEnv;
13
+ if (isPerp) {
14
+ const marketConfigs = sdkEnv === 'mainnet-beta' ? sdk_1.MainnetPerpMarkets : sdk_1.DevnetPerpMarkets;
15
+ const targetMarketConfig = marketConfigs.find((config) => config.marketIndex === marketId.marketIndex);
16
+ return targetMarketConfig.symbol;
17
+ }
18
+ else {
19
+ const marketConfigs = sdkEnv === 'mainnet-beta' ? sdk_1.MainnetSpotMarkets : sdk_1.DevnetSpotMarkets;
20
+ const targetMarketConfig = marketConfigs.find((config) => config.marketIndex === marketId.marketIndex);
21
+ return targetMarketConfig.symbol;
22
+ }
23
+ };
24
+ // This is the maximum number of candles that can be fetched in a single GET request
25
+ const CANDLE_FETCH_LIMIT = 1000;
26
+ const getBaseDataApiUrl = (env) => {
27
+ const constantEnv = env.isStaging ? 'staging' : env.isDevnet ? 'dev' : 'mainnet';
28
+ const dataApiUrl = EnvironmentConstants_1.EnvironmentConstants.dataServerUrl[constantEnv];
29
+ return dataApiUrl.replace('https://', '');
30
+ };
31
+ const getCandleFetchUrl = ({ env, marketId, resolution, startTs, countToFetch, }) => {
32
+ const baseDataApiUrl = getBaseDataApiUrl(env);
33
+ // Base URL without startTs parameter
34
+ let fetchUrl = `https://${baseDataApiUrl}/market/${getMarketSymbolForMarketId(marketId, env)}/candles/${resolution}?limit=${Math.min(countToFetch, CANDLE_FETCH_LIMIT)}`;
35
+ // Only add startTs parameter if it's provided
36
+ if (startTs !== undefined) {
37
+ fetchUrl += `&startTs=${startTs}`;
38
+ }
39
+ return fetchUrl;
40
+ };
41
+ // Separate event bus for candle events
42
+ class CandleEventBus extends StrictEventEmitter_1.StrictEventEmitter {
43
+ constructor() {
44
+ super();
45
+ }
46
+ }
47
+ // This class is reponsible for fetching candles from the data API's GET endpoint
48
+ class CandleFetcher {
49
+ // Helper method to generate a cache key from market ID and resolution
50
+ static getCacheKey(marketId, resolution) {
51
+ return `${marketId.key}-${resolution}`;
52
+ }
53
+ // Public method to clear the entire cache
54
+ static clearWholeCache() {
55
+ CandleFetcher.recentCandlesCache.clear();
56
+ }
57
+ static clearCacheForSubscription(marketId, resolution) {
58
+ CandleFetcher.recentCandlesCache.delete(CandleFetcher.getCacheKey(marketId, resolution));
59
+ }
60
+ constructor(config) {
61
+ /**
62
+ * Candles are fetched in ascending order of time (index 0 -> oldest to index n -> newest)
63
+ */
64
+ this.fetchCandlesFromApi = async (fetchUrl) => {
65
+ const response = await fetch(fetchUrl);
66
+ const parsedResponse = (await response.json());
67
+ if (!parsedResponse.success) {
68
+ throw new Error('Failed to fetch candles from data API');
69
+ }
70
+ return parsedResponse.records;
71
+ };
72
+ this.getCountOfCandlesBetweenStartAndEndTs = (startTs, endTs) => {
73
+ const diffInSeconds = endTs - startTs;
74
+ const resolutionInSeconds = Candle_1.Candle.resolutionStringToCandleLengthMs(this.config.resolution) / 1000;
75
+ const diffInCandles = diffInSeconds / resolutionInSeconds;
76
+ return Math.ceil(diffInCandles);
77
+ };
78
+ /**
79
+ * Try to get candles from the cache if they're available.
80
+ * Returns null if no cached candles are available for the requested range.
81
+ */
82
+ this.getFromCache = () => {
83
+ // Generate cache key for the current request
84
+ const cacheKey = CandleFetcher.getCacheKey(this.config.marketId, this.config.resolution);
85
+ const cachedCandles = CandleFetcher.recentCandlesCache.get(cacheKey);
86
+ // Check if we have cached candles for this market and resolution
87
+ if (cachedCandles) {
88
+ // Check if the requested time range is within the bounds of cached candles
89
+ if (this.config.fromTs >= cachedCandles.earliestTs &&
90
+ this.config.toTs <= cachedCandles.latestTs) {
91
+ // Filter cached candles to the requested time range
92
+ const filteredCandles = cachedCandles.candles.filter((candle) => candle.ts >= this.config.fromTs && candle.ts <= this.config.toTs);
93
+ return filteredCandles;
94
+ }
95
+ }
96
+ return null;
97
+ };
98
+ /**
99
+ * Determines if we should use the recent candles approach (without startTs for better caching).
100
+ */
101
+ this.isRequestingRecentCandles = (nowSeconds, candleLengthSeconds) => {
102
+ // Calculate cutoff time for "recent" candles (now - 1000 candles worth of time)
103
+ const recentCandlesCutoffTs = nowSeconds - candleLengthSeconds * CANDLE_FETCH_LIMIT;
104
+ // Check if we're fetching recent candles based on the fromTs
105
+ return this.config.fromTs >= recentCandlesCutoffTs;
106
+ };
107
+ /**
108
+ * Fetch recent candles without using startTs for better caching.
109
+ */
110
+ this.fetchRecentCandles = async (nowSeconds) => {
111
+ // Fetch recent candles without specifying startTs
112
+ const fetchUrl = getCandleFetchUrl({
113
+ env: this.config.env,
114
+ marketId: this.config.marketId,
115
+ resolution: this.config.resolution,
116
+ countToFetch: CANDLE_FETCH_LIMIT, // Ask for max candles to ensure we get enough
117
+ });
118
+ // Get the candles and reverse them (into ascending order)
119
+ const fetchedCandles = await this.fetchCandlesFromApi(fetchUrl);
120
+ fetchedCandles.reverse();
121
+ if (fetchedCandles.length === 0) {
122
+ return [];
123
+ }
124
+ // Store the full fetchedCandles in cache before filtering
125
+ this.updateCandleCache(fetchedCandles, nowSeconds);
126
+ // Filter to only include candles in the requested time range
127
+ const filteredCandles = this.filterCandlesByTimeRange(fetchedCandles);
128
+ return filteredCandles;
129
+ };
130
+ /**
131
+ * Filter candles to only include those in the requested time range.
132
+ */
133
+ this.filterCandlesByTimeRange = (candles) => {
134
+ return candles.filter((candle) => candle.ts >= this.config.fromTs && candle.ts <= this.config.toTs);
135
+ };
136
+ /**
137
+ * Update the candle cache with the latest fetched candles.
138
+ */
139
+ this.updateCandleCache = (fetchedCandles, nowSeconds) => {
140
+ if (fetchedCandles.length > 0) {
141
+ // Generate cache key
142
+ const cacheKey = CandleFetcher.getCacheKey(this.config.marketId, this.config.resolution);
143
+ // Sort candles by timestamp to find earliest and latest
144
+ const sortedCandles = [...fetchedCandles].sort((a, b) => a.ts - b.ts);
145
+ const earliestTs = sortedCandles[0].ts;
146
+ const latestTs = sortedCandles[sortedCandles.length - 1].ts;
147
+ // Update or add to cache
148
+ CandleFetcher.recentCandlesCache.set(cacheKey, {
149
+ candles: sortedCandles,
150
+ earliestTs,
151
+ latestTs,
152
+ fetchTime: nowSeconds,
153
+ });
154
+ }
155
+ };
156
+ /**
157
+ * Fetch historical candles with pagination using startTs.
158
+ */
159
+ this.fetchHistoricalCandles = async () => {
160
+ let candlesRemainingToFetch = this.getCountOfCandlesBetweenStartAndEndTs(this.config.fromTs, this.config.toTs);
161
+ let currentStartTs = this.config.toTs; // The data API takes "startTs" as the "first timestamp you want going backwards in time" e.g. all candles will be returned with descending time backwards from the startTs
162
+ let hitEndTsCutoff = false;
163
+ let candles = [];
164
+ while (candlesRemainingToFetch > 0) {
165
+ const result = await this.fetchHistoricalCandlesBatch(candlesRemainingToFetch, currentStartTs);
166
+ if (result.fetchedCandles.length === 0) {
167
+ candlesRemainingToFetch = 0;
168
+ break;
169
+ }
170
+ // the deeper the loop, the older the result.candlesToAdd will be
171
+ candles = [...result.candlesToAdd, ...candles];
172
+ candlesRemainingToFetch -= result.candlesToAdd.length;
173
+ hitEndTsCutoff = result.hitEndTsCutoff;
174
+ if (result.requiresAnotherFetch) {
175
+ currentStartTs = result.nextStartTs;
176
+ }
177
+ else if (candlesRemainingToFetch > 0) {
178
+ // This means we have fetched all the candles available for this time range and we can stop fetching
179
+ candlesRemainingToFetch = 0;
180
+ }
181
+ }
182
+ if (hitEndTsCutoff) {
183
+ return this.filterCandlesByTimeRange(candles);
184
+ }
185
+ return candles;
186
+ };
187
+ /**
188
+ * Fetch historical candles with pagination, backwards from the toTs value given in the config.
189
+ *
190
+ * This method works by looping backwards from the LATEST (toTs) timestamp to the OLDEST (fromTs) timestamp.
191
+ *
192
+ * Things to note:
193
+ * - There is a limit to how many candles can be fetched in a single request (see CANDLE_FETCH_LIMIT)
194
+ * - We have implemented this to minimise the cardinality in the API request because that helps with caching
195
+ */
196
+ this.fetchHistoricalCandlesBatch = async (candlesRemainingToFetch, currentStartTs) => {
197
+ const candlesToFetch = Math.min(candlesRemainingToFetch, CANDLE_FETCH_LIMIT);
198
+ const fetchUrl = getCandleFetchUrl({
199
+ env: this.config.env,
200
+ marketId: this.config.marketId,
201
+ resolution: this.config.resolution,
202
+ startTs: currentStartTs, // Include startTs for historical candles
203
+ countToFetch: candlesToFetch,
204
+ });
205
+ const fetchedCandles = await this.fetchCandlesFromApi(fetchUrl);
206
+ // Reverse candles into ascending order
207
+ fetchedCandles.reverse();
208
+ if (fetchedCandles.length === 0) {
209
+ return {
210
+ fetchedCandles,
211
+ candlesToAdd: [],
212
+ hitEndTsCutoff: false,
213
+ requiresAnotherFetch: false,
214
+ nextStartTs: currentStartTs,
215
+ };
216
+ }
217
+ const lastCandle = fetchedCandles[fetchedCandles.length - 1]; // This is the LATEST candle .. (they are sorted ascending by time right now)
218
+ const hitPageSizeCutoff = fetchedCandles.length === CANDLE_FETCH_LIMIT;
219
+ const hitEndTsCutoff = lastCandle.ts < this.config.fromTs;
220
+ const requiresAnotherFetch = hitPageSizeCutoff && !hitEndTsCutoff; // If the number of candles returned is equal to the maximum number of candles that can be fetched in a single GET request, then we need to fetch more candles
221
+ let candlesToAdd = fetchedCandles;
222
+ let nextStartTs = currentStartTs;
223
+ if (requiresAnotherFetch) {
224
+ // If we need to do another fetch, trim any candles with the same timestamp as the last candle in the previous fetch, because that is the pointer for our next fetch and we don't want to duplicate candles
225
+ candlesToAdd = candlesToAdd.filter((candle) => {
226
+ return candle.ts < lastCandle.ts;
227
+ });
228
+ const oldestCandle = fetchedCandles[0]; // first candle is the oldest
229
+ nextStartTs = oldestCandle.ts; // If we are doing another loop, then the trimmed candles have all the candles except for ones with the last candle's timestamp. For the next loop we want to fetch from that timestamp;
230
+ }
231
+ return {
232
+ fetchedCandles,
233
+ candlesToAdd,
234
+ hitEndTsCutoff,
235
+ requiresAnotherFetch,
236
+ nextStartTs,
237
+ };
238
+ };
239
+ /**
240
+ * This class needs to fetch candles based on the config.
241
+ *
242
+ * If the number of candles requested exceeds the maximum number of candles that can be fetched in a single GET request, then it needs to loop multiple get requests, using the last candle's timestamp as the offset startTs for each subsequent request. If the number of candles returned is less than the requested number of candles, then we have fetched all the candles available.
243
+ *
244
+ * For recent candles (ones where fromTs > now - candleLength*1000), we avoid using startTs in the URL to improve caching,
245
+ * and instead fetch the most recent 1000 candles and then trim the result.
246
+ */
247
+ this.fetchCandles = async () => {
248
+ // Check cache first
249
+ const cachedCandles = this.getFromCache();
250
+ if (cachedCandles) {
251
+ return cachedCandles;
252
+ }
253
+ // Calculate the candle length in seconds for the current resolution
254
+ const candleLengthMs = Candle_1.Candle.resolutionStringToCandleLengthMs(this.config.resolution);
255
+ const candleLengthSeconds = candleLengthMs / 1000;
256
+ // Get current time in seconds
257
+ const nowSeconds = Math.floor(Date.now() / 1000);
258
+ // Check if we're fetching recent candles
259
+ if (this.isRequestingRecentCandles(nowSeconds, candleLengthSeconds)) {
260
+ return this.fetchRecentCandles(nowSeconds);
261
+ }
262
+ // For historical candles (older than the last 1000 candles), use the previous approach
263
+ // with startTs for pagination
264
+ return this.fetchHistoricalCandles();
265
+ };
266
+ this.config = config;
267
+ }
268
+ }
269
+ // Cache for storing recent candles by market ID and resolution
270
+ CandleFetcher.recentCandlesCache = new Map();
271
+ class CandleSubscriber {
272
+ constructor(config, eventBus) {
273
+ this.config = config;
274
+ this.eventBus = eventBus;
275
+ this.subscribeToCandles = async () => {
276
+ this.subscription = marketDataFeed_1.MarketDataFeed.subscribe({
277
+ type: 'candles',
278
+ resolution: this.config.resolution,
279
+ env: this.config.env,
280
+ marketSymbol: getMarketSymbolForMarketId(this.config.marketId, this.config.env),
281
+ });
282
+ this.subscription.observable.subscribe((candle) => {
283
+ this.eventBus.emit('candle-update', candle);
284
+ });
285
+ };
286
+ this.unsubscribe = () => {
287
+ marketDataFeed_1.MarketDataFeed.unsubscribe(this.subscription.id);
288
+ };
289
+ }
290
+ }
291
+ /**
292
+ * This class will subscribe to candles from the Drift Data API.
293
+ *
294
+ * Note: If you are using TradingView you probably want to just use the DriftTvFeed class instead.
295
+ */
296
+ class CandleClient {
297
+ constructor() {
298
+ this.activeSubscriptions = new Map();
299
+ this.subscribe = async (config, subscriptionKey) => {
300
+ // Kill any existing subscription with the same key before creating a new one
301
+ if (this.activeSubscriptions.has(subscriptionKey)) {
302
+ this.unsubscribe(subscriptionKey);
303
+ }
304
+ const eventBus = new CandleEventBus();
305
+ const subscriber = new CandleSubscriber(config, eventBus);
306
+ await subscriber.subscribeToCandles();
307
+ this.activeSubscriptions.set(subscriptionKey, {
308
+ subscriber,
309
+ eventBus,
310
+ });
311
+ return;
312
+ };
313
+ /**
314
+ *
315
+ * @param config {
316
+ *
317
+ * env: UIEnv;
318
+ *
319
+ * marketId: MarketId;
320
+ *
321
+ * resolution: CandleResolution;
322
+ *
323
+ * fromTs: number; // Seconds :: This should be the START (oldest) timestamp of the candles to fetch
324
+ *
325
+ * toTs: number; // Seconds :: This should be the END (newest) timestamp of the candles to fetch
326
+ *
327
+ * }
328
+ * @returns
329
+ */
330
+ this.fetch = async (config) => {
331
+ (0, assert_1.assert)(config.fromTs < config.toTs, 'fromTs must be less than toTs');
332
+ const nowSeconds = Math.floor(Date.now() / 1000);
333
+ (0, assert_1.assert)(config.fromTs <= nowSeconds && config.toTs <= nowSeconds, `fromTs and toTs cannot be in the future (Requested fromTs: ${new Date(config.fromTs * 1000).toISOString()} and toTs: ${new Date(config.toTs * 1000).toISOString()}, Current time: ${new Date(nowSeconds * 1000).toISOString()})`);
334
+ const candleFetcher = new CandleFetcher(config);
335
+ const candles = await candleFetcher.fetchCandles();
336
+ return candles;
337
+ };
338
+ this.unsubscribe = (subscriptionKey) => {
339
+ const subscription = this.activeSubscriptions.get(subscriptionKey);
340
+ if (subscription) {
341
+ CandleFetcher.clearCacheForSubscription(subscription.subscriber.config.marketId, subscription.subscriber.config.resolution);
342
+ subscription.subscriber.unsubscribe();
343
+ subscription.eventBus.removeAllListeners();
344
+ this.activeSubscriptions.delete(subscriptionKey);
345
+ }
346
+ };
347
+ this.unsubscribeAll = () => {
348
+ for (const subscriptionKey of this.activeSubscriptions.keys()) {
349
+ this.unsubscribe(subscriptionKey);
350
+ }
351
+ };
352
+ }
353
+ on(subscriptionKey, event, listener) {
354
+ const subscription = this.activeSubscriptions.get(subscriptionKey);
355
+ if (subscription) {
356
+ subscription.eventBus.on(event, listener);
357
+ }
358
+ else {
359
+ console.warn(`No active subscription found for key: ${subscriptionKey}`);
360
+ }
361
+ }
362
+ }
363
+ exports.CandleClient = CandleClient;
364
+ //# sourceMappingURL=candleClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candleClient.js","sourceRoot":"","sources":["../../src/clients/candleClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tCandleResolution,\n\tDevnetPerpMarkets,\n\tDevnetSpotMarkets,\n\tMainnetPerpMarkets,\n\tMainnetSpotMarkets,\n} from '@drift-labs/sdk';\nimport { JsonCandle, MarketId, MarketSymbol } from '../types';\nimport { Candle } from '../utils/candles/Candle';\nimport { StrictEventEmitter } from '../utils/StrictEventEmitter';\nimport { EnvironmentConstants } from '../EnvironmentConstants';\nimport { UIEnv } from '../types/UIEnv';\nimport { assert } from '../utils/assert';\nimport { CandleSubscriberSubscription, MarketDataFeed } from './marketDataFeed';\n\n/**\n * # CANDLE CLIENT HIGH LEVEL EXPLANATION:\n * The Candle Client uses the Data API (see https://data.api.drift.trade/playground) to source candles to display.\n *\n * There are two key parts of the client:\n * - Fetching Candles\n * - Subscribing to Candles\n *\n * ## Fetching Candles:\n * - We can fetch candles between any timestamp range.\n * - The maximum number of candles we can fetch in a single request is 1000 (see CANDLE_FETCH_LIMIT).\n * - We define \"recent history\" to be the last 1000 candles .. basically whatever comes back from the infra when we don't use a startTs and use the maximum fetch limit.\n * - We want to avoid using high cardinality parameters in the fetch because otherwise we will miss the cache in the infra.\n * \t- A concrete example of this is that we don't attach a startTs parameter when we are fetching candles within recent history (past 1000 candles)\n * - We cache the recent candles in memory so that any subsequent fetches within recent history after the first one will be served from cache.\n * \t- e.g. moving back to a further timeframe on TradingView - the required candles could potentially be in the cache, so we don't need to refetch them.\n *\n * ## Subscribing to Candles:\n * - We subscribe to a websocket endpoint for a given market and resolution.\n * - We allow the client to support multiple concurrent subscriptions, because the TradingView comopnent will sometimes do this when switching between markets.\n *\n * ## Possible Improvements:\n * - Create a more advanced cache which can store more than the most recent 1000 candles, dynamically growing as more candles are added (for now seems unnecessary, rare for someone to go back further than 1000 candles)\n */\n\n// Used by the subscriber client to fetch candles from the data API\ntype CandleFetchConfig = {\n\tenv: UIEnv;\n\tmarketId: MarketId;\n\tresolution: CandleResolution;\n\tfromTs: number; // Seconds\n\ttoTs: number; // Seconds\n};\n\n// Used by the subscriber client to subscribe to the candles websocket endpoint\ntype CandleSubscriptionConfig = {\n\tresolution: CandleResolution;\n\tmarketId: MarketId;\n\tenv: UIEnv;\n};\n\n// This is what the client subscriber uses internally to fetch the candles from the data API\ntype CandleFetchUrlConfig = {\n\tenv: UIEnv;\n\tmarketId: MarketId;\n\tresolution: CandleResolution;\n\tstartTs?: number; // Seconds - now optional\n\tcountToFetch: number;\n};\n\ntype CandleFetchResponseJson = {\n\tsuccess: boolean;\n\trecords: JsonCandle[];\n};\n\nconst getMarketSymbolForMarketId = (marketId: MarketId, uiEnv: UIEnv) => {\n\tconst isPerp = marketId.isPerp;\n\n\tconst sdkEnv = uiEnv.sdkEnv;\n\n\tif (isPerp) {\n\t\tconst marketConfigs =\n\t\t\tsdkEnv === 'mainnet-beta' ? MainnetPerpMarkets : DevnetPerpMarkets;\n\t\tconst targetMarketConfig = marketConfigs.find(\n\t\t\t(config) => config.marketIndex === marketId.marketIndex\n\t\t);\n\t\treturn targetMarketConfig.symbol as MarketSymbol;\n\t} else {\n\t\tconst marketConfigs =\n\t\t\tsdkEnv === 'mainnet-beta' ? MainnetSpotMarkets : DevnetSpotMarkets;\n\t\tconst targetMarketConfig = marketConfigs.find(\n\t\t\t(config) => config.marketIndex === marketId.marketIndex\n\t\t);\n\t\treturn targetMarketConfig.symbol as MarketSymbol;\n\t}\n};\n\n// This is the maximum number of candles that can be fetched in a single GET request\nconst CANDLE_FETCH_LIMIT = 1000;\n\nconst getBaseDataApiUrl = (env: UIEnv) => {\n\tconst constantEnv: keyof typeof EnvironmentConstants.dataServerUrl =\n\t\tenv.isStaging ? 'staging' : env.isDevnet ? 'dev' : 'mainnet';\n\tconst dataApiUrl = EnvironmentConstants.dataServerUrl[constantEnv];\n\treturn dataApiUrl.replace('https://', '');\n};\n\nconst getCandleFetchUrl = ({\n\tenv,\n\tmarketId,\n\tresolution,\n\tstartTs,\n\tcountToFetch,\n}: CandleFetchUrlConfig) => {\n\tconst baseDataApiUrl = getBaseDataApiUrl(env);\n\n\t// Base URL without startTs parameter\n\tlet fetchUrl = `https://${baseDataApiUrl}/market/${getMarketSymbolForMarketId(\n\t\tmarketId,\n\t\tenv\n\t)}/candles/${resolution}?limit=${Math.min(countToFetch, CANDLE_FETCH_LIMIT)}`;\n\n\t// Only add startTs parameter if it's provided\n\tif (startTs !== undefined) {\n\t\tfetchUrl += `&startTs=${startTs}`;\n\t}\n\n\treturn fetchUrl;\n};\n\ntype CandleSubscriberEvents = {\n\t'candle-update': JsonCandle;\n};\n\n// Separate event bus for candle events\nclass CandleEventBus extends StrictEventEmitter<CandleSubscriberEvents> {\n\tconstructor() {\n\t\tsuper();\n\t}\n}\n\n// This class is reponsible for fetching candles from the data API's GET endpoint\nclass CandleFetcher {\n\tprivate readonly config: CandleFetchConfig;\n\n\t// Cache for storing recent candles by market ID and resolution\n\tpublic static recentCandlesCache: Map<\n\t\tstring, // key: `${marketId.key}-${resolution}`\n\t\t{\n\t\t\tcandles: JsonCandle[];\n\t\t\tearliestTs: number;\n\t\t\tlatestTs: number;\n\t\t\tfetchTime: number;\n\t\t}\n\t> = new Map();\n\n\t// Helper method to generate a cache key from market ID and resolution\n\tpublic static getCacheKey(\n\t\tmarketId: MarketId,\n\t\tresolution: CandleResolution\n\t): string {\n\t\treturn `${marketId.key}-${resolution}`;\n\t}\n\n\t// Public method to clear the entire cache\n\tpublic static clearWholeCache() {\n\t\tCandleFetcher.recentCandlesCache.clear();\n\t}\n\n\tpublic static clearCacheForSubscription(\n\t\tmarketId: MarketId,\n\t\tresolution: CandleResolution\n\t) {\n\t\tCandleFetcher.recentCandlesCache.delete(\n\t\t\tCandleFetcher.getCacheKey(marketId, resolution)\n\t\t);\n\t}\n\n\tconstructor(config: CandleFetchConfig) {\n\t\tthis.config = config;\n\t}\n\n\t/**\n\t * Candles are fetched in ascending order of time (index 0 -> oldest to index n -> newest)\n\t */\n\tprivate fetchCandlesFromApi = async (\n\t\tfetchUrl: string\n\t): Promise<JsonCandle[]> => {\n\t\tconst response = await fetch(fetchUrl);\n\t\tconst parsedResponse = (await response.json()) as CandleFetchResponseJson;\n\n\t\tif (!parsedResponse.success) {\n\t\t\tthrow new Error('Failed to fetch candles from data API');\n\t\t}\n\n\t\treturn parsedResponse.records;\n\t};\n\n\tprivate getCountOfCandlesBetweenStartAndEndTs = (\n\t\tstartTs: number,\n\t\tendTs: number\n\t) => {\n\t\tconst diffInSeconds = endTs - startTs;\n\t\tconst resolutionInSeconds =\n\t\t\tCandle.resolutionStringToCandleLengthMs(this.config.resolution) / 1000;\n\t\tconst diffInCandles = diffInSeconds / resolutionInSeconds;\n\t\treturn Math.ceil(diffInCandles);\n\t};\n\n\t/**\n\t * Try to get candles from the cache if they're available.\n\t * Returns null if no cached candles are available for the requested range.\n\t */\n\tprivate getFromCache = (): JsonCandle[] | null => {\n\t\t// Generate cache key for the current request\n\t\tconst cacheKey = CandleFetcher.getCacheKey(\n\t\t\tthis.config.marketId,\n\t\t\tthis.config.resolution\n\t\t);\n\t\tconst cachedCandles = CandleFetcher.recentCandlesCache.get(cacheKey);\n\n\t\t// Check if we have cached candles for this market and resolution\n\t\tif (cachedCandles) {\n\t\t\t// Check if the requested time range is within the bounds of cached candles\n\t\t\tif (\n\t\t\t\tthis.config.fromTs >= cachedCandles.earliestTs &&\n\t\t\t\tthis.config.toTs <= cachedCandles.latestTs\n\t\t\t) {\n\t\t\t\t// Filter cached candles to the requested time range\n\t\t\t\tconst filteredCandles = cachedCandles.candles.filter(\n\t\t\t\t\t(candle) =>\n\t\t\t\t\t\tcandle.ts >= this.config.fromTs && candle.ts <= this.config.toTs\n\t\t\t\t);\n\n\t\t\t\treturn filteredCandles;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t};\n\n\t/**\n\t * Determines if we should use the recent candles approach (without startTs for better caching).\n\t */\n\tprivate isRequestingRecentCandles = (\n\t\tnowSeconds: number,\n\t\tcandleLengthSeconds: number\n\t): boolean => {\n\t\t// Calculate cutoff time for \"recent\" candles (now - 1000 candles worth of time)\n\t\tconst recentCandlesCutoffTs =\n\t\t\tnowSeconds - candleLengthSeconds * CANDLE_FETCH_LIMIT;\n\n\t\t// Check if we're fetching recent candles based on the fromTs\n\t\treturn this.config.fromTs >= recentCandlesCutoffTs;\n\t};\n\n\t/**\n\t * Fetch recent candles without using startTs for better caching.\n\t */\n\tprivate fetchRecentCandles = async (\n\t\tnowSeconds: number\n\t): Promise<JsonCandle[]> => {\n\t\t// Fetch recent candles without specifying startTs\n\t\tconst fetchUrl = getCandleFetchUrl({\n\t\t\tenv: this.config.env,\n\t\t\tmarketId: this.config.marketId,\n\t\t\tresolution: this.config.resolution,\n\t\t\tcountToFetch: CANDLE_FETCH_LIMIT, // Ask for max candles to ensure we get enough\n\t\t});\n\n\t\t// Get the candles and reverse them (into ascending order)\n\t\tconst fetchedCandles = await this.fetchCandlesFromApi(fetchUrl);\n\t\tfetchedCandles.reverse();\n\n\t\tif (fetchedCandles.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Store the full fetchedCandles in cache before filtering\n\t\tthis.updateCandleCache(fetchedCandles, nowSeconds);\n\n\t\t// Filter to only include candles in the requested time range\n\t\tconst filteredCandles = this.filterCandlesByTimeRange(fetchedCandles);\n\n\t\treturn filteredCandles;\n\t};\n\n\t/**\n\t * Filter candles to only include those in the requested time range.\n\t */\n\tprivate filterCandlesByTimeRange = (candles: JsonCandle[]): JsonCandle[] => {\n\t\treturn candles.filter(\n\t\t\t(candle) =>\n\t\t\t\tcandle.ts >= this.config.fromTs && candle.ts <= this.config.toTs\n\t\t);\n\t};\n\n\t/**\n\t * Update the candle cache with the latest fetched candles.\n\t */\n\tprivate updateCandleCache = (\n\t\tfetchedCandles: JsonCandle[],\n\t\tnowSeconds: number\n\t): void => {\n\t\tif (fetchedCandles.length > 0) {\n\t\t\t// Generate cache key\n\t\t\tconst cacheKey = CandleFetcher.getCacheKey(\n\t\t\t\tthis.config.marketId,\n\t\t\t\tthis.config.resolution\n\t\t\t);\n\n\t\t\t// Sort candles by timestamp to find earliest and latest\n\t\t\tconst sortedCandles = [...fetchedCandles].sort((a, b) => a.ts - b.ts);\n\t\t\tconst earliestTs = sortedCandles[0].ts;\n\t\t\tconst latestTs = sortedCandles[sortedCandles.length - 1].ts;\n\n\t\t\t// Update or add to cache\n\t\t\tCandleFetcher.recentCandlesCache.set(cacheKey, {\n\t\t\t\tcandles: sortedCandles,\n\t\t\t\tearliestTs,\n\t\t\t\tlatestTs,\n\t\t\t\tfetchTime: nowSeconds,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Fetch historical candles with pagination using startTs.\n\t */\n\tprivate fetchHistoricalCandles = async (): Promise<JsonCandle[]> => {\n\t\tlet candlesRemainingToFetch = this.getCountOfCandlesBetweenStartAndEndTs(\n\t\t\tthis.config.fromTs,\n\t\t\tthis.config.toTs\n\t\t);\n\n\t\tlet currentStartTs = this.config.toTs; // The data API takes \"startTs\" as the \"first timestamp you want going backwards in time\" e.g. all candles will be returned with descending time backwards from the startTs\n\t\tlet hitEndTsCutoff = false;\n\n\t\tlet candles: JsonCandle[] = [];\n\n\t\twhile (candlesRemainingToFetch > 0) {\n\t\t\tconst result = await this.fetchHistoricalCandlesBatch(\n\t\t\t\tcandlesRemainingToFetch,\n\t\t\t\tcurrentStartTs\n\t\t\t);\n\n\t\t\tif (result.fetchedCandles.length === 0) {\n\t\t\t\tcandlesRemainingToFetch = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// the deeper the loop, the older the result.candlesToAdd will be\n\t\t\tcandles = [...result.candlesToAdd, ...candles];\n\t\t\tcandlesRemainingToFetch -= result.candlesToAdd.length;\n\t\t\thitEndTsCutoff = result.hitEndTsCutoff;\n\n\t\t\tif (result.requiresAnotherFetch) {\n\t\t\t\tcurrentStartTs = result.nextStartTs;\n\t\t\t} else if (candlesRemainingToFetch > 0) {\n\t\t\t\t// This means we have fetched all the candles available for this time range and we can stop fetching\n\t\t\t\tcandlesRemainingToFetch = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (hitEndTsCutoff) {\n\t\t\treturn this.filterCandlesByTimeRange(candles);\n\t\t}\n\n\t\treturn candles;\n\t};\n\n\t/**\n\t * Fetch historical candles with pagination, backwards from the toTs value given in the config.\n\t *\n\t * This method works by looping backwards from the LATEST (toTs) timestamp to the OLDEST (fromTs) timestamp.\n\t *\n\t * Things to note:\n\t * - There is a limit to how many candles can be fetched in a single request (see CANDLE_FETCH_LIMIT)\n\t * - We have implemented this to minimise the cardinality in the API request because that helps with caching\n\t */\n\tprivate fetchHistoricalCandlesBatch = async (\n\t\tcandlesRemainingToFetch: number,\n\t\tcurrentStartTs: number\n\t): Promise<{\n\t\tfetchedCandles: JsonCandle[];\n\t\tcandlesToAdd: JsonCandle[];\n\t\thitEndTsCutoff: boolean;\n\t\trequiresAnotherFetch: boolean;\n\t\tnextStartTs: number;\n\t}> => {\n\t\tconst candlesToFetch = Math.min(\n\t\t\tcandlesRemainingToFetch,\n\t\t\tCANDLE_FETCH_LIMIT\n\t\t);\n\n\t\tconst fetchUrl = getCandleFetchUrl({\n\t\t\tenv: this.config.env,\n\t\t\tmarketId: this.config.marketId,\n\t\t\tresolution: this.config.resolution,\n\t\t\tstartTs: currentStartTs, // Include startTs for historical candles\n\t\t\tcountToFetch: candlesToFetch,\n\t\t});\n\n\t\tconst fetchedCandles = await this.fetchCandlesFromApi(fetchUrl);\n\n\t\t// Reverse candles into ascending order\n\t\tfetchedCandles.reverse();\n\n\t\tif (fetchedCandles.length === 0) {\n\t\t\treturn {\n\t\t\t\tfetchedCandles,\n\t\t\t\tcandlesToAdd: [],\n\t\t\t\thitEndTsCutoff: false,\n\t\t\t\trequiresAnotherFetch: false,\n\t\t\t\tnextStartTs: currentStartTs,\n\t\t\t};\n\t\t}\n\n\t\tconst lastCandle = fetchedCandles[fetchedCandles.length - 1]; // This is the LATEST candle .. (they are sorted ascending by time right now)\n\n\t\tconst hitPageSizeCutoff = fetchedCandles.length === CANDLE_FETCH_LIMIT;\n\t\tconst hitEndTsCutoff = lastCandle.ts < this.config.fromTs;\n\n\t\tconst requiresAnotherFetch = hitPageSizeCutoff && !hitEndTsCutoff; // If the number of candles returned is equal to the maximum number of candles that can be fetched in a single GET request, then we need to fetch more candles\n\n\t\tlet candlesToAdd = fetchedCandles;\n\t\tlet nextStartTs = currentStartTs;\n\n\t\tif (requiresAnotherFetch) {\n\t\t\t// If we need to do another fetch, trim any candles with the same timestamp as the last candle in the previous fetch, because that is the pointer for our next fetch and we don't want to duplicate candles\n\t\t\tcandlesToAdd = candlesToAdd.filter((candle) => {\n\t\t\t\treturn candle.ts < lastCandle.ts;\n\t\t\t});\n\n\t\t\tconst oldestCandle = fetchedCandles[0]; // first candle is the oldest\n\t\t\tnextStartTs = oldestCandle.ts; // If we are doing another loop, then the trimmed candles have all the candles except for ones with the last candle's timestamp. For the next loop we want to fetch from that timestamp;\n\t\t}\n\n\t\treturn {\n\t\t\tfetchedCandles,\n\t\t\tcandlesToAdd,\n\t\t\thitEndTsCutoff,\n\t\t\trequiresAnotherFetch,\n\t\t\tnextStartTs,\n\t\t};\n\t};\n\n\t/**\n\t * This class needs to fetch candles based on the config.\n\t *\n\t * If the number of candles requested exceeds the maximum number of candles that can be fetched in a single GET request, then it needs to loop multiple get requests, using the last candle's timestamp as the offset startTs for each subsequent request. If the number of candles returned is less than the requested number of candles, then we have fetched all the candles available.\n\t *\n\t * For recent candles (ones where fromTs > now - candleLength*1000), we avoid using startTs in the URL to improve caching,\n\t * and instead fetch the most recent 1000 candles and then trim the result.\n\t */\n\tpublic fetchCandles = async () => {\n\t\t// Check cache first\n\t\tconst cachedCandles = this.getFromCache();\n\t\tif (cachedCandles) {\n\t\t\treturn cachedCandles;\n\t\t}\n\n\t\t// Calculate the candle length in seconds for the current resolution\n\t\tconst candleLengthMs = Candle.resolutionStringToCandleLengthMs(\n\t\t\tthis.config.resolution\n\t\t);\n\t\tconst candleLengthSeconds = candleLengthMs / 1000;\n\n\t\t// Get current time in seconds\n\t\tconst nowSeconds = Math.floor(Date.now() / 1000);\n\n\t\t// Check if we're fetching recent candles\n\t\tif (this.isRequestingRecentCandles(nowSeconds, candleLengthSeconds)) {\n\t\t\treturn this.fetchRecentCandles(nowSeconds);\n\t\t}\n\n\t\t// For historical candles (older than the last 1000 candles), use the previous approach\n\t\t// with startTs for pagination\n\t\treturn this.fetchHistoricalCandles();\n\t};\n}\n\nclass CandleSubscriber {\n\tprivate subscription: CandleSubscriberSubscription;\n\n\tconstructor(\n\t\treadonly config: CandleSubscriptionConfig,\n\t\treadonly eventBus: CandleEventBus\n\t) {}\n\n\tsubscribeToCandles = async () => {\n\t\tthis.subscription = MarketDataFeed.subscribe({\n\t\t\ttype: 'candles',\n\t\t\tresolution: this.config.resolution,\n\t\t\tenv: this.config.env,\n\t\t\tmarketSymbol: getMarketSymbolForMarketId(\n\t\t\t\tthis.config.marketId,\n\t\t\t\tthis.config.env\n\t\t\t),\n\t\t});\n\n\t\tthis.subscription.observable.subscribe((candle) => {\n\t\t\tthis.eventBus.emit('candle-update', candle);\n\t\t});\n\t};\n\n\tunsubscribe = () => {\n\t\tMarketDataFeed.unsubscribe(this.subscription.id);\n\t};\n}\n\n/**\n * This class will subscribe to candles from the Drift Data API.\n *\n * Note: If you are using TradingView you probably want to just use the DriftTvFeed class instead.\n */\nexport class CandleClient {\n\tprivate activeSubscriptions: Map<\n\t\tstring,\n\t\t{\n\t\t\tsubscriber: CandleSubscriber;\n\t\t\teventBus: CandleEventBus;\n\t\t}\n\t> = new Map();\n\n\tconstructor() {}\n\n\tpublic subscribe = async (\n\t\tconfig: CandleSubscriptionConfig,\n\t\tsubscriptionKey: string\n\t) => {\n\t\t// Kill any existing subscription with the same key before creating a new one\n\t\tif (this.activeSubscriptions.has(subscriptionKey)) {\n\t\t\tthis.unsubscribe(subscriptionKey);\n\t\t}\n\n\t\tconst eventBus = new CandleEventBus();\n\t\tconst subscriber = new CandleSubscriber(config, eventBus);\n\t\tawait subscriber.subscribeToCandles();\n\n\t\tthis.activeSubscriptions.set(subscriptionKey, {\n\t\t\tsubscriber,\n\t\t\teventBus,\n\t\t});\n\n\t\treturn;\n\t};\n\n\t/**\n\t *\n\t * @param config {\n\t *\n\t * env: UIEnv;\n\t *\n\t * marketId: MarketId;\n\t *\n\t * resolution: CandleResolution;\n\t *\n\t * fromTs: number; // Seconds :: This should be the START (oldest) timestamp of the candles to fetch\n\t *\n\t * toTs: number; // Seconds :: This should be the END (newest) timestamp of the candles to fetch\n\t *\n\t * }\n\t * @returns\n\t */\n\tpublic fetch = async (config: CandleFetchConfig): Promise<JsonCandle[]> => {\n\t\tassert(config.fromTs < config.toTs, 'fromTs must be less than toTs');\n\t\tconst nowSeconds = Math.floor(Date.now() / 1000);\n\t\tassert(\n\t\t\tconfig.fromTs <= nowSeconds && config.toTs <= nowSeconds,\n\t\t\t`fromTs and toTs cannot be in the future (Requested fromTs: ${new Date(\n\t\t\t\tconfig.fromTs * 1000\n\t\t\t).toISOString()} and toTs: ${new Date(\n\t\t\t\tconfig.toTs * 1000\n\t\t\t).toISOString()}, Current time: ${new Date(\n\t\t\t\tnowSeconds * 1000\n\t\t\t).toISOString()})`\n\t\t);\n\t\tconst candleFetcher = new CandleFetcher(config);\n\t\tconst candles = await candleFetcher.fetchCandles();\n\t\treturn candles;\n\t};\n\n\tpublic unsubscribe = (subscriptionKey: string) => {\n\t\tconst subscription = this.activeSubscriptions.get(subscriptionKey);\n\t\tif (subscription) {\n\t\t\tCandleFetcher.clearCacheForSubscription(\n\t\t\t\tsubscription.subscriber.config.marketId,\n\t\t\t\tsubscription.subscriber.config.resolution\n\t\t\t);\n\t\t\tsubscription.subscriber.unsubscribe();\n\t\t\tsubscription.eventBus.removeAllListeners();\n\t\t\tthis.activeSubscriptions.delete(subscriptionKey);\n\t\t}\n\t};\n\n\tpublic unsubscribeAll = () => {\n\t\tfor (const subscriptionKey of this.activeSubscriptions.keys()) {\n\t\t\tthis.unsubscribe(subscriptionKey);\n\t\t}\n\t};\n\n\tpublic on(\n\t\tsubscriptionKey: string,\n\t\tevent: keyof CandleSubscriberEvents,\n\t\tlistener: (candle: JsonCandle) => void\n\t) {\n\t\tconst subscription = this.activeSubscriptions.get(subscriptionKey);\n\t\tif (subscription) {\n\t\t\tsubscription.eventBus.on(event, listener);\n\t\t} else {\n\t\t\tconsole.warn(`No active subscription found for key: ${subscriptionKey}`);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,33 @@
1
+ import { CandleResolution } from '@drift-labs/sdk';
2
+ import { JsonCandle, JsonTrade, MarketSymbol, UIEnv } from '../types';
3
+ import { Observable } from 'rxjs';
4
+ type DataApiWsSubscriptionConfig = {
5
+ resolution: CandleResolution;
6
+ marketSymbol: MarketSymbol;
7
+ env: UIEnv;
8
+ };
9
+ export declare class DataApiWsClient {
10
+ readonly config: DataApiWsSubscriptionConfig;
11
+ private readonly candleSubject;
12
+ private readonly tradesSubject;
13
+ private readonly _candleObservable;
14
+ private readonly _tradesObservable;
15
+ private multiplexSubscription;
16
+ constructor(config: DataApiWsSubscriptionConfig);
17
+ private handleWsMessage;
18
+ private handleError;
19
+ private handleClose;
20
+ subscribe: () => Promise<void>;
21
+ unsubscribe: () => void;
22
+ /**
23
+ * Get the candle updates stream
24
+ * @returns An observable that emits candle updates
25
+ */
26
+ get candlesObservable(): Observable<JsonCandle>;
27
+ /**
28
+ * Get the trade updates stream
29
+ * @returns An observable that emits trade updates
30
+ */
31
+ get tradesObservable(): Observable<JsonTrade[]>;
32
+ }
33
+ export {};
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataApiWsClient = void 0;
4
+ const EnvironmentConstants_1 = require("../EnvironmentConstants");
5
+ const rxjs_1 = require("rxjs");
6
+ const MultiplexWebSocket_1 = require("../utils/MultiplexWebSocket");
7
+ const getBaseDataApiUrl = (env) => {
8
+ const constantEnv = env.isStaging ? 'staging' : env.isDevnet ? 'dev' : 'mainnet';
9
+ const dataApiUrl = EnvironmentConstants_1.EnvironmentConstants.dataServerUrl[constantEnv];
10
+ return dataApiUrl.replace('https://', '');
11
+ };
12
+ const getWsSubscriptionPath = (config) => {
13
+ const baseDataApiUrl = getBaseDataApiUrl(config.env);
14
+ return `wss://${baseDataApiUrl}/ws`;
15
+ };
16
+ const getWsSubscriptionMessage = (config) => {
17
+ return JSON.stringify({
18
+ type: 'subscribe',
19
+ symbol: config.marketSymbol,
20
+ resolution: `${config.resolution}`,
21
+ });
22
+ };
23
+ class DataApiWsClient {
24
+ constructor(config) {
25
+ this.multiplexSubscription = null;
26
+ this.handleWsMessage = (message) => {
27
+ const parsedMessage = message;
28
+ switch (parsedMessage.type) {
29
+ case 'update':
30
+ {
31
+ const candle = parsedMessage.candle;
32
+ const trades = parsedMessage.trades;
33
+ if (candle)
34
+ this.candleSubject.next(candle);
35
+ if (trades)
36
+ this.tradesSubject.next(trades);
37
+ }
38
+ break;
39
+ default:
40
+ break;
41
+ }
42
+ };
43
+ this.handleError = () => {
44
+ console.error('candlesv2:: dataApiWsClient error occurred');
45
+ };
46
+ this.handleClose = () => {
47
+ console.log('candlesv2:: dataApiWsClient connection closed');
48
+ };
49
+ this.subscribe = async () => {
50
+ const subscriptionId = `${this.config.marketSymbol}-${this.config.resolution}`;
51
+ this.multiplexSubscription = MultiplexWebSocket_1.MultiplexWebSocket.createWebSocketSubscription({
52
+ wsUrl: getWsSubscriptionPath(this.config),
53
+ subscriptionId,
54
+ subscribeMessage: getWsSubscriptionMessage(this.config),
55
+ unsubscribeMessage: JSON.stringify({
56
+ type: 'unsubscribe',
57
+ symbol: this.config.marketSymbol,
58
+ resolution: `${this.config.resolution}`,
59
+ }),
60
+ onError: this.handleError,
61
+ onMessage: this.handleWsMessage,
62
+ onClose: this.handleClose,
63
+ messageFilter: (message) => {
64
+ var _a, _b;
65
+ try {
66
+ // Only accept `update` messages with a matching resolution and symbol for this subscription
67
+ if ((message === null || message === void 0 ? void 0 : message.type) === 'update' &&
68
+ ((_a = message.candle) === null || _a === void 0 ? void 0 : _a.resolution) === this.config.resolution &&
69
+ ((_b = message.candle) === null || _b === void 0 ? void 0 : _b.symbol) === this.config.marketSymbol) {
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ catch (error) {
75
+ console.error('candlesv2:: dataApiWsClient messageFilter error', {
76
+ error,
77
+ message,
78
+ });
79
+ return false;
80
+ }
81
+ },
82
+ errorMessageFilter: (_message) => {
83
+ return false; // No known error messages
84
+ },
85
+ });
86
+ return Promise.resolve();
87
+ };
88
+ this.unsubscribe = () => {
89
+ if (this.multiplexSubscription) {
90
+ this.multiplexSubscription.unsubscribe();
91
+ this.multiplexSubscription = null;
92
+ }
93
+ this.candleSubject.complete();
94
+ this.tradesSubject.complete();
95
+ };
96
+ this.config = config;
97
+ this.candleSubject = new rxjs_1.Subject();
98
+ this.tradesSubject = new rxjs_1.Subject();
99
+ this._candleObservable = this.candleSubject.asObservable();
100
+ this._tradesObservable = this.tradesSubject.asObservable();
101
+ }
102
+ /**
103
+ * Get the candle updates stream
104
+ * @returns An observable that emits candle updates
105
+ */
106
+ get candlesObservable() {
107
+ return this._candleObservable;
108
+ }
109
+ /**
110
+ * Get the trade updates stream
111
+ * @returns An observable that emits trade updates
112
+ */
113
+ get tradesObservable() {
114
+ return this._tradesObservable;
115
+ }
116
+ }
117
+ exports.DataApiWsClient = DataApiWsClient;
118
+ //# sourceMappingURL=dataApiWsClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataApiWsClient.js","sourceRoot":"","sources":["../../src/clients/dataApiWsClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { CandleResolution } from '@drift-labs/sdk';\nimport { EnvironmentConstants } from '../EnvironmentConstants';\nimport { JsonCandle, JsonTrade, MarketSymbol, UIEnv } from '../types';\nimport { Observable, Subject } from 'rxjs';\nimport { MultiplexWebSocket } from '../utils/MultiplexWebSocket';\n\nconst getBaseDataApiUrl = (env: UIEnv) => {\n\tconst constantEnv: keyof typeof EnvironmentConstants.dataServerUrl =\n\t\tenv.isStaging ? 'staging' : env.isDevnet ? 'dev' : 'mainnet';\n\tconst dataApiUrl = EnvironmentConstants.dataServerUrl[constantEnv];\n\treturn dataApiUrl.replace('https://', '');\n};\n\n// Used by the subscriber client to subscribe to the candles websocket endpoint\ntype DataApiWsSubscriptionConfig = {\n\tresolution: CandleResolution;\n\tmarketSymbol: MarketSymbol;\n\tenv: UIEnv;\n};\n\nconst getWsSubscriptionPath = (config: DataApiWsSubscriptionConfig) => {\n\tconst baseDataApiUrl = getBaseDataApiUrl(config.env);\n\treturn `wss://${baseDataApiUrl}/ws`;\n};\n\nconst getWsSubscriptionMessage = (config: DataApiWsSubscriptionConfig) => {\n\treturn JSON.stringify({\n\t\ttype: 'subscribe',\n\t\tsymbol: config.marketSymbol,\n\t\tresolution: `${config.resolution}`,\n\t});\n};\n\ntype WsSubscriptionMessageType =\n\t| 'subscribe'\n\t| 'init'\n\t| 'subscription'\n\t| 'update'\n\t| 'create';\n\ntype DataApiCandleProps = {\n\tresolution: string;\n\tsymbol: string;\n}; // There is other stuff in the candle objects but we only care about these properties\n\ntype WsSubscriptionMessage<T extends WsSubscriptionMessageType> = {\n\ttype: T;\n\tcandle: DataApiCandleProps;\n}; // There are more params in the various messages we can receive but we only care about these properties\n\ntype WsUpdateMessage = WsSubscriptionMessage<'update'> & {\n\tcandle: JsonCandle;\n\ttrades: JsonTrade[];\n};\n\nexport class DataApiWsClient {\n\tpublic readonly config: DataApiWsSubscriptionConfig;\n\tprivate readonly candleSubject: Subject<JsonCandle>;\n\tprivate readonly tradesSubject: Subject<JsonTrade[]>;\n\tprivate readonly _candleObservable: Observable<JsonCandle>;\n\tprivate readonly _tradesObservable: Observable<JsonTrade[]>;\n\tprivate multiplexSubscription: { unsubscribe: () => void } | null = null;\n\n\tconstructor(config: DataApiWsSubscriptionConfig) {\n\t\tthis.config = config;\n\t\tthis.candleSubject = new Subject<JsonCandle>();\n\t\tthis.tradesSubject = new Subject<JsonTrade[]>();\n\t\tthis._candleObservable = this.candleSubject.asObservable();\n\t\tthis._tradesObservable = this.tradesSubject.asObservable();\n\t}\n\n\tprivate handleWsMessage = (\n\t\tmessage: WsSubscriptionMessage<WsSubscriptionMessageType>\n\t) => {\n\t\tconst parsedMessage = message;\n\n\t\tswitch (parsedMessage.type) {\n\t\t\tcase 'update':\n\t\t\t\t{\n\t\t\t\t\tconst candle = (parsedMessage as WsUpdateMessage).candle;\n\t\t\t\t\tconst trades = (parsedMessage as WsUpdateMessage).trades;\n\t\t\t\t\tif (candle) this.candleSubject.next(candle);\n\t\t\t\t\tif (trades) this.tradesSubject.next(trades);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tprivate handleError = () => {\n\t\tconsole.error('candlesv2:: dataApiWsClient error occurred');\n\t};\n\n\tprivate handleClose = () => {\n\t\tconsole.log('candlesv2:: dataApiWsClient connection closed');\n\t};\n\n\tpublic subscribe = async () => {\n\t\tconst subscriptionId = `${this.config.marketSymbol}-${this.config.resolution}`;\n\n\t\tthis.multiplexSubscription = MultiplexWebSocket.createWebSocketSubscription<\n\t\t\tWsSubscriptionMessage<WsSubscriptionMessageType>\n\t\t>({\n\t\t\twsUrl: getWsSubscriptionPath(this.config),\n\t\t\tsubscriptionId,\n\t\t\tsubscribeMessage: getWsSubscriptionMessage(this.config),\n\t\t\tunsubscribeMessage: JSON.stringify({\n\t\t\t\ttype: 'unsubscribe',\n\t\t\t\tsymbol: this.config.marketSymbol,\n\t\t\t\tresolution: `${this.config.resolution}`,\n\t\t\t}),\n\t\t\tonError: this.handleError,\n\t\t\tonMessage: this.handleWsMessage,\n\t\t\tonClose: this.handleClose,\n\t\t\tmessageFilter: (message) => {\n\t\t\t\ttry {\n\t\t\t\t\t// Only accept `update` messages with a matching resolution and symbol for this subscription\n\t\t\t\t\tif (\n\t\t\t\t\t\tmessage?.type === 'update' &&\n\t\t\t\t\t\tmessage.candle?.resolution === this.config.resolution &&\n\t\t\t\t\t\tmessage.candle?.symbol === this.config.marketSymbol\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('candlesv2:: dataApiWsClient messageFilter error', {\n\t\t\t\t\t\terror,\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\terrorMessageFilter: (_message) => {\n\t\t\t\treturn false; // No known error messages\n\t\t\t},\n\t\t});\n\n\t\treturn Promise.resolve();\n\t};\n\n\tpublic unsubscribe = () => {\n\t\tif (this.multiplexSubscription) {\n\t\t\tthis.multiplexSubscription.unsubscribe();\n\t\t\tthis.multiplexSubscription = null;\n\t\t}\n\t\tthis.candleSubject.complete();\n\t\tthis.tradesSubject.complete();\n\t};\n\n\t/**\n\t * Get the candle updates stream\n\t * @returns An observable that emits candle updates\n\t */\n\tpublic get candlesObservable(): Observable<JsonCandle> {\n\t\treturn this._candleObservable;\n\t}\n\n\t/**\n\t * Get the trade updates stream\n\t * @returns An observable that emits trade updates\n\t */\n\tpublic get tradesObservable(): Observable<JsonTrade[]> {\n\t\treturn this._tradesObservable;\n\t}\n}\n"]}
@@ -0,0 +1 @@
1
+ export * from './redisClient';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./redisClient"), exports);
18
+ // do not add other clients here, since this is meant to be imported by nodejs servers (has browser incompatible code)
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,sHAAsH","sourcesContent":["export * from './redisClient';\n// do not add other clients here, since this is meant to be imported by nodejs servers (has browser incompatible code)\n"]}