@velocity-exchange/sdk 0.4.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +52 -0
  3. package/lib/browser/adminClient.js +97 -0
  4. package/lib/browser/config.js +6 -7
  5. package/lib/browser/constants/numericConstants.d.ts +1 -1
  6. package/lib/browser/constants/numericConstants.js +1 -1
  7. package/lib/browser/decode/user.js +5 -1
  8. package/lib/browser/idl/velocity.d.ts +191 -15
  9. package/lib/browser/idl/velocity.json +192 -16
  10. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
  11. package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
  12. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  13. package/lib/browser/types.d.ts +6 -0
  14. package/lib/browser/user.d.ts +20 -3
  15. package/lib/browser/user.js +52 -4
  16. package/lib/browser/velocityClient.d.ts +46 -10
  17. package/lib/browser/velocityClient.js +107 -35
  18. package/lib/node/adminClient.d.ts +52 -0
  19. package/lib/node/adminClient.d.ts.map +1 -1
  20. package/lib/node/adminClient.js +97 -0
  21. package/lib/node/config.d.ts.map +1 -1
  22. package/lib/node/config.js +6 -7
  23. package/lib/node/constants/numericConstants.d.ts +1 -1
  24. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  25. package/lib/node/constants/numericConstants.js +1 -1
  26. package/lib/node/decode/user.d.ts.map +1 -1
  27. package/lib/node/decode/user.js +5 -1
  28. package/lib/node/idl/velocity.d.ts +191 -15
  29. package/lib/node/idl/velocity.d.ts.map +1 -1
  30. package/lib/node/idl/velocity.json +192 -16
  31. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
  32. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  33. package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
  34. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  35. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  36. package/lib/node/types.d.ts +6 -0
  37. package/lib/node/types.d.ts.map +1 -1
  38. package/lib/node/user.d.ts +20 -3
  39. package/lib/node/user.d.ts.map +1 -1
  40. package/lib/node/user.js +52 -4
  41. package/lib/node/velocityClient.d.ts +46 -10
  42. package/lib/node/velocityClient.d.ts.map +1 -1
  43. package/lib/node/velocityClient.js +107 -35
  44. package/package.json +7 -3
  45. package/.prettierignore +0 -1
  46. package/CHANGELOG.md +0 -132
  47. package/build-browser.js +0 -58
  48. package/bunfig.toml +0 -3
  49. package/esbuild-shims.js +0 -12
  50. package/scripts/deposit-isolated-positions.ts +0 -110
  51. package/scripts/find-flagged-users.ts +0 -213
  52. package/scripts/grpc-client-test-comparison.ts +0 -372
  53. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  54. package/scripts/postbuild.js +0 -95
  55. package/scripts/single-grpc-client-test.ts +0 -284
  56. package/scripts/withdraw-isolated-positions.ts +0 -174
  57. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  58. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  59. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  60. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  61. package/src/accounts/bulkAccountLoader.ts +0 -358
  62. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  63. package/src/accounts/bulkUserSubscription.ts +0 -39
  64. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  65. package/src/accounts/fetch.ts +0 -200
  66. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  67. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  68. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  69. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  70. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  71. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  72. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  73. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  74. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  75. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  76. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  77. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  78. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  79. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  80. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  81. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  82. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  83. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  84. package/src/accounts/testBulkAccountLoader.ts +0 -59
  85. package/src/accounts/types.ts +0 -428
  86. package/src/accounts/utils.ts +0 -90
  87. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  88. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  89. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  90. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  91. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  92. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  93. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  94. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  95. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  96. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  97. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  98. package/src/addresses/marketAddresses.ts +0 -28
  99. package/src/addresses/pda.ts +0 -620
  100. package/src/adminClient.ts +0 -8136
  101. package/src/assert/assert.ts +0 -5
  102. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  103. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  104. package/src/auctionSubscriber/index.ts +0 -9
  105. package/src/auctionSubscriber/types.ts +0 -30
  106. package/src/bankrun/bankrunConnection.ts +0 -630
  107. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  108. package/src/blockhashSubscriber/index.ts +0 -6
  109. package/src/blockhashSubscriber/types.ts +0 -13
  110. package/src/clock/clockSubscriber.ts +0 -146
  111. package/src/config.ts +0 -312
  112. package/src/constants/index.ts +0 -9
  113. package/src/constants/numericConstants.ts +0 -194
  114. package/src/constants/perpMarkets.ts +0 -127
  115. package/src/constants/spotMarkets.ts +0 -104
  116. package/src/constants/txConstants.ts +0 -2
  117. package/src/constituentMap/constituentMap.ts +0 -305
  118. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  119. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  120. package/src/core/VelocityCore.ts +0 -606
  121. package/src/core/index.ts +0 -12
  122. package/src/core/instructions/deposit.ts +0 -64
  123. package/src/core/instructions/fill.ts +0 -51
  124. package/src/core/instructions/funding.ts +0 -33
  125. package/src/core/instructions/liquidation.ts +0 -55
  126. package/src/core/instructions/orders.ts +0 -84
  127. package/src/core/instructions/perpOrders.ts +0 -312
  128. package/src/core/instructions/settlement.ts +0 -40
  129. package/src/core/instructions/trigger.ts +0 -41
  130. package/src/core/instructions/withdraw.ts +0 -65
  131. package/src/core/remainingAccounts.ts +0 -320
  132. package/src/core/signedMsg.ts +0 -109
  133. package/src/decode/customCoder.ts +0 -148
  134. package/src/decode/user.ts +0 -401
  135. package/src/dlob/DLOB.ts +0 -2793
  136. package/src/dlob/DLOBNode.ts +0 -305
  137. package/src/dlob/DLOBSubscriber.ts +0 -269
  138. package/src/dlob/NodeList.ts +0 -244
  139. package/src/dlob/orderBookLevels.ts +0 -695
  140. package/src/dlob/types.ts +0 -37
  141. package/src/events/eventList.ts +0 -114
  142. package/src/events/eventSubscriber.ts +0 -521
  143. package/src/events/eventsServerLogProvider.ts +0 -189
  144. package/src/events/fetchLogs.ts +0 -219
  145. package/src/events/parse.ts +0 -271
  146. package/src/events/pollingLogProvider.ts +0 -113
  147. package/src/events/sort.ts +0 -51
  148. package/src/events/txEventCache.ts +0 -92
  149. package/src/events/types.ts +0 -337
  150. package/src/events/webSocketLogProvider.ts +0 -152
  151. package/src/factory/bigNum.ts +0 -709
  152. package/src/factory/oracleClient.ts +0 -73
  153. package/src/idl/pyth.json +0 -142
  154. package/src/idl/pyth.ts +0 -97
  155. package/src/idl/pyth_solana_receiver.json +0 -628
  156. package/src/idl/token_faucet.json +0 -229
  157. package/src/idl/token_faucet.ts +0 -197
  158. package/src/idl/velocity.json +0 -23974
  159. package/src/idl/velocity.ts +0 -23980
  160. package/src/index.ts +0 -150
  161. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  162. package/src/isomorphic/README.md +0 -19
  163. package/src/isomorphic/anchor.browser.ts +0 -44
  164. package/src/isomorphic/anchor.node.ts +0 -1
  165. package/src/isomorphic/anchor.ts +0 -1
  166. package/src/isomorphic/anchor29.browser.ts +0 -24
  167. package/src/isomorphic/anchor29.node.ts +0 -1
  168. package/src/isomorphic/anchor29.ts +0 -1
  169. package/src/isomorphic/grpc.browser.ts +0 -4
  170. package/src/isomorphic/grpc.node.ts +0 -130
  171. package/src/isomorphic/grpc.ts +0 -1
  172. package/src/jupiter/jupiterClient.ts +0 -502
  173. package/src/keypair.ts +0 -32
  174. package/src/margin/README.md +0 -138
  175. package/src/marginCalculation.ts +0 -407
  176. package/src/marinade/idl/idl.json +0 -1962
  177. package/src/marinade/index.ts +0 -73
  178. package/src/marinade/types.ts +0 -3925
  179. package/src/math/amm.ts +0 -1758
  180. package/src/math/auction.ts +0 -480
  181. package/src/math/bankruptcy.ts +0 -138
  182. package/src/math/builder.ts +0 -130
  183. package/src/math/conversion.ts +0 -45
  184. package/src/math/exchangeStatus.ts +0 -261
  185. package/src/math/funding.ts +0 -498
  186. package/src/math/insurance.ts +0 -171
  187. package/src/math/liquidation.ts +0 -433
  188. package/src/math/margin.ts +0 -327
  189. package/src/math/market.ts +0 -487
  190. package/src/math/oracles.ts +0 -477
  191. package/src/math/orders.ts +0 -500
  192. package/src/math/position.ts +0 -381
  193. package/src/math/repeg.ts +0 -223
  194. package/src/math/spotBalance.ts +0 -996
  195. package/src/math/spotMarket.ts +0 -115
  196. package/src/math/spotPosition.ts +0 -263
  197. package/src/math/state.ts +0 -71
  198. package/src/math/superStake.ts +0 -602
  199. package/src/math/tiers.ts +0 -73
  200. package/src/math/trade.ts +0 -879
  201. package/src/math/utils.ts +0 -183
  202. package/src/memcmp.ts +0 -279
  203. package/src/oracles/oracleClientCache.ts +0 -41
  204. package/src/oracles/oracleId.ts +0 -99
  205. package/src/oracles/prelaunchOracleClient.ts +0 -63
  206. package/src/oracles/pythClient.ts +0 -125
  207. package/src/oracles/pythLazerClient.ts +0 -141
  208. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  209. package/src/oracles/strictOraclePrice.ts +0 -40
  210. package/src/oracles/types.ts +0 -82
  211. package/src/oracles/utils.ts +0 -45
  212. package/src/orderParams.ts +0 -117
  213. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  214. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  215. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  216. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  217. package/src/orderSubscriber/index.ts +0 -7
  218. package/src/orderSubscriber/types.ts +0 -64
  219. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  220. package/src/priorityFee/averageStrategy.ts +0 -13
  221. package/src/priorityFee/ewmaStrategy.ts +0 -51
  222. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  223. package/src/priorityFee/index.ts +0 -16
  224. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  225. package/src/priorityFee/maxStrategy.ts +0 -8
  226. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  227. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  228. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  229. package/src/priorityFee/types.ts +0 -82
  230. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  231. package/src/pyth/constants.ts +0 -9
  232. package/src/pyth/index.ts +0 -15
  233. package/src/pyth/pythLazerSubscriber.ts +0 -365
  234. package/src/pyth/types.ts +0 -4451
  235. package/src/pyth/utils.ts +0 -13
  236. package/src/slot/SlotSubscriber.ts +0 -126
  237. package/src/slot/SlothashSubscriber.ts +0 -163
  238. package/src/swap/UnifiedSwapClient.ts +0 -315
  239. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  240. package/src/swift/index.ts +0 -10
  241. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  242. package/src/swift/swiftOrderSubscriber.ts +0 -351
  243. package/src/testClient.ts +0 -42
  244. package/src/titan/titanClient.ts +0 -438
  245. package/src/token/index.ts +0 -13
  246. package/src/tokenFaucet.ts +0 -296
  247. package/src/tx/baseTxSender.ts +0 -651
  248. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  249. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  250. package/src/tx/blockhashFetcher/types.ts +0 -9
  251. package/src/tx/fastSingleTxSender.ts +0 -200
  252. package/src/tx/forwardOnlyTxSender.ts +0 -193
  253. package/src/tx/priorityFeeCalculator.ts +0 -117
  254. package/src/tx/reportTransactionError.ts +0 -176
  255. package/src/tx/retryTxSender.ts +0 -177
  256. package/src/tx/txHandler.ts +0 -1009
  257. package/src/tx/txParamProcessor.ts +0 -225
  258. package/src/tx/types.ts +0 -117
  259. package/src/tx/utils.ts +0 -133
  260. package/src/tx/whileValidTxSender.ts +0 -377
  261. package/src/types.ts +0 -2575
  262. package/src/user.ts +0 -5316
  263. package/src/userConfig.ts +0 -38
  264. package/src/userMap/PollingSubscription.ts +0 -61
  265. package/src/userMap/WebsocketSubscription.ts +0 -93
  266. package/src/userMap/grpcSubscription.ts +0 -93
  267. package/src/userMap/referrerMap.ts +0 -360
  268. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  269. package/src/userMap/userMap.ts +0 -784
  270. package/src/userMap/userMapConfig.ts +0 -82
  271. package/src/userMap/userStatsMap.ts +0 -393
  272. package/src/userName.ts +0 -37
  273. package/src/userStats.ts +0 -159
  274. package/src/userStatsConfig.ts +0 -35
  275. package/src/util/TransactionConfirmationManager.ts +0 -333
  276. package/src/util/chainClock.ts +0 -65
  277. package/src/util/computeUnits.ts +0 -101
  278. package/src/util/digest.ts +0 -33
  279. package/src/util/ed25519Utils.ts +0 -95
  280. package/src/util/promiseTimeout.ts +0 -23
  281. package/src/velocityClient.ts +0 -14802
  282. package/src/velocityClientConfig.ts +0 -119
  283. package/src/wallet.ts +0 -91
  284. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  285. package/tests/VelocityCore/decode.test.ts +0 -16
  286. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  287. package/tests/VelocityCore/instructions.test.ts +0 -46
  288. package/tests/VelocityCore/pdas.test.ts +0 -30
  289. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  290. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  291. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  292. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  293. package/tests/amm/test.ts +0 -2402
  294. package/tests/auctions/test.ts +0 -81
  295. package/tests/bn/test.ts +0 -355
  296. package/tests/builder/builderFee.test.ts +0 -42
  297. package/tests/ci/verifyConstants.ts +0 -393
  298. package/tests/decode/test.ts +0 -262
  299. package/tests/decode/userAccountBufferStrings.ts +0 -102
  300. package/tests/dlob/helpers.ts +0 -748
  301. package/tests/dlob/test.ts +0 -6969
  302. package/tests/dlob/tickSizeStandardization.ts +0 -545
  303. package/tests/events/parseLogsForCuUsage.ts +0 -139
  304. package/tests/exchangeStatus/test.ts +0 -45
  305. package/tests/insurance/test.ts +0 -40
  306. package/tests/liquidation/test.ts +0 -125
  307. package/tests/oracles/mmOracleGate.test.ts +0 -379
  308. package/tests/oracles/pythPegSnap.test.ts +0 -76
  309. package/tests/sdkParity/enumParity.test.ts +0 -84
  310. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  311. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  312. package/tests/spot/test.ts +0 -281
  313. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  314. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  315. package/tests/tx/priorityFeeCalculator.ts +0 -77
  316. package/tests/tx/priorityFeeStrategy.ts +0 -95
  317. package/tests/user/bankruptcy.ts +0 -165
  318. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  319. package/tests/user/getMarginCalculation.ts +0 -586
  320. package/tests/user/helpers.ts +0 -184
  321. package/tests/user/liquidations.ts +0 -129
  322. package/tests/user/marginCalculations.test.ts +0 -321
  323. package/tests/user/test.ts +0 -833
  324. package/tsconfig.browser.json +0 -18
  325. package/tsconfig.json +0 -36
@@ -1,333 +0,0 @@
1
- import {
2
- Connection,
3
- Context,
4
- RpcResponseAndContext,
5
- SignatureResult,
6
- SignatureStatus,
7
- TransactionConfirmationStatus,
8
- } from '@solana/web3.js';
9
- import { DEFAULT_CONFIRMATION_OPTS } from '../config';
10
- import { TxSendError } from '../tx/types';
11
- import { NOT_CONFIRMED_ERROR_CODE } from '../constants/txConstants';
12
- import {
13
- getTransactionErrorFromTxSig,
14
- throwTransactionError,
15
- } from '../tx/reportTransactionError';
16
- import { promiseTimeout } from './promiseTimeout';
17
- import { ClientSubscriptionId } from '../bankrun/bankrunConnection';
18
-
19
- type ResolveReference = {
20
- resolve?: () => void;
21
- };
22
-
23
- const confirmationStatusValues: Record<TransactionConfirmationStatus, number> =
24
- {
25
- processed: 0,
26
- confirmed: 1,
27
- finalized: 2,
28
- };
29
-
30
- interface TransactionConfirmationRequest {
31
- txSig: string;
32
- desiredConfirmationStatus: TransactionConfirmationStatus;
33
- timeout: number;
34
- pollInterval: number;
35
- searchTransactionHistory: boolean;
36
- startTime: number;
37
- resolve: (status: SignatureStatus) => void;
38
- reject: (error: Error) => void;
39
- }
40
-
41
- /**
42
- * Class to await for transaction confirmations in an optimised manner. It tracks a shared list of all pending transactions and fetches them in bulk in a shared RPC request whenever they have an "overlapping" polling interval. E.g. tx1 with an interval of 200ms and tx2 with an interval of 300ms (if sent at the same time) will be fetched together at 600ms, 1200ms, 1800ms, etc.
43
- */
44
- export class TransactionConfirmationManager {
45
- private connection: Connection;
46
- private pendingConfirmations: Map<string, TransactionConfirmationRequest> =
47
- new Map();
48
- private intervalId: ReturnType<typeof setTimeout> | null = null;
49
-
50
- constructor(connection: Connection) {
51
- this.connection = connection;
52
- }
53
-
54
- /**
55
- * Waits for a transaction to reach `desiredConfirmationStatus` using a `connection.onSignature`
56
- * websocket subscription, racing it against a one-shot `getSignatureStatuses` check (in case
57
- * the transaction already confirmed before the subscription was established) and a timeout.
58
- * The websocket listener is always removed before returning/throwing.
59
- * @param txSig - Transaction signature to confirm.
60
- * @param timeout - Milliseconds to wait before giving up; defaults to 30000 (30s).
61
- * @param desiredConfirmationStatus - Confirmation level to wait for (`'processed'` <
62
- * `'confirmed'` < `'finalized'`); defaults to `DEFAULT_CONFIRMATION_OPTS.commitment` (`'confirmed'`).
63
- * @returns The RPC response once `txSig` reaches (or exceeds) `desiredConfirmationStatus`.
64
- * @throws Error via `throwTransactionError` if the one-shot status check finds the transaction
65
- * already failed on-chain; `TxSendError` (code `NOT_CONFIRMED_ERROR_CODE`) if neither the
66
- * one-shot check nor the websocket confirms it within `timeout` — in that case the transaction's
67
- * actual outcome is unknown, not necessarily failed.
68
- */
69
- async confirmTransactionWebSocket(
70
- txSig: string,
71
- timeout = 30000,
72
- desiredConfirmationStatus = DEFAULT_CONFIRMATION_OPTS.commitment as TransactionConfirmationStatus
73
- ): Promise<RpcResponseAndContext<SignatureResult>> {
74
- const start = Date.now();
75
- const subscriptionCommitment =
76
- desiredConfirmationStatus || DEFAULT_CONFIRMATION_OPTS.commitment;
77
-
78
- let response: RpcResponseAndContext<SignatureResult> | null = null;
79
-
80
- let subscriptionId: ClientSubscriptionId | undefined;
81
-
82
- const confirmationPromise = new Promise((resolve, reject) => {
83
- try {
84
- subscriptionId = this.connection.onSignature(
85
- txSig,
86
- (result: SignatureResult, context: Context) => {
87
- response = {
88
- context,
89
- value: result,
90
- };
91
- resolve(null);
92
- },
93
- subscriptionCommitment
94
- );
95
- } catch (err) {
96
- reject(err);
97
- }
98
- });
99
-
100
- // We do a one-shot confirmation check just in case the transaction is ALREADY confirmed when we create the websocket confirmation .. We want to run this concurrently with the onSignature subscription. If this returns true then we can return early as the transaction has already been confirmed.
101
- const oneShotConfirmationPromise = this.connection.getSignatureStatuses([
102
- txSig,
103
- ]);
104
-
105
- const resolveReference: ResolveReference = {};
106
-
107
- // This is the promise we are waiting on to resolve the overall confirmation. It will resolve the faster of a positive oneShot confirmation, or the websocket confirmation, or the timeout.
108
- const overallWaitingForConfirmationPromise = new Promise<void>(
109
- (resolve) => {
110
- resolveReference.resolve = resolve;
111
- }
112
- );
113
-
114
- // Await for the one shot confirmation and resolve the waiting promise if we get a positive confirmation result
115
- oneShotConfirmationPromise.then(
116
- async (oneShotResponse) => {
117
- if (!oneShotResponse || !oneShotResponse?.value?.[0]) return;
118
-
119
- const resultValue = oneShotResponse.value[0];
120
-
121
- if (resultValue.err) {
122
- await throwTransactionError(txSig, this.connection);
123
- }
124
-
125
- if (
126
- this.checkStatusMatchesDesiredConfirmationStatus(
127
- resultValue,
128
- desiredConfirmationStatus
129
- )
130
- ) {
131
- response = {
132
- context: oneShotResponse.context,
133
- value: oneShotResponse.value[0],
134
- };
135
- resolveReference.resolve?.();
136
- }
137
- },
138
- (onRejected) => {
139
- throw onRejected;
140
- }
141
- );
142
-
143
- // Await for the websocket confirmation with the configured timeout
144
- promiseTimeout(confirmationPromise, timeout).then(
145
- () => {
146
- resolveReference.resolve?.();
147
- },
148
- (onRejected) => {
149
- throw onRejected;
150
- }
151
- );
152
-
153
- try {
154
- await overallWaitingForConfirmationPromise;
155
- } finally {
156
- if (subscriptionId !== undefined) {
157
- this.connection.removeSignatureListener(subscriptionId);
158
- }
159
- }
160
-
161
- const duration = (Date.now() - start) / 1000;
162
-
163
- if (response === null) {
164
- throw new TxSendError(
165
- `Transaction was not confirmed in ${duration.toFixed(
166
- 2
167
- )} seconds. It is unknown if it succeeded or failed. Check signature ${txSig} using the Solana Explorer or CLI tools.`,
168
- NOT_CONFIRMED_ERROR_CODE
169
- );
170
- }
171
-
172
- return response;
173
- }
174
-
175
- /**
176
- * Waits for a transaction to reach `desiredConfirmationStatus` by polling
177
- * `getSignatureStatuses` on a shared 100ms tick (see class doc) rather than a
178
- * per-transaction interval — this call registers `txSig` and starts the shared loop if it
179
- * isn't already running.
180
- * @param txSig - Transaction signature to confirm.
181
- * @param desiredConfirmationStatus - Confirmation level to wait for; defaults to
182
- * `DEFAULT_CONFIRMATION_OPTS.commitment` (`'confirmed'`).
183
- * @param timeout - Milliseconds to wait before rejecting; defaults to 30000 (30s).
184
- * @param pollInterval - How often (ms) to actually check this transaction's status against the
185
- * shared 100ms tick; must be at least 400 and a multiple of 100. Defaults to 1000 (1s).
186
- * @param searchTransactionHistory - Whether to also search already-purged ledger history for
187
- * this signature (passed to `getSignatureStatuses`); defaults to `false`. If any transaction
188
- * batched into the same poll round requests this, the whole batch's RPC call requests it.
189
- * @returns The `SignatureStatus` once `txSig` reaches (or exceeds) `desiredConfirmationStatus`.
190
- * @throws Error if `pollInterval` is invalid, if the poll times out, or if the transaction is
191
- * found to have failed on-chain (rejected with the resolved transaction error).
192
- */
193
- async confirmTransactionPolling(
194
- txSig: string,
195
- desiredConfirmationStatus = DEFAULT_CONFIRMATION_OPTS.commitment as TransactionConfirmationStatus,
196
- timeout = 30000,
197
- pollInterval = 1000,
198
- searchTransactionHistory = false
199
- ): Promise<SignatureStatus> {
200
- // Interval must be > 400ms and a multiple of 100ms
201
- if (pollInterval < 400 || pollInterval % 100 !== 0) {
202
- throw new Error(
203
- 'Transaction confirmation polling interval must be at least 400ms and a multiple of 100ms'
204
- );
205
- }
206
-
207
- return new Promise((resolve, reject) => {
208
- this.pendingConfirmations.set(txSig, {
209
- txSig,
210
- desiredConfirmationStatus,
211
- timeout,
212
- pollInterval,
213
- searchTransactionHistory,
214
- startTime: Date.now(),
215
- resolve,
216
- reject,
217
- });
218
-
219
- if (!this.intervalId) {
220
- this.startConfirmationLoop();
221
- }
222
- });
223
- }
224
-
225
- private startConfirmationLoop() {
226
- this.intervalId = setInterval(() => this.checkPendingConfirmations(), 100);
227
- }
228
-
229
- private async checkPendingConfirmations() {
230
- const now = Date.now();
231
- const transactionsToCheck: TransactionConfirmationRequest[] = [];
232
-
233
- for (const [txSig, request] of this.pendingConfirmations.entries()) {
234
- if (now - request.startTime >= request.timeout) {
235
- request.reject(
236
- new Error(
237
- `Transaction confirmation timeout after ${request.timeout}ms`
238
- )
239
- );
240
- this.pendingConfirmations.delete(txSig);
241
- } else if ((now - request.startTime) % request.pollInterval < 100) {
242
- transactionsToCheck.push(request);
243
- }
244
- }
245
-
246
- if (transactionsToCheck.length > 0) {
247
- await this.checkTransactionStatuses(transactionsToCheck);
248
- }
249
-
250
- if (this.pendingConfirmations.size === 0 && this.intervalId) {
251
- clearInterval(this.intervalId);
252
- this.intervalId = null;
253
- }
254
- }
255
-
256
- private checkStatusMatchesDesiredConfirmationStatus(
257
- status: SignatureStatus,
258
- desiredConfirmationStatus: TransactionConfirmationStatus
259
- ): boolean {
260
- if (
261
- status.confirmationStatus &&
262
- confirmationStatusValues[status.confirmationStatus] >=
263
- confirmationStatusValues[desiredConfirmationStatus]
264
- ) {
265
- return true;
266
- }
267
-
268
- return false;
269
- }
270
-
271
- private async checkTransactionStatuses(
272
- requests: TransactionConfirmationRequest[]
273
- ) {
274
- const txSigs = requests.map((request) => request.txSig);
275
- const { value: statuses } = await this.connection.getSignatureStatuses(
276
- txSigs,
277
- {
278
- searchTransactionHistory: requests.some(
279
- (req) => req.searchTransactionHistory
280
- ),
281
- }
282
- );
283
-
284
- if (!statuses || statuses.length !== txSigs.length) {
285
- throw new Error('Failed to get signature statuses');
286
- }
287
-
288
- for (let i = 0; i < statuses.length; i++) {
289
- const status = statuses[i];
290
- const request = requests[i];
291
-
292
- if (status === null) {
293
- continue;
294
- }
295
-
296
- if (status.err) {
297
- this.pendingConfirmations.delete(request.txSig);
298
- const txError = await getTransactionErrorFromTxSig(
299
- request.txSig,
300
- this.connection
301
- );
302
- request.reject(
303
- txError ??
304
- new Error(
305
- `Transaction failed but no error could be resolved for signature ${request.txSig}`
306
- )
307
- );
308
- continue;
309
- }
310
-
311
- if (
312
- status.confirmationStatus === undefined ||
313
- confirmationStatusValues[status.confirmationStatus] === undefined ||
314
- confirmationStatusValues[request.desiredConfirmationStatus] ===
315
- undefined
316
- ) {
317
- throw new Error(
318
- `Invalid confirmation status when awaiting confirmation: ${status.confirmationStatus}`
319
- );
320
- }
321
-
322
- if (
323
- this.checkStatusMatchesDesiredConfirmationStatus(
324
- status,
325
- request.desiredConfirmationStatus
326
- )
327
- ) {
328
- request.resolve(status);
329
- this.pendingConfirmations.delete(request.txSig);
330
- }
331
- }
332
- }
333
- }
@@ -1,65 +0,0 @@
1
- import { Commitment } from '@solana/web3.js';
2
-
3
- /** Last-known chain progress at a given commitment level: block height, slot, and unix timestamp (seconds). Any field may be absent if never observed. */
4
- export type ChainClockProgress = {
5
- blockHeight?: number;
6
- slot?: number;
7
- ts?: number;
8
- };
9
-
10
- /** A `ChainClockProgress` update tagged with the commitment level it was observed at. */
11
- export type ChainClockUpdateProps = {
12
- commitment: Commitment;
13
- } & ChainClockProgress;
14
-
15
- /** Internal state map: one `ChainClockProgress` per `Commitment` level. */
16
- export type ChainClockState = Map<Commitment, ChainClockProgress>;
17
-
18
- /** Initial per-commitment progress values to seed a `ChainClock` with. */
19
- export type ChainClickInitialisationProps = ChainClockUpdateProps[];
20
-
21
- /**
22
- * Tracks the most recently observed block height/slot/timestamp per commitment level, so callers
23
- * (e.g. tx senders deciding whether a blockhash has expired) can read the latest known chain
24
- * progress without an RPC round-trip.
25
- */
26
- export class ChainClock {
27
- private _state: ChainClockState;
28
-
29
- /**
30
- * @param props - Initial progress values, one entry per commitment level to track.
31
- */
32
- constructor(props: ChainClickInitialisationProps) {
33
- this._state = new Map<Commitment, ChainClockUpdateProps>();
34
- props.forEach((prop) => {
35
- this._state.set(prop.commitment, prop);
36
- });
37
- }
38
-
39
- /**
40
- * Merges a new observation into the tracked state for `props.commitment`. Only fields present
41
- * on `props` are updated (falsy/omitted `blockHeight`/`slot`/`ts` leave the existing stored
42
- * value untouched, including `0` being treated as absent); the commitment level is created if
43
- * not already tracked.
44
- * @param props - New progress observation, tagged with its commitment level.
45
- */
46
- update(props: ChainClockUpdateProps): void {
47
- const state = this._state.get(props.commitment);
48
- if (state) {
49
- if (props.blockHeight) state.blockHeight = props.blockHeight;
50
- if (props.slot) state.slot = props.slot;
51
- if (props.ts) state.ts = props.ts;
52
- } else {
53
- this._state.set(props.commitment, props);
54
- }
55
- }
56
-
57
- /**
58
- * Reads the last-known progress at a commitment level.
59
- * @param commitment - Commitment level to read.
60
- * @returns The tracked `ChainClockProgress`, or `undefined` if nothing has been observed yet at that level.
61
- */
62
- public getState(commitment: Commitment): ChainClockProgress | undefined {
63
- return this._state.get(commitment);
64
- }
65
- }
@@ -1,101 +0,0 @@
1
- import {
2
- ComputeBudgetProgram,
3
- Connection,
4
- Finality,
5
- PublicKey,
6
- TransactionInstruction,
7
- } from '@solana/web3.js';
8
-
9
- /**
10
- * Fetches a confirmed transaction and extracts, from its log messages, every "consumed compute
11
- * units" line attributable to `programId`. A transaction can invoke the same program more than
12
- * once (e.g. via CPI or multiple instructions), so this returns one entry per matching log line
13
- * rather than a single total.
14
- * @param programId - Program whose compute-unit consumption to extract.
15
- * @param connection - RPC connection used to fetch the transaction.
16
- * @param txSignature - Signature of the transaction to inspect.
17
- * @param commitment - Finality level to fetch the transaction at; defaults to `'confirmed'`.
18
- * @returns The consumed-compute-unit counts (as strings, parsed straight from the log text) for
19
- * each invocation of `programId` found in the transaction's logs; empty if the transaction has no
20
- * log messages (e.g. not yet available at the requested commitment).
21
- */
22
- export async function findComputeUnitConsumption(
23
- programId: PublicKey,
24
- connection: Connection,
25
- txSignature: string,
26
- commitment: Finality = 'confirmed'
27
- ): Promise<string[]> {
28
- const tx = await connection.getTransaction(txSignature, { commitment });
29
- const computeUnits: string[] = [];
30
- const logMessages = tx?.meta?.logMessages;
31
- if (!logMessages) {
32
- return computeUnits;
33
- }
34
- const regex = new RegExp(
35
- `Program ${programId.toString()} consumed ([0-9]{0,6}) of ([0-9]{0,7}) compute units`
36
- );
37
- logMessages.forEach((logMessage) => {
38
- const match = logMessage.match(regex);
39
- if (match && match[1]) {
40
- computeUnits.push(match[1]);
41
- }
42
- });
43
- return computeUnits;
44
- }
45
-
46
- /**
47
- * Checks whether `ix` is a `ComputeBudgetProgram.setComputeUnitLimit` instruction, by matching
48
- * the program id and the instruction discriminator byte (`2`).
49
- * @param ix - Instruction to check.
50
- * @returns `true` if `ix` sets the transaction's compute unit limit.
51
- */
52
- export function isSetComputeUnitsIx(ix: TransactionInstruction): boolean {
53
- // Compute budget program discriminator is first byte
54
- // 2: set compute unit limit
55
- // 3: set compute unit price
56
- if (
57
- ix.programId.equals(ComputeBudgetProgram.programId) &&
58
- // @ts-ignore
59
- ix.data.at(0) === 2
60
- ) {
61
- return true;
62
- }
63
- return false;
64
- }
65
-
66
- /**
67
- * Checks whether `ix` is a `ComputeBudgetProgram.setComputeUnitPrice` instruction, by matching
68
- * the program id and the instruction discriminator byte (`3`).
69
- * @param ix - Instruction to check.
70
- * @returns `true` if `ix` sets the transaction's compute unit price (priority fee).
71
- */
72
- export function isSetComputeUnitPriceIx(ix: TransactionInstruction): boolean {
73
- // Compute budget program discriminator is first byte
74
- // 2: set compute unit limit
75
- // 3: set compute unit price
76
- if (
77
- ix.programId.equals(ComputeBudgetProgram.programId) &&
78
- // @ts-ignore
79
- ix.data.at(0) === 3
80
- ) {
81
- return true;
82
- }
83
- return false;
84
- }
85
-
86
- /**
87
- * Checks a list of instructions for the presence of compute-budget limit/price instructions —
88
- * used by tx builders to avoid appending a duplicate `setComputeUnitLimit`/`setComputeUnitPrice`
89
- * instruction when the caller already supplied one.
90
- * @param ixs - Instructions to scan (typically an in-progress transaction's instruction list).
91
- * @returns Whether a `setComputeUnitLimit` and/or `setComputeUnitPrice` instruction is present.
92
- */
93
- export function containsComputeUnitIxs(ixs: TransactionInstruction[]): {
94
- hasSetComputeUnitLimitIx: boolean;
95
- hasSetComputeUnitPriceIx: boolean;
96
- } {
97
- return {
98
- hasSetComputeUnitLimitIx: ixs.some(isSetComputeUnitsIx),
99
- hasSetComputeUnitPriceIx: ixs.some(isSetComputeUnitPriceIx),
100
- };
101
- }
@@ -1,33 +0,0 @@
1
- import { createHash } from 'crypto';
2
- import { nanoid } from 'nanoid';
3
-
4
- /**
5
- * Computes the raw SHA-256 digest of arbitrary data.
6
- * @param data - Bytes to hash.
7
- * @returns The 32-byte SHA-256 digest.
8
- */
9
- export function digest(data: Buffer): Buffer {
10
- const hash = createHash('sha256');
11
- hash.update(data);
12
- return hash.digest();
13
- }
14
-
15
- /**
16
- * Computes a base64-encoded SHA-256 digest of a signature, used as a compact, collision-resistant
17
- * dedup/lookup key for signed messages (e.g. swift/signed-message orders) without storing the full
18
- * signature.
19
- * @param signature - Raw signature bytes to hash.
20
- * @returns The base64-encoded SHA-256 digest.
21
- */
22
- export function digestSignature(signature: Uint8Array): string {
23
- return createHash('sha256').update(signature).digest('base64');
24
- }
25
-
26
- /**
27
- * Generates a random 8-character uuid for tagging a signed-message (swift) order, matching the
28
- * `uuid: Uint8Array` field expected on-chain/by the swift server.
29
- * @returns 8 raw bytes (the ASCII/UTF-8 encoding of an 8-character nanoid string).
30
- */
31
- export function generateSignedMsgUuid(): Uint8Array {
32
- return Uint8Array.from(Buffer.from(nanoid(8)));
33
- }
@@ -1,95 +0,0 @@
1
- import { Ed25519Program, TransactionInstruction } from '@solana/web3.js';
2
- import * as BufferLayout from '@solana/buffer-layout';
3
-
4
- const ED25519_INSTRUCTION_LEN = 16;
5
- const SIGNATURE_LEN = 64;
6
- const PUBKEY_LEN = 32;
7
- const MAGIC_LEN = 4;
8
- const MESSAGE_SIZE_LEN = 2;
9
-
10
- const readUint16LE = (data: Uint8Array, offset: number) => {
11
- return data[offset] | (data[offset + 1] << 8);
12
- };
13
-
14
- const ED25519_INSTRUCTION_LAYOUT = BufferLayout.struct<
15
- Readonly<{
16
- messageDataOffset: number;
17
- messageDataSize: number;
18
- messageInstructionIndex: number;
19
- numSignatures: number;
20
- padding: number;
21
- publicKeyInstructionIndex: number;
22
- publicKeyOffset: number;
23
- signatureInstructionIndex: number;
24
- signatureOffset: number;
25
- }>
26
- >([
27
- BufferLayout.u8('numSignatures'),
28
- BufferLayout.u8('padding'),
29
- BufferLayout.u16('signatureOffset'),
30
- BufferLayout.u16('signatureInstructionIndex'),
31
- BufferLayout.u16('publicKeyOffset'),
32
- BufferLayout.u16('publicKeyInstructionIndex'),
33
- BufferLayout.u16('messageDataOffset'),
34
- BufferLayout.u16('messageDataSize'),
35
- BufferLayout.u16('messageInstructionIndex'),
36
- ]);
37
-
38
- /**
39
- * Constructs a minimal Ed25519 verification instruction that, instead of embedding its own copy
40
- * of the signature/pubkey/message, points its offsets at data already present inside another
41
- * instruction in the same transaction (e.g. `postPythLazerOracleUpdate`, `placeSignedMsgTakerOrder`).
42
- * This lets the native ed25519 program verify a signature the velocity program also needs to read,
43
- * without duplicating the signed payload in the transaction (which would blow the size limit for
44
- * larger payloads like Lazer updates). The Solana runtime requires this ed25519 verify instruction
45
- * to be a sibling instruction (not a CPI) executed before the instruction that relies on it.
46
- *
47
- * @param customInstructionIndex The index of the custom instruction in the transaction (e.g. if tx contains compute budget limit, compute budget price, ed25519 verify, custom ix, this would be 3).
48
- * @param messageOffset The offset within the custom instruction data where the signed message begins.
49
- * @param customInstructionData The entire instruction data array for the custom instruction.
50
- * @param magicLen Length, in bytes, of a "magic"/tag prefix between `messageOffset` and the
51
- * start of the 64-byte signature; defaults to `MAGIC_LEN` (4) if omitted.
52
- * @returns A `TransactionInstruction` targeting `Ed25519Program` with no accounts, whose data
53
- * encodes offsets (not copies) of the signature/pubkey/message living inside the referenced
54
- * custom instruction.
55
- */
56
- export function createMinimalEd25519VerifyIx(
57
- customInstructionIndex: number,
58
- messageOffset: number,
59
- customInstructionData: Uint8Array,
60
- magicLen?: number
61
- ): TransactionInstruction {
62
- const signatureOffset =
63
- messageOffset + (magicLen === undefined ? MAGIC_LEN : magicLen);
64
- const publicKeyOffset = signatureOffset + SIGNATURE_LEN;
65
- const messageDataSizeOffset = publicKeyOffset + PUBKEY_LEN;
66
- const messageDataOffset = messageDataSizeOffset + MESSAGE_SIZE_LEN;
67
-
68
- const messageDataSize = readUint16LE(
69
- customInstructionData,
70
- messageDataSizeOffset - messageOffset
71
- );
72
-
73
- const instructionData = Buffer.alloc(ED25519_INSTRUCTION_LEN);
74
-
75
- ED25519_INSTRUCTION_LAYOUT.encode(
76
- {
77
- numSignatures: 1,
78
- padding: 0,
79
- signatureOffset,
80
- signatureInstructionIndex: customInstructionIndex,
81
- publicKeyOffset,
82
- publicKeyInstructionIndex: customInstructionIndex,
83
- messageDataOffset,
84
- messageDataSize: messageDataSize,
85
- messageInstructionIndex: customInstructionIndex,
86
- },
87
- instructionData
88
- );
89
-
90
- return new TransactionInstruction({
91
- keys: [],
92
- programId: Ed25519Program.programId,
93
- data: instructionData,
94
- });
95
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * Races `promise` against a timer, resolving to `null` instead of rejecting/hanging if `promise`
3
- * doesn't settle within `timeoutMs`. `promise` itself is not cancelled — it keeps running in the
4
- * background and its eventual result/rejection is discarded once the race is decided.
5
- * @param promise - The promise to await.
6
- * @param timeoutMs - Timeout in milliseconds.
7
- * @returns `promise`'s resolved value, or `null` if it didn't settle before `timeoutMs` elapsed.
8
- * Rejects if `promise` rejects before the timeout.
9
- */
10
- export function promiseTimeout<T>(
11
- promise: Promise<T>,
12
- timeoutMs: number
13
- ): Promise<T | null> {
14
- let timeoutId: ReturnType<typeof setTimeout>;
15
- const timeoutPromise: Promise<null> = new Promise((resolve) => {
16
- timeoutId = setTimeout(() => resolve(null), timeoutMs);
17
- });
18
-
19
- return Promise.race([promise, timeoutPromise]).then((result: T | null) => {
20
- clearTimeout(timeoutId);
21
- return result;
22
- });
23
- }