@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
package/src/tx/baseTxSender.ts
DELETED
|
@@ -1,651 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ConfirmationStrategy,
|
|
3
|
-
TxSender,
|
|
4
|
-
TxSendError,
|
|
5
|
-
TxSigAndSlot,
|
|
6
|
-
} from './types';
|
|
7
|
-
import {
|
|
8
|
-
Commitment,
|
|
9
|
-
ConfirmOptions,
|
|
10
|
-
Context,
|
|
11
|
-
RpcResponseAndContext,
|
|
12
|
-
Signer,
|
|
13
|
-
SignatureResult,
|
|
14
|
-
Transaction,
|
|
15
|
-
TransactionSignature,
|
|
16
|
-
Connection,
|
|
17
|
-
VersionedTransaction,
|
|
18
|
-
TransactionInstruction,
|
|
19
|
-
AddressLookupTableAccount,
|
|
20
|
-
BlockhashWithExpiryBlockHeight,
|
|
21
|
-
} from '@solana/web3.js';
|
|
22
|
-
import assert from 'assert';
|
|
23
|
-
import bs58 from 'bs58';
|
|
24
|
-
import { TxHandler } from './txHandler';
|
|
25
|
-
import { IWallet } from '../types';
|
|
26
|
-
import NodeCache from 'node-cache';
|
|
27
|
-
import { DEFAULT_CONFIRMATION_OPTS } from '../config';
|
|
28
|
-
import { NOT_CONFIRMED_ERROR_CODE } from '../constants/txConstants';
|
|
29
|
-
import { throwTransactionError } from './reportTransactionError';
|
|
30
|
-
|
|
31
|
-
const BASELINE_TX_LAND_RATE = 0.9;
|
|
32
|
-
const DEFAULT_TIMEOUT = 35000;
|
|
33
|
-
const DEFAULT_TX_LAND_RATE_LOOKBACK_WINDOW_MINUTES = 10;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Shared base for all `TxSender` implementations (`RetryTxSender`, `WhileValidTxSender`,
|
|
37
|
-
* `FastSingleTxSender`, `ForwardOnlyTxSender`). Provides signing/serialization via `TxHandler`,
|
|
38
|
-
* confirmation via websocket subscription and/or polling (per `ConfirmationStrategy`),
|
|
39
|
-
* timeout/land-rate bookkeeping, and fan-out to `additionalConnections`. Subclasses are expected
|
|
40
|
-
* to implement `sendRawTransaction` with their specific retry/broadcast behavior — the base
|
|
41
|
-
* implementation always throws.
|
|
42
|
-
*/
|
|
43
|
-
export abstract class BaseTxSender implements TxSender {
|
|
44
|
-
connection: Connection;
|
|
45
|
-
wallet: IWallet;
|
|
46
|
-
opts: ConfirmOptions;
|
|
47
|
-
/** Confirmation timeout in milliseconds, applied to both websocket and polling confirmation. */
|
|
48
|
-
timeout: number;
|
|
49
|
-
/** Extra RPC connections a raw transaction is also broadcast to (best-effort, errors logged not thrown), for redundancy. */
|
|
50
|
-
additionalConnections: Connection[];
|
|
51
|
-
/** Count of `confirmTransactionWebSocket`/`confirmTransactionPolling` calls that hit `timeout` without a definitive result. */
|
|
52
|
-
timeoutCount = 0;
|
|
53
|
-
confirmationStrategy: ConfirmationStrategy;
|
|
54
|
-
/** Callbacks invoked with the base58-encoded raw transaction alongside `additionalConnections` broadcasts, e.g. for logging/mempool submission. */
|
|
55
|
-
additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
|
|
56
|
-
txHandler: TxHandler;
|
|
57
|
-
/** Whether to record each sent signature (via `txSigCache`) to compute `getTxLandRate()`. */
|
|
58
|
-
trackTxLandRate?: boolean;
|
|
59
|
-
/** Whether `confirmTransactionWebSocket`/`confirmTransactionPolling` throw `TxSendError` on timeout (`true`) or return `undefined` (`false`). */
|
|
60
|
-
throwOnTimeoutError: boolean;
|
|
61
|
-
/** Whether `checkConfirmationResultForError` throws the resolved on-chain error, or is a no-op. */
|
|
62
|
-
throwOnTransactionError: boolean;
|
|
63
|
-
|
|
64
|
-
// For landing rate calcs
|
|
65
|
-
/** Lookback window, in seconds, over which `txSigCache` entries expire for the land-rate calculation. */
|
|
66
|
-
lookbackWindowMinutes: number;
|
|
67
|
-
/** TTL cache of `txSig -> landed?` used to compute `getTxLandRate()` when `trackTxLandRate` is set. */
|
|
68
|
-
txSigCache?: NodeCache;
|
|
69
|
-
txLandRate = 0;
|
|
70
|
-
lastPriorityFeeSuggestion = 1;
|
|
71
|
-
/** Maps a land rate (0-1) to a priority-fee multiplier; defaults to `defaultLandRateToFeeFunc`. */
|
|
72
|
-
landRateToFeeFunc: (landRate: number) => number;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @param props.connection - Primary RPC connection used for sending and confirming transactions.
|
|
76
|
-
* @param props.wallet - Wallet used to sign transactions that aren't already `preSigned`.
|
|
77
|
-
* @param props.opts - Default `ConfirmOptions` used when a call site doesn't pass its own; defaults to `DEFAULT_CONFIRMATION_OPTS` (`'confirmed'`).
|
|
78
|
-
* @param props.timeout - Confirmation timeout in milliseconds; defaults to 35000 (35s).
|
|
79
|
-
* @param props.additionalConnections - Extra connections to also broadcast raw transactions to.
|
|
80
|
-
* @param props.confirmationStrategy - How to wait for confirmation; defaults to `ConfirmationStrategy.Combo`.
|
|
81
|
-
* @param props.additionalTxSenderCallbacks - Callbacks invoked with each sent transaction's base58 encoding.
|
|
82
|
-
* @param props.trackTxLandRate - Enables land-rate tracking (backs `getTxLandRate()`/`getSuggestedPriorityFeeMultiplier()`).
|
|
83
|
-
* @param props.txHandler - Custom `TxHandler` for signing/building transactions; defaults to one constructed from `connection`/`wallet`/`opts`.
|
|
84
|
-
* @param props.txLandRateLookbackWindowMinutes - Rolling window, in minutes, of sent signatures kept for the land-rate calculation; defaults to 10.
|
|
85
|
-
* @param props.landRateToFeeFunc - Custom mapping from land rate to priority-fee multiplier; defaults to `defaultLandRateToFeeFunc`.
|
|
86
|
-
* @param props.throwOnTimeoutError - Whether confirmation timeouts throw `TxSendError` instead of returning `undefined`; defaults to `true`.
|
|
87
|
-
* @param props.throwOnTransactionError - Whether a failed on-chain result throws the resolved program error; defaults to `true`.
|
|
88
|
-
*/
|
|
89
|
-
public constructor({
|
|
90
|
-
connection,
|
|
91
|
-
wallet,
|
|
92
|
-
opts = DEFAULT_CONFIRMATION_OPTS,
|
|
93
|
-
timeout = DEFAULT_TIMEOUT,
|
|
94
|
-
additionalConnections = new Array<Connection>(),
|
|
95
|
-
confirmationStrategy = ConfirmationStrategy.Combo,
|
|
96
|
-
additionalTxSenderCallbacks,
|
|
97
|
-
trackTxLandRate,
|
|
98
|
-
txHandler,
|
|
99
|
-
txLandRateLookbackWindowMinutes = DEFAULT_TX_LAND_RATE_LOOKBACK_WINDOW_MINUTES,
|
|
100
|
-
landRateToFeeFunc,
|
|
101
|
-
throwOnTimeoutError = true,
|
|
102
|
-
throwOnTransactionError = true,
|
|
103
|
-
}: {
|
|
104
|
-
connection: Connection;
|
|
105
|
-
wallet: IWallet;
|
|
106
|
-
opts?: ConfirmOptions;
|
|
107
|
-
timeout?: number;
|
|
108
|
-
additionalConnections?: Connection[];
|
|
109
|
-
confirmationStrategy?: ConfirmationStrategy;
|
|
110
|
-
additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
|
|
111
|
-
txHandler?: TxHandler;
|
|
112
|
-
trackTxLandRate?: boolean;
|
|
113
|
-
txLandRateLookbackWindowMinutes?: number;
|
|
114
|
-
landRateToFeeFunc?: (landRate: number) => number;
|
|
115
|
-
throwOnTimeoutError?: boolean;
|
|
116
|
-
throwOnTransactionError?: boolean;
|
|
117
|
-
}) {
|
|
118
|
-
this.connection = connection;
|
|
119
|
-
this.wallet = wallet;
|
|
120
|
-
this.opts = opts;
|
|
121
|
-
this.timeout = timeout;
|
|
122
|
-
this.additionalConnections = additionalConnections;
|
|
123
|
-
this.confirmationStrategy = confirmationStrategy;
|
|
124
|
-
this.additionalTxSenderCallbacks = additionalTxSenderCallbacks;
|
|
125
|
-
this.txHandler =
|
|
126
|
-
txHandler ??
|
|
127
|
-
new TxHandler({
|
|
128
|
-
connection: this.connection,
|
|
129
|
-
wallet: this.wallet,
|
|
130
|
-
confirmationOptions: this.opts,
|
|
131
|
-
});
|
|
132
|
-
this.trackTxLandRate = trackTxLandRate;
|
|
133
|
-
this.lookbackWindowMinutes = txLandRateLookbackWindowMinutes * 60;
|
|
134
|
-
if (this.trackTxLandRate) {
|
|
135
|
-
this.txSigCache = new NodeCache({
|
|
136
|
-
stdTTL: this.lookbackWindowMinutes,
|
|
137
|
-
checkperiod: 120,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
this.landRateToFeeFunc =
|
|
141
|
-
landRateToFeeFunc ?? this.defaultLandRateToFeeFunc.bind(this);
|
|
142
|
-
this.throwOnTimeoutError = throwOnTimeoutError;
|
|
143
|
-
this.throwOnTransactionError = throwOnTransactionError;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Signs (via `prepareTx`, unless `preSigned`) and sends a legacy `Transaction`.
|
|
148
|
-
* @param tx - Transaction to send.
|
|
149
|
-
* @param additionalSigners - Extra signers to co-sign alongside the wallet; defaults to none.
|
|
150
|
-
* @param opts - Confirmation options; defaults to `this.opts`.
|
|
151
|
-
* @param preSigned - If `true`, skip wallet signing.
|
|
152
|
-
* @returns The result of `sendRawTransaction` on the serialized, signed transaction.
|
|
153
|
-
*/
|
|
154
|
-
async send(
|
|
155
|
-
tx: Transaction,
|
|
156
|
-
additionalSigners?: Array<Signer>,
|
|
157
|
-
opts?: ConfirmOptions,
|
|
158
|
-
preSigned?: boolean
|
|
159
|
-
): Promise<TxSigAndSlot> {
|
|
160
|
-
if (additionalSigners === undefined) {
|
|
161
|
-
additionalSigners = [];
|
|
162
|
-
}
|
|
163
|
-
if (opts === undefined) {
|
|
164
|
-
opts = this.opts;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const signedTx = await this.prepareTx(
|
|
168
|
-
tx,
|
|
169
|
-
additionalSigners,
|
|
170
|
-
opts,
|
|
171
|
-
preSigned
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
return this.sendRawTransaction(signedTx.serialize(), opts);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Delegates to `TxHandler.prepareTx` to attach a recent blockhash, fee payer, and signatures.
|
|
179
|
-
* @param tx - Transaction to prepare.
|
|
180
|
-
* @param additionalSigners - Extra signers to co-sign alongside the wallet.
|
|
181
|
-
* @param opts - Confirmation options (affects blockhash commitment).
|
|
182
|
-
* @param preSigned - If `true`, skip wallet signing.
|
|
183
|
-
* @returns The prepared (blockhash-populated, signed unless `preSigned`) transaction.
|
|
184
|
-
*/
|
|
185
|
-
async prepareTx(
|
|
186
|
-
tx: Transaction,
|
|
187
|
-
additionalSigners: Array<Signer>,
|
|
188
|
-
opts: ConfirmOptions,
|
|
189
|
-
preSigned?: boolean
|
|
190
|
-
): Promise<Transaction> {
|
|
191
|
-
return this.txHandler.prepareTx(
|
|
192
|
-
tx,
|
|
193
|
-
additionalSigners,
|
|
194
|
-
undefined,
|
|
195
|
-
opts,
|
|
196
|
-
preSigned
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Builds (but does not send) a `VersionedTransaction` from raw instructions via
|
|
202
|
-
* `TxHandler.generateVersionedTransaction`.
|
|
203
|
-
* @param ixs - Instructions to include, in order.
|
|
204
|
-
* @param lookupTableAccounts - Address lookup tables to compile the message against.
|
|
205
|
-
* @param _additionalSigners - Unused by this implementation.
|
|
206
|
-
* @param opts - Unused by this implementation (present for `TxSender` interface compatibility).
|
|
207
|
-
* @param blockhash - Blockhash to use; if omitted, fetched fresh via `connection.getLatestBlockhash()`.
|
|
208
|
-
* @returns The compiled `VersionedTransaction` (not yet signed by additional signers beyond the wallet).
|
|
209
|
-
*/
|
|
210
|
-
async getVersionedTransaction(
|
|
211
|
-
ixs: TransactionInstruction[],
|
|
212
|
-
lookupTableAccounts: AddressLookupTableAccount[],
|
|
213
|
-
_additionalSigners?: Array<Signer>,
|
|
214
|
-
opts?: ConfirmOptions,
|
|
215
|
-
blockhash?: BlockhashWithExpiryBlockHeight
|
|
216
|
-
): Promise<VersionedTransaction> {
|
|
217
|
-
return this.txHandler.generateVersionedTransaction(
|
|
218
|
-
blockhash ?? (await this.connection.getLatestBlockhash()),
|
|
219
|
-
ixs,
|
|
220
|
-
lookupTableAccounts,
|
|
221
|
-
this.wallet
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Signs (unless `preSigned`) and sends a `VersionedTransaction`. When the wallet exposes a
|
|
227
|
-
* `payer` `Keypair` directly, signs in-place with `tx.sign(...)`; otherwise delegates to
|
|
228
|
-
* `TxHandler.signVersionedTx` (needed for wallet adapters without direct keypair access).
|
|
229
|
-
* @param tx - Transaction to send.
|
|
230
|
-
* @param additionalSigners - Extra signers to co-sign alongside the wallet.
|
|
231
|
-
* @param opts - Confirmation options; defaults to `this.opts`.
|
|
232
|
-
* @param preSigned - If `true`, skip signing entirely.
|
|
233
|
-
* @returns The result of `sendRawTransaction` on the serialized, signed transaction.
|
|
234
|
-
*/
|
|
235
|
-
async sendVersionedTransaction(
|
|
236
|
-
tx: VersionedTransaction,
|
|
237
|
-
additionalSigners?: Array<Signer>,
|
|
238
|
-
opts?: ConfirmOptions,
|
|
239
|
-
preSigned?: boolean
|
|
240
|
-
): Promise<TxSigAndSlot> {
|
|
241
|
-
let signedTx;
|
|
242
|
-
|
|
243
|
-
if (preSigned) {
|
|
244
|
-
signedTx = tx;
|
|
245
|
-
// @ts-ignore
|
|
246
|
-
} else if (this.wallet.payer) {
|
|
247
|
-
// @ts-ignore
|
|
248
|
-
tx.sign((additionalSigners ?? []).concat(this.wallet.payer));
|
|
249
|
-
signedTx = tx;
|
|
250
|
-
} else {
|
|
251
|
-
signedTx = await this.txHandler.signVersionedTx(
|
|
252
|
-
tx,
|
|
253
|
-
additionalSigners ?? [],
|
|
254
|
-
undefined,
|
|
255
|
-
this.wallet
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (opts === undefined) {
|
|
260
|
-
opts = this.opts;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return this.sendRawTransaction(signedTx.serialize(), opts);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Sends and confirms an already-serialized, already-signed transaction. `BaseTxSender` itself
|
|
268
|
-
* has no broadcast/retry strategy — every concrete sender (`RetryTxSender`,
|
|
269
|
-
* `WhileValidTxSender`, `FastSingleTxSender`, `ForwardOnlyTxSender`) must override this.
|
|
270
|
-
* @throws Error always, if not overridden by a subclass.
|
|
271
|
-
*/
|
|
272
|
-
async sendRawTransaction(
|
|
273
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
274
|
-
rawTransaction: Buffer | Uint8Array,
|
|
275
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
276
|
-
opts: ConfirmOptions
|
|
277
|
-
): Promise<TxSigAndSlot> {
|
|
278
|
-
throw new Error('Must be implemented by subclass');
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Simulates a transaction via `connection.simulateTransaction` without sending it, swallowing
|
|
283
|
-
* both simulation errors and RPC-call failures into a `false` result (logged to `console.error`).
|
|
284
|
-
* @param tx - Transaction to simulate.
|
|
285
|
-
* @returns `true` if simulation succeeded with no error, `false` otherwise.
|
|
286
|
-
*/
|
|
287
|
-
async simulateTransaction(tx: VersionedTransaction): Promise<boolean> {
|
|
288
|
-
try {
|
|
289
|
-
const result = await this.connection.simulateTransaction(tx);
|
|
290
|
-
if (result.value.err != null) {
|
|
291
|
-
console.error('Error in transaction simulation: ', result.value.err);
|
|
292
|
-
return false;
|
|
293
|
-
}
|
|
294
|
-
return true;
|
|
295
|
-
} catch (e) {
|
|
296
|
-
console.error('Error calling simulateTransaction: ', e);
|
|
297
|
-
return false;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Waits for a transaction to confirm by subscribing to `onSignature` on `connection` and every
|
|
303
|
-
* `additionalConnections` entry simultaneously, resolving on whichever responds first. If no
|
|
304
|
-
* connection confirms within `this.timeout` and `confirmationStrategy` is `Combo`, falls back
|
|
305
|
-
* to a one-shot `getSignatureStatuses` check before giving up.
|
|
306
|
-
* @param signature - Base58-encoded transaction signature to confirm.
|
|
307
|
-
* @param commitment - Commitment level for the subscription; defaults to `this.opts.commitment`.
|
|
308
|
-
* @returns The confirmation result, or `undefined` if it timed out and `throwOnTimeoutError` is `false`.
|
|
309
|
-
* @throws Error if `signature` isn't valid base58 or isn't 64 bytes decoded. `TxSendError`
|
|
310
|
-
* (code `NOT_CONFIRMED_ERROR_CODE`) on timeout if `throwOnTimeoutError` is `true` (the default) —
|
|
311
|
-
* in that case the transaction's actual outcome is unknown, not necessarily failed.
|
|
312
|
-
*/
|
|
313
|
-
async confirmTransactionWebSocket(
|
|
314
|
-
signature: TransactionSignature,
|
|
315
|
-
commitment?: Commitment
|
|
316
|
-
): Promise<RpcResponseAndContext<SignatureResult> | undefined> {
|
|
317
|
-
let decodedSignature;
|
|
318
|
-
try {
|
|
319
|
-
decodedSignature = bs58.decode(signature);
|
|
320
|
-
} catch (err) {
|
|
321
|
-
throw new Error('signature must be base58 encoded: ' + signature);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
assert(decodedSignature.length === 64, 'signature has invalid length');
|
|
325
|
-
|
|
326
|
-
const start = Date.now();
|
|
327
|
-
const subscriptionCommitment = commitment || this.opts.commitment;
|
|
328
|
-
|
|
329
|
-
const subscriptionIds = new Array<number | undefined>();
|
|
330
|
-
const connections = [this.connection, ...this.additionalConnections];
|
|
331
|
-
let response: RpcResponseAndContext<SignatureResult> | null = null;
|
|
332
|
-
const promises = connections.map((connection, i) => {
|
|
333
|
-
let subscriptionId: number | undefined;
|
|
334
|
-
// a failed subscription setup on one connection is best-effort: log and
|
|
335
|
-
// leave its promise pending so the race keeps waiting on the others
|
|
336
|
-
// (if every subscription fails, the timeout/Combo fallback still applies)
|
|
337
|
-
const confirmPromise = new Promise((resolve) => {
|
|
338
|
-
try {
|
|
339
|
-
subscriptionId = connection.onSignature(
|
|
340
|
-
signature,
|
|
341
|
-
(result: SignatureResult, context: Context) => {
|
|
342
|
-
subscriptionIds[i] = undefined;
|
|
343
|
-
response = {
|
|
344
|
-
context,
|
|
345
|
-
value: result,
|
|
346
|
-
};
|
|
347
|
-
resolve(null);
|
|
348
|
-
},
|
|
349
|
-
subscriptionCommitment
|
|
350
|
-
);
|
|
351
|
-
} catch (err) {
|
|
352
|
-
console.error(
|
|
353
|
-
'confirmTransactionWebSocket: failed to set up onSignature listener',
|
|
354
|
-
err
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
subscriptionIds.push(subscriptionId);
|
|
359
|
-
return confirmPromise;
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
try {
|
|
363
|
-
await this.promiseTimeout(promises, this.timeout);
|
|
364
|
-
} finally {
|
|
365
|
-
for (const [i, subscriptionId] of subscriptionIds.entries()) {
|
|
366
|
-
if (subscriptionId) {
|
|
367
|
-
connections[i].removeSignatureListener(subscriptionId);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (response === null) {
|
|
373
|
-
if (this.confirmationStrategy === ConfirmationStrategy.Combo) {
|
|
374
|
-
try {
|
|
375
|
-
const rpcResponse = await this.connection.getSignatureStatuses([
|
|
376
|
-
signature,
|
|
377
|
-
]);
|
|
378
|
-
|
|
379
|
-
if (rpcResponse?.value?.[0]?.confirmationStatus) {
|
|
380
|
-
response = {
|
|
381
|
-
context: rpcResponse.context,
|
|
382
|
-
value: { err: rpcResponse.value[0].err },
|
|
383
|
-
};
|
|
384
|
-
return response;
|
|
385
|
-
}
|
|
386
|
-
} catch (error) {
|
|
387
|
-
// Ignore error to pass through to timeout error
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
this.timeoutCount += 1;
|
|
391
|
-
const duration = (Date.now() - start) / 1000;
|
|
392
|
-
if (this.throwOnTimeoutError) {
|
|
393
|
-
throw new TxSendError(
|
|
394
|
-
`Transaction was not confirmed in ${duration.toFixed(
|
|
395
|
-
2
|
|
396
|
-
)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`,
|
|
397
|
-
NOT_CONFIRMED_ERROR_CODE
|
|
398
|
-
);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
return response ?? undefined;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Waits for a transaction to confirm by polling `getSignatureStatuses` with exponential
|
|
407
|
-
* backoff, starting at 400ms and capping at 5000ms, until `commitment` is reached or
|
|
408
|
-
* `this.timeout` elapses.
|
|
409
|
-
* @param signature - Base58-encoded transaction signature to confirm.
|
|
410
|
-
* @param commitment - Commitment level to wait for; defaults to `'finalized'`.
|
|
411
|
-
* @returns The confirmation result (`{ err: null }` on success), or `undefined` if it timed out and `throwOnTimeoutError` is `false`.
|
|
412
|
-
* @throws TxSendError (code `NOT_CONFIRMED_ERROR_CODE`) on timeout if `throwOnTimeoutError` is
|
|
413
|
-
* `true` (the default) — in that case the transaction's actual outcome is unknown, not
|
|
414
|
-
* necessarily failed.
|
|
415
|
-
*/
|
|
416
|
-
async confirmTransactionPolling(
|
|
417
|
-
signature: TransactionSignature,
|
|
418
|
-
commitment: Commitment = 'finalized'
|
|
419
|
-
): Promise<RpcResponseAndContext<SignatureResult> | undefined> {
|
|
420
|
-
let totalTime = 0;
|
|
421
|
-
let backoffTime = 400; // approx block time
|
|
422
|
-
const start = Date.now();
|
|
423
|
-
|
|
424
|
-
while (totalTime < this.timeout) {
|
|
425
|
-
await new Promise((resolve) => setTimeout(resolve, backoffTime));
|
|
426
|
-
|
|
427
|
-
const rpcResponse = await this.connection.getSignatureStatuses([
|
|
428
|
-
signature,
|
|
429
|
-
]);
|
|
430
|
-
|
|
431
|
-
const signatureResult = rpcResponse && rpcResponse.value?.[0];
|
|
432
|
-
|
|
433
|
-
// a stronger status satisfies a weaker commitment (processed < confirmed < finalized),
|
|
434
|
-
// e.g. a tx already finalized must not keep a 'confirmed' wait polling until timeout
|
|
435
|
-
const statusRank: Record<string, number> = {
|
|
436
|
-
processed: 0,
|
|
437
|
-
confirmed: 1,
|
|
438
|
-
finalized: 2,
|
|
439
|
-
};
|
|
440
|
-
if (
|
|
441
|
-
rpcResponse &&
|
|
442
|
-
signatureResult &&
|
|
443
|
-
signatureResult.confirmationStatus &&
|
|
444
|
-
statusRank[signatureResult.confirmationStatus] >=
|
|
445
|
-
(statusRank[commitment] ?? 2)
|
|
446
|
-
) {
|
|
447
|
-
return {
|
|
448
|
-
context: rpcResponse.context,
|
|
449
|
-
value: { err: signatureResult.err },
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
totalTime += backoffTime;
|
|
454
|
-
backoffTime = Math.min(backoffTime * 2, 5000);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// Transaction not confirmed within 30 seconds
|
|
458
|
-
this.timeoutCount += 1;
|
|
459
|
-
const duration = (Date.now() - start) / 1000;
|
|
460
|
-
if (this.throwOnTimeoutError) {
|
|
461
|
-
throw new TxSendError(
|
|
462
|
-
`Transaction was not confirmed in ${duration.toFixed(
|
|
463
|
-
2
|
|
464
|
-
)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`,
|
|
465
|
-
NOT_CONFIRMED_ERROR_CODE
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Confirms a transaction using whichever strategy `this.confirmationStrategy` selects:
|
|
472
|
-
* `WebSocket`/`Combo` route to `confirmTransactionWebSocket`, `Polling` to `confirmTransactionPolling`.
|
|
473
|
-
* @param signature - Base58-encoded transaction signature to confirm.
|
|
474
|
-
* @param commitment - Commitment level to wait for.
|
|
475
|
-
* @returns The confirmation result, or `undefined` on timeout if `throwOnTimeoutError` is `false`.
|
|
476
|
-
* @throws TxSendError on timeout if `throwOnTimeoutError` is `true` (see `confirmTransactionWebSocket`/`confirmTransactionPolling`).
|
|
477
|
-
*/
|
|
478
|
-
async confirmTransaction(
|
|
479
|
-
signature: TransactionSignature,
|
|
480
|
-
commitment?: Commitment
|
|
481
|
-
): Promise<RpcResponseAndContext<SignatureResult> | undefined> {
|
|
482
|
-
if (
|
|
483
|
-
this.confirmationStrategy === ConfirmationStrategy.WebSocket ||
|
|
484
|
-
this.confirmationStrategy === ConfirmationStrategy.Combo
|
|
485
|
-
) {
|
|
486
|
-
return await this.confirmTransactionWebSocket(signature, commitment);
|
|
487
|
-
} else if (this.confirmationStrategy === ConfirmationStrategy.Polling) {
|
|
488
|
-
return await this.confirmTransactionPolling(signature, commitment);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/** Current time in milliseconds since epoch (thin wrapper over `Date.now()`, overridable in tests). */
|
|
493
|
-
getTimestamp(): number {
|
|
494
|
-
return new Date().getTime();
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
/**
|
|
498
|
-
* Races an array of promises against a timeout, resolving to `null` (rather than rejecting) if
|
|
499
|
-
* none settle in time. Unlike `../util/promiseTimeout`, this accepts multiple promises (used to
|
|
500
|
-
* race confirmation across `connection` plus every `additionalConnections` entry).
|
|
501
|
-
* @param promises - Promises to race.
|
|
502
|
-
* @param timeoutMs - Timeout in milliseconds.
|
|
503
|
-
* @returns The first promise's resolved value, or `null` if none settled before `timeoutMs`.
|
|
504
|
-
*/
|
|
505
|
-
promiseTimeout<T>(
|
|
506
|
-
promises: Promise<T>[],
|
|
507
|
-
timeoutMs: number
|
|
508
|
-
): Promise<T | null> {
|
|
509
|
-
let timeoutId: ReturnType<typeof setTimeout>;
|
|
510
|
-
const timeoutPromise: Promise<null> = new Promise((resolve) => {
|
|
511
|
-
timeoutId = setTimeout(() => resolve(null), timeoutMs);
|
|
512
|
-
});
|
|
513
|
-
|
|
514
|
-
return Promise.race([...promises, timeoutPromise]).then(
|
|
515
|
-
(result: T | null) => {
|
|
516
|
-
clearTimeout(timeoutId);
|
|
517
|
-
return result;
|
|
518
|
-
}
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* Best-effort broadcasts a raw transaction to every `additionalConnections` entry and invokes
|
|
524
|
-
* `additionalTxSenderCallbacks` with its base58 encoding. Failures are logged, not thrown or
|
|
525
|
-
* awaited by the caller — this never affects whether the primary send/confirm succeeds.
|
|
526
|
-
* @param rawTx - Serialized, signed transaction bytes.
|
|
527
|
-
* @param opts - Options passed through to each connection's `sendRawTransaction`.
|
|
528
|
-
*/
|
|
529
|
-
sendToAdditionalConnections(
|
|
530
|
-
rawTx: Buffer | Uint8Array,
|
|
531
|
-
opts: ConfirmOptions
|
|
532
|
-
): void {
|
|
533
|
-
this.additionalConnections.map((connection) => {
|
|
534
|
-
connection.sendRawTransaction(rawTx, opts).catch((e) => {
|
|
535
|
-
console.error(
|
|
536
|
-
// @ts-ignore
|
|
537
|
-
`error sending tx to additional connection ${connection._rpcEndpoint}`
|
|
538
|
-
);
|
|
539
|
-
console.error(e);
|
|
540
|
-
});
|
|
541
|
-
});
|
|
542
|
-
this.additionalTxSenderCallbacks?.map((callback) => {
|
|
543
|
-
callback(bs58.encode(rawTx));
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/**
|
|
548
|
-
* Adds an extra RPC connection to broadcast future transactions to, unless a connection with
|
|
549
|
-
* the same RPC endpoint is already registered.
|
|
550
|
-
* @param newConnection - Connection to add to `additionalConnections`.
|
|
551
|
-
*/
|
|
552
|
-
public addAdditionalConnection(newConnection: Connection): void {
|
|
553
|
-
const alreadyUsingConnection =
|
|
554
|
-
this.additionalConnections.filter((connection) => {
|
|
555
|
-
// @ts-ignore
|
|
556
|
-
return connection._rpcEndpoint === newConnection.rpcEndpoint;
|
|
557
|
-
}).length > 0;
|
|
558
|
-
|
|
559
|
-
if (!alreadyUsingConnection) {
|
|
560
|
-
this.additionalConnections.push(newConnection);
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/** @returns The number of confirmation attempts that have timed out so far. */
|
|
565
|
-
public getTimeoutCount(): number {
|
|
566
|
-
return this.timeoutCount;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* Inspects a confirmed signature's result and, if it recorded an on-chain error, resolves the
|
|
571
|
-
* detailed program error via `throwTransactionError` and throws it. Note this check runs
|
|
572
|
-
* whenever `result.err` is set, independent of the `throwOnTransactionError` field — callers
|
|
573
|
-
* that want to suppress transaction-error throwing should avoid calling this method rather
|
|
574
|
-
* than rely on that flag here.
|
|
575
|
-
* @param txSig - Transaction signature to look up the detailed error for.
|
|
576
|
-
* @param result - The `SignatureResult` returned by confirmation.
|
|
577
|
-
* @throws Error the resolved on-chain program error, if `result.err` is set.
|
|
578
|
-
*/
|
|
579
|
-
public async checkConfirmationResultForError(
|
|
580
|
-
txSig: string,
|
|
581
|
-
result: SignatureResult
|
|
582
|
-
): Promise<void> {
|
|
583
|
-
if (result?.err) {
|
|
584
|
-
await throwTransactionError(
|
|
585
|
-
txSig,
|
|
586
|
-
this.connection,
|
|
587
|
-
this.opts?.commitment
|
|
588
|
-
);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* Computes the fraction of recently sent transactions (within `lookbackWindowMinutes`) that
|
|
596
|
-
* landed, from `txSigCache`'s current entries. Returns the last computed `txLandRate` (default
|
|
597
|
-
* 0) if `trackTxLandRate` is disabled or the cache is empty, rather than recomputing.
|
|
598
|
-
* @returns The land rate as a fraction between 0 and 1.
|
|
599
|
-
*/
|
|
600
|
-
public getTxLandRate(): number {
|
|
601
|
-
if (!this.trackTxLandRate || !this.txSigCache) {
|
|
602
|
-
return this.txLandRate;
|
|
603
|
-
}
|
|
604
|
-
const keys = this.txSigCache.keys();
|
|
605
|
-
const denominator = keys.length;
|
|
606
|
-
if (denominator === 0) {
|
|
607
|
-
return this.txLandRate;
|
|
608
|
-
}
|
|
609
|
-
let numerator = 0;
|
|
610
|
-
for (const key of keys) {
|
|
611
|
-
const value = this.txSigCache.get(key);
|
|
612
|
-
if (value) {
|
|
613
|
-
numerator += 1;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
this.txLandRate = numerator / denominator;
|
|
617
|
-
return this.txLandRate;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
/**
|
|
621
|
-
* Default `landRateToFeeFunc`: returns `1` (no boost) if the land rate is already at/above
|
|
622
|
-
* `BASELINE_TX_LAND_RATE` (0.9) or fewer than 3 samples have been recorded yet (too little data
|
|
623
|
-
* to react); otherwise returns a multiplier that grows logarithmically as the land rate falls
|
|
624
|
-
* further below baseline, capped at `10`.
|
|
625
|
-
* @param txLandRate - Recent land rate, 0-1 (see `getTxLandRate`).
|
|
626
|
-
* @returns A priority-fee multiplier between 1 and 10.
|
|
627
|
-
*/
|
|
628
|
-
private defaultLandRateToFeeFunc(txLandRate: number) {
|
|
629
|
-
if (
|
|
630
|
-
txLandRate >= BASELINE_TX_LAND_RATE ||
|
|
631
|
-
(this.txSigCache?.keys().length ?? 0) < 3
|
|
632
|
-
) {
|
|
633
|
-
return 1;
|
|
634
|
-
}
|
|
635
|
-
const multiplier =
|
|
636
|
-
10 * Math.log10(1 + (BASELINE_TX_LAND_RATE - txLandRate) * 5);
|
|
637
|
-
return Math.min(multiplier, 10);
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
/**
|
|
641
|
-
* Suggests a multiplier to apply to a base priority fee, based on recent land rate — intended
|
|
642
|
-
* for callers to scale up their compute-unit price when transactions have been landing poorly.
|
|
643
|
-
* @returns `1` (no change) if `trackTxLandRate` is disabled; otherwise `landRateToFeeFunc(getTxLandRate())`.
|
|
644
|
-
*/
|
|
645
|
-
public getSuggestedPriorityFeeMultiplier(): number {
|
|
646
|
-
if (!this.trackTxLandRate) {
|
|
647
|
-
return 1;
|
|
648
|
-
}
|
|
649
|
-
return this.landRateToFeeFunc(this.getTxLandRate());
|
|
650
|
-
}
|
|
651
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BlockhashWithExpiryBlockHeight,
|
|
3
|
-
Commitment,
|
|
4
|
-
Connection,
|
|
5
|
-
} from '@solana/web3.js';
|
|
6
|
-
import { BlockhashFetcher } from './types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Simplest `BlockhashFetcher`: makes a fresh `getLatestBlockhash` RPC call on every request, no
|
|
10
|
-
* caching or retry. Prefer `CachedBlockhashFetcher` for senders issuing many transactions in quick
|
|
11
|
-
* succession to avoid RPC rate limits.
|
|
12
|
-
*/
|
|
13
|
-
export class BaseBlockhashFetcher implements BlockhashFetcher {
|
|
14
|
-
/**
|
|
15
|
-
* @param connection - RPC connection to fetch the blockhash from.
|
|
16
|
-
* @param blockhashCommitment - Commitment level to request the blockhash at.
|
|
17
|
-
*/
|
|
18
|
-
constructor(
|
|
19
|
-
private connection: Connection,
|
|
20
|
-
private blockhashCommitment: Commitment
|
|
21
|
-
) {}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @returns The latest blockhash and its expiry block height, fetched fresh from `connection`.
|
|
25
|
-
*/
|
|
26
|
-
public async getLatestBlockhash(): Promise<
|
|
27
|
-
BlockhashWithExpiryBlockHeight | undefined
|
|
28
|
-
> {
|
|
29
|
-
return this.connection.getLatestBlockhash(this.blockhashCommitment);
|
|
30
|
-
}
|
|
31
|
-
}
|