@metamask/transaction-controller 8.0.0 → 8.0.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.
- package/CHANGELOG.md +6 -1
- package/dist/EtherscanRemoteTransactionSource.d.ts +15 -0
- package/dist/EtherscanRemoteTransactionSource.d.ts.map +1 -0
- package/dist/EtherscanRemoteTransactionSource.js +87 -0
- package/dist/EtherscanRemoteTransactionSource.js.map +1 -0
- package/dist/IncomingTransactionHelper.d.ts +23 -0
- package/dist/IncomingTransactionHelper.d.ts.map +1 -0
- package/dist/IncomingTransactionHelper.js +144 -0
- package/dist/IncomingTransactionHelper.js.map +1 -0
- package/dist/TransactionController.d.ts +2 -203
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +46 -248
- package/dist/TransactionController.js.map +1 -1
- package/dist/etherscan.d.ts +66 -0
- package/dist/etherscan.d.ts.map +1 -0
- package/dist/etherscan.js +114 -0
- package/dist/etherscan.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +139 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +2 -23
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -77
- package/dist/utils.js.map +1 -1
- package/package.json +5 -5
- package/dist/mocks/txsMock.d.ts +0 -64
- package/dist/mocks/txsMock.d.ts.map +0 -1
- package/dist/mocks/txsMock.js +0 -516
- package/dist/mocks/txsMock.js.map +0 -1
|
@@ -12,46 +12,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.TransactionController = exports.SPEED_UP_RATE = exports.CANCEL_RATE = exports.
|
|
15
|
+
exports.TransactionController = exports.SPEED_UP_RATE = exports.CANCEL_RATE = exports.HARDFORK = void 0;
|
|
16
16
|
const common_1 = require("@ethereumjs/common");
|
|
17
17
|
const tx_1 = require("@ethereumjs/tx");
|
|
18
18
|
const base_controller_1 = require("@metamask/base-controller");
|
|
19
19
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
20
|
+
const eth_query_1 = __importDefault(require("@metamask/eth-query"));
|
|
20
21
|
const async_mutex_1 = require("async-mutex");
|
|
21
22
|
const eth_method_registry_1 = __importDefault(require("eth-method-registry"));
|
|
22
|
-
const eth_query_1 = __importDefault(require("eth-query"));
|
|
23
23
|
const eth_rpc_errors_1 = require("eth-rpc-errors");
|
|
24
24
|
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
25
25
|
const events_1 = require("events");
|
|
26
26
|
const nonce_tracker_1 = __importDefault(require("nonce-tracker"));
|
|
27
27
|
const uuid_1 = require("uuid");
|
|
28
|
+
const EtherscanRemoteTransactionSource_1 = require("./EtherscanRemoteTransactionSource");
|
|
29
|
+
const IncomingTransactionHelper_1 = require("./IncomingTransactionHelper");
|
|
30
|
+
const types_1 = require("./types");
|
|
28
31
|
const utils_1 = require("./utils");
|
|
29
32
|
exports.HARDFORK = common_1.Hardfork.London;
|
|
30
|
-
/**
|
|
31
|
-
* The status of the transaction. Each status represents the state of the transaction internally
|
|
32
|
-
* in the wallet. Some of these correspond with the state of the transaction on the network, but
|
|
33
|
-
* some are wallet-specific.
|
|
34
|
-
*/
|
|
35
|
-
var TransactionStatus;
|
|
36
|
-
(function (TransactionStatus) {
|
|
37
|
-
TransactionStatus["approved"] = "approved";
|
|
38
|
-
TransactionStatus["cancelled"] = "cancelled";
|
|
39
|
-
TransactionStatus["confirmed"] = "confirmed";
|
|
40
|
-
TransactionStatus["failed"] = "failed";
|
|
41
|
-
TransactionStatus["rejected"] = "rejected";
|
|
42
|
-
TransactionStatus["signed"] = "signed";
|
|
43
|
-
TransactionStatus["submitted"] = "submitted";
|
|
44
|
-
TransactionStatus["unapproved"] = "unapproved";
|
|
45
|
-
})(TransactionStatus = exports.TransactionStatus || (exports.TransactionStatus = {}));
|
|
46
|
-
/**
|
|
47
|
-
* Options for wallet device.
|
|
48
|
-
*/
|
|
49
|
-
var WalletDevice;
|
|
50
|
-
(function (WalletDevice) {
|
|
51
|
-
WalletDevice["MM_MOBILE"] = "metamask_mobile";
|
|
52
|
-
WalletDevice["MM_EXTENSION"] = "metamask_extension";
|
|
53
|
-
WalletDevice["OTHER"] = "other_device";
|
|
54
|
-
})(WalletDevice = exports.WalletDevice || (exports.WalletDevice = {}));
|
|
55
33
|
/**
|
|
56
34
|
* Multiplier used to determine a transaction's increased gas fee during cancellation
|
|
57
35
|
*/
|
|
@@ -83,34 +61,6 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
83
61
|
constructor({ getNetworkState, onNetworkStateChange, provider, blockTracker, messenger, }, config, state) {
|
|
84
62
|
super(config, state);
|
|
85
63
|
this.mutex = new async_mutex_1.Mutex();
|
|
86
|
-
this.normalizeTokenTx = (txMeta, currentNetworkID, currentChainId) => {
|
|
87
|
-
const time = parseInt(txMeta.timeStamp, 10) * 1000;
|
|
88
|
-
const { to, from, gas, gasPrice, gasUsed, hash, contractAddress, tokenDecimal, tokenSymbol, value, } = txMeta;
|
|
89
|
-
return {
|
|
90
|
-
id: (0, uuid_1.v1)({ msecs: time }),
|
|
91
|
-
isTransfer: true,
|
|
92
|
-
networkID: currentNetworkID,
|
|
93
|
-
chainId: currentChainId,
|
|
94
|
-
status: TransactionStatus.confirmed,
|
|
95
|
-
time,
|
|
96
|
-
transaction: {
|
|
97
|
-
chainId: currentChainId,
|
|
98
|
-
from,
|
|
99
|
-
gas,
|
|
100
|
-
gasPrice,
|
|
101
|
-
gasUsed,
|
|
102
|
-
to,
|
|
103
|
-
value,
|
|
104
|
-
},
|
|
105
|
-
transactionHash: hash,
|
|
106
|
-
transferInformation: {
|
|
107
|
-
contractAddress,
|
|
108
|
-
decimals: Number(tokenDecimal),
|
|
109
|
-
symbol: tokenSymbol,
|
|
110
|
-
},
|
|
111
|
-
verifiedOnBlockchain: false,
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
64
|
/**
|
|
115
65
|
* EventEmitter instance used to listen to specific transactional events
|
|
116
66
|
*/
|
|
@@ -136,8 +86,14 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
136
86
|
this.nonceTracker = new nonce_tracker_1.default({
|
|
137
87
|
provider,
|
|
138
88
|
blockTracker,
|
|
139
|
-
getPendingTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, TransactionStatus.submitted, this.state.transactions),
|
|
140
|
-
getConfirmedTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, TransactionStatus.confirmed, this.state.transactions),
|
|
89
|
+
getPendingTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, types_1.TransactionStatus.submitted, this.state.transactions),
|
|
90
|
+
getConfirmedTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, types_1.TransactionStatus.confirmed, this.state.transactions),
|
|
91
|
+
});
|
|
92
|
+
this.incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
|
|
93
|
+
getNetworkState,
|
|
94
|
+
getEthQuery: () => this.ethQuery,
|
|
95
|
+
transactionLimit: this.config.txHistoryLimit,
|
|
96
|
+
remoteTransactionSource: new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource(),
|
|
141
97
|
});
|
|
142
98
|
onNetworkStateChange(() => {
|
|
143
99
|
this.ethQuery = new eth_query_1.default(this.provider);
|
|
@@ -146,7 +102,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
146
102
|
this.poll();
|
|
147
103
|
}
|
|
148
104
|
failTransaction(transactionMeta, error) {
|
|
149
|
-
const newTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { error, status: TransactionStatus.failed });
|
|
105
|
+
const newTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { error, status: types_1.TransactionStatus.failed });
|
|
150
106
|
this.updateTransaction(newTransactionMeta);
|
|
151
107
|
this.hub.emit(`${transactionMeta.id}:finished`, newTransactionMeta);
|
|
152
108
|
}
|
|
@@ -157,43 +113,6 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
157
113
|
return { registryMethod, parsedRegistryMethod };
|
|
158
114
|
});
|
|
159
115
|
}
|
|
160
|
-
/**
|
|
161
|
-
* Normalizes the transaction information from etherscan
|
|
162
|
-
* to be compatible with the TransactionMeta interface.
|
|
163
|
-
*
|
|
164
|
-
* @param txMeta - The transaction.
|
|
165
|
-
* @param currentNetworkID - The current network ID.
|
|
166
|
-
* @param currentChainId - The current chain ID.
|
|
167
|
-
* @returns The normalized transaction.
|
|
168
|
-
*/
|
|
169
|
-
normalizeTx(txMeta, currentNetworkID, currentChainId) {
|
|
170
|
-
const time = parseInt(txMeta.timeStamp, 10) * 1000;
|
|
171
|
-
const normalizedTransactionBase = {
|
|
172
|
-
blockNumber: txMeta.blockNumber,
|
|
173
|
-
id: (0, uuid_1.v1)({ msecs: time }),
|
|
174
|
-
networkID: currentNetworkID,
|
|
175
|
-
chainId: currentChainId,
|
|
176
|
-
time,
|
|
177
|
-
transaction: {
|
|
178
|
-
data: txMeta.input,
|
|
179
|
-
from: txMeta.from,
|
|
180
|
-
gas: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gas)),
|
|
181
|
-
gasPrice: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasPrice)),
|
|
182
|
-
gasUsed: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasUsed)),
|
|
183
|
-
nonce: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.nonce)),
|
|
184
|
-
to: txMeta.to,
|
|
185
|
-
value: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.value)),
|
|
186
|
-
},
|
|
187
|
-
transactionHash: txMeta.hash,
|
|
188
|
-
verifiedOnBlockchain: false,
|
|
189
|
-
};
|
|
190
|
-
/* istanbul ignore else */
|
|
191
|
-
if (txMeta.isError === '0') {
|
|
192
|
-
return Object.assign(Object.assign({}, normalizedTransactionBase), { status: TransactionStatus.confirmed });
|
|
193
|
-
}
|
|
194
|
-
/* istanbul ignore next */
|
|
195
|
-
return Object.assign(Object.assign({}, normalizedTransactionBase), { error: new Error('Transaction failed'), status: TransactionStatus.failed });
|
|
196
|
-
}
|
|
197
116
|
/**
|
|
198
117
|
* Starts a new polling interval.
|
|
199
118
|
*
|
|
@@ -256,7 +175,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
256
175
|
networkID: networkId !== null && networkId !== void 0 ? networkId : undefined,
|
|
257
176
|
chainId: providerConfig.chainId,
|
|
258
177
|
origin,
|
|
259
|
-
status: TransactionStatus.unapproved,
|
|
178
|
+
status: types_1.TransactionStatus.unapproved,
|
|
260
179
|
time: Date.now(),
|
|
261
180
|
transaction,
|
|
262
181
|
deviceConfirmedOn,
|
|
@@ -373,7 +292,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
373
292
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.transaction.from);
|
|
374
293
|
const rawTransaction = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
|
|
375
294
|
yield (0, controller_utils_1.query)(this.ethQuery, 'sendRawTransaction', [rawTransaction]);
|
|
376
|
-
transactionMeta.status = TransactionStatus.cancelled;
|
|
295
|
+
transactionMeta.status = types_1.TransactionStatus.cancelled;
|
|
377
296
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
378
297
|
});
|
|
379
298
|
}
|
|
@@ -585,57 +504,19 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
585
504
|
*/
|
|
586
505
|
fetchAll(address, opt) {
|
|
587
506
|
return __awaiter(this, void 0, void 0, function* () {
|
|
588
|
-
const {
|
|
589
|
-
const {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
return undefined;
|
|
596
|
-
}
|
|
597
|
-
const [etherscanTxResponse, etherscanTokenResponse] = yield (0, utils_1.handleTransactionFetch)(networkType, address, this.config.txHistoryLimit, opt);
|
|
598
|
-
const normalizedTxs = etherscanTxResponse.result.map((tx) => this.normalizeTx(tx, currentNetworkID, currentChainId));
|
|
599
|
-
const normalizedTokenTxs = etherscanTokenResponse.result.map((tx) => this.normalizeTokenTx(tx, currentNetworkID, currentChainId));
|
|
600
|
-
const [updateRequired, allTxs] = this.etherscanTransactionStateReconciler([...normalizedTxs, ...normalizedTokenTxs], transactions);
|
|
601
|
-
allTxs.sort((a, b) => (a.time < b.time ? -1 : 1));
|
|
602
|
-
let latestIncomingTxBlockNumber;
|
|
603
|
-
allTxs.forEach((tx) => __awaiter(this, void 0, void 0, function* () {
|
|
604
|
-
/* istanbul ignore next */
|
|
605
|
-
if (
|
|
606
|
-
// Using fallback to networkID only when there is no chainId present. Should be removed when networkID is completely removed.
|
|
607
|
-
(tx.chainId === currentChainId ||
|
|
608
|
-
(!tx.chainId && tx.networkID === currentNetworkID)) &&
|
|
609
|
-
tx.transaction.to &&
|
|
610
|
-
tx.transaction.to.toLowerCase() === address.toLowerCase()) {
|
|
611
|
-
if (tx.blockNumber &&
|
|
612
|
-
(!latestIncomingTxBlockNumber ||
|
|
613
|
-
parseInt(latestIncomingTxBlockNumber, 10) <
|
|
614
|
-
parseInt(tx.blockNumber, 10))) {
|
|
615
|
-
latestIncomingTxBlockNumber = tx.blockNumber;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
/* istanbul ignore else */
|
|
619
|
-
if (tx.toSmartContract === undefined) {
|
|
620
|
-
// If not `to` is a contract deploy, if not `data` is send eth
|
|
621
|
-
if (tx.transaction.to &&
|
|
622
|
-
(!tx.transaction.data || tx.transaction.data !== '0x')) {
|
|
623
|
-
const code = yield (0, controller_utils_1.query)(this.ethQuery, 'getCode', [
|
|
624
|
-
tx.transaction.to,
|
|
625
|
-
]);
|
|
626
|
-
tx.toSmartContract = (0, controller_utils_1.isSmartContractCode)(code);
|
|
627
|
-
}
|
|
628
|
-
else {
|
|
629
|
-
tx.toSmartContract = false;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
}));
|
|
633
|
-
// Update state only if new transactions were fetched or
|
|
634
|
-
// the status or gas data of a transaction has changed
|
|
507
|
+
const { transactions: localTransactions } = this.state;
|
|
508
|
+
const { updateRequired, transactions, latestBlockNumber } = yield this.incomingTransactionHelper.reconcile({
|
|
509
|
+
address,
|
|
510
|
+
localTransactions,
|
|
511
|
+
fromBlock: opt === null || opt === void 0 ? void 0 : opt.fromBlock,
|
|
512
|
+
apiKey: opt === null || opt === void 0 ? void 0 : opt.etherscanApiKey,
|
|
513
|
+
});
|
|
635
514
|
if (updateRequired) {
|
|
636
|
-
this.update({
|
|
515
|
+
this.update({
|
|
516
|
+
transactions: this.trimTransactionsForState(transactions),
|
|
517
|
+
});
|
|
637
518
|
}
|
|
638
|
-
return
|
|
519
|
+
return latestBlockNumber;
|
|
639
520
|
});
|
|
640
521
|
}
|
|
641
522
|
processApproval(transactionMeta) {
|
|
@@ -664,14 +545,14 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
664
545
|
}
|
|
665
546
|
const finalMeta = this.getTransaction(transactionId);
|
|
666
547
|
switch (finalMeta === null || finalMeta === void 0 ? void 0 : finalMeta.status) {
|
|
667
|
-
case TransactionStatus.failed:
|
|
548
|
+
case types_1.TransactionStatus.failed:
|
|
668
549
|
resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.error(finalMeta.error);
|
|
669
550
|
throw eth_rpc_errors_1.ethErrors.rpc.internal(finalMeta.error.message);
|
|
670
|
-
case TransactionStatus.cancelled:
|
|
551
|
+
case types_1.TransactionStatus.cancelled:
|
|
671
552
|
const cancelError = eth_rpc_errors_1.ethErrors.rpc.internal('User cancelled the transaction');
|
|
672
553
|
resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.error(cancelError);
|
|
673
554
|
throw cancelError;
|
|
674
|
-
case TransactionStatus.submitted:
|
|
555
|
+
case types_1.TransactionStatus.submitted:
|
|
675
556
|
resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.success();
|
|
676
557
|
return finalMeta.transactionHash;
|
|
677
558
|
default:
|
|
@@ -710,7 +591,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
710
591
|
this.failTransaction(transactionMeta, new Error('No chainId defined.'));
|
|
711
592
|
return;
|
|
712
593
|
}
|
|
713
|
-
const { approved: status } = TransactionStatus;
|
|
594
|
+
const { approved: status } = types_1.TransactionStatus;
|
|
714
595
|
let nonceToUse = nonce;
|
|
715
596
|
// if a nonce already exists on the transactionMeta it means this is a speedup or cancel transaction
|
|
716
597
|
// so we want to reuse that nonce and hope that it beats the previous attempt to chain. Otherwise use a new locked nonce
|
|
@@ -733,7 +614,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
733
614
|
}
|
|
734
615
|
const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
|
|
735
616
|
const signedTx = yield this.sign(unsignedEthTx, from);
|
|
736
|
-
transactionMeta.status = TransactionStatus.signed;
|
|
617
|
+
transactionMeta.status = types_1.TransactionStatus.signed;
|
|
737
618
|
this.updateTransaction(transactionMeta);
|
|
738
619
|
const rawTransaction = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
|
|
739
620
|
transactionMeta.rawTransaction = rawTransaction;
|
|
@@ -742,7 +623,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
742
623
|
rawTransaction,
|
|
743
624
|
]);
|
|
744
625
|
transactionMeta.transactionHash = transactionHash;
|
|
745
|
-
transactionMeta.status = TransactionStatus.submitted;
|
|
626
|
+
transactionMeta.status = types_1.TransactionStatus.submitted;
|
|
746
627
|
this.updateTransaction(transactionMeta);
|
|
747
628
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
748
629
|
}
|
|
@@ -769,7 +650,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
769
650
|
if (!transactionMeta) {
|
|
770
651
|
return;
|
|
771
652
|
}
|
|
772
|
-
transactionMeta.status = TransactionStatus.rejected;
|
|
653
|
+
transactionMeta.status = types_1.TransactionStatus.rejected;
|
|
773
654
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
774
655
|
const transactions = this.state.transactions.filter(({ id }) => id !== transactionID);
|
|
775
656
|
this.update({ transactions: this.trimTransactionsForState(transactions) });
|
|
@@ -815,10 +696,10 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
815
696
|
* @returns Whether the transaction is in a final state.
|
|
816
697
|
*/
|
|
817
698
|
isFinalState(status) {
|
|
818
|
-
return (status === TransactionStatus.rejected ||
|
|
819
|
-
status === TransactionStatus.confirmed ||
|
|
820
|
-
status === TransactionStatus.failed ||
|
|
821
|
-
status === TransactionStatus.cancelled);
|
|
699
|
+
return (status === types_1.TransactionStatus.rejected ||
|
|
700
|
+
status === types_1.TransactionStatus.confirmed ||
|
|
701
|
+
status === types_1.TransactionStatus.failed ||
|
|
702
|
+
status === types_1.TransactionStatus.cancelled);
|
|
822
703
|
}
|
|
823
704
|
/**
|
|
824
705
|
* Whether the transaction has at least completed all local processing.
|
|
@@ -828,11 +709,11 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
828
709
|
*/
|
|
829
710
|
isLocalFinalState(status) {
|
|
830
711
|
return [
|
|
831
|
-
TransactionStatus.cancelled,
|
|
832
|
-
TransactionStatus.confirmed,
|
|
833
|
-
TransactionStatus.failed,
|
|
834
|
-
TransactionStatus.rejected,
|
|
835
|
-
TransactionStatus.submitted,
|
|
712
|
+
types_1.TransactionStatus.cancelled,
|
|
713
|
+
types_1.TransactionStatus.confirmed,
|
|
714
|
+
types_1.TransactionStatus.failed,
|
|
715
|
+
types_1.TransactionStatus.rejected,
|
|
716
|
+
types_1.TransactionStatus.submitted,
|
|
836
717
|
].includes(status);
|
|
837
718
|
}
|
|
838
719
|
/**
|
|
@@ -845,7 +726,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
845
726
|
return __awaiter(this, void 0, void 0, function* () {
|
|
846
727
|
const { status, transactionHash } = meta;
|
|
847
728
|
switch (status) {
|
|
848
|
-
case TransactionStatus.confirmed:
|
|
729
|
+
case types_1.TransactionStatus.confirmed:
|
|
849
730
|
const txReceipt = yield (0, controller_utils_1.query)(this.ethQuery, 'getTransactionReceipt', [
|
|
850
731
|
transactionHash,
|
|
851
732
|
]);
|
|
@@ -862,7 +743,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
862
743
|
return [meta, false];
|
|
863
744
|
}
|
|
864
745
|
return [meta, true];
|
|
865
|
-
case TransactionStatus.submitted:
|
|
746
|
+
case types_1.TransactionStatus.submitted:
|
|
866
747
|
const txObj = yield (0, controller_utils_1.query)(this.ethQuery, 'getTransactionByHash', [
|
|
867
748
|
transactionHash,
|
|
868
749
|
]);
|
|
@@ -877,7 +758,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
877
758
|
}
|
|
878
759
|
/* istanbul ignore next */
|
|
879
760
|
if (txObj === null || txObj === void 0 ? void 0 : txObj.blockNumber) {
|
|
880
|
-
meta.status = TransactionStatus.confirmed;
|
|
761
|
+
meta.status = types_1.TransactionStatus.confirmed;
|
|
881
762
|
this.hub.emit(`${meta.id}:confirmed`, meta);
|
|
882
763
|
return [meta, true];
|
|
883
764
|
}
|
|
@@ -908,89 +789,6 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
908
789
|
return Number(txReceipt.status) === 0;
|
|
909
790
|
});
|
|
910
791
|
}
|
|
911
|
-
/**
|
|
912
|
-
* Method to verify the state of transactions using Etherscan as a source of truth.
|
|
913
|
-
*
|
|
914
|
-
* @param remoteTxs - Transactions to reconcile that are from a remote source.
|
|
915
|
-
* @param localTxs - Transactions to reconcile that are local.
|
|
916
|
-
* @returns A tuple containing a boolean indicating whether or not an update was required, and the updated transaction.
|
|
917
|
-
*/
|
|
918
|
-
etherscanTransactionStateReconciler(remoteTxs, localTxs) {
|
|
919
|
-
const updatedTxs = this.getUpdatedTransactions(remoteTxs, localTxs);
|
|
920
|
-
const newTxs = this.getNewTransactions(remoteTxs, localTxs);
|
|
921
|
-
const updatedLocalTxs = localTxs.map((tx) => {
|
|
922
|
-
const txIdx = updatedTxs.findIndex(({ transactionHash }) => transactionHash === tx.transactionHash);
|
|
923
|
-
return txIdx === -1 ? tx : updatedTxs[txIdx];
|
|
924
|
-
});
|
|
925
|
-
const updateRequired = newTxs.length > 0 || updatedLocalTxs.length > 0;
|
|
926
|
-
return [updateRequired, [...newTxs, ...updatedLocalTxs]];
|
|
927
|
-
}
|
|
928
|
-
/**
|
|
929
|
-
* Get all transactions that are in the remote transactions array
|
|
930
|
-
* but not in the local transactions array.
|
|
931
|
-
*
|
|
932
|
-
* @param remoteTxs - Array of transactions from remote source.
|
|
933
|
-
* @param localTxs - Array of transactions stored locally.
|
|
934
|
-
* @returns The new transactions.
|
|
935
|
-
*/
|
|
936
|
-
getNewTransactions(remoteTxs, localTxs) {
|
|
937
|
-
return remoteTxs.filter((tx) => {
|
|
938
|
-
const alreadyInTransactions = localTxs.find(({ transactionHash }) => transactionHash === tx.transactionHash);
|
|
939
|
-
return !alreadyInTransactions;
|
|
940
|
-
});
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* Get all the transactions that are locally outdated with respect
|
|
944
|
-
* to a remote source (etherscan or blockchain). The returned array
|
|
945
|
-
* contains the transactions with the updated data.
|
|
946
|
-
*
|
|
947
|
-
* @param remoteTxs - Array of transactions from remote source.
|
|
948
|
-
* @param localTxs - Array of transactions stored locally.
|
|
949
|
-
* @returns The updated transactions.
|
|
950
|
-
*/
|
|
951
|
-
getUpdatedTransactions(remoteTxs, localTxs) {
|
|
952
|
-
return remoteTxs.filter((remoteTx) => {
|
|
953
|
-
const isTxOutdated = localTxs.find((localTx) => {
|
|
954
|
-
return (remoteTx.transactionHash === localTx.transactionHash &&
|
|
955
|
-
this.isTransactionOutdated(remoteTx, localTx));
|
|
956
|
-
});
|
|
957
|
-
return isTxOutdated;
|
|
958
|
-
});
|
|
959
|
-
}
|
|
960
|
-
/**
|
|
961
|
-
* Verifies if a local transaction is outdated with respect to the remote transaction.
|
|
962
|
-
*
|
|
963
|
-
* @param remoteTx - The remote transaction from Etherscan.
|
|
964
|
-
* @param localTx - The local transaction.
|
|
965
|
-
* @returns Whether the transaction is outdated.
|
|
966
|
-
*/
|
|
967
|
-
isTransactionOutdated(remoteTx, localTx) {
|
|
968
|
-
const statusOutdated = this.isStatusOutdated(remoteTx.transactionHash, localTx.transactionHash, remoteTx.status, localTx.status);
|
|
969
|
-
const gasDataOutdated = this.isGasDataOutdated(remoteTx.transaction.gasUsed, localTx.transaction.gasUsed);
|
|
970
|
-
return statusOutdated || gasDataOutdated;
|
|
971
|
-
}
|
|
972
|
-
/**
|
|
973
|
-
* Verifies if the status of a local transaction is outdated with respect to the remote transaction.
|
|
974
|
-
*
|
|
975
|
-
* @param remoteTxHash - Remote transaction hash.
|
|
976
|
-
* @param localTxHash - Local transaction hash.
|
|
977
|
-
* @param remoteTxStatus - Remote transaction status.
|
|
978
|
-
* @param localTxStatus - Local transaction status.
|
|
979
|
-
* @returns Whether the status is outdated.
|
|
980
|
-
*/
|
|
981
|
-
isStatusOutdated(remoteTxHash, localTxHash, remoteTxStatus, localTxStatus) {
|
|
982
|
-
return remoteTxHash === localTxHash && remoteTxStatus !== localTxStatus;
|
|
983
|
-
}
|
|
984
|
-
/**
|
|
985
|
-
* Verifies if the gas data of a local transaction is outdated with respect to the remote transaction.
|
|
986
|
-
*
|
|
987
|
-
* @param remoteGasUsed - Remote gas used in the transaction.
|
|
988
|
-
* @param localGasUsed - Local gas used in the transaction.
|
|
989
|
-
* @returns Whether the gas data is outdated.
|
|
990
|
-
*/
|
|
991
|
-
isGasDataOutdated(remoteGasUsed, localGasUsed) {
|
|
992
|
-
return remoteGasUsed !== localGasUsed;
|
|
993
|
-
}
|
|
994
792
|
requestApproval(txMeta) {
|
|
995
793
|
return __awaiter(this, void 0, void 0, function* () {
|
|
996
794
|
const id = this.getApprovalId(txMeta);
|