@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.
- package/README.md +3 -3
- package/lib/browser/adminClient.d.ts +35 -0
- package/lib/browser/adminClient.js +65 -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 +146 -3
- package/lib/browser/idl/velocity.json +147 -4
- package/lib/browser/orderSubscriber/OrderSubscriber.js +3 -0
- package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
- package/lib/browser/types.d.ts +4 -0
- package/lib/browser/user.d.ts +15 -0
- package/lib/browser/user.js +37 -1
- package/lib/browser/velocityClient.d.ts +46 -10
- package/lib/browser/velocityClient.js +107 -35
- package/lib/node/adminClient.d.ts +35 -0
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +65 -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 +146 -3
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +147 -4
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
- package/lib/node/orderSubscriber/OrderSubscriber.js +3 -0
- package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
- package/lib/node/pyth/pythLazerSubscriber.js +37 -27
- package/lib/node/types.d.ts +4 -0
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/user.d.ts +15 -0
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +37 -1
- 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,95 +0,0 @@
|
|
|
1
|
-
# WebSocketAccountSubscriberV2
|
|
2
|
-
|
|
3
|
-
This is a new implementation of the WebSocket account subscriber that utilizes the [gill](https://www.npmjs.com/package/gill) library for improved RPC and WebSocket functionality.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The `WebSocketAccountSubscriberV2` class provides the same interface as the original `WebSocketAccountSubscriber` but uses gill's modern TypeScript client library for Solana blockchain interactions.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
The usage is identical to the original `WebSocketAccountSubscriber`:
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { WebSocketAccountSubscriberV2 } from './accounts/webSocketAccountSubscriberV2';
|
|
15
|
-
|
|
16
|
-
const subscriber = new WebSocketAccountSubscriberV2(
|
|
17
|
-
'userAccount', // account name
|
|
18
|
-
program, // Anchor program instance
|
|
19
|
-
userAccountPublicKey, // PublicKey of the account to subscribe to
|
|
20
|
-
decodeBuffer, // optional custom decode function
|
|
21
|
-
resubOpts, // optional resubscription options
|
|
22
|
-
commitment // optional commitment level
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
// Subscribe to account changes
|
|
26
|
-
await subscriber.subscribe((data) => {
|
|
27
|
-
console.log('Account updated:', data);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// Unsubscribe when done
|
|
31
|
-
await subscriber.unsubscribe();
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### Polling Instead of Resubscribing
|
|
35
|
-
|
|
36
|
-
For accounts that rarely update (like long-tail markets), you can use polling instead of resubscribing to reduce resource usage:
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
const resubOpts = {
|
|
40
|
-
resubTimeoutMs: 30000, // 30 seconds
|
|
41
|
-
logResubMessages: true,
|
|
42
|
-
usePollingInsteadOfResub: true, // Enable polling mode
|
|
43
|
-
pollingIntervalMs: 30000, // Poll every 30 seconds (optional, defaults to 30000)
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const subscriber = new WebSocketAccountSubscriberV2(
|
|
47
|
-
'perpMarket', // account name
|
|
48
|
-
program,
|
|
49
|
-
marketPublicKey,
|
|
50
|
-
undefined, // decodeBuffer
|
|
51
|
-
resubOpts
|
|
52
|
-
);
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**How it works:**
|
|
56
|
-
1. Initially subscribes to WebSocket updates
|
|
57
|
-
2. If no WebSocket data is received for `resubTimeoutMs` (30s), switches to websocket+polling mode if `usePollingInsteadOfResub` is specified true, else just resubscribes(unsub, sub).
|
|
58
|
-
3. Polls every `pollingIntervalMs` (alongside websocket connection) to check for updates by:
|
|
59
|
-
- Storing current account buffer state
|
|
60
|
-
- Fetching latest account data
|
|
61
|
-
- Comparing buffers to detect any missed updates
|
|
62
|
-
4. If polling detects new data (indicating missed WebSocket events):
|
|
63
|
-
- Immediately stops polling
|
|
64
|
-
- Resubscribes to WebSocket to restore real-time updates
|
|
65
|
-
- This helps recover from degraded WebSocket connections
|
|
66
|
-
5. If a WebSocket event is received while polling:
|
|
67
|
-
- Polling is automatically stopped
|
|
68
|
-
- System continues with normal WebSocket updates
|
|
69
|
-
6. This approach provides:
|
|
70
|
-
- Efficient handling of rarely-updated accounts
|
|
71
|
-
- Automatic recovery from WebSocket connection issues
|
|
72
|
-
- Seamless fallback between polling and WebSocket modes
|
|
73
|
-
|
|
74
|
-
## Implementation Details
|
|
75
|
-
|
|
76
|
-
### Gill Integration
|
|
77
|
-
|
|
78
|
-
The implementation uses gill's `createSolanaClient` function to create RPC and WebSocket clients:
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
import { createSolanaClient } from 'gill';
|
|
82
|
-
|
|
83
|
-
const { rpc, rpcSubscriptions } = createSolanaClient({
|
|
84
|
-
urlOrMoniker: rpcUrl, // or "mainnet", "devnet", etc.
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Key Differences from Original
|
|
89
|
-
|
|
90
|
-
1. **RPC Client**: Uses gill's `rpc` client for account fetching
|
|
91
|
-
2. **WebSocket Subscriptions**: Uses gill's `rpcSubscriptions` for real-time updates
|
|
92
|
-
3. **Address Handling**: Converts `PublicKey` to gill's `Address` type for compatibility
|
|
93
|
-
4. **Response Formatting**: Converts gill responses to match the expected `AccountInfo<Buffer>` format
|
|
94
|
-
5. **Abort Signal**: Utilizes AbortSignal nodejs/web class to shutdown websocket connection synchronously
|
|
95
|
-
6. **Polling Mode**: Optional polling mechanism for accounts that rarely update
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
# WebSocketProgramAccountSubscriberV2
|
|
2
|
-
|
|
3
|
-
This is a new implementation of the WebSocket program account subscriber that utilizes the [gill](https://www.npmjs.com/package/gill) library for improved RPC and WebSocket functionality, with additional smart polling logic for specific accounts.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The `WebSocketProgramAccountSubscriberV2` class provides the same interface as the original `WebSocketProgramAccountSubscriber` but uses gill's modern TypeScript client library for Solana blockchain interactions. Additionally, it implements smart polling logic for accounts that don't update frequently (like long-tail markets) to prevent missing updates.
|
|
8
|
-
|
|
9
|
-
## Key Features
|
|
10
|
-
|
|
11
|
-
1. **Gill Integration**: Uses gill's `createSolanaClient` for RPC and WebSocket functionality
|
|
12
|
-
2. **Smart Polling**: Optional polling for specific accounts that don't update frequently
|
|
13
|
-
3. **Missed Update Detection**: Automatically detects when updates are missed and resubscribes
|
|
14
|
-
4. **Configurable Polling**: 30-second default polling interval, customizable per instance
|
|
15
|
-
|
|
16
|
-
## Usage
|
|
17
|
-
|
|
18
|
-
The usage is similar to the original `WebSocketProgramAccountSubscriber` with additional options:
|
|
19
|
-
|
|
20
|
-
```typescript
|
|
21
|
-
import { WebSocketProgramAccountSubscriberV2 } from './accounts/webSocketProgramAccountSubscriberV2';
|
|
22
|
-
|
|
23
|
-
// Create subscriber with optional accounts to poll
|
|
24
|
-
const subscriber = new WebSocketProgramAccountSubscriberV2(
|
|
25
|
-
'perpMarket', // account name
|
|
26
|
-
'perpMarket', // account discriminator
|
|
27
|
-
program, // Anchor program instance
|
|
28
|
-
decodeBuffer, // decode function
|
|
29
|
-
{ filters: [] }, // options
|
|
30
|
-
resubOpts, // optional resubscription options
|
|
31
|
-
[longTailMarket1, longTailMarket2] // optional list of accounts to poll
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
// Subscribe to program account changes
|
|
35
|
-
await subscriber.subscribe((accountId, data, context, buffer) => {
|
|
36
|
-
console.log('Account updated:', accountId.toBase58(), data);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// Add more accounts to poll dynamically
|
|
40
|
-
subscriber.addAccountToPoll(newMarketPublicKey);
|
|
41
|
-
|
|
42
|
-
// Remove accounts from polling
|
|
43
|
-
subscriber.removeAccountFromPoll(oldMarketPublicKey);
|
|
44
|
-
|
|
45
|
-
// Change polling interval
|
|
46
|
-
subscriber.setPollingInterval(60000); // 60 seconds
|
|
47
|
-
|
|
48
|
-
// Unsubscribe when done
|
|
49
|
-
await subscriber.unsubscribe();
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Implementation Details
|
|
53
|
-
|
|
54
|
-
### Gill Integration
|
|
55
|
-
|
|
56
|
-
The implementation uses gill's `createSolanaClient` function to create RPC and WebSocket clients:
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
import { createSolanaClient } from 'gill';
|
|
60
|
-
|
|
61
|
-
const { rpc, rpcSubscriptions } = createSolanaClient({
|
|
62
|
-
urlOrMoniker: rpcUrl, // or "mainnet", "devnet", etc.
|
|
63
|
-
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Smart Polling Logic
|
|
67
|
-
|
|
68
|
-
1. **Account Selection**: Only accounts in the `accountsToMonitor` set are monitored
|
|
69
|
-
2. **Monitoring Period**: Default 30 seconds before starting to poll an account
|
|
70
|
-
3. **WebSocket Tracking**: Tracks the last WebSocket notification time for each account
|
|
71
|
-
4. **Conditional Polling**: Only starts polling if no WebSocket notification received in 30 seconds
|
|
72
|
-
5. **Batch Polling**: Uses `getMultipleAccounts` to poll all accounts in a single RPC call
|
|
73
|
-
6. **Dynamic Polling**: Stops polling individual accounts when WebSocket notifications are received
|
|
74
|
-
7. **Missed Update Detection**: Compares current slot and buffer with cached data
|
|
75
|
-
8. **Automatic Resubscription**: If a missed update is detected, the entire subscription is resubscribed
|
|
76
|
-
|
|
77
|
-
### Key Differences from Original
|
|
78
|
-
|
|
79
|
-
1. **RPC Client**: Uses gill's `rpc` client for account fetching
|
|
80
|
-
2. **WebSocket Subscriptions**: Uses gill's `rpcSubscriptions` for real-time updates
|
|
81
|
-
3. **Address Handling**: Converts `PublicKey` to gill's `Address` type for compatibility
|
|
82
|
-
4. **Response Formatting**: Converts gill responses to match the expected `AccountInfo<Buffer>` format
|
|
83
|
-
5. **Abort Signal**: Utilizes AbortSignal nodejs/web class to shutdown websocket connection synchronously
|
|
84
|
-
6. **Smart Polling**: Implements polling logic for specific accounts to prevent missed updates
|
|
85
|
-
|
|
86
|
-
## Configuration Options
|
|
87
|
-
|
|
88
|
-
### Constructor Parameters
|
|
89
|
-
|
|
90
|
-
- `subscriptionName`: Name for logging purposes
|
|
91
|
-
- `accountDiscriminator`: Account discriminator for decoding
|
|
92
|
-
- `program`: Anchor program instance
|
|
93
|
-
- `decodeBufferFn`: Function to decode account data
|
|
94
|
-
- `options`: Subscription options (filters, commitment)
|
|
95
|
-
- `resubOpts`: Resubscription options
|
|
96
|
-
- `accountsToPoll`: Optional array of PublicKeys to poll
|
|
97
|
-
|
|
98
|
-
### Polling Configuration
|
|
99
|
-
|
|
100
|
-
- **Default Monitoring Period**: 30 seconds before starting to poll
|
|
101
|
-
- **WebSocket Tracking**: Records timestamp of last WebSocket notification per account
|
|
102
|
-
- **Conditional Polling**: Only polls accounts that haven't received WebSocket updates recently
|
|
103
|
-
- **Batch Polling**: Uses `getMultipleAccounts` for efficient polling of multiple accounts
|
|
104
|
-
- **Dynamic Management**: Automatically starts/stops polling based on WebSocket activity
|
|
105
|
-
- **Detection Logic**: Compares slot numbers and buffer contents
|
|
106
|
-
- **Resubscription**: Triggers when missed updates are detected
|
|
107
|
-
- **Logging**: Optional logging of polling events
|
|
108
|
-
|
|
109
|
-
## Current Limitations
|
|
110
|
-
|
|
111
|
-
1. **Gill API Compatibility**: Some type mismatches exist with the current gill version
|
|
112
|
-
2. **Account Key Handling**: The account key extraction from gill notifications needs refinement
|
|
113
|
-
3. **Encoding Types**: Some encoding type comparisons need to be resolved
|
|
114
|
-
|
|
115
|
-
## Future Improvements
|
|
116
|
-
|
|
117
|
-
1. **Better Gill Integration**: Resolve remaining type compatibility issues
|
|
118
|
-
2. **Enhanced Logging**: More detailed logging for debugging
|
|
119
|
-
3. **Performance Optimization**: Optimize polling frequency based on account activity
|
|
120
|
-
4. **Batch Polling**: Poll multiple accounts in a single RPC call
|
|
121
|
-
|
|
122
|
-
## Migration from V1
|
|
123
|
-
|
|
124
|
-
The V2 implementation maintains the same interface as V1, making migration straightforward:
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
// V1
|
|
128
|
-
const subscriber = new WebSocketProgramAccountSubscriber(...);
|
|
129
|
-
|
|
130
|
-
// V2 (same interface)
|
|
131
|
-
const subscriber = new WebSocketProgramAccountSubscriberV2(...);
|
|
132
|
-
|
|
133
|
-
// V2 with polling (new feature)
|
|
134
|
-
const subscriber = new WebSocketProgramAccountSubscriberV2(..., accountsToPoll);
|
|
135
|
-
```
|
|
@@ -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
|
-
}
|