@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.
- package/README.md +3 -3
- package/lib/browser/adminClient.d.ts +52 -0
- package/lib/browser/adminClient.js +97 -0
- package/lib/browser/config.js +6 -7
- package/lib/browser/constants/numericConstants.d.ts +1 -1
- package/lib/browser/constants/numericConstants.js +1 -1
- package/lib/browser/decode/user.js +5 -1
- package/lib/browser/idl/velocity.d.ts +191 -15
- package/lib/browser/idl/velocity.json +192 -16
- package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
- package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
- package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
- package/lib/browser/types.d.ts +6 -0
- package/lib/browser/user.d.ts +20 -3
- package/lib/browser/user.js +52 -4
- package/lib/browser/velocityClient.d.ts +46 -10
- package/lib/browser/velocityClient.js +107 -35
- package/lib/node/adminClient.d.ts +52 -0
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +97 -0
- package/lib/node/config.d.ts.map +1 -1
- package/lib/node/config.js +6 -7
- package/lib/node/constants/numericConstants.d.ts +1 -1
- package/lib/node/constants/numericConstants.d.ts.map +1 -1
- package/lib/node/constants/numericConstants.js +1 -1
- package/lib/node/decode/user.d.ts.map +1 -1
- package/lib/node/decode/user.js +5 -1
- package/lib/node/idl/velocity.d.ts +191 -15
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +192 -16
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
- package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
- package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
- package/lib/node/pyth/pythLazerSubscriber.js +37 -27
- package/lib/node/types.d.ts +6 -0
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/user.d.ts +20 -3
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +52 -4
- package/lib/node/velocityClient.d.ts +46 -10
- package/lib/node/velocityClient.d.ts.map +1 -1
- package/lib/node/velocityClient.js +107 -35
- package/package.json +7 -3
- package/.prettierignore +0 -1
- package/CHANGELOG.md +0 -132
- package/build-browser.js +0 -58
- package/bunfig.toml +0 -3
- package/esbuild-shims.js +0 -12
- package/scripts/deposit-isolated-positions.ts +0 -110
- package/scripts/find-flagged-users.ts +0 -213
- package/scripts/grpc-client-test-comparison.ts +0 -372
- package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
- package/scripts/postbuild.js +0 -95
- package/scripts/single-grpc-client-test.ts +0 -284
- package/scripts/withdraw-isolated-positions.ts +0 -174
- package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
- package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
- package/src/accounts/basicUserAccountSubscriber.ts +0 -79
- package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
- package/src/accounts/bulkAccountLoader.ts +0 -358
- package/src/accounts/bulkUserStatsSubscription.ts +0 -40
- package/src/accounts/bulkUserSubscription.ts +0 -39
- package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
- package/src/accounts/fetch.ts +0 -200
- package/src/accounts/grpcAccountSubscriber.ts +0 -225
- package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
- package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
- package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
- package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
- package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
- package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
- package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
- package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
- package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
- package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
- package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
- package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
- package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
- package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
- package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
- package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
- package/src/accounts/testBulkAccountLoader.ts +0 -59
- package/src/accounts/types.ts +0 -428
- package/src/accounts/utils.ts +0 -90
- package/src/accounts/webSocketAccountSubscriber.ts +0 -304
- package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
- package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
- package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
- package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
- package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
- package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
- package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
- package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
- package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
- package/src/addresses/marketAddresses.ts +0 -28
- package/src/addresses/pda.ts +0 -620
- package/src/adminClient.ts +0 -8136
- package/src/assert/assert.ts +0 -5
- package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
- package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
- package/src/auctionSubscriber/index.ts +0 -9
- package/src/auctionSubscriber/types.ts +0 -30
- package/src/bankrun/bankrunConnection.ts +0 -630
- package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
- package/src/blockhashSubscriber/index.ts +0 -6
- package/src/blockhashSubscriber/types.ts +0 -13
- package/src/clock/clockSubscriber.ts +0 -146
- package/src/config.ts +0 -312
- package/src/constants/index.ts +0 -9
- package/src/constants/numericConstants.ts +0 -194
- package/src/constants/perpMarkets.ts +0 -127
- package/src/constants/spotMarkets.ts +0 -104
- package/src/constants/txConstants.ts +0 -2
- package/src/constituentMap/constituentMap.ts +0 -305
- package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
- package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
- package/src/core/VelocityCore.ts +0 -606
- package/src/core/index.ts +0 -12
- package/src/core/instructions/deposit.ts +0 -64
- package/src/core/instructions/fill.ts +0 -51
- package/src/core/instructions/funding.ts +0 -33
- package/src/core/instructions/liquidation.ts +0 -55
- package/src/core/instructions/orders.ts +0 -84
- package/src/core/instructions/perpOrders.ts +0 -312
- package/src/core/instructions/settlement.ts +0 -40
- package/src/core/instructions/trigger.ts +0 -41
- package/src/core/instructions/withdraw.ts +0 -65
- package/src/core/remainingAccounts.ts +0 -320
- package/src/core/signedMsg.ts +0 -109
- package/src/decode/customCoder.ts +0 -148
- package/src/decode/user.ts +0 -401
- package/src/dlob/DLOB.ts +0 -2793
- package/src/dlob/DLOBNode.ts +0 -305
- package/src/dlob/DLOBSubscriber.ts +0 -269
- package/src/dlob/NodeList.ts +0 -244
- package/src/dlob/orderBookLevels.ts +0 -695
- package/src/dlob/types.ts +0 -37
- package/src/events/eventList.ts +0 -114
- package/src/events/eventSubscriber.ts +0 -521
- package/src/events/eventsServerLogProvider.ts +0 -189
- package/src/events/fetchLogs.ts +0 -219
- package/src/events/parse.ts +0 -271
- package/src/events/pollingLogProvider.ts +0 -113
- package/src/events/sort.ts +0 -51
- package/src/events/txEventCache.ts +0 -92
- package/src/events/types.ts +0 -337
- package/src/events/webSocketLogProvider.ts +0 -152
- package/src/factory/bigNum.ts +0 -709
- package/src/factory/oracleClient.ts +0 -73
- package/src/idl/pyth.json +0 -142
- package/src/idl/pyth.ts +0 -97
- package/src/idl/pyth_solana_receiver.json +0 -628
- package/src/idl/token_faucet.json +0 -229
- package/src/idl/token_faucet.ts +0 -197
- package/src/idl/velocity.json +0 -23974
- package/src/idl/velocity.ts +0 -23980
- package/src/index.ts +0 -150
- package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
- package/src/isomorphic/README.md +0 -19
- package/src/isomorphic/anchor.browser.ts +0 -44
- package/src/isomorphic/anchor.node.ts +0 -1
- package/src/isomorphic/anchor.ts +0 -1
- package/src/isomorphic/anchor29.browser.ts +0 -24
- package/src/isomorphic/anchor29.node.ts +0 -1
- package/src/isomorphic/anchor29.ts +0 -1
- package/src/isomorphic/grpc.browser.ts +0 -4
- package/src/isomorphic/grpc.node.ts +0 -130
- package/src/isomorphic/grpc.ts +0 -1
- package/src/jupiter/jupiterClient.ts +0 -502
- package/src/keypair.ts +0 -32
- package/src/margin/README.md +0 -138
- package/src/marginCalculation.ts +0 -407
- package/src/marinade/idl/idl.json +0 -1962
- package/src/marinade/index.ts +0 -73
- package/src/marinade/types.ts +0 -3925
- package/src/math/amm.ts +0 -1758
- package/src/math/auction.ts +0 -480
- package/src/math/bankruptcy.ts +0 -138
- package/src/math/builder.ts +0 -130
- package/src/math/conversion.ts +0 -45
- package/src/math/exchangeStatus.ts +0 -261
- package/src/math/funding.ts +0 -498
- package/src/math/insurance.ts +0 -171
- package/src/math/liquidation.ts +0 -433
- package/src/math/margin.ts +0 -327
- package/src/math/market.ts +0 -487
- package/src/math/oracles.ts +0 -477
- package/src/math/orders.ts +0 -500
- package/src/math/position.ts +0 -381
- package/src/math/repeg.ts +0 -223
- package/src/math/spotBalance.ts +0 -996
- package/src/math/spotMarket.ts +0 -115
- package/src/math/spotPosition.ts +0 -263
- package/src/math/state.ts +0 -71
- package/src/math/superStake.ts +0 -602
- package/src/math/tiers.ts +0 -73
- package/src/math/trade.ts +0 -879
- package/src/math/utils.ts +0 -183
- package/src/memcmp.ts +0 -279
- package/src/oracles/oracleClientCache.ts +0 -41
- package/src/oracles/oracleId.ts +0 -99
- package/src/oracles/prelaunchOracleClient.ts +0 -63
- package/src/oracles/pythClient.ts +0 -125
- package/src/oracles/pythLazerClient.ts +0 -141
- package/src/oracles/quoteAssetOracleClient.ts +0 -43
- package/src/oracles/strictOraclePrice.ts +0 -40
- package/src/oracles/types.ts +0 -82
- package/src/oracles/utils.ts +0 -45
- package/src/orderParams.ts +0 -117
- package/src/orderSubscriber/OrderSubscriber.ts +0 -378
- package/src/orderSubscriber/PollingSubscription.ts +0 -50
- package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
- package/src/orderSubscriber/grpcSubscription.ts +0 -155
- package/src/orderSubscriber/index.ts +0 -7
- package/src/orderSubscriber/types.ts +0 -64
- package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
- package/src/priorityFee/averageStrategy.ts +0 -13
- package/src/priorityFee/ewmaStrategy.ts +0 -51
- package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
- package/src/priorityFee/index.ts +0 -16
- package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
- package/src/priorityFee/maxStrategy.ts +0 -8
- package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
- package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
- package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
- package/src/priorityFee/types.ts +0 -82
- package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
- package/src/pyth/constants.ts +0 -9
- package/src/pyth/index.ts +0 -15
- package/src/pyth/pythLazerSubscriber.ts +0 -365
- package/src/pyth/types.ts +0 -4451
- package/src/pyth/utils.ts +0 -13
- package/src/slot/SlotSubscriber.ts +0 -126
- package/src/slot/SlothashSubscriber.ts +0 -163
- package/src/swap/UnifiedSwapClient.ts +0 -315
- package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
- package/src/swift/index.ts +0 -10
- package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
- package/src/swift/swiftOrderSubscriber.ts +0 -351
- package/src/testClient.ts +0 -42
- package/src/titan/titanClient.ts +0 -438
- package/src/token/index.ts +0 -13
- package/src/tokenFaucet.ts +0 -296
- package/src/tx/baseTxSender.ts +0 -651
- package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
- package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
- package/src/tx/blockhashFetcher/types.ts +0 -9
- package/src/tx/fastSingleTxSender.ts +0 -200
- package/src/tx/forwardOnlyTxSender.ts +0 -193
- package/src/tx/priorityFeeCalculator.ts +0 -117
- package/src/tx/reportTransactionError.ts +0 -176
- package/src/tx/retryTxSender.ts +0 -177
- package/src/tx/txHandler.ts +0 -1009
- package/src/tx/txParamProcessor.ts +0 -225
- package/src/tx/types.ts +0 -117
- package/src/tx/utils.ts +0 -133
- package/src/tx/whileValidTxSender.ts +0 -377
- package/src/types.ts +0 -2575
- package/src/user.ts +0 -5316
- package/src/userConfig.ts +0 -38
- package/src/userMap/PollingSubscription.ts +0 -61
- package/src/userMap/WebsocketSubscription.ts +0 -93
- package/src/userMap/grpcSubscription.ts +0 -93
- package/src/userMap/referrerMap.ts +0 -360
- package/src/userMap/revenueShareEscrowMap.ts +0 -342
- package/src/userMap/userMap.ts +0 -784
- package/src/userMap/userMapConfig.ts +0 -82
- package/src/userMap/userStatsMap.ts +0 -393
- package/src/userName.ts +0 -37
- package/src/userStats.ts +0 -159
- package/src/userStatsConfig.ts +0 -35
- package/src/util/TransactionConfirmationManager.ts +0 -333
- package/src/util/chainClock.ts +0 -65
- package/src/util/computeUnits.ts +0 -101
- package/src/util/digest.ts +0 -33
- package/src/util/ed25519Utils.ts +0 -95
- package/src/util/promiseTimeout.ts +0 -23
- package/src/velocityClient.ts +0 -14802
- package/src/velocityClientConfig.ts +0 -119
- package/src/wallet.ts +0 -91
- package/tests/VelocityCore/builder_escrow.test.ts +0 -121
- package/tests/VelocityCore/decode.test.ts +0 -16
- package/tests/VelocityCore/fill_trigger.test.ts +0 -73
- package/tests/VelocityCore/instructions.test.ts +0 -46
- package/tests/VelocityCore/pdas.test.ts +0 -30
- package/tests/VelocityCore/perp_orders.test.ts +0 -205
- package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
- package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
- package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
- package/tests/amm/test.ts +0 -2402
- package/tests/auctions/test.ts +0 -81
- package/tests/bn/test.ts +0 -355
- package/tests/builder/builderFee.test.ts +0 -42
- package/tests/ci/verifyConstants.ts +0 -393
- package/tests/decode/test.ts +0 -262
- package/tests/decode/userAccountBufferStrings.ts +0 -102
- package/tests/dlob/helpers.ts +0 -748
- package/tests/dlob/test.ts +0 -6969
- package/tests/dlob/tickSizeStandardization.ts +0 -545
- package/tests/events/parseLogsForCuUsage.ts +0 -139
- package/tests/exchangeStatus/test.ts +0 -45
- package/tests/insurance/test.ts +0 -40
- package/tests/liquidation/test.ts +0 -125
- package/tests/oracles/mmOracleGate.test.ts +0 -379
- package/tests/oracles/pythPegSnap.test.ts +0 -76
- package/tests/sdkParity/enumParity.test.ts +0 -84
- package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
- package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
- package/tests/spot/test.ts +0 -281
- package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
- package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
- package/tests/tx/priorityFeeCalculator.ts +0 -77
- package/tests/tx/priorityFeeStrategy.ts +0 -95
- package/tests/user/bankruptcy.ts +0 -165
- package/tests/user/feeAndWithdrawLimits.ts +0 -284
- package/tests/user/getMarginCalculation.ts +0 -586
- package/tests/user/helpers.ts +0 -184
- package/tests/user/liquidations.ts +0 -129
- package/tests/user/marginCalculations.test.ts +0 -321
- package/tests/user/test.ts +0 -833
- package/tsconfig.browser.json +0 -18
- package/tsconfig.json +0 -36
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { DataAndSlot, UserAccountEvents, UserAccountSubscriber } from './types';
|
|
2
|
-
import { PublicKey } from '@solana/web3.js';
|
|
3
|
-
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
4
|
-
import { EventEmitter } from 'events';
|
|
5
|
-
import { UserAccount } from '../types';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Basic implementation of UserAccountSubscriber. It will only take in UserAccount
|
|
9
|
-
* data during initialization and will not fetch or subscribe to updates.
|
|
10
|
-
*/
|
|
11
|
-
export class BasicUserAccountSubscriber implements UserAccountSubscriber {
|
|
12
|
-
isSubscribed: boolean;
|
|
13
|
-
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
14
|
-
userAccountPublicKey: PublicKey;
|
|
15
|
-
|
|
16
|
-
callbackId?: string;
|
|
17
|
-
errorCallbackId?: string;
|
|
18
|
-
|
|
19
|
-
user?: DataAndSlot<UserAccount>;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @param userAccountPublicKey Address of the `UserAccount` this subscriber represents (not fetched — used only for identity).
|
|
23
|
-
* @param data Optional decoded account data to seed with; if omitted, `getUserAccountAndSlot()` returns undefined until `updateData` is called.
|
|
24
|
-
* @param slot Slot `data` was observed at; defaults to 0 (the seeded sentinel) if omitted.
|
|
25
|
-
*/
|
|
26
|
-
public constructor(
|
|
27
|
-
userAccountPublicKey: PublicKey,
|
|
28
|
-
data?: UserAccount,
|
|
29
|
-
slot?: number
|
|
30
|
-
) {
|
|
31
|
-
this.isSubscribed = true;
|
|
32
|
-
this.eventEmitter = new EventEmitter();
|
|
33
|
-
this.userAccountPublicKey = userAccountPublicKey;
|
|
34
|
-
// `slot ?? 0` keeps {data, slot} atomic: a seeded account always carries a
|
|
35
|
-
// slot (0 = oldest-possible sentinel, overwritten by the first real fetch).
|
|
36
|
-
this.user = data ? { data, slot: slot ?? 0 } : undefined;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** No-op; this subscriber never performs network I/O. Always resolves `true` since `isSubscribed` is already `true` from construction. */
|
|
40
|
-
async subscribe(_userAccount?: UserAccount): Promise<boolean> {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async addToAccountLoader(): Promise<void> {}
|
|
45
|
-
|
|
46
|
-
/** No-op; this subscriber never fetches. Data only changes via `updateData`. */
|
|
47
|
-
async fetch(): Promise<void> {}
|
|
48
|
-
|
|
49
|
-
/** Type predicate: true once `user` has been seeded or set via `updateData`, narrowing `this.user` to non-undefined. */
|
|
50
|
-
doesAccountExist(): this is { user: DataAndSlot<UserAccount> } {
|
|
51
|
-
return this.user !== undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** No-op; there is no live subscription to tear down. */
|
|
55
|
-
async unsubscribe(): Promise<void> {}
|
|
56
|
-
|
|
57
|
-
/** No-op; this subscriber is always considered subscribed and never throws `NotSubscribedError`. */
|
|
58
|
-
assertIsSubscribed(): void {}
|
|
59
|
-
|
|
60
|
-
/** Returns the currently cached data/slot, or undefined if never seeded/updated. Never throws (unlike other implementations, this subscriber has no "not subscribed" state). */
|
|
61
|
-
public getUserAccountAndSlot(): DataAndSlot<UserAccount> | undefined {
|
|
62
|
-
return this.user;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Applies an externally-obtained account update if `slot` is not older than the currently
|
|
67
|
-
* cached slot, emitting `userAccountUpdate`/`update` on acceptance. This is the only way this
|
|
68
|
-
* subscriber's data changes after construction.
|
|
69
|
-
* @param userAccount Decoded account data to apply.
|
|
70
|
-
* @param slot Slot the data was observed at.
|
|
71
|
-
*/
|
|
72
|
-
public updateData(userAccount: UserAccount, slot: number): void {
|
|
73
|
-
if (!this.user || slot >= this.user.slot) {
|
|
74
|
-
this.user = { data: userAccount, slot };
|
|
75
|
-
this.eventEmitter.emit('userAccountUpdate', userAccount);
|
|
76
|
-
this.eventEmitter.emit('update');
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DataAndSlot,
|
|
3
|
-
UserStatsAccountEvents,
|
|
4
|
-
UserStatsAccountSubscriber,
|
|
5
|
-
} from './types';
|
|
6
|
-
import { PublicKey } from '@solana/web3.js';
|
|
7
|
-
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
8
|
-
import { EventEmitter } from 'events';
|
|
9
|
-
import { UserStatsAccount } from '../types';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Basic implementation of UserStatsAccountSubscriber. It will only take in UserStatsAccount
|
|
13
|
-
* data during initialization and will not fetch or subscribe to updates.
|
|
14
|
-
*/
|
|
15
|
-
export class BasicUserStatsAccountSubscriber
|
|
16
|
-
implements UserStatsAccountSubscriber
|
|
17
|
-
{
|
|
18
|
-
isSubscribed: boolean;
|
|
19
|
-
eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
|
|
20
|
-
userStatsAccountPublicKey: PublicKey;
|
|
21
|
-
|
|
22
|
-
callbackId?: string;
|
|
23
|
-
errorCallbackId?: string;
|
|
24
|
-
|
|
25
|
-
userStats?: DataAndSlot<UserStatsAccount>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @param userStatsAccountPublicKey Address of the `UserStatsAccount` this subscriber represents (not fetched — used only for identity).
|
|
29
|
-
* @param data Optional decoded account data to seed with; if omitted, `getUserStatsAccountAndSlot()` returns undefined until `updateData` is called.
|
|
30
|
-
* @param slot Slot `data` was observed at; defaults to 0 (the seeded sentinel) if omitted.
|
|
31
|
-
*/
|
|
32
|
-
public constructor(
|
|
33
|
-
userStatsAccountPublicKey: PublicKey,
|
|
34
|
-
data?: UserStatsAccount,
|
|
35
|
-
slot?: number
|
|
36
|
-
) {
|
|
37
|
-
this.isSubscribed = true;
|
|
38
|
-
this.eventEmitter = new EventEmitter();
|
|
39
|
-
this.userStatsAccountPublicKey = userStatsAccountPublicKey;
|
|
40
|
-
// `slot ?? 0` keeps {data, slot} atomic: a seeded account always carries a
|
|
41
|
-
// slot (0 = oldest-possible sentinel, overwritten by the first real fetch).
|
|
42
|
-
this.userStats = data ? { data, slot: slot ?? 0 } : undefined;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** No-op; this subscriber never performs network I/O. Always resolves `true` since `isSubscribed` is already `true` from construction. */
|
|
46
|
-
async subscribe(_userStatsAccount?: UserStatsAccount): Promise<boolean> {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async addToAccountLoader(): Promise<void> {}
|
|
51
|
-
|
|
52
|
-
/** No-op; this subscriber never fetches. Data only changes via `updateData`. */
|
|
53
|
-
async fetch(): Promise<void> {}
|
|
54
|
-
|
|
55
|
-
/** Type predicate: true once `userStats` has been seeded or set via `updateData`, narrowing `this.userStats` to non-undefined. */
|
|
56
|
-
doesAccountExist(): this is { userStats: DataAndSlot<UserStatsAccount> } {
|
|
57
|
-
return this.userStats !== undefined;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** No-op; there is no live subscription to tear down. */
|
|
61
|
-
async unsubscribe(): Promise<void> {}
|
|
62
|
-
|
|
63
|
-
/** No-op; this subscriber is always considered subscribed and never throws `NotSubscribedError`. */
|
|
64
|
-
assertIsSubscribed(): void {}
|
|
65
|
-
|
|
66
|
-
/** Returns the currently cached data/slot, or undefined if never seeded/updated. Never throws (unlike other implementations, this subscriber has no "not subscribed" state). */
|
|
67
|
-
public getUserStatsAccountAndSlot():
|
|
68
|
-
| DataAndSlot<UserStatsAccount>
|
|
69
|
-
| undefined {
|
|
70
|
-
return this.userStats;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Applies an externally-obtained account update if `slot` is not older than the currently
|
|
75
|
-
* cached slot, emitting `userStatsAccountUpdate`/`update` on acceptance. This is the only way
|
|
76
|
-
* this subscriber's data changes after construction.
|
|
77
|
-
* @param userStatsAccount Decoded account data to apply.
|
|
78
|
-
* @param slot Slot the data was observed at.
|
|
79
|
-
*/
|
|
80
|
-
public updateData(userStatsAccount: UserStatsAccount, slot: number): void {
|
|
81
|
-
if (!this.userStats || slot >= this.userStats.slot) {
|
|
82
|
-
this.userStats = { data: userStatsAccount, slot };
|
|
83
|
-
this.eventEmitter.emit('userStatsAccountUpdate', userStatsAccount);
|
|
84
|
-
this.eventEmitter.emit('update');
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
2
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
-
import { BufferAndSlot } from './types';
|
|
4
|
-
import { promiseTimeout } from '../util/promiseTimeout';
|
|
5
|
-
import { Connection } from '../bankrun/bankrunConnection';
|
|
6
|
-
import { GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE } from '../constants/numericConstants';
|
|
7
|
-
|
|
8
|
-
/** An account registered with a `BulkAccountLoader`, along with every callback subscribed to its updates (keyed by callback id). */
|
|
9
|
-
export type AccountToLoad = {
|
|
10
|
-
publicKey: PublicKey;
|
|
11
|
-
callbacks: Map<string, (buffer: Buffer, slot: number) => void>;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const oneMinute = 60 * 1000;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Batches many accounts behind a single periodic `getMultipleAccounts` RPC poll instead of one
|
|
18
|
-
* WebSocket subscription per account. Multiple independent callbacks (e.g. from different
|
|
19
|
-
* `PollingUserAccountSubscriber`/`PollingVelocityClientAccountSubscriber` instances) can register
|
|
20
|
-
* against the same `publicKey`; polling starts automatically on the first `addAccount` and stops
|
|
21
|
-
* when the last callback for the last account is removed. A buffer is only re-delivered to
|
|
22
|
-
* callbacks when its slot is not older than the last-seen slot for that account and its bytes
|
|
23
|
-
* actually changed, so a callback never observes a stale or duplicate update. `load()` calls are
|
|
24
|
-
* coalesced: concurrent callers share one in-flight RPC batch rather than issuing redundant
|
|
25
|
-
* requests.
|
|
26
|
-
*/
|
|
27
|
-
export class BulkAccountLoader {
|
|
28
|
-
connection: Connection;
|
|
29
|
-
commitment: Commitment;
|
|
30
|
-
pollingFrequency: number;
|
|
31
|
-
accountsToLoad = new Map<string, AccountToLoad>();
|
|
32
|
-
bufferAndSlotMap = new Map<string, BufferAndSlot>();
|
|
33
|
-
errorCallbacks = new Map<string, (e: Error) => void>();
|
|
34
|
-
intervalId?: ReturnType<typeof setTimeout>;
|
|
35
|
-
// to handle clients spamming load
|
|
36
|
-
loadPromise?: Promise<void>;
|
|
37
|
-
private loadPromiseResolver: () => void = () => {};
|
|
38
|
-
lastTimeLoadingPromiseCleared = Date.now();
|
|
39
|
-
mostRecentSlot = 0;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @param connection Connection (or bankrun-compatible shim) used for the batched `getMultipleAccounts` polls.
|
|
43
|
-
* @param commitment Commitment level applied to every poll.
|
|
44
|
-
* @param pollingFrequency Poll interval in ms; `0` disables automatic polling (`startPolling` becomes a no-op), useful when the loader is driven manually via `load()`.
|
|
45
|
-
*/
|
|
46
|
-
public constructor(
|
|
47
|
-
connection: Connection,
|
|
48
|
-
commitment: Commitment,
|
|
49
|
-
pollingFrequency: number
|
|
50
|
-
) {
|
|
51
|
-
this.connection = connection;
|
|
52
|
-
this.commitment = commitment;
|
|
53
|
-
this.pollingFrequency = pollingFrequency;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Registers a callback to be invoked whenever `publicKey`'s account data changes on a poll.
|
|
58
|
-
* Multiple callbacks may be registered for the same account. Starts polling automatically if
|
|
59
|
-
* this is the loader's first account. Awaits any in-flight `load()` before returning so a
|
|
60
|
-
* caller can immediately follow with its own `load()` without racing the poll interval.
|
|
61
|
-
* @param publicKey Account to track.
|
|
62
|
-
* @param callback Invoked with the raw account buffer and the slot it was fetched at whenever the buffer changes at a non-decreasing slot.
|
|
63
|
-
* @returns A callback id to pass to `removeAccount` later.
|
|
64
|
-
*/
|
|
65
|
-
public async addAccount(
|
|
66
|
-
publicKey: PublicKey,
|
|
67
|
-
callback: (buffer: Buffer, slot: number) => void
|
|
68
|
-
): Promise<string> {
|
|
69
|
-
if (!publicKey) {
|
|
70
|
-
console.trace(`Caught adding blank publickey to bulkAccountLoader`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const existingSize = this.accountsToLoad.size;
|
|
74
|
-
|
|
75
|
-
const callbackId = uuidv4();
|
|
76
|
-
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
77
|
-
if (existingAccountToLoad) {
|
|
78
|
-
existingAccountToLoad.callbacks.set(callbackId, callback);
|
|
79
|
-
} else {
|
|
80
|
-
const callbacks = new Map<
|
|
81
|
-
string,
|
|
82
|
-
(buffer: Buffer, slot: number) => void
|
|
83
|
-
>();
|
|
84
|
-
callbacks.set(callbackId, callback);
|
|
85
|
-
const newAccountToLoad = {
|
|
86
|
-
publicKey,
|
|
87
|
-
callbacks,
|
|
88
|
-
};
|
|
89
|
-
this.accountsToLoad.set(publicKey.toString(), newAccountToLoad);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (existingSize === 0) {
|
|
93
|
-
this.startPolling();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// resolve the current loadPromise in case client wants to call load
|
|
97
|
-
await this.loadPromise;
|
|
98
|
-
|
|
99
|
-
return callbackId;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Unregisters a callback previously returned by `addAccount`. Once an account has no
|
|
104
|
-
* remaining callbacks, its cached buffer/slot is dropped and it stops being polled; if no
|
|
105
|
-
* accounts remain at all, polling stops entirely. A no-op if `callbackId` is undefined.
|
|
106
|
-
* @param publicKey Account the callback was registered against.
|
|
107
|
-
* @param callbackId Id returned by `addAccount`.
|
|
108
|
-
*/
|
|
109
|
-
public removeAccount(
|
|
110
|
-
publicKey: PublicKey,
|
|
111
|
-
callbackId: string | undefined
|
|
112
|
-
): void {
|
|
113
|
-
if (callbackId === undefined) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
117
|
-
if (existingAccountToLoad) {
|
|
118
|
-
existingAccountToLoad.callbacks.delete(callbackId);
|
|
119
|
-
if (existingAccountToLoad.callbacks.size === 0) {
|
|
120
|
-
this.bufferAndSlotMap.delete(publicKey.toString());
|
|
121
|
-
this.accountsToLoad.delete(existingAccountToLoad.publicKey.toString());
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (this.accountsToLoad.size === 0) {
|
|
126
|
-
this.stopPolling();
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Registers a callback invoked whenever a `load()` batch throws (e.g. RPC failure or timeout).
|
|
132
|
-
* The loader continues polling afterward; errors do not stop the interval.
|
|
133
|
-
* @returns A callback id to pass to `removeErrorCallbacks` later.
|
|
134
|
-
*/
|
|
135
|
-
public addErrorCallbacks(callback: (error: Error) => void): string {
|
|
136
|
-
const callbackId = uuidv4();
|
|
137
|
-
this.errorCallbacks.set(callbackId, callback);
|
|
138
|
-
return callbackId;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/** Unregisters an error callback previously returned by `addErrorCallbacks`. A no-op if `callbackId` is undefined. */
|
|
142
|
-
public removeErrorCallbacks(callbackId: string | undefined): void {
|
|
143
|
-
if (callbackId === undefined) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
this.errorCallbacks.delete(callbackId);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
chunks<T>(array: readonly T[], size: number): T[][] {
|
|
150
|
-
return new Array(Math.ceil(array.length / size))
|
|
151
|
-
.fill(null)
|
|
152
|
-
.map((_, index) => index * size)
|
|
153
|
-
.map((begin) => array.slice(begin, begin + size));
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Fetches every registered account in one or more chunked, concurrent `getMultipleAccounts`
|
|
158
|
-
* batches (via `loadChunk`) and dispatches changed accounts to their callbacks. Concurrent
|
|
159
|
-
* calls while a load is already in flight share that same in-flight promise rather than
|
|
160
|
-
* issuing a duplicate RPC batch, unless the previous load has been running for over a minute
|
|
161
|
-
* (treated as stuck and restarted). On failure, invokes every registered error callback
|
|
162
|
-
* instead of throwing.
|
|
163
|
-
*/
|
|
164
|
-
public async load(): Promise<void> {
|
|
165
|
-
if (this.loadPromise) {
|
|
166
|
-
const now = Date.now();
|
|
167
|
-
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
168
|
-
this.loadPromise = undefined;
|
|
169
|
-
} else {
|
|
170
|
-
return this.loadPromise;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
this.loadPromise = new Promise((resolver) => {
|
|
175
|
-
this.loadPromiseResolver = resolver;
|
|
176
|
-
});
|
|
177
|
-
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
178
|
-
|
|
179
|
-
try {
|
|
180
|
-
const chunks = this.chunks(
|
|
181
|
-
this.chunks(
|
|
182
|
-
Array.from(this.accountsToLoad.values()),
|
|
183
|
-
GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
|
|
184
|
-
),
|
|
185
|
-
10
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
await Promise.all(
|
|
189
|
-
chunks.map((chunk) => {
|
|
190
|
-
return this.loadChunk(chunk);
|
|
191
|
-
})
|
|
192
|
-
);
|
|
193
|
-
} catch (e) {
|
|
194
|
-
console.error(`Error in bulkAccountLoader.load()`);
|
|
195
|
-
console.error(e);
|
|
196
|
-
const error = e instanceof Error ? e : new Error(String(e));
|
|
197
|
-
for (const [_, callback] of this.errorCallbacks) {
|
|
198
|
-
callback(error);
|
|
199
|
-
}
|
|
200
|
-
} finally {
|
|
201
|
-
this.loadPromiseResolver();
|
|
202
|
-
this.loadPromise = undefined;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async loadChunk(accountsToLoadChunks: AccountToLoad[][]): Promise<void> {
|
|
207
|
-
if (accountsToLoadChunks.length === 0) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const requests = new Array<{ methodName: string; args: any }>();
|
|
212
|
-
for (const accountsToLoadChunk of accountsToLoadChunks) {
|
|
213
|
-
const args = [
|
|
214
|
-
accountsToLoadChunk
|
|
215
|
-
.filter((accountToLoad) => accountToLoad.callbacks.size > 0)
|
|
216
|
-
.map((accountToLoad) => {
|
|
217
|
-
return accountToLoad.publicKey.toBase58();
|
|
218
|
-
}),
|
|
219
|
-
{ commitment: this.commitment },
|
|
220
|
-
];
|
|
221
|
-
|
|
222
|
-
requests.push({
|
|
223
|
-
methodName: 'getMultipleAccounts',
|
|
224
|
-
args,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const rpcResponses: any | null = await promiseTimeout(
|
|
229
|
-
// @ts-ignore
|
|
230
|
-
this.connection._rpcBatchRequest(requests),
|
|
231
|
-
10 * 1000 // 30 second timeout
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
if (rpcResponses === null) {
|
|
235
|
-
this.log('request to rpc timed out');
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
rpcResponses.forEach((rpcResponse: any, i: number) => {
|
|
240
|
-
if (!rpcResponse.result) {
|
|
241
|
-
console.error('rpc response missing result:');
|
|
242
|
-
console.log(JSON.stringify(rpcResponse));
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
const newSlot = rpcResponse.result.context.slot;
|
|
246
|
-
|
|
247
|
-
if (newSlot > this.mostRecentSlot) {
|
|
248
|
-
this.mostRecentSlot = newSlot;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const accountsToLoad = accountsToLoadChunks[i];
|
|
252
|
-
accountsToLoad.forEach((accountToLoad, j) => {
|
|
253
|
-
if (accountToLoad.callbacks.size === 0) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const key = accountToLoad.publicKey.toBase58();
|
|
258
|
-
const oldRPCResponse = this.bufferAndSlotMap.get(key);
|
|
259
|
-
|
|
260
|
-
if (oldRPCResponse && newSlot < oldRPCResponse.slot) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
let newBuffer: Buffer | undefined = undefined;
|
|
265
|
-
if (rpcResponse.result.value[j]) {
|
|
266
|
-
const raw: string = rpcResponse.result.value[j].data[0];
|
|
267
|
-
const dataType = rpcResponse.result.value[j].data[1];
|
|
268
|
-
newBuffer = Buffer.from(raw, dataType);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (!oldRPCResponse) {
|
|
272
|
-
this.bufferAndSlotMap.set(key, {
|
|
273
|
-
slot: newSlot,
|
|
274
|
-
buffer: newBuffer,
|
|
275
|
-
});
|
|
276
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const oldBuffer = oldRPCResponse.buffer;
|
|
281
|
-
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
282
|
-
this.bufferAndSlotMap.set(key, {
|
|
283
|
-
slot: newSlot,
|
|
284
|
-
buffer: newBuffer,
|
|
285
|
-
});
|
|
286
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
handleAccountCallbacks(
|
|
293
|
-
accountToLoad: AccountToLoad,
|
|
294
|
-
buffer: Buffer | undefined,
|
|
295
|
-
slot: number
|
|
296
|
-
): void {
|
|
297
|
-
if (buffer === undefined) {
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
for (const [_, callback] of accountToLoad.callbacks) {
|
|
301
|
-
try {
|
|
302
|
-
callback(buffer, slot);
|
|
303
|
-
} catch (e) {
|
|
304
|
-
console.log('Bulk account load: error in account callback');
|
|
305
|
-
console.log('accounto to load', accountToLoad.publicKey.toString());
|
|
306
|
-
console.log('buffer', buffer.toString('base64'));
|
|
307
|
-
for (const callback of accountToLoad.callbacks.values()) {
|
|
308
|
-
console.log('account to load cb', callback);
|
|
309
|
-
}
|
|
310
|
-
throw e;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/** Returns the last-fetched raw buffer/slot for `publicKey`, or undefined if it has never been loaded. */
|
|
316
|
-
public getBufferAndSlot(publicKey: PublicKey): BufferAndSlot | undefined {
|
|
317
|
-
return this.bufferAndSlotMap.get(publicKey.toString());
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/** Returns the highest slot number observed across any account fetched by this loader so far. */
|
|
321
|
-
public getSlot(): number {
|
|
322
|
-
return this.mostRecentSlot;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/** Starts the polling interval if not already running and `pollingFrequency !== 0`. Called automatically by `addAccount`. */
|
|
326
|
-
public startPolling(): void {
|
|
327
|
-
if (this.intervalId) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (this.pollingFrequency !== 0)
|
|
332
|
-
this.intervalId = setInterval(
|
|
333
|
-
this.load.bind(this),
|
|
334
|
-
this.pollingFrequency
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/** Stops the polling interval, if running. Called automatically by `removeAccount` once no accounts remain. */
|
|
339
|
-
public stopPolling(): void {
|
|
340
|
-
if (this.intervalId) {
|
|
341
|
-
clearInterval(this.intervalId);
|
|
342
|
-
this.intervalId = undefined;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
public log(msg: string): void {
|
|
347
|
-
console.log(msg);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/** Restarts polling at a new interval (ms), preserving all registered accounts and callbacks. */
|
|
351
|
-
public updatePollingFrequency(pollingFrequency: number): void {
|
|
352
|
-
this.stopPolling();
|
|
353
|
-
this.pollingFrequency = pollingFrequency;
|
|
354
|
-
if (this.accountsToLoad.size > 0) {
|
|
355
|
-
this.startPolling();
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { UserStats } from '../userStats';
|
|
2
|
-
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
3
|
-
import { PollingUserStatsAccountSubscriber } from './pollingUserStatsAccountSubscriber';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Subscribes many `UserStats`s that share a single `BulkAccountLoader` in one batched round trip,
|
|
7
|
-
* instead of each `UserStats.subscribe()` triggering its own `addAccount`/`load()`. Registers
|
|
8
|
-
* every account's `PollingUserStatsAccountSubscriber` with the loader first, issues one `load()`
|
|
9
|
-
* to seed all of them from a single batched `getMultipleAccounts` call, and only then calls
|
|
10
|
-
* `userStat.subscribe()` (which becomes a fast no-op fetch since data is already cached). If
|
|
11
|
-
* `userStats` is empty, still calls `accountLoader.load()` so any other accounts already
|
|
12
|
-
* registered on the loader get polled.
|
|
13
|
-
* @param userStats `UserStats` instances to subscribe; each must already be constructed with a `PollingUserStatsAccountSubscriber`.
|
|
14
|
-
* @param accountLoader Shared `BulkAccountLoader` batching the underlying RPC polls.
|
|
15
|
-
*/
|
|
16
|
-
export async function bulkPollingUserStatsSubscribe(
|
|
17
|
-
userStats: UserStats[],
|
|
18
|
-
accountLoader: BulkAccountLoader
|
|
19
|
-
): Promise<void> {
|
|
20
|
-
if (userStats.length === 0) {
|
|
21
|
-
await accountLoader.load();
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
await Promise.all(
|
|
26
|
-
userStats.map((userStat) => {
|
|
27
|
-
return (
|
|
28
|
-
userStat.accountSubscriber as PollingUserStatsAccountSubscriber
|
|
29
|
-
).addToAccountLoader();
|
|
30
|
-
})
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
await accountLoader.load();
|
|
34
|
-
|
|
35
|
-
await Promise.all(
|
|
36
|
-
userStats.map(async (userStat) => {
|
|
37
|
-
return userStat.subscribe();
|
|
38
|
-
})
|
|
39
|
-
);
|
|
40
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { User } from '../user';
|
|
2
|
-
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
3
|
-
import { PollingUserAccountSubscriber } from './pollingUserAccountSubscriber';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Subscribes many `User`s that share a single `BulkAccountLoader` in one batched round trip,
|
|
7
|
-
* instead of each `User.subscribe()` triggering its own `addAccount`/`load()`. Registers every
|
|
8
|
-
* user's `PollingUserAccountSubscriber` with the loader first, issues one `load()` to seed all of
|
|
9
|
-
* them from a single batched `getMultipleAccounts` call, and only then calls `user.subscribe()`
|
|
10
|
-
* (which becomes a fast no-op fetch since data is already cached). If `users` is empty, still
|
|
11
|
-
* calls `accountLoader.load()` so any other accounts already registered on the loader get polled.
|
|
12
|
-
* @param users Users to subscribe; each must already be constructed with a `PollingUserAccountSubscriber`.
|
|
13
|
-
* @param accountLoader Shared `BulkAccountLoader` batching the underlying RPC polls.
|
|
14
|
-
*/
|
|
15
|
-
export async function bulkPollingUserSubscribe(
|
|
16
|
-
users: User[],
|
|
17
|
-
accountLoader: BulkAccountLoader
|
|
18
|
-
): Promise<void> {
|
|
19
|
-
if (users.length === 0) {
|
|
20
|
-
await accountLoader.load();
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
await Promise.all(
|
|
25
|
-
users.map((user) => {
|
|
26
|
-
return (
|
|
27
|
-
user.accountSubscriber as PollingUserAccountSubscriber
|
|
28
|
-
).addToAccountLoader();
|
|
29
|
-
})
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
await accountLoader.load();
|
|
33
|
-
|
|
34
|
-
await Promise.all(
|
|
35
|
-
users.map(async (user) => {
|
|
36
|
-
return user.subscribe();
|
|
37
|
-
})
|
|
38
|
-
);
|
|
39
|
-
}
|