@velocity-exchange/sdk 0.4.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +52 -0
  3. package/lib/browser/adminClient.js +97 -0
  4. package/lib/browser/config.js +6 -7
  5. package/lib/browser/constants/numericConstants.d.ts +1 -1
  6. package/lib/browser/constants/numericConstants.js +1 -1
  7. package/lib/browser/decode/user.js +5 -1
  8. package/lib/browser/idl/velocity.d.ts +191 -15
  9. package/lib/browser/idl/velocity.json +192 -16
  10. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
  11. package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
  12. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  13. package/lib/browser/types.d.ts +6 -0
  14. package/lib/browser/user.d.ts +20 -3
  15. package/lib/browser/user.js +52 -4
  16. package/lib/browser/velocityClient.d.ts +46 -10
  17. package/lib/browser/velocityClient.js +107 -35
  18. package/lib/node/adminClient.d.ts +52 -0
  19. package/lib/node/adminClient.d.ts.map +1 -1
  20. package/lib/node/adminClient.js +97 -0
  21. package/lib/node/config.d.ts.map +1 -1
  22. package/lib/node/config.js +6 -7
  23. package/lib/node/constants/numericConstants.d.ts +1 -1
  24. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  25. package/lib/node/constants/numericConstants.js +1 -1
  26. package/lib/node/decode/user.d.ts.map +1 -1
  27. package/lib/node/decode/user.js +5 -1
  28. package/lib/node/idl/velocity.d.ts +191 -15
  29. package/lib/node/idl/velocity.d.ts.map +1 -1
  30. package/lib/node/idl/velocity.json +192 -16
  31. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
  32. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  33. package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
  34. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  35. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  36. package/lib/node/types.d.ts +6 -0
  37. package/lib/node/types.d.ts.map +1 -1
  38. package/lib/node/user.d.ts +20 -3
  39. package/lib/node/user.d.ts.map +1 -1
  40. package/lib/node/user.js +52 -4
  41. package/lib/node/velocityClient.d.ts +46 -10
  42. package/lib/node/velocityClient.d.ts.map +1 -1
  43. package/lib/node/velocityClient.js +107 -35
  44. package/package.json +7 -3
  45. package/.prettierignore +0 -1
  46. package/CHANGELOG.md +0 -132
  47. package/build-browser.js +0 -58
  48. package/bunfig.toml +0 -3
  49. package/esbuild-shims.js +0 -12
  50. package/scripts/deposit-isolated-positions.ts +0 -110
  51. package/scripts/find-flagged-users.ts +0 -213
  52. package/scripts/grpc-client-test-comparison.ts +0 -372
  53. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  54. package/scripts/postbuild.js +0 -95
  55. package/scripts/single-grpc-client-test.ts +0 -284
  56. package/scripts/withdraw-isolated-positions.ts +0 -174
  57. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  58. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  59. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  60. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  61. package/src/accounts/bulkAccountLoader.ts +0 -358
  62. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  63. package/src/accounts/bulkUserSubscription.ts +0 -39
  64. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  65. package/src/accounts/fetch.ts +0 -200
  66. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  67. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  68. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  69. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  70. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  71. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  72. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  73. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  74. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  75. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  76. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  77. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  78. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  79. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  80. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  81. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  82. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  83. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  84. package/src/accounts/testBulkAccountLoader.ts +0 -59
  85. package/src/accounts/types.ts +0 -428
  86. package/src/accounts/utils.ts +0 -90
  87. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  88. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  89. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  90. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  91. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  92. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  93. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  94. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  95. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  96. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  97. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  98. package/src/addresses/marketAddresses.ts +0 -28
  99. package/src/addresses/pda.ts +0 -620
  100. package/src/adminClient.ts +0 -8136
  101. package/src/assert/assert.ts +0 -5
  102. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  103. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  104. package/src/auctionSubscriber/index.ts +0 -9
  105. package/src/auctionSubscriber/types.ts +0 -30
  106. package/src/bankrun/bankrunConnection.ts +0 -630
  107. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  108. package/src/blockhashSubscriber/index.ts +0 -6
  109. package/src/blockhashSubscriber/types.ts +0 -13
  110. package/src/clock/clockSubscriber.ts +0 -146
  111. package/src/config.ts +0 -312
  112. package/src/constants/index.ts +0 -9
  113. package/src/constants/numericConstants.ts +0 -194
  114. package/src/constants/perpMarkets.ts +0 -127
  115. package/src/constants/spotMarkets.ts +0 -104
  116. package/src/constants/txConstants.ts +0 -2
  117. package/src/constituentMap/constituentMap.ts +0 -305
  118. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  119. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  120. package/src/core/VelocityCore.ts +0 -606
  121. package/src/core/index.ts +0 -12
  122. package/src/core/instructions/deposit.ts +0 -64
  123. package/src/core/instructions/fill.ts +0 -51
  124. package/src/core/instructions/funding.ts +0 -33
  125. package/src/core/instructions/liquidation.ts +0 -55
  126. package/src/core/instructions/orders.ts +0 -84
  127. package/src/core/instructions/perpOrders.ts +0 -312
  128. package/src/core/instructions/settlement.ts +0 -40
  129. package/src/core/instructions/trigger.ts +0 -41
  130. package/src/core/instructions/withdraw.ts +0 -65
  131. package/src/core/remainingAccounts.ts +0 -320
  132. package/src/core/signedMsg.ts +0 -109
  133. package/src/decode/customCoder.ts +0 -148
  134. package/src/decode/user.ts +0 -401
  135. package/src/dlob/DLOB.ts +0 -2793
  136. package/src/dlob/DLOBNode.ts +0 -305
  137. package/src/dlob/DLOBSubscriber.ts +0 -269
  138. package/src/dlob/NodeList.ts +0 -244
  139. package/src/dlob/orderBookLevels.ts +0 -695
  140. package/src/dlob/types.ts +0 -37
  141. package/src/events/eventList.ts +0 -114
  142. package/src/events/eventSubscriber.ts +0 -521
  143. package/src/events/eventsServerLogProvider.ts +0 -189
  144. package/src/events/fetchLogs.ts +0 -219
  145. package/src/events/parse.ts +0 -271
  146. package/src/events/pollingLogProvider.ts +0 -113
  147. package/src/events/sort.ts +0 -51
  148. package/src/events/txEventCache.ts +0 -92
  149. package/src/events/types.ts +0 -337
  150. package/src/events/webSocketLogProvider.ts +0 -152
  151. package/src/factory/bigNum.ts +0 -709
  152. package/src/factory/oracleClient.ts +0 -73
  153. package/src/idl/pyth.json +0 -142
  154. package/src/idl/pyth.ts +0 -97
  155. package/src/idl/pyth_solana_receiver.json +0 -628
  156. package/src/idl/token_faucet.json +0 -229
  157. package/src/idl/token_faucet.ts +0 -197
  158. package/src/idl/velocity.json +0 -23974
  159. package/src/idl/velocity.ts +0 -23980
  160. package/src/index.ts +0 -150
  161. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  162. package/src/isomorphic/README.md +0 -19
  163. package/src/isomorphic/anchor.browser.ts +0 -44
  164. package/src/isomorphic/anchor.node.ts +0 -1
  165. package/src/isomorphic/anchor.ts +0 -1
  166. package/src/isomorphic/anchor29.browser.ts +0 -24
  167. package/src/isomorphic/anchor29.node.ts +0 -1
  168. package/src/isomorphic/anchor29.ts +0 -1
  169. package/src/isomorphic/grpc.browser.ts +0 -4
  170. package/src/isomorphic/grpc.node.ts +0 -130
  171. package/src/isomorphic/grpc.ts +0 -1
  172. package/src/jupiter/jupiterClient.ts +0 -502
  173. package/src/keypair.ts +0 -32
  174. package/src/margin/README.md +0 -138
  175. package/src/marginCalculation.ts +0 -407
  176. package/src/marinade/idl/idl.json +0 -1962
  177. package/src/marinade/index.ts +0 -73
  178. package/src/marinade/types.ts +0 -3925
  179. package/src/math/amm.ts +0 -1758
  180. package/src/math/auction.ts +0 -480
  181. package/src/math/bankruptcy.ts +0 -138
  182. package/src/math/builder.ts +0 -130
  183. package/src/math/conversion.ts +0 -45
  184. package/src/math/exchangeStatus.ts +0 -261
  185. package/src/math/funding.ts +0 -498
  186. package/src/math/insurance.ts +0 -171
  187. package/src/math/liquidation.ts +0 -433
  188. package/src/math/margin.ts +0 -327
  189. package/src/math/market.ts +0 -487
  190. package/src/math/oracles.ts +0 -477
  191. package/src/math/orders.ts +0 -500
  192. package/src/math/position.ts +0 -381
  193. package/src/math/repeg.ts +0 -223
  194. package/src/math/spotBalance.ts +0 -996
  195. package/src/math/spotMarket.ts +0 -115
  196. package/src/math/spotPosition.ts +0 -263
  197. package/src/math/state.ts +0 -71
  198. package/src/math/superStake.ts +0 -602
  199. package/src/math/tiers.ts +0 -73
  200. package/src/math/trade.ts +0 -879
  201. package/src/math/utils.ts +0 -183
  202. package/src/memcmp.ts +0 -279
  203. package/src/oracles/oracleClientCache.ts +0 -41
  204. package/src/oracles/oracleId.ts +0 -99
  205. package/src/oracles/prelaunchOracleClient.ts +0 -63
  206. package/src/oracles/pythClient.ts +0 -125
  207. package/src/oracles/pythLazerClient.ts +0 -141
  208. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  209. package/src/oracles/strictOraclePrice.ts +0 -40
  210. package/src/oracles/types.ts +0 -82
  211. package/src/oracles/utils.ts +0 -45
  212. package/src/orderParams.ts +0 -117
  213. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  214. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  215. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  216. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  217. package/src/orderSubscriber/index.ts +0 -7
  218. package/src/orderSubscriber/types.ts +0 -64
  219. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  220. package/src/priorityFee/averageStrategy.ts +0 -13
  221. package/src/priorityFee/ewmaStrategy.ts +0 -51
  222. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  223. package/src/priorityFee/index.ts +0 -16
  224. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  225. package/src/priorityFee/maxStrategy.ts +0 -8
  226. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  227. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  228. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  229. package/src/priorityFee/types.ts +0 -82
  230. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  231. package/src/pyth/constants.ts +0 -9
  232. package/src/pyth/index.ts +0 -15
  233. package/src/pyth/pythLazerSubscriber.ts +0 -365
  234. package/src/pyth/types.ts +0 -4451
  235. package/src/pyth/utils.ts +0 -13
  236. package/src/slot/SlotSubscriber.ts +0 -126
  237. package/src/slot/SlothashSubscriber.ts +0 -163
  238. package/src/swap/UnifiedSwapClient.ts +0 -315
  239. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  240. package/src/swift/index.ts +0 -10
  241. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  242. package/src/swift/swiftOrderSubscriber.ts +0 -351
  243. package/src/testClient.ts +0 -42
  244. package/src/titan/titanClient.ts +0 -438
  245. package/src/token/index.ts +0 -13
  246. package/src/tokenFaucet.ts +0 -296
  247. package/src/tx/baseTxSender.ts +0 -651
  248. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  249. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  250. package/src/tx/blockhashFetcher/types.ts +0 -9
  251. package/src/tx/fastSingleTxSender.ts +0 -200
  252. package/src/tx/forwardOnlyTxSender.ts +0 -193
  253. package/src/tx/priorityFeeCalculator.ts +0 -117
  254. package/src/tx/reportTransactionError.ts +0 -176
  255. package/src/tx/retryTxSender.ts +0 -177
  256. package/src/tx/txHandler.ts +0 -1009
  257. package/src/tx/txParamProcessor.ts +0 -225
  258. package/src/tx/types.ts +0 -117
  259. package/src/tx/utils.ts +0 -133
  260. package/src/tx/whileValidTxSender.ts +0 -377
  261. package/src/types.ts +0 -2575
  262. package/src/user.ts +0 -5316
  263. package/src/userConfig.ts +0 -38
  264. package/src/userMap/PollingSubscription.ts +0 -61
  265. package/src/userMap/WebsocketSubscription.ts +0 -93
  266. package/src/userMap/grpcSubscription.ts +0 -93
  267. package/src/userMap/referrerMap.ts +0 -360
  268. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  269. package/src/userMap/userMap.ts +0 -784
  270. package/src/userMap/userMapConfig.ts +0 -82
  271. package/src/userMap/userStatsMap.ts +0 -393
  272. package/src/userName.ts +0 -37
  273. package/src/userStats.ts +0 -159
  274. package/src/userStatsConfig.ts +0 -35
  275. package/src/util/TransactionConfirmationManager.ts +0 -333
  276. package/src/util/chainClock.ts +0 -65
  277. package/src/util/computeUnits.ts +0 -101
  278. package/src/util/digest.ts +0 -33
  279. package/src/util/ed25519Utils.ts +0 -95
  280. package/src/util/promiseTimeout.ts +0 -23
  281. package/src/velocityClient.ts +0 -14802
  282. package/src/velocityClientConfig.ts +0 -119
  283. package/src/wallet.ts +0 -91
  284. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  285. package/tests/VelocityCore/decode.test.ts +0 -16
  286. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  287. package/tests/VelocityCore/instructions.test.ts +0 -46
  288. package/tests/VelocityCore/pdas.test.ts +0 -30
  289. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  290. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  291. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  292. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  293. package/tests/amm/test.ts +0 -2402
  294. package/tests/auctions/test.ts +0 -81
  295. package/tests/bn/test.ts +0 -355
  296. package/tests/builder/builderFee.test.ts +0 -42
  297. package/tests/ci/verifyConstants.ts +0 -393
  298. package/tests/decode/test.ts +0 -262
  299. package/tests/decode/userAccountBufferStrings.ts +0 -102
  300. package/tests/dlob/helpers.ts +0 -748
  301. package/tests/dlob/test.ts +0 -6969
  302. package/tests/dlob/tickSizeStandardization.ts +0 -545
  303. package/tests/events/parseLogsForCuUsage.ts +0 -139
  304. package/tests/exchangeStatus/test.ts +0 -45
  305. package/tests/insurance/test.ts +0 -40
  306. package/tests/liquidation/test.ts +0 -125
  307. package/tests/oracles/mmOracleGate.test.ts +0 -379
  308. package/tests/oracles/pythPegSnap.test.ts +0 -76
  309. package/tests/sdkParity/enumParity.test.ts +0 -84
  310. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  311. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  312. package/tests/spot/test.ts +0 -281
  313. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  314. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  315. package/tests/tx/priorityFeeCalculator.ts +0 -77
  316. package/tests/tx/priorityFeeStrategy.ts +0 -95
  317. package/tests/user/bankruptcy.ts +0 -165
  318. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  319. package/tests/user/getMarginCalculation.ts +0 -586
  320. package/tests/user/helpers.ts +0 -184
  321. package/tests/user/liquidations.ts +0 -129
  322. package/tests/user/marginCalculations.test.ts +0 -321
  323. package/tests/user/test.ts +0 -833
  324. package/tsconfig.browser.json +0 -18
  325. package/tsconfig.json +0 -36
package/src/dlob/types.ts DELETED
@@ -1,37 +0,0 @@
1
- import { DLOB } from './DLOB';
2
- import { VelocityClient } from '../velocityClient';
3
-
4
- /** Configuration for constructing a `DLOBSubscriber`. */
5
- export type DLOBSubscriptionConfig = {
6
- /** Client used to resolve market accounts/oracle data for `getL2`/`getL3`. Required — the constructor throws if omitted. */
7
- velocityClient?: VelocityClient;
8
- /** Provides the `DLOB` snapshot to poll, e.g. built from a `UserMap`. */
9
- dlobSource: DLOBSource;
10
- /** Provides the current slot used both to request the next `DLOB` snapshot and to price orders when serving `getL2`/`getL3`. */
11
- slotSource: SlotSource;
12
- /** Polling interval in milliseconds between calls to `dlobSource.getDLOB`. */
13
- updateFrequency: number;
14
- };
15
-
16
- /** Events emitted by `DLOBSubscriber`'s `eventEmitter`. */
17
- export interface DLOBSubscriberEvents {
18
- /** Fired after each successful periodic `DLOB` refresh, with the newly fetched `DLOB`. */
19
- update: (dlob: DLOB) => void;
20
- /** Fired if a periodic refresh's `dlobSource.getDLOB` call throws. */
21
- error: (e: Error) => void;
22
- }
23
-
24
- /** Supplies a fresh `DLOB` snapshot on demand, e.g. built from a `UserMap` of on-chain user accounts. */
25
- export interface DLOBSource {
26
- /**
27
- * @param slot slot to build/tag the returned `DLOB` snapshot at
28
- * @returns a promise resolving to a populated `DLOB`
29
- */
30
- getDLOB(slot: number): Promise<DLOB>;
31
- }
32
-
33
- /** Supplies the current slot, e.g. backed by a `SlotSubscriber`. */
34
- export interface SlotSource {
35
- /** @returns the most recently observed slot. */
36
- getSlot(): number;
37
- }
@@ -1,114 +0,0 @@
1
- import {
2
- EventType,
3
- EventMap,
4
- EventSubscriptionOrderDirection,
5
- SortFn,
6
- } from './types';
7
-
8
- class Node<Type extends EventType, Event extends EventMap[Type]> {
9
- constructor(
10
- public event: Event,
11
- public next?: Node<Type, Event>,
12
- public prev?: Node<Type, Event>
13
- ) {}
14
- }
15
-
16
- /**
17
- * Fixed-capacity, sorted doubly-linked list of decoded events for a single
18
- * `EventType`, used internally by `EventSubscriber` to retain the most
19
- * recent `maxSize` events per type in the configured order.
20
- */
21
- export class EventList<Type extends EventType> {
22
- size = 0;
23
- head?: Node<Type, EventMap[Type]>;
24
- tail?: Node<Type, EventMap[Type]>;
25
-
26
- /**
27
- * @param eventType The `EventType` this list holds.
28
- * @param maxSize Max events retained; once exceeded, the tail (least-recent per `sortFn`/`orderDirection`) is evicted.
29
- * @param sortFn Comparator determining insertion order (see `getSortFn`).
30
- * @param orderDirection Whether `'less than'` per `sortFn` sorts toward the head (`'asc'`) or tail (`'desc'`).
31
- */
32
- public constructor(
33
- public eventType: Type,
34
- public maxSize: number,
35
- private sortFn: SortFn,
36
- private orderDirection: EventSubscriptionOrderDirection
37
- ) {}
38
-
39
- /** Inserts `event` in sorted position (per `sortFn`/`orderDirection`), evicting the tail if this pushes the list over `maxSize`. */
40
- public insert(event: EventMap[Type]): void {
41
- this.size++;
42
- const newNode = new Node(event);
43
- if (this.head === undefined) {
44
- this.head = this.tail = newNode;
45
- return;
46
- }
47
-
48
- if (
49
- this.sortFn(this.head.event, newNode.event) ===
50
- (this.orderDirection === 'asc' ? 'less than' : 'greater than')
51
- ) {
52
- this.head.prev = newNode;
53
- newNode.next = this.head;
54
- this.head = newNode;
55
- } else {
56
- let currentNode = this.head;
57
- while (
58
- currentNode.next !== undefined &&
59
- this.sortFn(currentNode.next.event, newNode.event) !==
60
- (this.orderDirection === 'asc' ? 'less than' : 'greater than')
61
- ) {
62
- currentNode = currentNode.next;
63
- }
64
-
65
- newNode.next = currentNode.next;
66
- if (newNode.next !== undefined) {
67
- newNode.next.prev = newNode;
68
- } else {
69
- this.tail = newNode;
70
- }
71
-
72
- currentNode.next = newNode;
73
- newNode.prev = currentNode;
74
- }
75
-
76
- if (this.size > this.maxSize) {
77
- this.detach();
78
- }
79
- }
80
-
81
- /** Removes the tail node (the least-recent event per the list's order) and decrements `size`. No-ops on an empty list. */
82
- detach(): void {
83
- const node = this.tail;
84
- if (node === undefined) {
85
- return;
86
- }
87
- if (node.prev !== undefined) {
88
- node.prev.next = node.next;
89
- } else {
90
- this.head = node.next;
91
- }
92
-
93
- if (node.next !== undefined) {
94
- node.next.prev = node.prev;
95
- } else {
96
- this.tail = node.prev;
97
- }
98
-
99
- this.size--;
100
- }
101
-
102
- /** Materializes the list into a plain array, in current sort order. Allocates a new array — prefer iterating the list directly for hot paths. */
103
- toArray(): EventMap[Type][] {
104
- return Array.from(this);
105
- }
106
-
107
- *[Symbol.iterator]() {
108
- let node = this.head;
109
- while (node) {
110
- yield node.event;
111
- node = node.next;
112
- }
113
- }
114
- }
@@ -1,521 +0,0 @@
1
- // EventSubscriber — see the class doc below for behavior. This module also
2
- // wires together the LogProvider implementations (websocket/polling/events-server);
3
- // see `events/types.ts` for the full event type union and `events/parse.ts` for log parsing.
4
- import { Connection, PublicKey, TransactionSignature } from '@solana/web3.js';
5
- import { Program } from '../isomorphic/anchor';
6
- import {
7
- DefaultEventSubscriptionOptions,
8
- EventSubscriptionOptions,
9
- EventType,
10
- WrappedEvents,
11
- EventMap,
12
- LogProvider,
13
- EventSubscriberEvents,
14
- WebSocketLogProviderConfig,
15
- EventsServerLogProviderConfig,
16
- LogProviderType,
17
- StreamingLogProviderConfig,
18
- PollingLogProviderConfig,
19
- LogProviderConfig,
20
- } from './types';
21
- import { TxEventCache } from './txEventCache';
22
- import { EventList } from './eventList';
23
- import { PollingLogProvider } from './pollingLogProvider';
24
- import { fetchLogs } from './fetchLogs';
25
- import { WebSocketLogProvider } from './webSocketLogProvider';
26
- import { EventEmitter } from 'events';
27
- import StrictEventEmitter from 'strict-event-emitter-types';
28
- import { getSortFn } from './sort';
29
- import { parseLogs } from './parse';
30
- import { EventsServerLogProvider } from './eventsServerLogProvider';
31
-
32
- /**
33
- * EventSubscriber — streams and decodes Velocity program events from
34
- * transaction logs (all records emitted via `emit!` from `state/events.rs`:
35
- * `DepositRecord`, `OrderActionRecord`, `LiquidationRecord`,
36
- * `FundingPaymentRecord`, etc. — see `EventMap` for the full set), via a
37
- * pluggable `LogProvider` (websocket, polling, or the Velocity events server),
38
- * and surfaces them both through per-type `EventList`s and a `'newEvent'`
39
- * `eventEmitter`.
40
- *
41
- * Ordering and dedup: each decoded event is tagged with `slot` and a
42
- * `txSigIndex` (its position among decoded events within the same
43
- * transaction); the per-event-type `EventList`s use these to sort either by
44
- * blockchain order (slot, then `txSigIndex`) or by client arrival order, per
45
- * `EventSubscriptionOptions.orderBy`. Whole transactions are deduped by
46
- * signature via an internal LRU (`TxEventCache`, sized by `options.maxTx`):
47
- * a transaction already in the cache is skipped entirely on a subsequent
48
- * delivery from the *same* log provider, which protects against a
49
- * websocket/polling provider redelivering the same tx. Events pushed by the
50
- * events-server provider bypass this cache (it dedups upstream and supplies
51
- * an authoritative `txSigIndex`). Event names are also normalized from the
52
- * `@coral-xyz/anchor` 0.32+ camelCase IDL form back to the PascalCase used by
53
- * `EventType`/`EventMap` before being matched against the subscribed types.
54
- */
55
- export class EventSubscriber {
56
- private address: PublicKey;
57
- private eventListMap: Map<EventType, EventList<EventType>>;
58
- /** Case-insensitive lookup from decoded (camelCase) IDL event names to subscribed `EventType` keys. */
59
- private eventTypeByLowercaseName = new Map<string, EventType>();
60
- private txEventCache: TxEventCache;
61
- private awaitTxPromises = new Map<string, Promise<void>>();
62
- private awaitTxResolver = new Map<string, () => void>();
63
- private _logProvider?: LogProvider;
64
- private _currentProviderType: LogProviderType;
65
- public eventEmitter: StrictEventEmitter<EventEmitter, EventSubscriberEvents>;
66
- private lastSeenSlot: number | undefined;
67
- private lastSeenBlockTime: number | undefined;
68
- public lastSeenTxSig: string | undefined;
69
-
70
- private get logProvider(): LogProvider {
71
- if (!this._logProvider) {
72
- throw new Error(
73
- 'EventSubscriber: logProvider accessed before initializeLogProvider()'
74
- );
75
- }
76
- return this._logProvider;
77
- }
78
-
79
- /**
80
- * @param connection RPC connection used by the polling/websocket log providers and by `fetchPreviousTx`.
81
- * @param program Anchor `Program` whose IDL coder decodes event logs (see `parse.ts`).
82
- * @param options Subscription options; merged over `DefaultEventSubscriptionOptions` so any field left unset uses the default.
83
- */
84
- public constructor(
85
- private connection: Connection,
86
- private program: Program,
87
- private options: EventSubscriptionOptions = DefaultEventSubscriptionOptions
88
- ) {
89
- this.options = Object.assign({}, DefaultEventSubscriptionOptions, options);
90
- this.address = this.options.address ?? program.programId;
91
- this.txEventCache = new TxEventCache(this.options.maxTx);
92
- this.eventListMap = new Map<EventType, EventList<EventType>>();
93
- this.eventEmitter = new EventEmitter();
94
-
95
- this._currentProviderType = this.getLogProviderConfig().type;
96
- this.initializeLogProvider();
97
- }
98
-
99
- private getLogProviderConfig(): LogProviderConfig {
100
- if (this.options.logProviderConfig === undefined) {
101
- throw new Error('EventSubscriber: logProviderConfig is not set');
102
- }
103
- return this.options.logProviderConfig;
104
- }
105
-
106
- private getEventTypes(): EventType[] {
107
- if (this.options.eventTypes === undefined) {
108
- throw new Error('EventSubscriber: eventTypes is not set');
109
- }
110
- return this.options.eventTypes;
111
- }
112
-
113
- /** The `LogProviderType` currently in use. May differ from the configured type after a fallback failover (see `updateFallbackProviderType`). */
114
- get currentProviderType() {
115
- return this._currentProviderType;
116
- }
117
-
118
- private initializeLogProvider(subscribe = false) {
119
- const logProviderConfig = this.getLogProviderConfig();
120
-
121
- if (this._currentProviderType === 'websocket') {
122
- this._logProvider = new WebSocketLogProvider(
123
- // @ts-ignore
124
- this.connection,
125
- this.address,
126
- this.options.commitment ?? 'confirmed',
127
- (logProviderConfig as WebSocketLogProviderConfig).resubTimeoutMs
128
- );
129
- } else if (this._currentProviderType === 'polling') {
130
- const frequency =
131
- 'frequency' in logProviderConfig
132
- ? (logProviderConfig as PollingLogProviderConfig).frequency
133
- : (logProviderConfig as StreamingLogProviderConfig).fallbackFrequency;
134
- const batchSize =
135
- 'batchSize' in logProviderConfig
136
- ? (logProviderConfig as PollingLogProviderConfig).batchSize
137
- : (logProviderConfig as StreamingLogProviderConfig).fallbackBatchSize;
138
-
139
- this._logProvider = new PollingLogProvider(
140
- // @ts-ignore
141
- this.connection,
142
- this.address,
143
- this.options.commitment ?? 'confirmed',
144
- frequency,
145
- batchSize
146
- );
147
- } else if (this._currentProviderType === 'events-server') {
148
- this._logProvider = new EventsServerLogProvider(
149
- (logProviderConfig as EventsServerLogProviderConfig).url,
150
- this.getEventTypes(),
151
- this.options.address ? this.options.address.toString() : undefined
152
- );
153
- } else {
154
- throw new Error(
155
- `Invalid log provider type: ${this._currentProviderType}`
156
- );
157
- }
158
-
159
- if (subscribe) {
160
- this.logProvider.subscribe(
161
- (txSig, slot, logs, mostRecentBlockTime, txSigIndex) => {
162
- this.handleTxLogs(
163
- txSig,
164
- slot,
165
- logs,
166
- mostRecentBlockTime,
167
- this._currentProviderType === 'events-server',
168
- txSigIndex
169
- );
170
- },
171
- true
172
- );
173
- }
174
- }
175
-
176
- private populateInitialEventListMap() {
177
- const maxEventsPerType = this.options.maxEventsPerType;
178
- const orderBy = this.options.orderBy;
179
- const orderDir = this.options.orderDir;
180
- if (
181
- maxEventsPerType === undefined ||
182
- orderBy === undefined ||
183
- orderDir === undefined
184
- ) {
185
- throw new Error(
186
- 'EventSubscriber: maxEventsPerType, orderBy and orderDir must be set'
187
- );
188
- }
189
- for (const eventType of this.getEventTypes()) {
190
- this.eventListMap.set(
191
- eventType,
192
- new EventList(
193
- eventType,
194
- maxEventsPerType,
195
- getSortFn(orderBy, orderDir),
196
- orderDir
197
- )
198
- );
199
- this.eventTypeByLowercaseName.set(eventType.toLowerCase(), eventType);
200
- }
201
- }
202
-
203
- /**
204
- * Implements fallback logic for reconnecting to LogProvider. Currently terminates at polling,
205
- * could be improved to try the original type again after some cooldown.
206
- */
207
- private updateFallbackProviderType(
208
- reconnectAttempts: number,
209
- maxReconnectAttempts: number
210
- ) {
211
- if (reconnectAttempts < maxReconnectAttempts) {
212
- return;
213
- }
214
-
215
- let nextProviderType = this._currentProviderType;
216
- if (this._currentProviderType === 'events-server') {
217
- nextProviderType = 'websocket';
218
- } else if (this._currentProviderType === 'websocket') {
219
- nextProviderType = 'polling';
220
- } else if (this._currentProviderType === 'polling') {
221
- nextProviderType = 'polling';
222
- }
223
-
224
- console.log(
225
- `EventSubscriber: Failing over providerType ${this._currentProviderType} to ${nextProviderType}`
226
- );
227
- this._currentProviderType = nextProviderType;
228
- }
229
-
230
- /**
231
- * Starts streaming events via the configured `LogProvider`. Idempotent —
232
- * returns `true` immediately if already subscribed. (Re)initializes the
233
- * per-event-type `EventList`s, so any events retained from a prior
234
- * subscribe/unsubscribe cycle are discarded. For streaming providers
235
- * (websocket, events-server), also wires up automatic failover: if the
236
- * provider emits more than `maxReconnectAttempts` (default `Infinity`,
237
- * i.e. never) reconnect attempts, the subscriber tears down and
238
- * reinitializes with the next provider in the fallback chain
239
- * (events-server → websocket → polling; polling has no further fallback).
240
- * Does not itself backfill history — call `fetchPreviousTx` for that.
241
- * @returns `true` once subscribed, or `false` if an error occurred while starting the subscription (logged to console, not thrown).
242
- */
243
- public async subscribe(): Promise<boolean> {
244
- try {
245
- if (this.logProvider.isSubscribed()) {
246
- return true;
247
- }
248
-
249
- this.populateInitialEventListMap();
250
-
251
- if (
252
- this.getLogProviderConfig().type === 'websocket' ||
253
- this.getLogProviderConfig().type === 'events-server'
254
- ) {
255
- const logProviderConfig =
256
- this.getLogProviderConfig() as StreamingLogProviderConfig;
257
- // `maxReconnectAttempts` is optional; when unset the original
258
- // `reconnectAttempts > undefined` comparison was always false, so
259
- // fall back to Infinity to preserve that never-trigger behavior.
260
- const maxReconnectAttempts =
261
- logProviderConfig.maxReconnectAttempts ?? Infinity;
262
-
263
- const eventEmitter = this.logProvider.eventEmitter;
264
- if (eventEmitter) {
265
- eventEmitter.on('reconnect', async (reconnectAttempts) => {
266
- if (reconnectAttempts > maxReconnectAttempts) {
267
- console.log(
268
- `EventSubscriber: Reconnect attempts ${reconnectAttempts}/${maxReconnectAttempts}, reconnecting...`
269
- );
270
- eventEmitter.removeAllListeners('reconnect');
271
- await this.unsubscribe();
272
- this.updateFallbackProviderType(
273
- reconnectAttempts,
274
- maxReconnectAttempts
275
- );
276
- this.initializeLogProvider(true);
277
- }
278
- });
279
- }
280
- }
281
- this.logProvider.subscribe(
282
- (txSig, slot, logs, mostRecentBlockTime, txSigIndex) => {
283
- this.handleTxLogs(
284
- txSig,
285
- slot,
286
- logs,
287
- mostRecentBlockTime,
288
- this._currentProviderType === 'events-server',
289
- txSigIndex
290
- );
291
- },
292
- true
293
- );
294
-
295
- return true;
296
- } catch (e) {
297
- console.error('Error fetching previous txs in event subscriber');
298
- console.error(e);
299
- return false;
300
- }
301
- }
302
-
303
- private handleTxLogs(
304
- txSig: TransactionSignature,
305
- slot: number,
306
- logs: string[],
307
- mostRecentBlockTime: number | undefined,
308
- fromEventsServer = false,
309
- txSigIndex: number | undefined = undefined
310
- ): void {
311
- if (!fromEventsServer && this.txEventCache.has(txSig)) {
312
- return;
313
- }
314
-
315
- const wrappedEvents = this.parseEventsFromLogs(
316
- txSig,
317
- slot,
318
- logs,
319
- txSigIndex
320
- );
321
-
322
- for (const wrappedEvent of wrappedEvents) {
323
- const eventList = this.eventListMap.get(wrappedEvent.eventType);
324
- if (eventList === undefined) {
325
- throw new Error(
326
- `EventSubscriber: no EventList for eventType ${wrappedEvent.eventType}`
327
- );
328
- }
329
- eventList.insert(wrappedEvent);
330
- }
331
-
332
- // dont emit event till we've added all the events to the eventListMap
333
- for (const wrappedEvent of wrappedEvents) {
334
- this.eventEmitter.emit('newEvent', wrappedEvent);
335
- }
336
-
337
- if (this.awaitTxPromises.has(txSig)) {
338
- this.awaitTxPromises.delete(txSig);
339
- const resolver = this.awaitTxResolver.get(txSig);
340
- if (resolver !== undefined) {
341
- resolver();
342
- }
343
- this.awaitTxResolver.delete(txSig);
344
- }
345
-
346
- if (!this.lastSeenSlot || slot > this.lastSeenSlot) {
347
- this.lastSeenTxSig = txSig;
348
- this.lastSeenSlot = slot;
349
- }
350
-
351
- if (
352
- this.lastSeenBlockTime === undefined ||
353
- (mostRecentBlockTime !== undefined &&
354
- mostRecentBlockTime > this.lastSeenBlockTime)
355
- ) {
356
- this.lastSeenBlockTime = mostRecentBlockTime;
357
- }
358
-
359
- this.txEventCache.add(txSig, wrappedEvents);
360
- }
361
-
362
- /**
363
- * Backfills historical events by walking transactions for `address` via
364
- * `getSignaturesForAddress`/`getTransaction`, newest-first, until either
365
- * `options.untilTx` is reached or `options.maxTx` transactions have been
366
- * fetched. Each fetched transaction is decoded and inserted into the
367
- * event lists exactly like a live update, so `newEvent` fires for
368
- * backfilled events too. No-ops if neither `untilTx` is set nor
369
- * `fetchMax` is true — the subscriber does not backfill by default.
370
- * @param fetchMax If true, backfill up to `maxTx` transactions even without an `untilTx` cutoff.
371
- */
372
- public async fetchPreviousTx(fetchMax?: boolean): Promise<void> {
373
- if (!this.options.untilTx && !fetchMax) {
374
- return;
375
- }
376
-
377
- let txFetched = 0;
378
- let beforeTx: TransactionSignature | undefined = undefined;
379
- const untilTx: TransactionSignature | undefined = this.options.untilTx;
380
- const maxTx = this.options.maxTx;
381
- if (maxTx === undefined) {
382
- throw new Error('EventSubscriber: maxTx is not set');
383
- }
384
- while (txFetched < maxTx) {
385
- const response = await fetchLogs(
386
- // @ts-ignore
387
- this.connection,
388
- this.address,
389
- this.options.commitment === 'finalized' ? 'finalized' : 'confirmed',
390
- beforeTx,
391
- untilTx
392
- );
393
-
394
- if (response === undefined) {
395
- break;
396
- }
397
-
398
- txFetched += response.transactionLogs.length;
399
- beforeTx = response.earliestTx;
400
-
401
- for (const { txSig, slot, logs } of response.transactionLogs) {
402
- this.handleTxLogs(txSig, slot, logs, response.mostRecentBlockTime);
403
- }
404
- }
405
- }
406
-
407
- /**
408
- * Stops the log provider and clears all in-memory state: the per-event-type
409
- * `EventList`s, the `TxEventCache`, and any pending `awaitTx` promises
410
- * (which are left unresolved/unrejected — callers awaiting a tx signature
411
- * across an unsubscribe will hang).
412
- * @returns Whatever the underlying `LogProvider.unsubscribe` returns.
413
- */
414
- public async unsubscribe(): Promise<boolean> {
415
- this.eventListMap.clear();
416
- this.txEventCache.clear();
417
- this.awaitTxPromises.clear();
418
- this.awaitTxResolver.clear();
419
-
420
- return await this.logProvider.unsubscribe(true);
421
- }
422
-
423
- private parseEventsFromLogs(
424
- txSig: TransactionSignature,
425
- slot: number,
426
- logs: string[],
427
- txSigIndex: number | undefined
428
- ): WrappedEvents {
429
- const records = [];
430
- // @ts-ignore
431
- const events = parseLogs(this.program, logs);
432
- let runningEventIndex = 0;
433
- for (const event of events) {
434
- // @coral-xyz/anchor 0.32+ converts IDL names to camelCase; match
435
- // case-insensitively so names with leading acronyms (LPSwapRecord →
436
- // lpSwapRecord) still resolve to their PascalCase EventType keys.
437
- const eventType = this.eventTypeByLowercaseName.get(
438
- event.name.toLowerCase()
439
- );
440
- if (eventType) {
441
- event.data.txSig = txSig;
442
- event.data.slot = slot;
443
- event.data.eventType = eventType;
444
- event.data.txSigIndex =
445
- txSigIndex !== undefined ? txSigIndex : runningEventIndex;
446
- records.push(event.data);
447
- }
448
- runningEventIndex++;
449
- }
450
- return records;
451
- }
452
-
453
- /**
454
- * Resolves once the subscriber has observed and decoded events for `txSig`
455
- * (immediately if it's already in the `TxEventCache`). Useful for waiting
456
- * on the events of a transaction the caller just sent, before reading them
457
- * via `getEventsByTx`. Never rejects; a transaction that never arrives
458
- * (e.g. it failed, or the subscriber isn't subscribed) leaves the returned
459
- * promise pending forever.
460
- * @param txSig Signature to wait for.
461
- * @returns A promise that resolves (with no value) once that transaction's events have been processed.
462
- */
463
- public awaitTx(txSig: TransactionSignature): Promise<void> {
464
- const existingPromise = this.awaitTxPromises.get(txSig);
465
- if (existingPromise !== undefined) {
466
- return existingPromise;
467
- }
468
-
469
- if (this.txEventCache.has(txSig)) {
470
- return Promise.resolve();
471
- }
472
-
473
- const promise = new Promise<void>((resolve) => {
474
- this.awaitTxResolver.set(txSig, resolve);
475
- });
476
- this.awaitTxPromises.set(txSig, promise);
477
- return promise;
478
- }
479
-
480
- /**
481
- * Returns the live `EventList` for `eventType` — the ordered, size-bounded
482
- * (`maxEventsPerType`) linked list the subscriber inserts new events into.
483
- * Prefer this over `getEventsArray` to iterate without copying.
484
- * @param eventType Event type to look up; must be one of `options.eventTypes` (subscribed types).
485
- * @returns The `EventList` for that type, or `undefined` if `eventType` was never subscribed (list not yet populated by `subscribe()`).
486
- */
487
- public getEventList<Type extends keyof EventMap>(
488
- eventType: Type
489
- ): EventList<Type> | undefined {
490
- return this.eventListMap.get(eventType) as EventList<Type> | undefined;
491
- }
492
-
493
- /**
494
- * This requires the EventList be cast to an array, which requires reallocation of memory.
495
- * Would bias to using getEventList over getEvents
496
- *
497
- * @param eventType Event type to snapshot.
498
- * @returns All currently retained events of that type, in the `EventList`'s sort order (see `EventSubscriptionOptions.orderBy`/`orderDir`).
499
- * @throws If `eventType` has no `EventList` (i.e. it isn't in `options.eventTypes`).
500
- */
501
- public getEventsArray<Type extends EventType>(
502
- eventType: Type
503
- ): EventMap[Type][] {
504
- const eventList = this.eventListMap.get(eventType);
505
- if (eventList === undefined) {
506
- throw new Error(
507
- `EventSubscriber: no EventList for eventType ${eventType}`
508
- );
509
- }
510
- return eventList.toArray() as EventMap[Type][];
511
- }
512
-
513
- /**
514
- * Looks up the decoded events previously observed for a transaction.
515
- * @param txSig Transaction signature to look up.
516
- * @returns The wrapped events emitted by that transaction, or `undefined` if the transaction has aged out of the `TxEventCache` (bounded by `options.maxTx`) or was never observed.
517
- */
518
- public getEventsByTx(txSig: TransactionSignature): WrappedEvents | undefined {
519
- return this.txEventCache.get(txSig);
520
- }
521
- }