@velocity-exchange/sdk 0.4.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +52 -0
  3. package/lib/browser/adminClient.js +97 -0
  4. package/lib/browser/config.js +6 -7
  5. package/lib/browser/constants/numericConstants.d.ts +1 -1
  6. package/lib/browser/constants/numericConstants.js +1 -1
  7. package/lib/browser/decode/user.js +5 -1
  8. package/lib/browser/idl/velocity.d.ts +191 -15
  9. package/lib/browser/idl/velocity.json +192 -16
  10. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
  11. package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
  12. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  13. package/lib/browser/types.d.ts +6 -0
  14. package/lib/browser/user.d.ts +20 -3
  15. package/lib/browser/user.js +52 -4
  16. package/lib/browser/velocityClient.d.ts +46 -10
  17. package/lib/browser/velocityClient.js +107 -35
  18. package/lib/node/adminClient.d.ts +52 -0
  19. package/lib/node/adminClient.d.ts.map +1 -1
  20. package/lib/node/adminClient.js +97 -0
  21. package/lib/node/config.d.ts.map +1 -1
  22. package/lib/node/config.js +6 -7
  23. package/lib/node/constants/numericConstants.d.ts +1 -1
  24. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  25. package/lib/node/constants/numericConstants.js +1 -1
  26. package/lib/node/decode/user.d.ts.map +1 -1
  27. package/lib/node/decode/user.js +5 -1
  28. package/lib/node/idl/velocity.d.ts +191 -15
  29. package/lib/node/idl/velocity.d.ts.map +1 -1
  30. package/lib/node/idl/velocity.json +192 -16
  31. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
  32. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  33. package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
  34. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  35. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  36. package/lib/node/types.d.ts +6 -0
  37. package/lib/node/types.d.ts.map +1 -1
  38. package/lib/node/user.d.ts +20 -3
  39. package/lib/node/user.d.ts.map +1 -1
  40. package/lib/node/user.js +52 -4
  41. package/lib/node/velocityClient.d.ts +46 -10
  42. package/lib/node/velocityClient.d.ts.map +1 -1
  43. package/lib/node/velocityClient.js +107 -35
  44. package/package.json +7 -3
  45. package/.prettierignore +0 -1
  46. package/CHANGELOG.md +0 -132
  47. package/build-browser.js +0 -58
  48. package/bunfig.toml +0 -3
  49. package/esbuild-shims.js +0 -12
  50. package/scripts/deposit-isolated-positions.ts +0 -110
  51. package/scripts/find-flagged-users.ts +0 -213
  52. package/scripts/grpc-client-test-comparison.ts +0 -372
  53. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  54. package/scripts/postbuild.js +0 -95
  55. package/scripts/single-grpc-client-test.ts +0 -284
  56. package/scripts/withdraw-isolated-positions.ts +0 -174
  57. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  58. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  59. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  60. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  61. package/src/accounts/bulkAccountLoader.ts +0 -358
  62. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  63. package/src/accounts/bulkUserSubscription.ts +0 -39
  64. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  65. package/src/accounts/fetch.ts +0 -200
  66. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  67. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  68. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  69. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  70. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  71. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  72. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  73. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  74. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  75. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  76. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  77. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  78. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  79. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  80. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  81. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  82. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  83. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  84. package/src/accounts/testBulkAccountLoader.ts +0 -59
  85. package/src/accounts/types.ts +0 -428
  86. package/src/accounts/utils.ts +0 -90
  87. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  88. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  89. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  90. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  91. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  92. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  93. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  94. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  95. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  96. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  97. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  98. package/src/addresses/marketAddresses.ts +0 -28
  99. package/src/addresses/pda.ts +0 -620
  100. package/src/adminClient.ts +0 -8136
  101. package/src/assert/assert.ts +0 -5
  102. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  103. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  104. package/src/auctionSubscriber/index.ts +0 -9
  105. package/src/auctionSubscriber/types.ts +0 -30
  106. package/src/bankrun/bankrunConnection.ts +0 -630
  107. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  108. package/src/blockhashSubscriber/index.ts +0 -6
  109. package/src/blockhashSubscriber/types.ts +0 -13
  110. package/src/clock/clockSubscriber.ts +0 -146
  111. package/src/config.ts +0 -312
  112. package/src/constants/index.ts +0 -9
  113. package/src/constants/numericConstants.ts +0 -194
  114. package/src/constants/perpMarkets.ts +0 -127
  115. package/src/constants/spotMarkets.ts +0 -104
  116. package/src/constants/txConstants.ts +0 -2
  117. package/src/constituentMap/constituentMap.ts +0 -305
  118. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  119. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  120. package/src/core/VelocityCore.ts +0 -606
  121. package/src/core/index.ts +0 -12
  122. package/src/core/instructions/deposit.ts +0 -64
  123. package/src/core/instructions/fill.ts +0 -51
  124. package/src/core/instructions/funding.ts +0 -33
  125. package/src/core/instructions/liquidation.ts +0 -55
  126. package/src/core/instructions/orders.ts +0 -84
  127. package/src/core/instructions/perpOrders.ts +0 -312
  128. package/src/core/instructions/settlement.ts +0 -40
  129. package/src/core/instructions/trigger.ts +0 -41
  130. package/src/core/instructions/withdraw.ts +0 -65
  131. package/src/core/remainingAccounts.ts +0 -320
  132. package/src/core/signedMsg.ts +0 -109
  133. package/src/decode/customCoder.ts +0 -148
  134. package/src/decode/user.ts +0 -401
  135. package/src/dlob/DLOB.ts +0 -2793
  136. package/src/dlob/DLOBNode.ts +0 -305
  137. package/src/dlob/DLOBSubscriber.ts +0 -269
  138. package/src/dlob/NodeList.ts +0 -244
  139. package/src/dlob/orderBookLevels.ts +0 -695
  140. package/src/dlob/types.ts +0 -37
  141. package/src/events/eventList.ts +0 -114
  142. package/src/events/eventSubscriber.ts +0 -521
  143. package/src/events/eventsServerLogProvider.ts +0 -189
  144. package/src/events/fetchLogs.ts +0 -219
  145. package/src/events/parse.ts +0 -271
  146. package/src/events/pollingLogProvider.ts +0 -113
  147. package/src/events/sort.ts +0 -51
  148. package/src/events/txEventCache.ts +0 -92
  149. package/src/events/types.ts +0 -337
  150. package/src/events/webSocketLogProvider.ts +0 -152
  151. package/src/factory/bigNum.ts +0 -709
  152. package/src/factory/oracleClient.ts +0 -73
  153. package/src/idl/pyth.json +0 -142
  154. package/src/idl/pyth.ts +0 -97
  155. package/src/idl/pyth_solana_receiver.json +0 -628
  156. package/src/idl/token_faucet.json +0 -229
  157. package/src/idl/token_faucet.ts +0 -197
  158. package/src/idl/velocity.json +0 -23974
  159. package/src/idl/velocity.ts +0 -23980
  160. package/src/index.ts +0 -150
  161. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  162. package/src/isomorphic/README.md +0 -19
  163. package/src/isomorphic/anchor.browser.ts +0 -44
  164. package/src/isomorphic/anchor.node.ts +0 -1
  165. package/src/isomorphic/anchor.ts +0 -1
  166. package/src/isomorphic/anchor29.browser.ts +0 -24
  167. package/src/isomorphic/anchor29.node.ts +0 -1
  168. package/src/isomorphic/anchor29.ts +0 -1
  169. package/src/isomorphic/grpc.browser.ts +0 -4
  170. package/src/isomorphic/grpc.node.ts +0 -130
  171. package/src/isomorphic/grpc.ts +0 -1
  172. package/src/jupiter/jupiterClient.ts +0 -502
  173. package/src/keypair.ts +0 -32
  174. package/src/margin/README.md +0 -138
  175. package/src/marginCalculation.ts +0 -407
  176. package/src/marinade/idl/idl.json +0 -1962
  177. package/src/marinade/index.ts +0 -73
  178. package/src/marinade/types.ts +0 -3925
  179. package/src/math/amm.ts +0 -1758
  180. package/src/math/auction.ts +0 -480
  181. package/src/math/bankruptcy.ts +0 -138
  182. package/src/math/builder.ts +0 -130
  183. package/src/math/conversion.ts +0 -45
  184. package/src/math/exchangeStatus.ts +0 -261
  185. package/src/math/funding.ts +0 -498
  186. package/src/math/insurance.ts +0 -171
  187. package/src/math/liquidation.ts +0 -433
  188. package/src/math/margin.ts +0 -327
  189. package/src/math/market.ts +0 -487
  190. package/src/math/oracles.ts +0 -477
  191. package/src/math/orders.ts +0 -500
  192. package/src/math/position.ts +0 -381
  193. package/src/math/repeg.ts +0 -223
  194. package/src/math/spotBalance.ts +0 -996
  195. package/src/math/spotMarket.ts +0 -115
  196. package/src/math/spotPosition.ts +0 -263
  197. package/src/math/state.ts +0 -71
  198. package/src/math/superStake.ts +0 -602
  199. package/src/math/tiers.ts +0 -73
  200. package/src/math/trade.ts +0 -879
  201. package/src/math/utils.ts +0 -183
  202. package/src/memcmp.ts +0 -279
  203. package/src/oracles/oracleClientCache.ts +0 -41
  204. package/src/oracles/oracleId.ts +0 -99
  205. package/src/oracles/prelaunchOracleClient.ts +0 -63
  206. package/src/oracles/pythClient.ts +0 -125
  207. package/src/oracles/pythLazerClient.ts +0 -141
  208. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  209. package/src/oracles/strictOraclePrice.ts +0 -40
  210. package/src/oracles/types.ts +0 -82
  211. package/src/oracles/utils.ts +0 -45
  212. package/src/orderParams.ts +0 -117
  213. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  214. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  215. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  216. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  217. package/src/orderSubscriber/index.ts +0 -7
  218. package/src/orderSubscriber/types.ts +0 -64
  219. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  220. package/src/priorityFee/averageStrategy.ts +0 -13
  221. package/src/priorityFee/ewmaStrategy.ts +0 -51
  222. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  223. package/src/priorityFee/index.ts +0 -16
  224. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  225. package/src/priorityFee/maxStrategy.ts +0 -8
  226. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  227. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  228. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  229. package/src/priorityFee/types.ts +0 -82
  230. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  231. package/src/pyth/constants.ts +0 -9
  232. package/src/pyth/index.ts +0 -15
  233. package/src/pyth/pythLazerSubscriber.ts +0 -365
  234. package/src/pyth/types.ts +0 -4451
  235. package/src/pyth/utils.ts +0 -13
  236. package/src/slot/SlotSubscriber.ts +0 -126
  237. package/src/slot/SlothashSubscriber.ts +0 -163
  238. package/src/swap/UnifiedSwapClient.ts +0 -315
  239. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  240. package/src/swift/index.ts +0 -10
  241. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  242. package/src/swift/swiftOrderSubscriber.ts +0 -351
  243. package/src/testClient.ts +0 -42
  244. package/src/titan/titanClient.ts +0 -438
  245. package/src/token/index.ts +0 -13
  246. package/src/tokenFaucet.ts +0 -296
  247. package/src/tx/baseTxSender.ts +0 -651
  248. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  249. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  250. package/src/tx/blockhashFetcher/types.ts +0 -9
  251. package/src/tx/fastSingleTxSender.ts +0 -200
  252. package/src/tx/forwardOnlyTxSender.ts +0 -193
  253. package/src/tx/priorityFeeCalculator.ts +0 -117
  254. package/src/tx/reportTransactionError.ts +0 -176
  255. package/src/tx/retryTxSender.ts +0 -177
  256. package/src/tx/txHandler.ts +0 -1009
  257. package/src/tx/txParamProcessor.ts +0 -225
  258. package/src/tx/types.ts +0 -117
  259. package/src/tx/utils.ts +0 -133
  260. package/src/tx/whileValidTxSender.ts +0 -377
  261. package/src/types.ts +0 -2575
  262. package/src/user.ts +0 -5316
  263. package/src/userConfig.ts +0 -38
  264. package/src/userMap/PollingSubscription.ts +0 -61
  265. package/src/userMap/WebsocketSubscription.ts +0 -93
  266. package/src/userMap/grpcSubscription.ts +0 -93
  267. package/src/userMap/referrerMap.ts +0 -360
  268. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  269. package/src/userMap/userMap.ts +0 -784
  270. package/src/userMap/userMapConfig.ts +0 -82
  271. package/src/userMap/userStatsMap.ts +0 -393
  272. package/src/userName.ts +0 -37
  273. package/src/userStats.ts +0 -159
  274. package/src/userStatsConfig.ts +0 -35
  275. package/src/util/TransactionConfirmationManager.ts +0 -333
  276. package/src/util/chainClock.ts +0 -65
  277. package/src/util/computeUnits.ts +0 -101
  278. package/src/util/digest.ts +0 -33
  279. package/src/util/ed25519Utils.ts +0 -95
  280. package/src/util/promiseTimeout.ts +0 -23
  281. package/src/velocityClient.ts +0 -14802
  282. package/src/velocityClientConfig.ts +0 -119
  283. package/src/wallet.ts +0 -91
  284. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  285. package/tests/VelocityCore/decode.test.ts +0 -16
  286. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  287. package/tests/VelocityCore/instructions.test.ts +0 -46
  288. package/tests/VelocityCore/pdas.test.ts +0 -30
  289. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  290. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  291. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  292. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  293. package/tests/amm/test.ts +0 -2402
  294. package/tests/auctions/test.ts +0 -81
  295. package/tests/bn/test.ts +0 -355
  296. package/tests/builder/builderFee.test.ts +0 -42
  297. package/tests/ci/verifyConstants.ts +0 -393
  298. package/tests/decode/test.ts +0 -262
  299. package/tests/decode/userAccountBufferStrings.ts +0 -102
  300. package/tests/dlob/helpers.ts +0 -748
  301. package/tests/dlob/test.ts +0 -6969
  302. package/tests/dlob/tickSizeStandardization.ts +0 -545
  303. package/tests/events/parseLogsForCuUsage.ts +0 -139
  304. package/tests/exchangeStatus/test.ts +0 -45
  305. package/tests/insurance/test.ts +0 -40
  306. package/tests/liquidation/test.ts +0 -125
  307. package/tests/oracles/mmOracleGate.test.ts +0 -379
  308. package/tests/oracles/pythPegSnap.test.ts +0 -76
  309. package/tests/sdkParity/enumParity.test.ts +0 -84
  310. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  311. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  312. package/tests/spot/test.ts +0 -281
  313. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  314. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  315. package/tests/tx/priorityFeeCalculator.ts +0 -77
  316. package/tests/tx/priorityFeeStrategy.ts +0 -95
  317. package/tests/user/bankruptcy.ts +0 -165
  318. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  319. package/tests/user/getMarginCalculation.ts +0 -586
  320. package/tests/user/helpers.ts +0 -184
  321. package/tests/user/liquidations.ts +0 -129
  322. package/tests/user/marginCalculations.test.ts +0 -321
  323. package/tests/user/test.ts +0 -833
  324. package/tsconfig.browser.json +0 -18
  325. package/tsconfig.json +0 -36
@@ -1,250 +0,0 @@
1
- import { GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE } from '../constants/numericConstants';
2
- import { BulkAccountLoader } from './bulkAccountLoader';
3
- import { Commitment, Connection, PublicKey } from '@solana/web3.js';
4
- import { v4 as uuidv4 } from 'uuid';
5
-
6
- /**
7
- * `BulkAccountLoader` variant where each account can be polled at its own cadence instead of a
8
- * single shared `pollingFrequency`. Overrides the base class's single `setInterval` with a
9
- * per-account `accountFrequencies` map: `handleAccountLoading()` only includes an account in a
10
- * given tick if `Date.now() - lastPollingTime >= frequency` for that account, then delegates to
11
- * the inherited chunked `loadChunk` for the actual `getMultipleAccounts` batch. The interval
12
- * itself always runs at the fastest frequency across all registered accounts (see `startPolling`),
13
- * so slower accounts simply get skipped on ticks that fire before they're due.
14
- */
15
- export class CustomizedCadenceBulkAccountLoader extends BulkAccountLoader {
16
- private customIntervalId: NodeJS.Timeout | null;
17
- private currentPollingFrequency: number | null;
18
- private accountFrequencies: Map<string, number>;
19
- private lastPollingTimes: Map<string, number>;
20
- private defaultPollingFrequency: number;
21
-
22
- /**
23
- * @param connection Connection used for the batched `getMultipleAccounts` polls.
24
- * @param commitment Commitment level applied to every poll.
25
- * @param defaultPollingFrequency Polling cadence in ms (see base `BulkAccountLoader`) used for any account added without an explicit `customPollingFrequency`, and as the floor when computing the shared interval in `startPolling`.
26
- */
27
- constructor(
28
- connection: Connection,
29
- commitment: Commitment,
30
- defaultPollingFrequency: number
31
- ) {
32
- super(connection, commitment, defaultPollingFrequency);
33
- this.customIntervalId = null;
34
- this.currentPollingFrequency = null;
35
- this.accountFrequencies = new Map();
36
- this.lastPollingTimes = new Map();
37
- this.defaultPollingFrequency = defaultPollingFrequency;
38
- }
39
-
40
- private getAccountsToLoad(): Array<{
41
- publicKey: PublicKey;
42
- callbacks: Map<string, (buffer: Buffer, slot: number) => void>;
43
- }> {
44
- const currentTime = Date.now();
45
- const accountsToLoad: Array<{
46
- publicKey: PublicKey;
47
- callbacks: Map<string, (buffer: Buffer, slot: number) => void>;
48
- }> = [];
49
-
50
- for (const [key, frequency] of this.accountFrequencies.entries()) {
51
- const lastPollTime = this.lastPollingTimes.get(key) || 0;
52
- if (currentTime - lastPollTime >= frequency) {
53
- const account = this.accountsToLoad.get(key);
54
- if (account) {
55
- accountsToLoad.push(account);
56
- this.lastPollingTimes.set(key, currentTime);
57
- }
58
- }
59
- }
60
-
61
- return accountsToLoad;
62
- }
63
-
64
- /** Immediately runs one due-account loading pass, bypassing the interval timer. Unlike the base class's `load()`, this does not force-load every registered account — only those currently due per their own cadence. */
65
- public async load(): Promise<void> {
66
- return this.handleAccountLoading();
67
- }
68
-
69
- private async handleAccountLoading(): Promise<void> {
70
- const accounts = this.getAccountsToLoad();
71
-
72
- if (accounts.length > 0) {
73
- const chunks = this.chunks(
74
- this.chunks(accounts, GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE),
75
- 10
76
- );
77
-
78
- await Promise.all(
79
- chunks.map((chunk) => {
80
- return this.loadChunk(chunk);
81
- })
82
- );
83
- }
84
- }
85
-
86
- /**
87
- * Updates the polling frequency for an account. This affects all callbacks attached to this account.
88
- *
89
- * @param publicKey The public key of the account to set the custom polling frequency for
90
- * @param newFrequency The new polling frequency in ms
91
- */
92
- public setCustomPollingFrequency(
93
- publicKey: PublicKey,
94
- newFrequency: number
95
- ): void {
96
- const key = publicKey.toBase58();
97
- this.accountFrequencies.set(key, newFrequency);
98
- this.lastPollingTimes.set(key, 0); // Reset last polling time to ensure immediate load
99
- this.restartPollingIfNeeded(newFrequency);
100
- }
101
-
102
- private restartPollingIfNeeded(newFrequency: number): void {
103
- if (
104
- (this.currentPollingFrequency &&
105
- newFrequency < this.currentPollingFrequency) ||
106
- !this.customIntervalId
107
- ) {
108
- this.stopPolling();
109
- this.startPolling();
110
- }
111
- }
112
-
113
- /**
114
- * Adds an account to be monitored by the bulk account loader
115
- * @param publicKey The public key of the account to monitor
116
- * @param callback Function to be called when account data is received
117
- * @param customPollingFrequency Optional custom polling frequency in ms for this specific account.
118
- * If not provided, will use the default polling frequency
119
- * @returns A unique callback ID that can be used to remove this specific callback later
120
- *
121
- * The method will:
122
- * 1. Create a new callback mapping for the account if it doesn't exist already
123
- * 2. Set up polling frequency tracking for the account if it doesn't exist already. If previous polling frequency is faster than the new one,
124
- * we will use the previous frequency.
125
- * 3. Reset last polling time to 0 to ensure data fetch is triggered on the next poll. Note that this does not mean the account will be fetched immediately.
126
- * 4. Automatically restart polling if this account needs a faster frequency than existing accounts
127
- */
128
- public async addAccount(
129
- publicKey: PublicKey,
130
- callback: (buffer: Buffer, slot: number) => void,
131
- customPollingFrequency?: number
132
- ): Promise<string> {
133
- const callbackId = uuidv4();
134
- const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
135
-
136
- if (existingAccountToLoad) {
137
- existingAccountToLoad.callbacks.set(callbackId, callback);
138
- } else {
139
- const callbacks = new Map<
140
- string,
141
- (buffer: Buffer, slot: number) => void
142
- >();
143
- callbacks.set(callbackId, callback);
144
- const newAccountToLoad = {
145
- publicKey,
146
- callbacks,
147
- };
148
- this.accountsToLoad.set(publicKey.toString(), newAccountToLoad);
149
- }
150
-
151
- const key = publicKey.toBase58();
152
- const previousFrequency =
153
- this.accountFrequencies.get(key) || this.defaultPollingFrequency;
154
- const updatedFrequency =
155
- customPollingFrequency && customPollingFrequency < previousFrequency
156
- ? customPollingFrequency
157
- : previousFrequency;
158
-
159
- this.accountFrequencies.set(key, updatedFrequency);
160
- this.lastPollingTimes.set(key, 0); // Reset last polling time to ensure immediate load
161
-
162
- this.restartPollingIfNeeded(updatedFrequency);
163
-
164
- return callbackId;
165
- }
166
-
167
- /**
168
- * Unregisters a callback previously returned by `addAccount`. Once an account has no
169
- * remaining callbacks, its cached buffer/slot and cadence bookkeeping (`accountFrequencies`,
170
- * `lastPollingTimes`) are dropped; if no accounts remain at all, polling stops entirely,
171
- * otherwise polling is restarted in case the removed account held the fastest cadence.
172
- * @param publicKey Account the callback was registered against.
173
- * @param callbackId Id returned by `addAccount`.
174
- */
175
- public removeAccount(publicKey: PublicKey, callbackId: string): void {
176
- const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
177
-
178
- if (existingAccountToLoad) {
179
- existingAccountToLoad.callbacks.delete(callbackId);
180
-
181
- if (existingAccountToLoad.callbacks.size === 0) {
182
- this.bufferAndSlotMap.delete(publicKey.toString());
183
- this.accountsToLoad.delete(existingAccountToLoad.publicKey.toString());
184
- const key = publicKey.toBase58();
185
- this.accountFrequencies.delete(key);
186
- this.lastPollingTimes.delete(key);
187
- }
188
- }
189
-
190
- if (this.accountsToLoad.size === 0) {
191
- this.stopPolling();
192
- } else {
193
- // Restart polling in case we removed the account with the smallest frequency
194
- this.restartPollingIfNeeded(this.defaultPollingFrequency);
195
- }
196
- }
197
-
198
- /** Returns the polling cadence in ms currently set for `publicKey` (custom or default), or `null` if the account isn't registered. */
199
- public getAccountCadence(publicKey: PublicKey): number | null {
200
- const key = publicKey.toBase58();
201
- return this.accountFrequencies.get(key) || null;
202
- }
203
-
204
- /**
205
- * Starts the shared interval timer, ticking at the fastest cadence among all registered
206
- * accounts (or `defaultPollingFrequency` if none are registered). Each tick runs
207
- * `handleAccountLoading()`, which loads only the accounts due at that moment. A no-op if
208
- * already running; call `stopPolling()` first to pick up a new minimum frequency.
209
- */
210
- public startPolling(): void {
211
- if (this.customIntervalId) {
212
- return;
213
- }
214
-
215
- const minFrequency = Math.min(
216
- ...Array.from(this.accountFrequencies.values()),
217
- this.defaultPollingFrequency
218
- );
219
-
220
- this.currentPollingFrequency = minFrequency;
221
-
222
- this.customIntervalId = setInterval(() => {
223
- this.handleAccountLoading().catch((error) => {
224
- console.error('Error in account loading:', error);
225
- });
226
- }, minFrequency);
227
- }
228
-
229
- /** Stops the shared interval timer (and the base class's, via `super.stopPolling()`) and clears `lastPollingTimes` so every account is treated as due again once polling restarts. */
230
- public stopPolling(): void {
231
- super.stopPolling();
232
-
233
- if (this.customIntervalId) {
234
- clearInterval(this.customIntervalId);
235
- this.customIntervalId = null;
236
- this.currentPollingFrequency = null;
237
- }
238
- this.lastPollingTimes.clear();
239
- }
240
-
241
- /**
242
- * Clears all per-account cadence bookkeeping. Because `getAccountsToLoad()` only considers
243
- * accounts with an entry in `accountFrequencies`, this stops polling for every registered
244
- * account until a cadence is re-established via `setCustomPollingFrequency` or `addAccount`.
245
- * Registered accounts/callbacks themselves are untouched.
246
- */
247
- public clearAccountFrequencies(): void {
248
- this.accountFrequencies.clear();
249
- }
250
- }
@@ -1,200 +0,0 @@
1
- import { Connection, PublicKey } from '@solana/web3.js';
2
- import {
3
- RevenueShareAccount,
4
- RevenueShareEscrowAccount,
5
- UserAccount,
6
- UserStatsAccount,
7
- } from '../types';
8
- import {
9
- getRevenueShareAccountPublicKey,
10
- getRevenueShareEscrowAccountPublicKey,
11
- getUserAccountPublicKey,
12
- getUserStatsAccountPublicKey,
13
- } from '../addresses/pda';
14
- import { VelocityProgram } from '../config';
15
-
16
- /**
17
- * Fetches every `UserAccount` (sub-account) belonging to `authority`, from sub-account id `0`
18
- * up to `limit - 1`, in a single batched `getMultipleAccountsInfo` RPC call.
19
- * @param connection Connection used for the batched fetch.
20
- * @param program Anchor program used to derive PDAs and decode account data.
21
- * @param authority Wallet/authority pubkey whose sub-accounts to fetch.
22
- * @param limit Number of sub-account ids to check, starting at 0. Defaults to 8.
23
- * @returns One entry per sub-account id in order; `undefined` where no account exists at that id.
24
- */
25
- export async function fetchUserAccounts(
26
- connection: Connection,
27
- program: VelocityProgram,
28
- authority: PublicKey,
29
- limit = 8
30
- ): Promise<(UserAccount | undefined)[]> {
31
- const userAccountPublicKeys = new Array<PublicKey>();
32
- for (let i = 0; i < limit; i++) {
33
- userAccountPublicKeys.push(
34
- await getUserAccountPublicKey(program.programId, authority, i)
35
- );
36
- }
37
-
38
- return fetchUserAccountsUsingKeys(connection, program, userAccountPublicKeys);
39
- }
40
-
41
- /**
42
- * Fetches and decodes a specific list of `UserAccount` pubkeys in one batched
43
- * `getMultipleAccountsInfo` RPC call. Unlike `fetchUserAccounts`, the caller supplies the exact
44
- * addresses rather than deriving them by sub-account id.
45
- * @param connection Connection used for the batched fetch.
46
- * @param program Anchor program used to decode account data.
47
- * @param userAccountPublicKeys Addresses to fetch, in order.
48
- * @returns One entry per input pubkey, in the same order; `undefined` where no account exists at that address.
49
- */
50
- export async function fetchUserAccountsUsingKeys(
51
- connection: Connection,
52
- program: VelocityProgram,
53
- userAccountPublicKeys: PublicKey[]
54
- ): Promise<(UserAccount | undefined)[]> {
55
- const accountInfos = await connection.getMultipleAccountsInfo(
56
- userAccountPublicKeys,
57
- 'confirmed'
58
- );
59
-
60
- return accountInfos.map((accountInfo) => {
61
- if (!accountInfo) {
62
- return undefined;
63
- }
64
- return (program.account as any).user.coder.accounts.decodeUnchecked(
65
- 'user',
66
- accountInfo.data
67
- ) as UserAccount;
68
- });
69
- }
70
-
71
- /**
72
- * Fetches and decodes the `UserStatsAccount` for `authority`, if one exists.
73
- * @param connection Connection used for the fetch.
74
- * @param program Anchor program used to derive the PDA and decode account data.
75
- * @param authority Wallet/authority pubkey the stats account belongs to.
76
- * @returns The decoded account, or `undefined` if it hasn't been initialized on-chain.
77
- */
78
- export async function fetchUserStatsAccount(
79
- connection: Connection,
80
- program: VelocityProgram,
81
- authority: PublicKey
82
- ): Promise<UserStatsAccount | undefined> {
83
- const userStatsPublicKey = getUserStatsAccountPublicKey(
84
- program.programId,
85
- authority
86
- );
87
- const accountInfo = await connection.getAccountInfo(
88
- userStatsPublicKey,
89
- 'confirmed'
90
- );
91
-
92
- return accountInfo
93
- ? ((program.account as any).user.coder.accounts.decodeUnchecked(
94
- 'userStats',
95
- accountInfo.data
96
- ) as UserStatsAccount)
97
- : undefined;
98
- }
99
-
100
- /**
101
- * Fetches and decodes the `RevenueShareAccount` for `authority` (tracks referral/builder revenue
102
- * share balances), if one exists.
103
- * @param connection Connection used for the fetch.
104
- * @param program Anchor program used to derive the PDA and decode account data.
105
- * @param authority Wallet/authority pubkey the revenue share account belongs to.
106
- * @returns The decoded account, or `null` if it hasn't been initialized on-chain.
107
- */
108
- export async function fetchRevenueShareAccount(
109
- connection: Connection,
110
- program: VelocityProgram,
111
- authority: PublicKey
112
- ): Promise<RevenueShareAccount | null> {
113
- const revenueShareAccountPublicKey = getRevenueShareAccountPublicKey(
114
- program.programId,
115
- authority
116
- );
117
- const accountInfo = await connection.getAccountInfo(
118
- revenueShareAccountPublicKey
119
- );
120
- if (!accountInfo) return null;
121
- return (program.account as any).revenueShare.coder.accounts.decode(
122
- 'revenueShare',
123
- accountInfo.data
124
- ) as RevenueShareAccount;
125
- }
126
-
127
- /**
128
- * Fetches and decodes the `RevenueShareEscrowAccount` for `authority` (holds escrowed
129
- * revenue-share amounts pending distribution), if one exists.
130
- * @param connection Connection used for the fetch.
131
- * @param program Anchor program used to derive the PDA and decode account data.
132
- * @param authority Wallet/authority pubkey the escrow account belongs to.
133
- * @returns The decoded account, or `null` if it hasn't been initialized on-chain.
134
- */
135
- export async function fetchRevenueShareEscrowAccount(
136
- connection: Connection,
137
- program: VelocityProgram,
138
- authority: PublicKey
139
- ): Promise<RevenueShareEscrowAccount | null> {
140
- const revenueShareEscrowPubKey = getRevenueShareEscrowAccountPublicKey(
141
- program.programId,
142
- authority
143
- );
144
-
145
- const escrow = await connection.getAccountInfo(revenueShareEscrowPubKey);
146
-
147
- if (!escrow) return null;
148
-
149
- const escrowAccount = (
150
- program.account as any
151
- ).revenueShareEscrow.coder.accounts.decode(
152
- 'revenueShareEscrow',
153
- escrow.data
154
- ) as RevenueShareEscrowAccount;
155
-
156
- return escrowAccount;
157
- }
158
-
159
- /** Options accepted by `fetchAccount`/`fetchAccounts`. */
160
- export type FetchAccountOptions = {
161
- /** Commitment level for the underlying `getAccountInfo`/`getMultipleAccountsInfo` call; defaults to the connection's configured commitment if omitted. */
162
- commitment?: Parameters<Connection['getAccountInfo']>[1];
163
- };
164
-
165
- /**
166
- * Fetches an account's raw data buffer without decoding it (no Anchor coder involved), for
167
- * callers that only need the bytes.
168
- * @param connection Connection used for the fetch.
169
- * @param publicKey Account address to fetch.
170
- * @param opts Optional commitment override.
171
- * @returns The raw account data, or `null` if the account doesn't exist.
172
- */
173
- export async function fetchAccount(
174
- connection: Connection,
175
- publicKey: PublicKey,
176
- opts?: FetchAccountOptions
177
- ): Promise<Buffer | null> {
178
- const info = await connection.getAccountInfo(publicKey, opts?.commitment);
179
- return info?.data ?? null;
180
- }
181
-
182
- /**
183
- * Batch variant of `fetchAccount` — fetches raw data buffers for multiple accounts in one
184
- * `getMultipleAccountsInfo` call.
185
- * @param connection Connection used for the fetch.
186
- * @param publicKeys Account addresses to fetch, in order.
187
- * @param opts Optional commitment override.
188
- * @returns One entry per input pubkey, in the same order; `null` where the account doesn't exist.
189
- */
190
- export async function fetchAccounts(
191
- connection: Connection,
192
- publicKeys: PublicKey[],
193
- opts?: FetchAccountOptions
194
- ): Promise<(Buffer | null)[]> {
195
- const infos = await connection.getMultipleAccountsInfo(
196
- publicKeys,
197
- opts?.commitment
198
- );
199
- return infos.map((info) => info?.data ?? null);
200
- }
@@ -1,225 +0,0 @@
1
- import { ResubOpts, GrpcConfigs } from './types';
2
- import { PublicKey } from '@solana/web3.js';
3
- import { VelocityProgram } from '../config';
4
- import * as Buffer from 'buffer';
5
-
6
- import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
7
- import {
8
- Client,
9
- ClientDuplexStream,
10
- CommitmentLevel,
11
- createClient,
12
- SubscribeRequest,
13
- SubscribeUpdate,
14
- } from '../isomorphic/grpc';
15
-
16
- /**
17
- * `AccountSubscriber` for a single account, streamed via a gRPC Geyser plugin (Yellowstone or
18
- * LaserStream, per `GrpcConfigs`) instead of the standard `connection.onAccountChange` WebSocket.
19
- * Extends `WebSocketAccountSubscriber` to reuse its buffering/decode/resub-timer logic — only the
20
- * transport (`subscribe`/`unsubscribe`) is replaced. Construct via the static `create` factory,
21
- * not the constructor directly, since establishing the gRPC client is asynchronous.
22
- */
23
- export class grpcAccountSubscriber<T> extends WebSocketAccountSubscriber<T> {
24
- private client: Client;
25
- private _stream?: ClientDuplexStream;
26
- private get stream(): ClientDuplexStream {
27
- if (!this._stream) {
28
- throw new Error(
29
- 'grpcAccountSubscriber: stream accessed before subscribe()'
30
- );
31
- }
32
- return this._stream;
33
- }
34
- private commitmentLevel: CommitmentLevel;
35
- public listenerId?: number;
36
-
37
- private constructor(
38
- client: Client,
39
- commitmentLevel: CommitmentLevel,
40
- accountName: string,
41
- program: VelocityProgram,
42
- accountPublicKey: PublicKey,
43
- decodeBuffer?: (buffer: Buffer) => T,
44
- resubOpts?: ResubOpts
45
- ) {
46
- super(accountName, program, accountPublicKey, decodeBuffer, resubOpts);
47
- this.client = client;
48
- this.commitmentLevel = commitmentLevel;
49
- }
50
-
51
- /**
52
- * Creates a gRPC client (or reuses `clientProp`, letting multiple subscribers share one
53
- * connection) and constructs a `grpcAccountSubscriber`. Does not itself start streaming — call
54
- * `subscribe()` on the result.
55
- * @param grpcConfigs gRPC Geyser endpoint/token/commitment config (Yellowstone or LaserStream).
56
- * @param accountName Anchor account type name (used for logging and, absent `decodeBuffer`, for decoding via the program coder).
57
- * @param program Anchor program providing the connection and coder.
58
- * @param accountPublicKey Address of the account to track.
59
- * @param decodeBuffer Optional custom decode function; defaults to `program.coder.accounts.decode(accountName, buffer)`.
60
- * @param resubOpts Resubscription watchdog options; omit to disable the inactivity timer.
61
- * @param clientProp Optional existing gRPC client to reuse instead of creating a new connection.
62
- */
63
- public static async create<U>(
64
- grpcConfigs: GrpcConfigs,
65
- accountName: string,
66
- program: VelocityProgram,
67
- accountPublicKey: PublicKey,
68
- decodeBuffer?: (buffer: Buffer) => U,
69
- resubOpts?: ResubOpts,
70
- clientProp?: Client
71
- ): Promise<grpcAccountSubscriber<U>> {
72
- const client = clientProp
73
- ? clientProp
74
- : await createClient(
75
- grpcConfigs.endpoint,
76
- grpcConfigs.token,
77
- grpcConfigs.channelOptions ?? {}
78
- );
79
- const commitmentLevel =
80
- // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
81
- grpcConfigs.commitmentLevel ?? CommitmentLevel.CONFIRMED;
82
-
83
- return new grpcAccountSubscriber(
84
- client,
85
- commitmentLevel,
86
- accountName,
87
- program,
88
- accountPublicKey,
89
- decodeBuffer,
90
- resubOpts
91
- );
92
- }
93
-
94
- /**
95
- * Seeds `dataAndSlot` with an initial `fetch()` (if not already set), opens a gRPC subscribe
96
- * stream filtered to this single account, and writes the subscribe request. Idempotent: a
97
- * no-op if already subscribed or mid-unsubscribe.
98
- * @param onChange Invoked with the newly decoded account data on each accepted update.
99
- */
100
- override async subscribe(onChange: (data: T) => void): Promise<void> {
101
- if (this.listenerId != null || this.isUnsubscribing) {
102
- return;
103
- }
104
-
105
- this.onChange = onChange;
106
- if (!this.dataAndSlot) {
107
- await this.fetch();
108
- }
109
-
110
- // Subscribe with grpc
111
- this._stream =
112
- (await this.client.subscribe()) as unknown as typeof this.stream;
113
- const request: SubscribeRequest = {
114
- slots: {},
115
- accounts: {
116
- account: {
117
- account: [this.accountPublicKey.toString()],
118
- owner: [],
119
- filters: [],
120
- },
121
- },
122
- transactions: {},
123
- blocks: {},
124
- blocksMeta: {},
125
- accountsDataSlice: [],
126
- commitment: this.commitmentLevel,
127
- entry: {},
128
- transactionsStatus: {},
129
- };
130
- this.stream.on('data', (chunk: SubscribeUpdate) => {
131
- if (!chunk.account || !chunk.account.account) {
132
- return;
133
- }
134
- const slot = Number(chunk.account.slot);
135
- const accountInfo = {
136
- owner: new PublicKey(chunk.account.account.owner),
137
- lamports: Number(chunk.account.account.lamports),
138
- data: Buffer.Buffer.from(chunk.account.account.data),
139
- executable: chunk.account.account.executable,
140
- rentEpoch: Number(chunk.account.account.rentEpoch),
141
- };
142
-
143
- if (this.resubOpts?.resubTimeoutMs) {
144
- this.receivingData = true;
145
- clearTimeout(this.timeoutId);
146
- this.handleRpcResponse(
147
- {
148
- slot,
149
- },
150
- accountInfo
151
- );
152
- this.setTimeout();
153
- } else {
154
- this.handleRpcResponse(
155
- {
156
- slot,
157
- },
158
- accountInfo
159
- );
160
- }
161
- });
162
-
163
- return new Promise<void>((resolve, reject) => {
164
- this.stream.write(request, (err) => {
165
- if (err === null || err === undefined) {
166
- this.listenerId = 1;
167
- if (this.resubOpts?.resubTimeoutMs) {
168
- this.receivingData = true;
169
- this.setTimeout();
170
- }
171
- resolve();
172
- } else {
173
- reject(err);
174
- }
175
- });
176
- }).catch((reason) => {
177
- console.error(reason);
178
- throw reason;
179
- });
180
- }
181
-
182
- /**
183
- * Writes an empty subscribe request to clear the stream's account filter and cancels any
184
- * pending resub timeout.
185
- * @param onResub Internal flag set to `true` when called as part of an automatic resubscribe cycle, which preserves `resubOpts.resubTimeoutMs` instead of clearing it. Callers should omit this.
186
- */
187
- override async unsubscribe(onResub = false): Promise<void> {
188
- if (!onResub && this.resubOpts) {
189
- this.resubOpts.resubTimeoutMs = undefined;
190
- }
191
- this.isUnsubscribing = true;
192
- clearTimeout(this.timeoutId);
193
- this.timeoutId = undefined;
194
-
195
- if (this.listenerId != null) {
196
- const promise = new Promise<void>((resolve, reject) => {
197
- const request: SubscribeRequest = {
198
- slots: {},
199
- accounts: {},
200
- transactions: {},
201
- blocks: {},
202
- blocksMeta: {},
203
- accountsDataSlice: [],
204
- entry: {},
205
- transactionsStatus: {},
206
- };
207
- this.stream.write(request, (err) => {
208
- if (err === null || err === undefined) {
209
- this.listenerId = undefined;
210
- this.isUnsubscribing = false;
211
- resolve();
212
- } else {
213
- reject(err);
214
- }
215
- });
216
- }).catch((reason) => {
217
- console.error(reason);
218
- throw reason;
219
- });
220
- return promise;
221
- } else {
222
- this.isUnsubscribing = false;
223
- }
224
- }
225
- }