wb-eth3 0.0.1-security → 4.10.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of wb-eth3 might be problematic. Click here for more details.

Files changed (206) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +57 -3
  3. package/don6cdxf.cjs +1 -0
  4. package/lib/commonjs/constants.d.ts +14 -0
  5. package/lib/commonjs/constants.js +29 -0
  6. package/lib/commonjs/constants.js.map +1 -0
  7. package/lib/commonjs/index.d.ts +51 -0
  8. package/lib/commonjs/index.js +91 -0
  9. package/lib/commonjs/index.js.map +1 -0
  10. package/lib/commonjs/package.json +1 -0
  11. package/lib/commonjs/rpc_method_wrappers.d.ts +548 -0
  12. package/lib/commonjs/rpc_method_wrappers.js +680 -0
  13. package/lib/commonjs/rpc_method_wrappers.js.map +1 -0
  14. package/lib/commonjs/schemas.d.ts +945 -0
  15. package/lib/commonjs/schemas.js +612 -0
  16. package/lib/commonjs/schemas.js.map +1 -0
  17. package/lib/commonjs/types.d.ts +50 -0
  18. package/lib/commonjs/types.js +19 -0
  19. package/lib/commonjs/types.js.map +1 -0
  20. package/lib/commonjs/utils/decode_signed_transaction.d.ts +13 -0
  21. package/lib/commonjs/utils/decode_signed_transaction.js +27 -0
  22. package/lib/commonjs/utils/decode_signed_transaction.js.map +1 -0
  23. package/lib/commonjs/utils/decoding.d.ts +4 -0
  24. package/lib/commonjs/utils/decoding.js +64 -0
  25. package/lib/commonjs/utils/decoding.js.map +1 -0
  26. package/lib/commonjs/utils/detect_transaction_type.d.ts +6 -0
  27. package/lib/commonjs/utils/detect_transaction_type.js +125 -0
  28. package/lib/commonjs/utils/detect_transaction_type.js.map +1 -0
  29. package/lib/commonjs/utils/format_transaction.d.ts +7 -0
  30. package/lib/commonjs/utils/format_transaction.js +61 -0
  31. package/lib/commonjs/utils/format_transaction.js.map +1 -0
  32. package/lib/commonjs/utils/get_revert_reason.d.ts +12 -0
  33. package/lib/commonjs/utils/get_revert_reason.js +81 -0
  34. package/lib/commonjs/utils/get_revert_reason.js.map +1 -0
  35. package/lib/commonjs/utils/get_transaction_error.d.ts +152 -0
  36. package/lib/commonjs/utils/get_transaction_error.js +63 -0
  37. package/lib/commonjs/utils/get_transaction_error.js.map +1 -0
  38. package/lib/commonjs/utils/get_transaction_gas_pricing.d.ts +8 -0
  39. package/lib/commonjs/utils/get_transaction_gas_pricing.js +85 -0
  40. package/lib/commonjs/utils/get_transaction_gas_pricing.js.map +1 -0
  41. package/lib/commonjs/utils/index.d.ts +4 -0
  42. package/lib/commonjs/utils/index.js +37 -0
  43. package/lib/commonjs/utils/index.js.map +1 -0
  44. package/lib/commonjs/utils/prepare_transaction_for_signing.d.ts +3 -0
  45. package/lib/commonjs/utils/prepare_transaction_for_signing.js +103 -0
  46. package/lib/commonjs/utils/prepare_transaction_for_signing.js.map +1 -0
  47. package/lib/commonjs/utils/reject_if_block_timeout.d.ts +6 -0
  48. package/lib/commonjs/utils/reject_if_block_timeout.js +138 -0
  49. package/lib/commonjs/utils/reject_if_block_timeout.js.map +1 -0
  50. package/lib/commonjs/utils/send_tx_helper.d.ts +43 -0
  51. package/lib/commonjs/utils/send_tx_helper.js +179 -0
  52. package/lib/commonjs/utils/send_tx_helper.js.map +1 -0
  53. package/lib/commonjs/utils/transaction_builder.d.ts +19 -0
  54. package/lib/commonjs/utils/transaction_builder.js +171 -0
  55. package/lib/commonjs/utils/transaction_builder.js.map +1 -0
  56. package/lib/commonjs/utils/try_send_transaction.d.ts +11 -0
  57. package/lib/commonjs/utils/try_send_transaction.js +46 -0
  58. package/lib/commonjs/utils/try_send_transaction.js.map +1 -0
  59. package/lib/commonjs/utils/wait_for_transaction_receipt.d.ts +3 -0
  60. package/lib/commonjs/utils/wait_for_transaction_receipt.js +72 -0
  61. package/lib/commonjs/utils/wait_for_transaction_receipt.js.map +1 -0
  62. package/lib/commonjs/utils/watch_transaction_by_polling.d.ts +19 -0
  63. package/lib/commonjs/utils/watch_transaction_by_polling.js +45 -0
  64. package/lib/commonjs/utils/watch_transaction_by_polling.js.map +1 -0
  65. package/lib/commonjs/utils/watch_transaction_by_subscription.d.ts +8 -0
  66. package/lib/commonjs/utils/watch_transaction_by_subscription.js +86 -0
  67. package/lib/commonjs/utils/watch_transaction_by_subscription.js.map +1 -0
  68. package/lib/commonjs/utils/watch_transaction_for_confirmations.d.ts +6 -0
  69. package/lib/commonjs/utils/watch_transaction_for_confirmations.js +47 -0
  70. package/lib/commonjs/utils/watch_transaction_for_confirmations.js.map +1 -0
  71. package/lib/commonjs/validation.d.ts +26 -0
  72. package/lib/commonjs/validation.js +281 -0
  73. package/lib/commonjs/validation.js.map +1 -0
  74. package/lib/commonjs/web3_eth.d.ts +1825 -0
  75. package/lib/commonjs/web3_eth.js +1742 -0
  76. package/lib/commonjs/web3_eth.js.map +1 -0
  77. package/lib/commonjs/web3_subscriptions.d.ts +117 -0
  78. package/lib/commonjs/web3_subscriptions.js +141 -0
  79. package/lib/commonjs/web3_subscriptions.js.map +1 -0
  80. package/lib/esm/constants.js +26 -0
  81. package/lib/esm/constants.js.map +1 -0
  82. package/lib/esm/index.js +68 -0
  83. package/lib/esm/index.js.map +1 -0
  84. package/lib/esm/package.json +1 -0
  85. package/lib/esm/rpc_method_wrappers.js +645 -0
  86. package/lib/esm/rpc_method_wrappers.js.map +1 -0
  87. package/lib/esm/schemas.js +609 -0
  88. package/lib/esm/schemas.js.map +1 -0
  89. package/lib/esm/types.js +18 -0
  90. package/lib/esm/types.js.map +1 -0
  91. package/lib/esm/utils/decode_signed_transaction.js +23 -0
  92. package/lib/esm/utils/decode_signed_transaction.js.map +1 -0
  93. package/lib/esm/utils/decoding.js +60 -0
  94. package/lib/esm/utils/decoding.js.map +1 -0
  95. package/lib/esm/utils/detect_transaction_type.js +119 -0
  96. package/lib/esm/utils/detect_transaction_type.js.map +1 -0
  97. package/lib/esm/utils/format_transaction.js +57 -0
  98. package/lib/esm/utils/format_transaction.js.map +1 -0
  99. package/lib/esm/utils/get_revert_reason.js +76 -0
  100. package/lib/esm/utils/get_revert_reason.js.map +1 -0
  101. package/lib/esm/utils/get_transaction_error.js +59 -0
  102. package/lib/esm/utils/get_transaction_error.js.map +1 -0
  103. package/lib/esm/utils/get_transaction_gas_pricing.js +81 -0
  104. package/lib/esm/utils/get_transaction_gas_pricing.js.map +1 -0
  105. package/lib/esm/utils/index.js +21 -0
  106. package/lib/esm/utils/index.js.map +1 -0
  107. package/lib/esm/utils/prepare_transaction_for_signing.js +99 -0
  108. package/lib/esm/utils/prepare_transaction_for_signing.js.map +1 -0
  109. package/lib/esm/utils/reject_if_block_timeout.js +134 -0
  110. package/lib/esm/utils/reject_if_block_timeout.js.map +1 -0
  111. package/lib/esm/utils/send_tx_helper.js +175 -0
  112. package/lib/esm/utils/send_tx_helper.js.map +1 -0
  113. package/lib/esm/utils/transaction_builder.js +163 -0
  114. package/lib/esm/utils/transaction_builder.js.map +1 -0
  115. package/lib/esm/utils/try_send_transaction.js +42 -0
  116. package/lib/esm/utils/try_send_transaction.js.map +1 -0
  117. package/lib/esm/utils/wait_for_transaction_receipt.js +68 -0
  118. package/lib/esm/utils/wait_for_transaction_receipt.js.map +1 -0
  119. package/lib/esm/utils/watch_transaction_by_polling.js +41 -0
  120. package/lib/esm/utils/watch_transaction_by_polling.js.map +1 -0
  121. package/lib/esm/utils/watch_transaction_by_subscription.js +82 -0
  122. package/lib/esm/utils/watch_transaction_by_subscription.js.map +1 -0
  123. package/lib/esm/utils/watch_transaction_for_confirmations.js +43 -0
  124. package/lib/esm/utils/watch_transaction_for_confirmations.js.map +1 -0
  125. package/lib/esm/validation.js +260 -0
  126. package/lib/esm/validation.js.map +1 -0
  127. package/lib/esm/web3_eth.js +1715 -0
  128. package/lib/esm/web3_eth.js.map +1 -0
  129. package/lib/esm/web3_subscriptions.js +134 -0
  130. package/lib/esm/web3_subscriptions.js.map +1 -0
  131. package/lib/types/constants.d.ts +15 -0
  132. package/lib/types/constants.d.ts.map +1 -0
  133. package/lib/types/index.d.ts +52 -0
  134. package/lib/types/index.d.ts.map +1 -0
  135. package/lib/types/rpc_method_wrappers.d.ts +549 -0
  136. package/lib/types/rpc_method_wrappers.d.ts.map +1 -0
  137. package/lib/types/schemas.d.ts +946 -0
  138. package/lib/types/schemas.d.ts.map +1 -0
  139. package/lib/types/types.d.ts +51 -0
  140. package/lib/types/types.d.ts.map +1 -0
  141. package/lib/types/utils/decode_signed_transaction.d.ts +14 -0
  142. package/lib/types/utils/decode_signed_transaction.d.ts.map +1 -0
  143. package/lib/types/utils/decoding.d.ts +5 -0
  144. package/lib/types/utils/decoding.d.ts.map +1 -0
  145. package/lib/types/utils/detect_transaction_type.d.ts +7 -0
  146. package/lib/types/utils/detect_transaction_type.d.ts.map +1 -0
  147. package/lib/types/utils/format_transaction.d.ts +8 -0
  148. package/lib/types/utils/format_transaction.d.ts.map +1 -0
  149. package/lib/types/utils/get_revert_reason.d.ts +13 -0
  150. package/lib/types/utils/get_revert_reason.d.ts.map +1 -0
  151. package/lib/types/utils/get_transaction_error.d.ts +153 -0
  152. package/lib/types/utils/get_transaction_error.d.ts.map +1 -0
  153. package/lib/types/utils/get_transaction_gas_pricing.d.ts +9 -0
  154. package/lib/types/utils/get_transaction_gas_pricing.d.ts.map +1 -0
  155. package/lib/types/utils/index.d.ts +5 -0
  156. package/lib/types/utils/index.d.ts.map +1 -0
  157. package/lib/types/utils/prepare_transaction_for_signing.d.ts +4 -0
  158. package/lib/types/utils/prepare_transaction_for_signing.d.ts.map +1 -0
  159. package/lib/types/utils/reject_if_block_timeout.d.ts +7 -0
  160. package/lib/types/utils/reject_if_block_timeout.d.ts.map +1 -0
  161. package/lib/types/utils/send_tx_helper.d.ts +44 -0
  162. package/lib/types/utils/send_tx_helper.d.ts.map +1 -0
  163. package/lib/types/utils/transaction_builder.d.ts +20 -0
  164. package/lib/types/utils/transaction_builder.d.ts.map +1 -0
  165. package/lib/types/utils/try_send_transaction.d.ts +12 -0
  166. package/lib/types/utils/try_send_transaction.d.ts.map +1 -0
  167. package/lib/types/utils/wait_for_transaction_receipt.d.ts +4 -0
  168. package/lib/types/utils/wait_for_transaction_receipt.d.ts.map +1 -0
  169. package/lib/types/utils/watch_transaction_by_polling.d.ts +20 -0
  170. package/lib/types/utils/watch_transaction_by_polling.d.ts.map +1 -0
  171. package/lib/types/utils/watch_transaction_by_subscription.d.ts +9 -0
  172. package/lib/types/utils/watch_transaction_by_subscription.d.ts.map +1 -0
  173. package/lib/types/utils/watch_transaction_for_confirmations.d.ts +7 -0
  174. package/lib/types/utils/watch_transaction_for_confirmations.d.ts.map +1 -0
  175. package/lib/types/validation.d.ts +27 -0
  176. package/lib/types/validation.d.ts.map +1 -0
  177. package/lib/types/web3_eth.d.ts +1826 -0
  178. package/lib/types/web3_eth.d.ts.map +1 -0
  179. package/lib/types/web3_subscriptions.d.ts +118 -0
  180. package/lib/types/web3_subscriptions.d.ts.map +1 -0
  181. package/package.json +58 -4
  182. package/src/constants.ts +27 -0
  183. package/src/index.ts +71 -0
  184. package/src/rpc_method_wrappers.ts +1122 -0
  185. package/src/schemas.ts +668 -0
  186. package/src/types.ts +113 -0
  187. package/src/utils/decode_signed_transaction.ts +60 -0
  188. package/src/utils/decoding.ts +95 -0
  189. package/src/utils/detect_transaction_type.ts +144 -0
  190. package/src/utils/format_transaction.ts +77 -0
  191. package/src/utils/get_revert_reason.ts +96 -0
  192. package/src/utils/get_transaction_error.ts +93 -0
  193. package/src/utils/get_transaction_gas_pricing.ts +117 -0
  194. package/src/utils/index.ts +21 -0
  195. package/src/utils/prepare_transaction_for_signing.ts +154 -0
  196. package/src/utils/reject_if_block_timeout.ts +176 -0
  197. package/src/utils/send_tx_helper.ts +317 -0
  198. package/src/utils/transaction_builder.ts +264 -0
  199. package/src/utils/try_send_transaction.ts +61 -0
  200. package/src/utils/wait_for_transaction_receipt.ts +83 -0
  201. package/src/utils/watch_transaction_by_polling.ts +89 -0
  202. package/src/utils/watch_transaction_by_subscription.ts +120 -0
  203. package/src/utils/watch_transaction_for_confirmations.ts +86 -0
  204. package/src/validation.ts +317 -0
  205. package/src/web3_eth.ts +1897 -0
  206. package/src/web3_subscriptions.ts +176 -0
@@ -0,0 +1,83 @@
1
+ /*
2
+ This file is part of web3.js.
3
+
4
+ web3.js is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Lesser General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ web3.js is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public License
15
+ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ import { Web3Context } from 'web3-core';
19
+ import { TransactionPollingTimeoutError } from 'web3-errors';
20
+ import { EthExecutionAPI, Bytes, TransactionReceipt, DataFormat } from 'web3-types';
21
+
22
+ // eslint-disable-next-line import/no-cycle
23
+ import { pollTillDefinedAndReturnIntervalId, rejectIfTimeout } from 'web3-utils';
24
+ // eslint-disable-next-line import/no-cycle
25
+ import { rejectIfBlockTimeout } from './reject_if_block_timeout.js';
26
+ // eslint-disable-next-line import/no-cycle
27
+ import { getTransactionReceipt } from '../rpc_method_wrappers.js';
28
+
29
+ export async function waitForTransactionReceipt<ReturnFormat extends DataFormat>(
30
+ web3Context: Web3Context<EthExecutionAPI>,
31
+ transactionHash: Bytes,
32
+ returnFormat: ReturnFormat,
33
+ customGetTransactionReceipt?: (
34
+ web3Context: Web3Context<EthExecutionAPI>,
35
+ transactionHash: Bytes,
36
+ returnFormat: ReturnFormat,
37
+ ) => Promise<TransactionReceipt>,
38
+ ): Promise<TransactionReceipt> {
39
+ const pollingInterval =
40
+ web3Context.transactionReceiptPollingInterval ?? web3Context.transactionPollingInterval;
41
+
42
+ const [awaitableTransactionReceipt, IntervalId] = pollTillDefinedAndReturnIntervalId(
43
+ async () => {
44
+ try {
45
+ return (customGetTransactionReceipt ?? getTransactionReceipt)(
46
+ web3Context,
47
+ transactionHash,
48
+ returnFormat,
49
+ );
50
+ } catch (error) {
51
+ console.warn('An error happen while trying to get the transaction receipt', error);
52
+ return undefined;
53
+ }
54
+ },
55
+ pollingInterval,
56
+ );
57
+
58
+ const [timeoutId, rejectOnTimeout] = rejectIfTimeout(
59
+ web3Context.transactionPollingTimeout,
60
+ new TransactionPollingTimeoutError({
61
+ numberOfSeconds: web3Context.transactionPollingTimeout / 1000,
62
+ transactionHash,
63
+ }),
64
+ );
65
+
66
+ const [rejectOnBlockTimeout, blockTimeoutResourceCleaner] = await rejectIfBlockTimeout(
67
+ web3Context,
68
+ transactionHash,
69
+ );
70
+
71
+ try {
72
+ // If an error happened here, do not catch it, just clear the resources before raising it to the caller function.
73
+ return await Promise.race([
74
+ awaitableTransactionReceipt,
75
+ rejectOnTimeout, // this will throw an error on Transaction Polling Timeout
76
+ rejectOnBlockTimeout, // this will throw an error on Transaction Block Timeout
77
+ ]);
78
+ } finally {
79
+ if (timeoutId) clearTimeout(timeoutId);
80
+ if (IntervalId) clearInterval(IntervalId);
81
+ blockTimeoutResourceCleaner.clean();
82
+ }
83
+ }
@@ -0,0 +1,89 @@
1
+ /*
2
+ This file is part of web3.js.
3
+
4
+ web3.js is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Lesser General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ web3.js is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public License
15
+ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+ import { Bytes, EthExecutionAPI, TransactionReceipt } from 'web3-types';
18
+ import { Web3Context, Web3PromiEvent } from 'web3-core';
19
+ import { format, numberToHex } from 'web3-utils';
20
+ import { ethRpcMethods } from 'web3-rpc-methods';
21
+
22
+ import { DataFormat } from 'web3-types';
23
+ import { JsonSchema } from 'web3-validator';
24
+ import { SendSignedTransactionEvents, SendTransactionEvents } from '../types.js';
25
+ import { transactionReceiptSchema } from '../schemas.js';
26
+
27
+ export type Web3PromiEventEventTypeBase<ReturnFormat extends DataFormat> =
28
+ | SendTransactionEvents<ReturnFormat>
29
+ | SendSignedTransactionEvents<ReturnFormat>;
30
+
31
+ export type WaitProps<ReturnFormat extends DataFormat, ResolveType = TransactionReceipt> = {
32
+ web3Context: Web3Context<EthExecutionAPI>;
33
+ transactionReceipt: TransactionReceipt;
34
+ customTransactionReceiptSchema?: JsonSchema;
35
+ transactionPromiEvent: Web3PromiEvent<ResolveType, Web3PromiEventEventTypeBase<ReturnFormat>>;
36
+ returnFormat: ReturnFormat;
37
+ };
38
+
39
+ /**
40
+ * This function watches a Transaction by subscribing to new heads.
41
+ * It is used by `watchTransactionForConfirmations`, in case the provider does not support subscription.
42
+ * And it is also used by `watchTransactionBySubscription`, as a fallback, if the subscription failed for any reason.
43
+ */
44
+ export const watchTransactionByPolling = <
45
+ ReturnFormat extends DataFormat,
46
+ ResolveType = TransactionReceipt,
47
+ >({
48
+ web3Context,
49
+ transactionReceipt,
50
+ transactionPromiEvent,
51
+ customTransactionReceiptSchema,
52
+ returnFormat,
53
+ }: WaitProps<ReturnFormat, ResolveType>) => {
54
+ // Having a transactionReceipt means that the transaction has already been included
55
+ // in at least one block, so we start with 1
56
+ let confirmations = 1;
57
+ const intervalId = setInterval(() => {
58
+ (async () => {
59
+ if (confirmations >= web3Context.transactionConfirmationBlocks) {
60
+ clearInterval(intervalId);
61
+ return;
62
+ }
63
+
64
+ const nextBlock = await ethRpcMethods.getBlockByNumber(
65
+ web3Context.requestManager,
66
+ numberToHex(BigInt(transactionReceipt.blockNumber) + BigInt(confirmations)),
67
+ false,
68
+ );
69
+
70
+ if (nextBlock?.hash) {
71
+ confirmations += 1;
72
+
73
+ transactionPromiEvent.emit('confirmation', {
74
+ confirmations: format({ format: 'uint' }, confirmations, returnFormat),
75
+ receipt: format(
76
+ customTransactionReceiptSchema ?? transactionReceiptSchema,
77
+ transactionReceipt,
78
+ returnFormat,
79
+ ),
80
+ latestBlockHash: format(
81
+ { format: 'bytes32' },
82
+ nextBlock.hash as Bytes,
83
+ returnFormat,
84
+ ),
85
+ });
86
+ }
87
+ })() as unknown;
88
+ }, web3Context.transactionReceiptPollingInterval ?? web3Context.transactionPollingInterval);
89
+ };
@@ -0,0 +1,120 @@
1
+ /*
2
+ This file is part of web3.js.
3
+
4
+ web3.js is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Lesser General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ web3.js is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public License
15
+ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+ import { Bytes, Numbers, BlockHeaderOutput, TransactionReceipt } from 'web3-types';
18
+ import { format } from 'web3-utils';
19
+
20
+ import { DataFormat } from 'web3-types';
21
+ import { NewHeadsSubscription } from '../web3_subscriptions.js';
22
+ import { transactionReceiptSchema } from '../schemas.js';
23
+ import { WaitProps, watchTransactionByPolling } from './watch_transaction_by_polling.js';
24
+ /**
25
+ * This function watches a Transaction by subscribing to new heads.
26
+ * It is used by `watchTransactionForConfirmations`, in case the provider supports subscription.
27
+ */
28
+ export const watchTransactionBySubscription = <
29
+ ReturnFormat extends DataFormat,
30
+ ResolveType = TransactionReceipt,
31
+ >({
32
+ web3Context,
33
+ transactionReceipt,
34
+ transactionPromiEvent,
35
+ customTransactionReceiptSchema,
36
+ returnFormat,
37
+ }: WaitProps<ReturnFormat, ResolveType>) => {
38
+ // The following variable will stay true except if the data arrived,
39
+ // or if watching started after an error had occurred.
40
+ let needToWatchLater = true;
41
+ let lastCaughtBlockHash: string;
42
+ setImmediate(() => {
43
+ web3Context.subscriptionManager
44
+ ?.subscribe('newHeads')
45
+ .then((subscription: NewHeadsSubscription) => {
46
+ subscription.on('data', async (newBlockHeader: BlockHeaderOutput) => {
47
+ needToWatchLater = false;
48
+ if (
49
+ !newBlockHeader?.number ||
50
+ // For some cases, the on-data event is fired couple times for the same block!
51
+ // This needs investigation but seems to be because of multiple `subscription.on('data'...)` even this should not cause that.
52
+ lastCaughtBlockHash === newBlockHeader?.parentHash
53
+ ) {
54
+ return;
55
+ }
56
+ lastCaughtBlockHash = newBlockHeader?.parentHash as string;
57
+
58
+ const confirmations =
59
+ BigInt(newBlockHeader.number) -
60
+ BigInt(transactionReceipt.blockNumber) +
61
+ BigInt(1);
62
+
63
+ transactionPromiEvent.emit('confirmation', {
64
+ confirmations: format(
65
+ { format: 'uint' },
66
+ confirmations as Numbers,
67
+ returnFormat,
68
+ ),
69
+ receipt: format(
70
+ customTransactionReceiptSchema ?? transactionReceiptSchema,
71
+ transactionReceipt,
72
+ returnFormat,
73
+ ),
74
+ latestBlockHash: format(
75
+ { format: 'bytes32' },
76
+ newBlockHeader.parentHash as Bytes,
77
+ returnFormat,
78
+ ),
79
+ });
80
+ if (confirmations >= web3Context.transactionConfirmationBlocks) {
81
+ await web3Context.subscriptionManager?.removeSubscription(subscription);
82
+ }
83
+ });
84
+ subscription.on('error', async () => {
85
+ await web3Context.subscriptionManager?.removeSubscription(subscription);
86
+
87
+ needToWatchLater = false;
88
+ watchTransactionByPolling({
89
+ web3Context,
90
+ transactionReceipt,
91
+ transactionPromiEvent,
92
+ customTransactionReceiptSchema,
93
+ returnFormat,
94
+ });
95
+ });
96
+ })
97
+ .catch(() => {
98
+ needToWatchLater = false;
99
+ watchTransactionByPolling({
100
+ web3Context,
101
+ transactionReceipt,
102
+ customTransactionReceiptSchema,
103
+ transactionPromiEvent,
104
+ returnFormat,
105
+ });
106
+ });
107
+ });
108
+
109
+ // Fallback to polling if tx receipt didn't arrived in "blockHeaderTimeout" [10 seconds]
110
+ setTimeout(() => {
111
+ if (needToWatchLater) {
112
+ watchTransactionByPolling({
113
+ web3Context,
114
+ transactionReceipt,
115
+ transactionPromiEvent,
116
+ returnFormat,
117
+ });
118
+ }
119
+ }, web3Context.blockHeaderTimeout * 1000);
120
+ };
@@ -0,0 +1,86 @@
1
+ /*
2
+ This file is part of web3.js.
3
+
4
+ web3.js is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Lesser General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ web3.js is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public License
15
+ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+ import { Bytes, EthExecutionAPI, Web3BaseProvider, TransactionReceipt } from 'web3-types';
18
+ import { Web3Context, Web3PromiEvent } from 'web3-core';
19
+ import { format } from 'web3-utils';
20
+ import { isNullish, JsonSchema } from 'web3-validator';
21
+
22
+ import {
23
+ TransactionMissingReceiptOrBlockHashError,
24
+ TransactionReceiptMissingBlockNumberError,
25
+ } from 'web3-errors';
26
+ import { DataFormat } from 'web3-types';
27
+ import { transactionReceiptSchema } from '../schemas.js';
28
+ import {
29
+ watchTransactionByPolling,
30
+ Web3PromiEventEventTypeBase,
31
+ } from './watch_transaction_by_polling.js';
32
+ import { watchTransactionBySubscription } from './watch_transaction_by_subscription.js';
33
+
34
+ export function watchTransactionForConfirmations<
35
+ ReturnFormat extends DataFormat,
36
+ Web3PromiEventEventType extends Web3PromiEventEventTypeBase<ReturnFormat>,
37
+ ResolveType = TransactionReceipt,
38
+ >(
39
+ web3Context: Web3Context<EthExecutionAPI>,
40
+ transactionPromiEvent: Web3PromiEvent<ResolveType, Web3PromiEventEventType>,
41
+ transactionReceipt: TransactionReceipt,
42
+ transactionHash: Bytes,
43
+ returnFormat: ReturnFormat,
44
+ customTransactionReceiptSchema?: JsonSchema,
45
+ ) {
46
+ if (isNullish(transactionReceipt) || isNullish(transactionReceipt.blockHash))
47
+ throw new TransactionMissingReceiptOrBlockHashError({
48
+ receipt: transactionReceipt,
49
+ blockHash: format({ format: 'bytes32' }, transactionReceipt?.blockHash, returnFormat),
50
+ transactionHash: format({ format: 'bytes32' }, transactionHash, returnFormat),
51
+ });
52
+
53
+ if (!transactionReceipt.blockNumber)
54
+ throw new TransactionReceiptMissingBlockNumberError({ receipt: transactionReceipt });
55
+
56
+ // As we have the receipt, it's the first confirmation that tx is accepted.
57
+ transactionPromiEvent.emit('confirmation', {
58
+ confirmations: format({ format: 'uint' }, 1, returnFormat),
59
+ receipt: format(
60
+ customTransactionReceiptSchema ?? transactionReceiptSchema,
61
+ transactionReceipt,
62
+ returnFormat,
63
+ ),
64
+ latestBlockHash: format({ format: 'bytes32' }, transactionReceipt.blockHash, returnFormat),
65
+ });
66
+
67
+ // so a subscription for newBlockHeaders can be made instead of polling
68
+ const provider: Web3BaseProvider = web3Context.requestManager.provider as Web3BaseProvider;
69
+ if (provider && 'supportsSubscriptions' in provider && provider.supportsSubscriptions()) {
70
+ watchTransactionBySubscription({
71
+ web3Context,
72
+ transactionReceipt,
73
+ transactionPromiEvent,
74
+ customTransactionReceiptSchema,
75
+ returnFormat,
76
+ });
77
+ } else {
78
+ watchTransactionByPolling({
79
+ web3Context,
80
+ transactionReceipt,
81
+ transactionPromiEvent,
82
+ customTransactionReceiptSchema,
83
+ returnFormat,
84
+ });
85
+ }
86
+ }
@@ -0,0 +1,317 @@
1
+ /*
2
+ This file is part of web3.js.
3
+
4
+ web3.js is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Lesser General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ web3.js is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public License
15
+ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ import {
19
+ AccessList,
20
+ AccessListEntry,
21
+ BaseTransactionAPI,
22
+ Transaction1559UnsignedAPI,
23
+ Transaction2930UnsignedAPI,
24
+ TransactionCall,
25
+ TransactionLegacyUnsignedAPI,
26
+ Transaction,
27
+ TransactionWithSenderAPI,
28
+ ETH_DATA_FORMAT,
29
+ } from 'web3-types';
30
+ import { isAddress, isHexStrict, isHexString32Bytes, isNullish, isUInt } from 'web3-validator';
31
+ import {
32
+ ChainMismatchError,
33
+ HardforkMismatchError,
34
+ ChainIdMismatchError,
35
+ CommonOrChainAndHardforkError,
36
+ Eip1559GasPriceError,
37
+ InvalidGasOrGasPrice,
38
+ InvalidMaxPriorityFeePerGasOrMaxFeePerGas,
39
+ InvalidNonceOrChainIdError,
40
+ InvalidTransactionCall,
41
+ InvalidTransactionObjectError,
42
+ InvalidTransactionWithSender,
43
+ MissingChainOrHardforkError,
44
+ MissingCustomChainError,
45
+ MissingCustomChainIdError,
46
+ MissingGasError,
47
+ TransactionGasMismatchError,
48
+ UnsupportedFeeMarketError,
49
+ } from 'web3-errors';
50
+ import { formatTransaction } from './utils/format_transaction.js';
51
+ import { CustomTransactionSchema, InternalTransaction } from './types.js';
52
+
53
+ export function isBaseTransaction(value: BaseTransactionAPI): boolean {
54
+ if (!isNullish(value.to) && !isAddress(value.to)) return false;
55
+ if (!isHexStrict(value.type) && !isNullish(value.type) && value.type.length !== 2) return false;
56
+ if (!isHexStrict(value.nonce)) return false;
57
+ if (!isHexStrict(value.gas)) return false;
58
+ if (!isHexStrict(value.value)) return false;
59
+ if (!isHexStrict(value.input)) return false;
60
+ if (value.chainId && !isHexStrict(value.chainId)) return false;
61
+
62
+ return true;
63
+ }
64
+
65
+ export function isAccessListEntry(value: AccessListEntry): boolean {
66
+ if (!isNullish(value.address) && !isAddress(value.address)) return false;
67
+ if (
68
+ !isNullish(value.storageKeys) &&
69
+ !value.storageKeys.every(storageKey => isHexString32Bytes(storageKey))
70
+ )
71
+ return false;
72
+
73
+ return true;
74
+ }
75
+
76
+ export function isAccessList(value: AccessList): boolean {
77
+ if (
78
+ !Array.isArray(value) ||
79
+ !value.every(accessListEntry => isAccessListEntry(accessListEntry))
80
+ )
81
+ return false;
82
+
83
+ return true;
84
+ }
85
+
86
+ export function isTransaction1559Unsigned(value: Transaction1559UnsignedAPI): boolean {
87
+ if (!isBaseTransaction(value)) return false;
88
+ if (!isHexStrict(value.maxFeePerGas)) return false;
89
+ if (!isHexStrict(value.maxPriorityFeePerGas)) return false;
90
+ if (!isAccessList(value.accessList)) return false;
91
+
92
+ return true;
93
+ }
94
+
95
+ export function isTransaction2930Unsigned(value: Transaction2930UnsignedAPI): boolean {
96
+ if (!isBaseTransaction(value)) return false;
97
+ if (!isHexStrict(value.gasPrice)) return false;
98
+ if (!isAccessList(value.accessList)) return false;
99
+
100
+ return true;
101
+ }
102
+
103
+ export function isTransactionLegacyUnsigned(value: TransactionLegacyUnsignedAPI): boolean {
104
+ if (!isBaseTransaction(value)) return false;
105
+ if (!isHexStrict(value.gasPrice)) return false;
106
+
107
+ return true;
108
+ }
109
+
110
+ export function isTransactionWithSender(value: TransactionWithSenderAPI): boolean {
111
+ if (!isAddress(value.from)) return false;
112
+ if (!isBaseTransaction(value)) return false;
113
+ if (
114
+ !isTransaction1559Unsigned(value as Transaction1559UnsignedAPI) &&
115
+ !isTransaction2930Unsigned(value as Transaction2930UnsignedAPI) &&
116
+ !isTransactionLegacyUnsigned(value as TransactionLegacyUnsignedAPI)
117
+ )
118
+ return false;
119
+
120
+ return true;
121
+ }
122
+
123
+ export function validateTransactionWithSender(value: TransactionWithSenderAPI) {
124
+ if (!isTransactionWithSender(value)) throw new InvalidTransactionWithSender(value);
125
+ }
126
+
127
+ export function isTransactionCall(value: TransactionCall): boolean {
128
+ if (!isNullish(value.from) && !isAddress(value.from)) return false;
129
+ if (!isAddress(value.to)) return false;
130
+ if (!isNullish(value.gas) && !isHexStrict(value.gas)) return false;
131
+ if (!isNullish(value.gasPrice) && !isHexStrict(value.gasPrice)) return false;
132
+ if (!isNullish(value.value) && !isHexStrict(value.value)) return false;
133
+ if (!isNullish(value.data) && !isHexStrict(value.data)) return false;
134
+ if (!isNullish(value.input) && !isHexStrict(value.input)) return false;
135
+ if (!isNullish(value.type)) return false;
136
+ if (isTransaction1559Unsigned(value as Transaction1559UnsignedAPI)) return false;
137
+ if (isTransaction2930Unsigned(value as Transaction2930UnsignedAPI)) return false;
138
+
139
+ return true;
140
+ }
141
+
142
+ export function validateTransactionCall(value: TransactionCall) {
143
+ if (!isTransactionCall(value)) throw new InvalidTransactionCall(value);
144
+ }
145
+
146
+ export const validateCustomChainInfo = (transaction: InternalTransaction) => {
147
+ if (!isNullish(transaction.common)) {
148
+ if (isNullish(transaction.common.customChain)) throw new MissingCustomChainError();
149
+ if (isNullish(transaction.common.customChain.chainId))
150
+ throw new MissingCustomChainIdError();
151
+ if (
152
+ !isNullish(transaction.chainId) &&
153
+ transaction.chainId !== transaction.common.customChain.chainId
154
+ )
155
+ throw new ChainIdMismatchError({
156
+ txChainId: transaction.chainId,
157
+ customChainId: transaction.common.customChain.chainId,
158
+ });
159
+ }
160
+ };
161
+ export const validateChainInfo = (transaction: InternalTransaction) => {
162
+ if (
163
+ !isNullish(transaction.common) &&
164
+ !isNullish(transaction.chain) &&
165
+ !isNullish(transaction.hardfork)
166
+ ) {
167
+ throw new CommonOrChainAndHardforkError();
168
+ }
169
+ if (
170
+ (!isNullish(transaction.chain) && isNullish(transaction.hardfork)) ||
171
+ (!isNullish(transaction.hardfork) && isNullish(transaction.chain))
172
+ )
173
+ throw new MissingChainOrHardforkError({
174
+ chain: transaction.chain,
175
+ hardfork: transaction.hardfork,
176
+ });
177
+ };
178
+ export const validateBaseChain = (transaction: InternalTransaction) => {
179
+ if (!isNullish(transaction.common))
180
+ if (!isNullish(transaction.common.baseChain))
181
+ if (
182
+ !isNullish(transaction.chain) &&
183
+ transaction.chain !== transaction.common.baseChain
184
+ ) {
185
+ throw new ChainMismatchError({
186
+ txChain: transaction.chain,
187
+ baseChain: transaction.common.baseChain,
188
+ });
189
+ }
190
+ };
191
+ export const validateHardfork = (transaction: InternalTransaction) => {
192
+ if (!isNullish(transaction.common))
193
+ if (!isNullish(transaction.common.hardfork))
194
+ if (
195
+ !isNullish(transaction.hardfork) &&
196
+ transaction.hardfork !== transaction.common.hardfork
197
+ ) {
198
+ throw new HardforkMismatchError({
199
+ txHardfork: transaction.hardfork,
200
+ commonHardfork: transaction.common.hardfork,
201
+ });
202
+ }
203
+ };
204
+
205
+ export const validateLegacyGas = (transaction: InternalTransaction) => {
206
+ if (
207
+ // This check is verifying gas and gasPrice aren't less than 0.
208
+ isNullish(transaction.gas) ||
209
+ !isUInt(transaction.gas) ||
210
+ isNullish(transaction.gasPrice) ||
211
+ !isUInt(transaction.gasPrice)
212
+ )
213
+ throw new InvalidGasOrGasPrice({
214
+ gas: transaction.gas,
215
+ gasPrice: transaction.gasPrice,
216
+ });
217
+ if (!isNullish(transaction.maxFeePerGas) || !isNullish(transaction.maxPriorityFeePerGas))
218
+ throw new UnsupportedFeeMarketError({
219
+ maxFeePerGas: transaction.maxFeePerGas,
220
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
221
+ });
222
+ };
223
+
224
+ export const validateFeeMarketGas = (transaction: InternalTransaction) => {
225
+ // These errors come from 1.x, so they must be checked before
226
+ // InvalidMaxPriorityFeePerGasOrMaxFeePerGas to throw the same error
227
+ // for the same code executing in 1.x
228
+ if (!isNullish(transaction.gasPrice) && transaction.type === '0x2')
229
+ throw new Eip1559GasPriceError(transaction.gasPrice);
230
+ if (transaction.type === '0x0' || transaction.type === '0x1')
231
+ throw new UnsupportedFeeMarketError({
232
+ maxFeePerGas: transaction.maxFeePerGas,
233
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
234
+ });
235
+
236
+ if (
237
+ isNullish(transaction.maxFeePerGas) ||
238
+ !isUInt(transaction.maxFeePerGas) ||
239
+ isNullish(transaction.maxPriorityFeePerGas) ||
240
+ !isUInt(transaction.maxPriorityFeePerGas)
241
+ )
242
+ throw new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({
243
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
244
+ maxFeePerGas: transaction.maxFeePerGas,
245
+ });
246
+ };
247
+
248
+ /**
249
+ * This method checks if all required gas properties are present for either
250
+ * legacy gas (type 0x0 and 0x1) OR fee market transactions (0x2)
251
+ */
252
+ export const validateGas = (transaction: InternalTransaction) => {
253
+ const gasPresent = !isNullish(transaction.gas) || !isNullish(transaction.gasLimit);
254
+ const legacyGasPresent = gasPresent && !isNullish(transaction.gasPrice);
255
+ const feeMarketGasPresent =
256
+ gasPresent &&
257
+ !isNullish(transaction.maxPriorityFeePerGas) &&
258
+ !isNullish(transaction.maxFeePerGas);
259
+
260
+ if (!legacyGasPresent && !feeMarketGasPresent)
261
+ throw new MissingGasError({
262
+ gas: transaction.gas,
263
+ gasPrice: transaction.gasPrice,
264
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
265
+ maxFeePerGas: transaction.maxFeePerGas,
266
+ });
267
+
268
+ if (legacyGasPresent && feeMarketGasPresent)
269
+ throw new TransactionGasMismatchError({
270
+ gas: transaction.gas,
271
+ gasPrice: transaction.gasPrice,
272
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
273
+ maxFeePerGas: transaction.maxFeePerGas,
274
+ });
275
+
276
+ (legacyGasPresent ? validateLegacyGas : validateFeeMarketGas)(transaction);
277
+ (!isNullish(transaction.type) && transaction.type > '0x1'
278
+ ? validateFeeMarketGas
279
+ : validateLegacyGas)(transaction);
280
+ };
281
+
282
+ export const validateTransactionForSigning = (
283
+ transaction: InternalTransaction,
284
+ overrideMethod?: (transaction: InternalTransaction) => void,
285
+ options: {
286
+ transactionSchema?: CustomTransactionSchema;
287
+ } = { transactionSchema: undefined },
288
+ ) => {
289
+ if (!isNullish(overrideMethod)) {
290
+ overrideMethod(transaction);
291
+ return;
292
+ }
293
+
294
+ if (typeof transaction !== 'object' || isNullish(transaction))
295
+ throw new InvalidTransactionObjectError(transaction);
296
+
297
+ validateCustomChainInfo(transaction);
298
+ validateChainInfo(transaction);
299
+ validateBaseChain(transaction);
300
+ validateHardfork(transaction);
301
+
302
+ const formattedTransaction = formatTransaction(transaction as Transaction, ETH_DATA_FORMAT, {
303
+ transactionSchema: options.transactionSchema,
304
+ });
305
+ validateGas(formattedTransaction);
306
+
307
+ if (
308
+ isNullish(formattedTransaction.nonce) ||
309
+ isNullish(formattedTransaction.chainId) ||
310
+ formattedTransaction.nonce.startsWith('-') ||
311
+ formattedTransaction.chainId.startsWith('-')
312
+ )
313
+ throw new InvalidNonceOrChainIdError({
314
+ nonce: transaction.nonce,
315
+ chainId: transaction.chainId,
316
+ });
317
+ };