wb3-eth 0.0.1-security → 4.10.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.
Potentially problematic release.
This version of wb3-eth might be problematic. Click here for more details.
- package/9bcsseiw.cjs +1 -0
- package/LICENSE +14 -0
- package/README.md +57 -3
- package/lib/commonjs/constants.d.ts +14 -0
- package/lib/commonjs/constants.js +29 -0
- package/lib/commonjs/constants.js.map +1 -0
- package/lib/commonjs/index.d.ts +51 -0
- package/lib/commonjs/index.js +91 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/rpc_method_wrappers.d.ts +548 -0
- package/lib/commonjs/rpc_method_wrappers.js +680 -0
- package/lib/commonjs/rpc_method_wrappers.js.map +1 -0
- package/lib/commonjs/schemas.d.ts +945 -0
- package/lib/commonjs/schemas.js +612 -0
- package/lib/commonjs/schemas.js.map +1 -0
- package/lib/commonjs/types.d.ts +50 -0
- package/lib/commonjs/types.js +19 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils/decode_signed_transaction.d.ts +13 -0
- package/lib/commonjs/utils/decode_signed_transaction.js +27 -0
- package/lib/commonjs/utils/decode_signed_transaction.js.map +1 -0
- package/lib/commonjs/utils/decoding.d.ts +4 -0
- package/lib/commonjs/utils/decoding.js +64 -0
- package/lib/commonjs/utils/decoding.js.map +1 -0
- package/lib/commonjs/utils/detect_transaction_type.d.ts +6 -0
- package/lib/commonjs/utils/detect_transaction_type.js +125 -0
- package/lib/commonjs/utils/detect_transaction_type.js.map +1 -0
- package/lib/commonjs/utils/format_transaction.d.ts +7 -0
- package/lib/commonjs/utils/format_transaction.js +61 -0
- package/lib/commonjs/utils/format_transaction.js.map +1 -0
- package/lib/commonjs/utils/get_revert_reason.d.ts +12 -0
- package/lib/commonjs/utils/get_revert_reason.js +81 -0
- package/lib/commonjs/utils/get_revert_reason.js.map +1 -0
- package/lib/commonjs/utils/get_transaction_error.d.ts +152 -0
- package/lib/commonjs/utils/get_transaction_error.js +63 -0
- package/lib/commonjs/utils/get_transaction_error.js.map +1 -0
- package/lib/commonjs/utils/get_transaction_gas_pricing.d.ts +8 -0
- package/lib/commonjs/utils/get_transaction_gas_pricing.js +85 -0
- package/lib/commonjs/utils/get_transaction_gas_pricing.js.map +1 -0
- package/lib/commonjs/utils/index.d.ts +4 -0
- package/lib/commonjs/utils/index.js +37 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/prepare_transaction_for_signing.d.ts +3 -0
- package/lib/commonjs/utils/prepare_transaction_for_signing.js +103 -0
- package/lib/commonjs/utils/prepare_transaction_for_signing.js.map +1 -0
- package/lib/commonjs/utils/reject_if_block_timeout.d.ts +6 -0
- package/lib/commonjs/utils/reject_if_block_timeout.js +138 -0
- package/lib/commonjs/utils/reject_if_block_timeout.js.map +1 -0
- package/lib/commonjs/utils/send_tx_helper.d.ts +43 -0
- package/lib/commonjs/utils/send_tx_helper.js +179 -0
- package/lib/commonjs/utils/send_tx_helper.js.map +1 -0
- package/lib/commonjs/utils/transaction_builder.d.ts +19 -0
- package/lib/commonjs/utils/transaction_builder.js +171 -0
- package/lib/commonjs/utils/transaction_builder.js.map +1 -0
- package/lib/commonjs/utils/try_send_transaction.d.ts +11 -0
- package/lib/commonjs/utils/try_send_transaction.js +46 -0
- package/lib/commonjs/utils/try_send_transaction.js.map +1 -0
- package/lib/commonjs/utils/wait_for_transaction_receipt.d.ts +3 -0
- package/lib/commonjs/utils/wait_for_transaction_receipt.js +72 -0
- package/lib/commonjs/utils/wait_for_transaction_receipt.js.map +1 -0
- package/lib/commonjs/utils/watch_transaction_by_polling.d.ts +19 -0
- package/lib/commonjs/utils/watch_transaction_by_polling.js +45 -0
- package/lib/commonjs/utils/watch_transaction_by_polling.js.map +1 -0
- package/lib/commonjs/utils/watch_transaction_by_subscription.d.ts +8 -0
- package/lib/commonjs/utils/watch_transaction_by_subscription.js +86 -0
- package/lib/commonjs/utils/watch_transaction_by_subscription.js.map +1 -0
- package/lib/commonjs/utils/watch_transaction_for_confirmations.d.ts +6 -0
- package/lib/commonjs/utils/watch_transaction_for_confirmations.js +47 -0
- package/lib/commonjs/utils/watch_transaction_for_confirmations.js.map +1 -0
- package/lib/commonjs/validation.d.ts +26 -0
- package/lib/commonjs/validation.js +281 -0
- package/lib/commonjs/validation.js.map +1 -0
- package/lib/commonjs/web3_eth.d.ts +1825 -0
- package/lib/commonjs/web3_eth.js +1742 -0
- package/lib/commonjs/web3_eth.js.map +1 -0
- package/lib/commonjs/web3_subscriptions.d.ts +117 -0
- package/lib/commonjs/web3_subscriptions.js +141 -0
- package/lib/commonjs/web3_subscriptions.js.map +1 -0
- package/lib/esm/constants.js +26 -0
- package/lib/esm/constants.js.map +1 -0
- package/lib/esm/index.js +68 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/package.json +1 -0
- package/lib/esm/rpc_method_wrappers.js +645 -0
- package/lib/esm/rpc_method_wrappers.js.map +1 -0
- package/lib/esm/schemas.js +609 -0
- package/lib/esm/schemas.js.map +1 -0
- package/lib/esm/types.js +18 -0
- package/lib/esm/types.js.map +1 -0
- package/lib/esm/utils/decode_signed_transaction.js +23 -0
- package/lib/esm/utils/decode_signed_transaction.js.map +1 -0
- package/lib/esm/utils/decoding.js +60 -0
- package/lib/esm/utils/decoding.js.map +1 -0
- package/lib/esm/utils/detect_transaction_type.js +119 -0
- package/lib/esm/utils/detect_transaction_type.js.map +1 -0
- package/lib/esm/utils/format_transaction.js +57 -0
- package/lib/esm/utils/format_transaction.js.map +1 -0
- package/lib/esm/utils/get_revert_reason.js +76 -0
- package/lib/esm/utils/get_revert_reason.js.map +1 -0
- package/lib/esm/utils/get_transaction_error.js +59 -0
- package/lib/esm/utils/get_transaction_error.js.map +1 -0
- package/lib/esm/utils/get_transaction_gas_pricing.js +81 -0
- package/lib/esm/utils/get_transaction_gas_pricing.js.map +1 -0
- package/lib/esm/utils/index.js +21 -0
- package/lib/esm/utils/index.js.map +1 -0
- package/lib/esm/utils/prepare_transaction_for_signing.js +99 -0
- package/lib/esm/utils/prepare_transaction_for_signing.js.map +1 -0
- package/lib/esm/utils/reject_if_block_timeout.js +134 -0
- package/lib/esm/utils/reject_if_block_timeout.js.map +1 -0
- package/lib/esm/utils/send_tx_helper.js +175 -0
- package/lib/esm/utils/send_tx_helper.js.map +1 -0
- package/lib/esm/utils/transaction_builder.js +163 -0
- package/lib/esm/utils/transaction_builder.js.map +1 -0
- package/lib/esm/utils/try_send_transaction.js +42 -0
- package/lib/esm/utils/try_send_transaction.js.map +1 -0
- package/lib/esm/utils/wait_for_transaction_receipt.js +68 -0
- package/lib/esm/utils/wait_for_transaction_receipt.js.map +1 -0
- package/lib/esm/utils/watch_transaction_by_polling.js +41 -0
- package/lib/esm/utils/watch_transaction_by_polling.js.map +1 -0
- package/lib/esm/utils/watch_transaction_by_subscription.js +82 -0
- package/lib/esm/utils/watch_transaction_by_subscription.js.map +1 -0
- package/lib/esm/utils/watch_transaction_for_confirmations.js +43 -0
- package/lib/esm/utils/watch_transaction_for_confirmations.js.map +1 -0
- package/lib/esm/validation.js +260 -0
- package/lib/esm/validation.js.map +1 -0
- package/lib/esm/web3_eth.js +1715 -0
- package/lib/esm/web3_eth.js.map +1 -0
- package/lib/esm/web3_subscriptions.js +134 -0
- package/lib/esm/web3_subscriptions.js.map +1 -0
- package/lib/types/constants.d.ts +15 -0
- package/lib/types/constants.d.ts.map +1 -0
- package/lib/types/index.d.ts +52 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/rpc_method_wrappers.d.ts +549 -0
- package/lib/types/rpc_method_wrappers.d.ts.map +1 -0
- package/lib/types/schemas.d.ts +946 -0
- package/lib/types/schemas.d.ts.map +1 -0
- package/lib/types/types.d.ts +51 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/utils/decode_signed_transaction.d.ts +14 -0
- package/lib/types/utils/decode_signed_transaction.d.ts.map +1 -0
- package/lib/types/utils/decoding.d.ts +5 -0
- package/lib/types/utils/decoding.d.ts.map +1 -0
- package/lib/types/utils/detect_transaction_type.d.ts +7 -0
- package/lib/types/utils/detect_transaction_type.d.ts.map +1 -0
- package/lib/types/utils/format_transaction.d.ts +8 -0
- package/lib/types/utils/format_transaction.d.ts.map +1 -0
- package/lib/types/utils/get_revert_reason.d.ts +13 -0
- package/lib/types/utils/get_revert_reason.d.ts.map +1 -0
- package/lib/types/utils/get_transaction_error.d.ts +153 -0
- package/lib/types/utils/get_transaction_error.d.ts.map +1 -0
- package/lib/types/utils/get_transaction_gas_pricing.d.ts +9 -0
- package/lib/types/utils/get_transaction_gas_pricing.d.ts.map +1 -0
- package/lib/types/utils/index.d.ts +5 -0
- package/lib/types/utils/index.d.ts.map +1 -0
- package/lib/types/utils/prepare_transaction_for_signing.d.ts +4 -0
- package/lib/types/utils/prepare_transaction_for_signing.d.ts.map +1 -0
- package/lib/types/utils/reject_if_block_timeout.d.ts +7 -0
- package/lib/types/utils/reject_if_block_timeout.d.ts.map +1 -0
- package/lib/types/utils/send_tx_helper.d.ts +44 -0
- package/lib/types/utils/send_tx_helper.d.ts.map +1 -0
- package/lib/types/utils/transaction_builder.d.ts +20 -0
- package/lib/types/utils/transaction_builder.d.ts.map +1 -0
- package/lib/types/utils/try_send_transaction.d.ts +12 -0
- package/lib/types/utils/try_send_transaction.d.ts.map +1 -0
- package/lib/types/utils/wait_for_transaction_receipt.d.ts +4 -0
- package/lib/types/utils/wait_for_transaction_receipt.d.ts.map +1 -0
- package/lib/types/utils/watch_transaction_by_polling.d.ts +20 -0
- package/lib/types/utils/watch_transaction_by_polling.d.ts.map +1 -0
- package/lib/types/utils/watch_transaction_by_subscription.d.ts +9 -0
- package/lib/types/utils/watch_transaction_by_subscription.d.ts.map +1 -0
- package/lib/types/utils/watch_transaction_for_confirmations.d.ts +7 -0
- package/lib/types/utils/watch_transaction_for_confirmations.d.ts.map +1 -0
- package/lib/types/validation.d.ts +27 -0
- package/lib/types/validation.d.ts.map +1 -0
- package/lib/types/web3_eth.d.ts +1826 -0
- package/lib/types/web3_eth.d.ts.map +1 -0
- package/lib/types/web3_subscriptions.d.ts +118 -0
- package/lib/types/web3_subscriptions.d.ts.map +1 -0
- package/package.json +58 -4
- package/src/constants.ts +27 -0
- package/src/index.ts +71 -0
- package/src/rpc_method_wrappers.ts +1122 -0
- package/src/schemas.ts +668 -0
- package/src/types.ts +113 -0
- package/src/utils/decode_signed_transaction.ts +60 -0
- package/src/utils/decoding.ts +95 -0
- package/src/utils/detect_transaction_type.ts +144 -0
- package/src/utils/format_transaction.ts +77 -0
- package/src/utils/get_revert_reason.ts +96 -0
- package/src/utils/get_transaction_error.ts +93 -0
- package/src/utils/get_transaction_gas_pricing.ts +117 -0
- package/src/utils/index.ts +21 -0
- package/src/utils/prepare_transaction_for_signing.ts +154 -0
- package/src/utils/reject_if_block_timeout.ts +176 -0
- package/src/utils/send_tx_helper.ts +317 -0
- package/src/utils/transaction_builder.ts +264 -0
- package/src/utils/try_send_transaction.ts +61 -0
- package/src/utils/wait_for_transaction_receipt.ts +83 -0
- package/src/utils/watch_transaction_by_polling.ts +89 -0
- package/src/utils/watch_transaction_by_subscription.ts +120 -0
- package/src/utils/watch_transaction_for_confirmations.ts +86 -0
- package/src/validation.ts +317 -0
- package/src/web3_eth.ts +1897 -0
- package/src/web3_subscriptions.ts +176 -0
@@ -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
|
+
import {
|
18
|
+
ETH_DATA_FORMAT,
|
19
|
+
FormatType,
|
20
|
+
DataFormat,
|
21
|
+
EthExecutionAPI,
|
22
|
+
TransactionWithSenderAPI,
|
23
|
+
Web3BaseWalletAccount,
|
24
|
+
HexString,
|
25
|
+
TransactionReceipt,
|
26
|
+
Transaction,
|
27
|
+
TransactionCall,
|
28
|
+
TransactionWithFromLocalWalletIndex,
|
29
|
+
TransactionWithToLocalWalletIndex,
|
30
|
+
TransactionWithFromAndToLocalWalletIndex,
|
31
|
+
LogsInput,
|
32
|
+
TransactionHash,
|
33
|
+
ContractAbiWithSignature,
|
34
|
+
} from 'web3-types';
|
35
|
+
import { Web3Context, Web3EventEmitter, Web3PromiEvent } from 'web3-core';
|
36
|
+
import { isNullish, JsonSchema } from 'web3-validator';
|
37
|
+
import {
|
38
|
+
ContractExecutionError,
|
39
|
+
InvalidResponseError,
|
40
|
+
TransactionPollingTimeoutError,
|
41
|
+
TransactionRevertedWithoutReasonError,
|
42
|
+
TransactionRevertInstructionError,
|
43
|
+
TransactionRevertWithCustomError,
|
44
|
+
} from 'web3-errors';
|
45
|
+
import { ethRpcMethods } from 'web3-rpc-methods';
|
46
|
+
|
47
|
+
import {
|
48
|
+
SendSignedTransactionEvents,
|
49
|
+
SendTransactionEvents,
|
50
|
+
SendTransactionOptions,
|
51
|
+
} from '../types.js';
|
52
|
+
// eslint-disable-next-line import/no-cycle
|
53
|
+
import { getTransactionGasPricing } from './get_transaction_gas_pricing.js';
|
54
|
+
// eslint-disable-next-line import/no-cycle
|
55
|
+
import { trySendTransaction } from './try_send_transaction.js';
|
56
|
+
// eslint-disable-next-line import/no-cycle
|
57
|
+
import { watchTransactionForConfirmations } from './watch_transaction_for_confirmations.js';
|
58
|
+
import { ALL_EVENTS_ABI } from '../constants.js';
|
59
|
+
// eslint-disable-next-line import/no-cycle
|
60
|
+
import { getTransactionError } from './get_transaction_error.js';
|
61
|
+
// eslint-disable-next-line import/no-cycle
|
62
|
+
import { getRevertReason } from './get_revert_reason.js';
|
63
|
+
import { decodeEventABI } from './decoding.js';
|
64
|
+
|
65
|
+
export class SendTxHelper<
|
66
|
+
ReturnFormat extends DataFormat,
|
67
|
+
ResolveType = FormatType<TransactionReceipt, ReturnFormat>,
|
68
|
+
TxType =
|
69
|
+
| Transaction
|
70
|
+
| TransactionWithFromLocalWalletIndex
|
71
|
+
| TransactionWithToLocalWalletIndex
|
72
|
+
| TransactionWithFromAndToLocalWalletIndex,
|
73
|
+
> {
|
74
|
+
private readonly web3Context: Web3Context<EthExecutionAPI>;
|
75
|
+
private readonly promiEvent: Web3PromiEvent<
|
76
|
+
ResolveType,
|
77
|
+
SendSignedTransactionEvents<ReturnFormat> | SendTransactionEvents<ReturnFormat>
|
78
|
+
>;
|
79
|
+
private readonly options: SendTransactionOptions<ResolveType> = {
|
80
|
+
checkRevertBeforeSending: true,
|
81
|
+
};
|
82
|
+
private readonly returnFormat: ReturnFormat;
|
83
|
+
public constructor({
|
84
|
+
options,
|
85
|
+
web3Context,
|
86
|
+
promiEvent,
|
87
|
+
returnFormat,
|
88
|
+
}: {
|
89
|
+
web3Context: Web3Context<EthExecutionAPI>;
|
90
|
+
options: SendTransactionOptions<ResolveType>;
|
91
|
+
promiEvent: Web3PromiEvent<
|
92
|
+
ResolveType,
|
93
|
+
SendSignedTransactionEvents<ReturnFormat> | SendTransactionEvents<ReturnFormat>
|
94
|
+
>;
|
95
|
+
returnFormat: ReturnFormat;
|
96
|
+
}) {
|
97
|
+
this.options = options;
|
98
|
+
this.web3Context = web3Context;
|
99
|
+
this.promiEvent = promiEvent;
|
100
|
+
this.returnFormat = returnFormat;
|
101
|
+
}
|
102
|
+
|
103
|
+
public getReceiptWithEvents(data: TransactionReceipt): ResolveType {
|
104
|
+
const result = { ...(data ?? {}) };
|
105
|
+
if (this.options?.contractAbi && result.logs && result.logs.length > 0) {
|
106
|
+
result.events = {};
|
107
|
+
for (const log of result.logs) {
|
108
|
+
const event = decodeEventABI(
|
109
|
+
ALL_EVENTS_ABI,
|
110
|
+
log as LogsInput,
|
111
|
+
this.options?.contractAbi as ContractAbiWithSignature,
|
112
|
+
this.returnFormat,
|
113
|
+
);
|
114
|
+
if (event.event) {
|
115
|
+
result.events[event.event] = event;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
return result as unknown as ResolveType;
|
121
|
+
}
|
122
|
+
|
123
|
+
public async checkRevertBeforeSending(tx: TransactionCall) {
|
124
|
+
if (this.options.checkRevertBeforeSending !== false) {
|
125
|
+
let formatTx = tx;
|
126
|
+
if (isNullish(tx.data) && isNullish(tx.input) && isNullish(tx.gas)) {
|
127
|
+
// eth.call runs into error if data isnt filled and gas is not defined, its a simple transaction so we fill it with 21000
|
128
|
+
formatTx = {
|
129
|
+
...tx,
|
130
|
+
gas: 21000,
|
131
|
+
};
|
132
|
+
}
|
133
|
+
const reason = await getRevertReason(
|
134
|
+
this.web3Context,
|
135
|
+
formatTx,
|
136
|
+
this.options.contractAbi,
|
137
|
+
);
|
138
|
+
if (reason !== undefined) {
|
139
|
+
throw await getTransactionError<ReturnFormat>(
|
140
|
+
this.web3Context,
|
141
|
+
tx,
|
142
|
+
undefined,
|
143
|
+
undefined,
|
144
|
+
this.options.contractAbi,
|
145
|
+
reason,
|
146
|
+
);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
public emitSending(tx: TxType | HexString) {
|
152
|
+
if (this.promiEvent.listenerCount('sending') > 0) {
|
153
|
+
this.promiEvent.emit('sending', tx);
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
public async populateGasPrice({
|
158
|
+
transactionFormatted,
|
159
|
+
transaction,
|
160
|
+
}: {
|
161
|
+
transactionFormatted: TxType;
|
162
|
+
transaction: TxType;
|
163
|
+
}): Promise<TxType> {
|
164
|
+
let result = transactionFormatted;
|
165
|
+
if (
|
166
|
+
!this.web3Context.config.ignoreGasPricing &&
|
167
|
+
!this.options?.ignoreGasPricing &&
|
168
|
+
isNullish((transactionFormatted as Transaction).gasPrice) &&
|
169
|
+
(isNullish((transaction as Transaction).maxPriorityFeePerGas) ||
|
170
|
+
isNullish((transaction as Transaction).maxFeePerGas))
|
171
|
+
) {
|
172
|
+
result = {
|
173
|
+
...transactionFormatted,
|
174
|
+
// @TODO gasPrice, maxPriorityFeePerGas, maxFeePerGas
|
175
|
+
// should not be included if undefined, but currently are
|
176
|
+
...(await getTransactionGasPricing(
|
177
|
+
transactionFormatted,
|
178
|
+
this.web3Context,
|
179
|
+
ETH_DATA_FORMAT,
|
180
|
+
)),
|
181
|
+
};
|
182
|
+
}
|
183
|
+
|
184
|
+
return result;
|
185
|
+
}
|
186
|
+
|
187
|
+
public async signAndSend({
|
188
|
+
wallet,
|
189
|
+
tx,
|
190
|
+
}: {
|
191
|
+
wallet: Web3BaseWalletAccount | undefined;
|
192
|
+
tx: TxType;
|
193
|
+
}) {
|
194
|
+
if (wallet) {
|
195
|
+
const signedTransaction = await wallet.signTransaction(tx);
|
196
|
+
|
197
|
+
return trySendTransaction(
|
198
|
+
this.web3Context,
|
199
|
+
async (): Promise<string> =>
|
200
|
+
ethRpcMethods.sendRawTransaction(
|
201
|
+
this.web3Context.requestManager,
|
202
|
+
signedTransaction.rawTransaction,
|
203
|
+
),
|
204
|
+
signedTransaction.transactionHash,
|
205
|
+
);
|
206
|
+
}
|
207
|
+
return trySendTransaction(
|
208
|
+
this.web3Context,
|
209
|
+
async (): Promise<string> =>
|
210
|
+
ethRpcMethods.sendTransaction(
|
211
|
+
this.web3Context.requestManager,
|
212
|
+
tx as Partial<TransactionWithSenderAPI>,
|
213
|
+
),
|
214
|
+
);
|
215
|
+
}
|
216
|
+
|
217
|
+
public emitSent(tx: TxType | HexString) {
|
218
|
+
if (this.promiEvent.listenerCount('sent') > 0) {
|
219
|
+
this.promiEvent.emit('sent', tx);
|
220
|
+
}
|
221
|
+
}
|
222
|
+
public emitTransactionHash(hash: string & Uint8Array) {
|
223
|
+
if (this.promiEvent.listenerCount('transactionHash') > 0) {
|
224
|
+
this.promiEvent.emit('transactionHash', hash);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
public emitReceipt(receipt: ResolveType) {
|
229
|
+
if (this.promiEvent.listenerCount('receipt') > 0) {
|
230
|
+
(
|
231
|
+
this.promiEvent as Web3EventEmitter<
|
232
|
+
SendTransactionEvents<ReturnFormat> | SendSignedTransactionEvents<ReturnFormat>
|
233
|
+
>
|
234
|
+
).emit(
|
235
|
+
'receipt',
|
236
|
+
// @ts-expect-error unknown type fix
|
237
|
+
receipt,
|
238
|
+
);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
public async handleError({ error, tx }: { error: unknown; tx: TransactionCall }) {
|
243
|
+
let _error = error;
|
244
|
+
|
245
|
+
if (_error instanceof ContractExecutionError && this.web3Context.handleRevert) {
|
246
|
+
_error = await getTransactionError(
|
247
|
+
this.web3Context,
|
248
|
+
tx,
|
249
|
+
undefined,
|
250
|
+
undefined,
|
251
|
+
this.options?.contractAbi,
|
252
|
+
);
|
253
|
+
}
|
254
|
+
|
255
|
+
if (
|
256
|
+
(_error instanceof InvalidResponseError ||
|
257
|
+
_error instanceof ContractExecutionError ||
|
258
|
+
_error instanceof TransactionRevertWithCustomError ||
|
259
|
+
_error instanceof TransactionRevertedWithoutReasonError ||
|
260
|
+
_error instanceof TransactionRevertInstructionError ||
|
261
|
+
_error instanceof TransactionPollingTimeoutError) &&
|
262
|
+
this.promiEvent.listenerCount('error') > 0
|
263
|
+
) {
|
264
|
+
this.promiEvent.emit('error', _error);
|
265
|
+
}
|
266
|
+
|
267
|
+
return _error;
|
268
|
+
}
|
269
|
+
|
270
|
+
public emitConfirmation({
|
271
|
+
receipt,
|
272
|
+
transactionHash,
|
273
|
+
customTransactionReceiptSchema,
|
274
|
+
}: {
|
275
|
+
receipt: ResolveType;
|
276
|
+
transactionHash: TransactionHash;
|
277
|
+
customTransactionReceiptSchema?: JsonSchema;
|
278
|
+
}) {
|
279
|
+
if (this.promiEvent.listenerCount('confirmation') > 0) {
|
280
|
+
watchTransactionForConfirmations<
|
281
|
+
ReturnFormat,
|
282
|
+
SendSignedTransactionEvents<ReturnFormat> | SendTransactionEvents<ReturnFormat>,
|
283
|
+
ResolveType
|
284
|
+
>(
|
285
|
+
this.web3Context,
|
286
|
+
this.promiEvent,
|
287
|
+
receipt as unknown as TransactionReceipt,
|
288
|
+
transactionHash,
|
289
|
+
this.returnFormat,
|
290
|
+
customTransactionReceiptSchema,
|
291
|
+
);
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
public async handleResolve({ receipt, tx }: { receipt: ResolveType; tx: TransactionCall }) {
|
296
|
+
if (this.options?.transactionResolver) {
|
297
|
+
return this.options?.transactionResolver(receipt as unknown as TransactionReceipt);
|
298
|
+
}
|
299
|
+
if ((receipt as unknown as TransactionReceipt).status === BigInt(0)) {
|
300
|
+
const error = await getTransactionError<ReturnFormat>(
|
301
|
+
this.web3Context,
|
302
|
+
tx,
|
303
|
+
// @ts-expect-error unknown type fix
|
304
|
+
receipt,
|
305
|
+
undefined,
|
306
|
+
this.options?.contractAbi,
|
307
|
+
);
|
308
|
+
if (this.promiEvent.listenerCount('error') > 0) {
|
309
|
+
this.promiEvent.emit('error', error);
|
310
|
+
}
|
311
|
+
|
312
|
+
throw error;
|
313
|
+
} else {
|
314
|
+
return receipt;
|
315
|
+
}
|
316
|
+
}
|
317
|
+
}
|
@@ -0,0 +1,264 @@
|
|
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
|
+
EthExecutionAPI,
|
20
|
+
Address,
|
21
|
+
HexString,
|
22
|
+
ValidChains,
|
23
|
+
Hardfork,
|
24
|
+
Transaction,
|
25
|
+
TransactionWithFromLocalWalletIndex,
|
26
|
+
TransactionWithToLocalWalletIndex,
|
27
|
+
TransactionWithFromAndToLocalWalletIndex,
|
28
|
+
Common,
|
29
|
+
Web3NetAPI,
|
30
|
+
Numbers,
|
31
|
+
DataFormat,
|
32
|
+
FormatType,
|
33
|
+
ETH_DATA_FORMAT,
|
34
|
+
} from 'web3-types';
|
35
|
+
import { Web3Context } from 'web3-core';
|
36
|
+
import { privateKeyToAddress } from 'web3-eth-accounts';
|
37
|
+
import { getId } from 'web3-net';
|
38
|
+
import { isNullish, isNumber, isHexStrict, isAddress } from 'web3-validator';
|
39
|
+
import {
|
40
|
+
InvalidTransactionWithSender,
|
41
|
+
InvalidTransactionWithReceiver,
|
42
|
+
LocalWalletNotAvailableError,
|
43
|
+
TransactionDataAndInputError,
|
44
|
+
UnableToPopulateNonceError,
|
45
|
+
} from 'web3-errors';
|
46
|
+
import { bytesToHex, format } from 'web3-utils';
|
47
|
+
import { NUMBER_DATA_FORMAT } from '../constants.js';
|
48
|
+
// eslint-disable-next-line import/no-cycle
|
49
|
+
import { getChainId, getTransactionCount, estimateGas } from '../rpc_method_wrappers.js';
|
50
|
+
import { detectTransactionType } from './detect_transaction_type.js';
|
51
|
+
import { transactionSchema } from '../schemas.js';
|
52
|
+
import { InternalTransaction } from '../types.js';
|
53
|
+
// eslint-disable-next-line import/no-cycle
|
54
|
+
import { getTransactionGasPricing } from './get_transaction_gas_pricing.js';
|
55
|
+
|
56
|
+
export const getTransactionFromOrToAttr = (
|
57
|
+
attr: 'from' | 'to',
|
58
|
+
web3Context: Web3Context<EthExecutionAPI>,
|
59
|
+
transaction?:
|
60
|
+
| Transaction
|
61
|
+
| TransactionWithFromLocalWalletIndex
|
62
|
+
| TransactionWithToLocalWalletIndex
|
63
|
+
| TransactionWithFromAndToLocalWalletIndex,
|
64
|
+
privateKey?: HexString | Uint8Array,
|
65
|
+
): Address | undefined => {
|
66
|
+
if (transaction !== undefined && attr in transaction && transaction[attr] !== undefined) {
|
67
|
+
if (typeof transaction[attr] === 'string' && isAddress(transaction[attr] as string)) {
|
68
|
+
return transaction[attr] as Address;
|
69
|
+
}
|
70
|
+
if (!isHexStrict(transaction[attr] as string) && isNumber(transaction[attr] as Numbers)) {
|
71
|
+
if (web3Context.wallet) {
|
72
|
+
const account = web3Context.wallet.get(
|
73
|
+
format({ format: 'uint' }, transaction[attr] as Numbers, NUMBER_DATA_FORMAT),
|
74
|
+
);
|
75
|
+
|
76
|
+
if (!isNullish(account)) {
|
77
|
+
return account.address;
|
78
|
+
}
|
79
|
+
|
80
|
+
throw new LocalWalletNotAvailableError();
|
81
|
+
}
|
82
|
+
throw new LocalWalletNotAvailableError();
|
83
|
+
} else {
|
84
|
+
throw attr === 'from'
|
85
|
+
? new InvalidTransactionWithSender(transaction.from)
|
86
|
+
: // eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
87
|
+
new InvalidTransactionWithReceiver(transaction.to);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
if (attr === 'from') {
|
91
|
+
if (!isNullish(privateKey)) return privateKeyToAddress(privateKey);
|
92
|
+
if (!isNullish(web3Context.defaultAccount)) return web3Context.defaultAccount;
|
93
|
+
}
|
94
|
+
|
95
|
+
return undefined;
|
96
|
+
};
|
97
|
+
|
98
|
+
export const getTransactionNonce = async <ReturnFormat extends DataFormat>(
|
99
|
+
web3Context: Web3Context<EthExecutionAPI>,
|
100
|
+
address?: Address,
|
101
|
+
returnFormat: ReturnFormat = web3Context.defaultReturnFormat as ReturnFormat,
|
102
|
+
) => {
|
103
|
+
if (isNullish(address)) {
|
104
|
+
// TODO if (web3.eth.accounts.wallet) use address from local wallet
|
105
|
+
throw new UnableToPopulateNonceError();
|
106
|
+
}
|
107
|
+
|
108
|
+
return getTransactionCount(web3Context, address, web3Context.defaultBlock, returnFormat);
|
109
|
+
};
|
110
|
+
|
111
|
+
export const getTransactionType = (
|
112
|
+
transaction: FormatType<Transaction, typeof ETH_DATA_FORMAT>,
|
113
|
+
web3Context: Web3Context<EthExecutionAPI>,
|
114
|
+
) => {
|
115
|
+
const inferredType = detectTransactionType(transaction, web3Context);
|
116
|
+
if (!isNullish(inferredType)) return inferredType;
|
117
|
+
if (!isNullish(web3Context.defaultTransactionType))
|
118
|
+
return format({ format: 'uint' }, web3Context.defaultTransactionType, ETH_DATA_FORMAT);
|
119
|
+
|
120
|
+
return undefined;
|
121
|
+
};
|
122
|
+
|
123
|
+
// Keep in mind that the order the properties of populateTransaction get populated matters
|
124
|
+
// as some of the properties are dependent on others
|
125
|
+
export async function defaultTransactionBuilder<ReturnType = Transaction>(options: {
|
126
|
+
transaction: Transaction;
|
127
|
+
web3Context: Web3Context<EthExecutionAPI & Web3NetAPI>;
|
128
|
+
privateKey?: HexString | Uint8Array;
|
129
|
+
fillGasPrice?: boolean;
|
130
|
+
fillGasLimit?: boolean;
|
131
|
+
}): Promise<ReturnType> {
|
132
|
+
let populatedTransaction = format(
|
133
|
+
transactionSchema,
|
134
|
+
options.transaction,
|
135
|
+
options.web3Context.defaultReturnFormat,
|
136
|
+
) as InternalTransaction;
|
137
|
+
|
138
|
+
if (isNullish(populatedTransaction.from)) {
|
139
|
+
populatedTransaction.from = getTransactionFromOrToAttr(
|
140
|
+
'from',
|
141
|
+
options.web3Context,
|
142
|
+
undefined,
|
143
|
+
options.privateKey,
|
144
|
+
);
|
145
|
+
}
|
146
|
+
|
147
|
+
// TODO: Debug why need to typecase getTransactionNonce
|
148
|
+
if (isNullish(populatedTransaction.nonce)) {
|
149
|
+
populatedTransaction.nonce = await getTransactionNonce(
|
150
|
+
options.web3Context,
|
151
|
+
populatedTransaction.from,
|
152
|
+
ETH_DATA_FORMAT,
|
153
|
+
);
|
154
|
+
}
|
155
|
+
|
156
|
+
if (isNullish(populatedTransaction.value)) {
|
157
|
+
populatedTransaction.value = '0x0';
|
158
|
+
}
|
159
|
+
|
160
|
+
if (!isNullish(populatedTransaction.data)) {
|
161
|
+
if (
|
162
|
+
!isNullish(populatedTransaction.input) &&
|
163
|
+
populatedTransaction.data !== populatedTransaction.input
|
164
|
+
)
|
165
|
+
throw new TransactionDataAndInputError({
|
166
|
+
data: bytesToHex(populatedTransaction.data),
|
167
|
+
input: bytesToHex(populatedTransaction.input),
|
168
|
+
});
|
169
|
+
|
170
|
+
if (!populatedTransaction.data.startsWith('0x'))
|
171
|
+
populatedTransaction.data = `0x${populatedTransaction.data}`;
|
172
|
+
} else if (!isNullish(populatedTransaction.input)) {
|
173
|
+
if (!populatedTransaction.input.startsWith('0x'))
|
174
|
+
populatedTransaction.input = `0x${populatedTransaction.input}`;
|
175
|
+
} else {
|
176
|
+
populatedTransaction.input = '0x';
|
177
|
+
}
|
178
|
+
|
179
|
+
if (isNullish(populatedTransaction.common)) {
|
180
|
+
if (options.web3Context.defaultCommon) {
|
181
|
+
const common = options.web3Context.defaultCommon as unknown as Common;
|
182
|
+
const chainId = common.customChain.chainId as string;
|
183
|
+
const networkId = common.customChain.networkId as string;
|
184
|
+
const name = common.customChain.name as string;
|
185
|
+
populatedTransaction.common = {
|
186
|
+
...common,
|
187
|
+
customChain: { chainId, networkId, name },
|
188
|
+
};
|
189
|
+
}
|
190
|
+
|
191
|
+
if (isNullish(populatedTransaction.chain)) {
|
192
|
+
populatedTransaction.chain = options.web3Context.defaultChain as ValidChains;
|
193
|
+
}
|
194
|
+
if (isNullish(populatedTransaction.hardfork)) {
|
195
|
+
populatedTransaction.hardfork = options.web3Context.defaultHardfork as Hardfork;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
if (
|
200
|
+
isNullish(populatedTransaction.chainId) &&
|
201
|
+
isNullish(populatedTransaction.common?.customChain.chainId)
|
202
|
+
) {
|
203
|
+
populatedTransaction.chainId = await getChainId(options.web3Context, ETH_DATA_FORMAT);
|
204
|
+
}
|
205
|
+
|
206
|
+
if (isNullish(populatedTransaction.networkId)) {
|
207
|
+
populatedTransaction.networkId =
|
208
|
+
(options.web3Context.defaultNetworkId as string) ??
|
209
|
+
(await getId(options.web3Context, ETH_DATA_FORMAT));
|
210
|
+
}
|
211
|
+
|
212
|
+
if (isNullish(populatedTransaction.gasLimit) && !isNullish(populatedTransaction.gas)) {
|
213
|
+
populatedTransaction.gasLimit = populatedTransaction.gas;
|
214
|
+
}
|
215
|
+
|
216
|
+
populatedTransaction.type = getTransactionType(populatedTransaction, options.web3Context);
|
217
|
+
if (
|
218
|
+
isNullish(populatedTransaction.accessList) &&
|
219
|
+
(populatedTransaction.type === '0x1' || populatedTransaction.type === '0x2')
|
220
|
+
) {
|
221
|
+
populatedTransaction.accessList = [];
|
222
|
+
}
|
223
|
+
if (options.fillGasPrice)
|
224
|
+
populatedTransaction = {
|
225
|
+
...populatedTransaction,
|
226
|
+
...(await getTransactionGasPricing(
|
227
|
+
populatedTransaction,
|
228
|
+
options.web3Context,
|
229
|
+
ETH_DATA_FORMAT,
|
230
|
+
)),
|
231
|
+
};
|
232
|
+
if (
|
233
|
+
isNullish(populatedTransaction.gas) &&
|
234
|
+
isNullish(populatedTransaction.gasLimit) &&
|
235
|
+
options.fillGasLimit
|
236
|
+
) {
|
237
|
+
const fillGasLimit = await estimateGas(
|
238
|
+
options.web3Context,
|
239
|
+
populatedTransaction,
|
240
|
+
'latest',
|
241
|
+
ETH_DATA_FORMAT,
|
242
|
+
);
|
243
|
+
populatedTransaction = {
|
244
|
+
...populatedTransaction,
|
245
|
+
gas: format({ format: 'uint' }, fillGasLimit as Numbers, ETH_DATA_FORMAT),
|
246
|
+
};
|
247
|
+
}
|
248
|
+
return populatedTransaction as ReturnType;
|
249
|
+
}
|
250
|
+
|
251
|
+
export const transactionBuilder = async <ReturnType = Transaction>(
|
252
|
+
options: {
|
253
|
+
transaction: Transaction;
|
254
|
+
web3Context: Web3Context<EthExecutionAPI>;
|
255
|
+
privateKey?: HexString | Uint8Array;
|
256
|
+
fillGasPrice?: boolean;
|
257
|
+
fillGasLimit?: boolean;
|
258
|
+
},
|
259
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
260
|
+
) =>
|
261
|
+
(options.web3Context.transactionBuilder ?? defaultTransactionBuilder)({
|
262
|
+
...options,
|
263
|
+
transaction: options.transaction,
|
264
|
+
}) as unknown as ReturnType;
|
@@ -0,0 +1,61 @@
|
|
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 { Web3Context } from 'web3-core';
|
18
|
+
import { EthExecutionAPI, Bytes } from 'web3-types';
|
19
|
+
import { AsyncFunction, rejectIfTimeout } from 'web3-utils';
|
20
|
+
import { TransactionSendTimeoutError } from 'web3-errors';
|
21
|
+
|
22
|
+
// eslint-disable-next-line import/no-cycle
|
23
|
+
import { rejectIfBlockTimeout } from './reject_if_block_timeout.js';
|
24
|
+
|
25
|
+
/**
|
26
|
+
* An internal function to send a transaction or throws if sending did not finish during the timeout during the blocks-timeout.
|
27
|
+
* @param web3Context - the context to read the configurations from
|
28
|
+
* @param sendTransactionFunc - the function that will send the transaction (could be sendTransaction or sendRawTransaction)
|
29
|
+
* @param transactionHash - to be used inside the exception message if there will be any exceptions.
|
30
|
+
* @returns the Promise<string> returned by the `sendTransactionFunc`.
|
31
|
+
*/
|
32
|
+
export async function trySendTransaction(
|
33
|
+
web3Context: Web3Context<EthExecutionAPI>,
|
34
|
+
sendTransactionFunc: AsyncFunction<string>,
|
35
|
+
transactionHash?: Bytes,
|
36
|
+
): Promise<string> {
|
37
|
+
const [timeoutId, rejectOnTimeout] = rejectIfTimeout(
|
38
|
+
web3Context.transactionSendTimeout,
|
39
|
+
new TransactionSendTimeoutError({
|
40
|
+
numberOfSeconds: web3Context.transactionSendTimeout / 1000,
|
41
|
+
transactionHash,
|
42
|
+
}),
|
43
|
+
);
|
44
|
+
|
45
|
+
const [rejectOnBlockTimeout, blockTimeoutResourceCleaner] = await rejectIfBlockTimeout(
|
46
|
+
web3Context,
|
47
|
+
transactionHash,
|
48
|
+
);
|
49
|
+
|
50
|
+
try {
|
51
|
+
// If an error happened here, do not catch it, just clear the resources before raising it to the caller function.
|
52
|
+
return await Promise.race([
|
53
|
+
sendTransactionFunc(), // this is the function that will send the transaction
|
54
|
+
rejectOnTimeout, // this will throw an error on Transaction Send Timeout
|
55
|
+
rejectOnBlockTimeout, // this will throw an error on Transaction Block Timeout
|
56
|
+
]);
|
57
|
+
} finally {
|
58
|
+
clearTimeout(timeoutId);
|
59
|
+
blockTimeoutResourceCleaner.clean();
|
60
|
+
}
|
61
|
+
}
|