@velocity-exchange/sdk 0.4.0 → 0.6.0

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