@metamask/transaction-controller 7.1.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 CHANGED
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [8.0.1]
10
+ ### Changed
11
+ - Replace `eth-query` ^2.1.2 with `@metamask/eth-query` ^3.0.1 ([#1546](https://github.com/MetaMask/core/pull/1546))
12
+
13
+ ## [8.0.0]
14
+ ### Changed
15
+ - **BREAKING**: Change `babel-runtime` from a `dependency` to a `peerDependency` ([#1504](https://github.com/MetaMask/core/pull/1504))
16
+ - Update `@metamask/utils` to `^6.2.0` ([#1514](https://github.com/MetaMask/core/pull/1514))
17
+
9
18
  ## [7.1.0]
10
19
  ### Added
11
20
  - Expose `HARDFORK` constant ([#1423](https://github.com/MetaMask/core/pull/1423))
@@ -89,7 +98,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
89
98
 
90
99
  All changes listed after this point were applied to this package following the monorepo conversion.
91
100
 
92
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@7.1.0...HEAD
101
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@8.0.1...HEAD
102
+ [8.0.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@8.0.0...@metamask/transaction-controller@8.0.1
103
+ [8.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@7.1.0...@metamask/transaction-controller@8.0.0
93
104
  [7.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@7.0.0...@metamask/transaction-controller@7.1.0
94
105
  [7.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@6.1.0...@metamask/transaction-controller@7.0.0
95
106
  [6.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@6.0.0...@metamask/transaction-controller@6.1.0
@@ -0,0 +1,15 @@
1
+ import type { RemoteTransactionSource, RemoteTransactionSourceRequest, TransactionMeta } from './types';
2
+ /**
3
+ * A RemoteTransactionSource that fetches transaction data from Etherscan.
4
+ */
5
+ export declare class EtherscanRemoteTransactionSource implements RemoteTransactionSource {
6
+ #private;
7
+ /**
8
+ * Retrieve transaction data from Etherscan.
9
+ *
10
+ * @param request - The configuration required to fetch Etherscan transaction data.
11
+ * @returns An array of transaction metadata.
12
+ */
13
+ fetchTransactions(request: RemoteTransactionSourceRequest): Promise<TransactionMeta[]>;
14
+ }
15
+ //# sourceMappingURL=EtherscanRemoteTransactionSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EtherscanRemoteTransactionSource.d.ts","sourceRoot":"","sources":["../src/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;IAElC;;;;;OAKG;IACG,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAqG9B"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
12
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
13
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
14
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
+ };
16
+ var _EtherscanRemoteTransactionSource_instances, _EtherscanRemoteTransactionSource_normalizeTransaction, _EtherscanRemoteTransactionSource_normalizeTokenTransaction, _EtherscanRemoteTransactionSource_normalizeTransactionBase;
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.EtherscanRemoteTransactionSource = void 0;
19
+ const controller_utils_1 = require("@metamask/controller-utils");
20
+ const ethereumjs_util_1 = require("ethereumjs-util");
21
+ const uuid_1 = require("uuid");
22
+ const etherscan_1 = require("./etherscan");
23
+ const types_1 = require("./types");
24
+ /**
25
+ * A RemoteTransactionSource that fetches transaction data from Etherscan.
26
+ */
27
+ class EtherscanRemoteTransactionSource {
28
+ constructor() {
29
+ _EtherscanRemoteTransactionSource_instances.add(this);
30
+ }
31
+ /**
32
+ * Retrieve transaction data from Etherscan.
33
+ *
34
+ * @param request - The configuration required to fetch Etherscan transaction data.
35
+ * @returns An array of transaction metadata.
36
+ */
37
+ fetchTransactions(request) {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ const [etherscanTransactions, etherscanTokenTransactions] = yield Promise.all([
40
+ (0, etherscan_1.fetchEtherscanTransactions)(request),
41
+ (0, etherscan_1.fetchEtherscanTokenTransactions)(request),
42
+ ]);
43
+ const transactions = etherscanTransactions.result.map((tx) => __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransaction).call(this, tx, request.currentNetworkId, request.currentChainId));
44
+ const tokenTransactions = etherscanTokenTransactions.result.map((tx) => __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTokenTransaction).call(this, tx, request.currentNetworkId, request.currentChainId));
45
+ return [...transactions, ...tokenTransactions];
46
+ });
47
+ }
48
+ }
49
+ exports.EtherscanRemoteTransactionSource = EtherscanRemoteTransactionSource;
50
+ _EtherscanRemoteTransactionSource_instances = new WeakSet(), _EtherscanRemoteTransactionSource_normalizeTransaction = function _EtherscanRemoteTransactionSource_normalizeTransaction(txMeta, currentNetworkId, currentChainId) {
51
+ const base = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransactionBase).call(this, txMeta, currentNetworkId, currentChainId);
52
+ return Object.assign(Object.assign(Object.assign({}, base), { transaction: Object.assign(Object.assign({}, base.transaction), { data: txMeta.input }) }), (txMeta.isError === '0'
53
+ ? { status: types_1.TransactionStatus.confirmed }
54
+ : {
55
+ error: new Error('Transaction failed'),
56
+ status: types_1.TransactionStatus.failed,
57
+ }));
58
+ }, _EtherscanRemoteTransactionSource_normalizeTokenTransaction = function _EtherscanRemoteTransactionSource_normalizeTokenTransaction(txMeta, currentNetworkId, currentChainId) {
59
+ const base = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransactionBase).call(this, txMeta, currentNetworkId, currentChainId);
60
+ return Object.assign(Object.assign({}, base), { isTransfer: true, transferInformation: {
61
+ contractAddress: txMeta.contractAddress,
62
+ decimals: Number(txMeta.tokenDecimal),
63
+ symbol: txMeta.tokenSymbol,
64
+ } });
65
+ }, _EtherscanRemoteTransactionSource_normalizeTransactionBase = function _EtherscanRemoteTransactionSource_normalizeTransactionBase(txMeta, currentNetworkId, currentChainId) {
66
+ const time = parseInt(txMeta.timeStamp, 10) * 1000;
67
+ return {
68
+ blockNumber: txMeta.blockNumber,
69
+ chainId: currentChainId,
70
+ id: (0, uuid_1.v1)({ msecs: time }),
71
+ networkID: currentNetworkId,
72
+ status: types_1.TransactionStatus.confirmed,
73
+ time,
74
+ transaction: {
75
+ from: txMeta.from,
76
+ gas: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gas)),
77
+ gasPrice: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasPrice)),
78
+ gasUsed: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasUsed)),
79
+ nonce: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.nonce)),
80
+ to: txMeta.to,
81
+ value: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.value)),
82
+ },
83
+ transactionHash: txMeta.hash,
84
+ verifiedOnBlockchain: false,
85
+ };
86
+ };
87
+ //# sourceMappingURL=EtherscanRemoteTransactionSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EtherscanRemoteTransactionSource.js","sourceRoot":"","sources":["../src/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { BN } from 'ethereumjs-util';\nimport { v1 as random } from 'uuid';\n\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n} from './etherscan';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from './etherscan';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionMeta,\n} from './types';\nimport { TransactionStatus } from './types';\n\n/**\n * A RemoteTransactionSource that fetches transaction data from Etherscan.\n */\nexport class EtherscanRemoteTransactionSource\n implements RemoteTransactionSource\n{\n /**\n * Retrieve transaction data from Etherscan.\n *\n * @param request - The configuration required to fetch Etherscan transaction data.\n * @returns An array of transaction metadata.\n */\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const [etherscanTransactions, etherscanTokenTransactions] =\n await Promise.all([\n fetchEtherscanTransactions(request),\n fetchEtherscanTokenTransactions(request),\n ]);\n\n const transactions = etherscanTransactions.result.map((tx) =>\n this.#normalizeTransaction(\n tx,\n request.currentNetworkId,\n request.currentChainId,\n ),\n );\n\n const tokenTransactions = etherscanTokenTransactions.result.map((tx) =>\n this.#normalizeTokenTransaction(\n tx,\n request.currentNetworkId,\n request.currentChainId,\n ),\n );\n\n return [...transactions, ...tokenTransactions];\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentNetworkId: string,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(\n txMeta,\n currentNetworkId,\n currentChainId,\n );\n\n return {\n ...base,\n transaction: {\n ...base.transaction,\n data: txMeta.input,\n },\n ...(txMeta.isError === '0'\n ? { status: TransactionStatus.confirmed }\n : {\n error: new Error('Transaction failed'),\n status: TransactionStatus.failed,\n }),\n };\n }\n\n #normalizeTokenTransaction(\n txMeta: EtherscanTokenTransactionMeta,\n currentNetworkId: string,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(\n txMeta,\n currentNetworkId,\n currentChainId,\n );\n\n return {\n ...base,\n isTransfer: true,\n transferInformation: {\n contractAddress: txMeta.contractAddress,\n decimals: Number(txMeta.tokenDecimal),\n symbol: txMeta.tokenSymbol,\n },\n };\n }\n\n #normalizeTransactionBase(\n txMeta: EtherscanTransactionMetaBase,\n currentNetworkId: string,\n currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n id: random({ msecs: time }),\n networkID: currentNetworkId,\n status: TransactionStatus.confirmed,\n time,\n transaction: {\n from: txMeta.from,\n gas: BNToHex(new BN(txMeta.gas)),\n gasPrice: BNToHex(new BN(txMeta.gasPrice)),\n gasUsed: BNToHex(new BN(txMeta.gasUsed)),\n nonce: BNToHex(new BN(txMeta.nonce)),\n to: txMeta.to,\n value: BNToHex(new BN(txMeta.value)),\n },\n transactionHash: txMeta.hash,\n verifiedOnBlockchain: false,\n };\n }\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import type EthQuery from '@metamask/eth-query';
2
+ import type { NetworkState } from '@metamask/network-controller';
3
+ import type { RemoteTransactionSource, TransactionMeta } from './types';
4
+ export declare class IncomingTransactionHelper {
5
+ #private;
6
+ constructor({ getNetworkState, getEthQuery, transactionLimit, remoteTransactionSource, }: {
7
+ getNetworkState: () => NetworkState;
8
+ getEthQuery: () => EthQuery;
9
+ transactionLimit: number;
10
+ remoteTransactionSource: RemoteTransactionSource;
11
+ });
12
+ reconcile({ address, localTransactions, fromBlock, apiKey, }: {
13
+ address: string;
14
+ localTransactions: TransactionMeta[];
15
+ fromBlock?: string;
16
+ apiKey?: string;
17
+ }): Promise<{
18
+ updateRequired: boolean;
19
+ transactions: TransactionMeta[];
20
+ latestBlockNumber?: string;
21
+ }>;
22
+ }
23
+ //# sourceMappingURL=IncomingTransactionHelper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IncomingTransactionHelper.d.ts","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,KAAK,EACV,uBAAuB,EAEvB,eAAe,EAEhB,MAAM,SAAS,CAAC;AAQjB,qBAAa,yBAAyB;;gBASxB,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,uBAAuB,GACxB,EAAE;QACD,eAAe,EAAE,MAAM,YAAY,CAAC;QACpC,WAAW,EAAE,MAAM,QAAQ,CAAC;QAC5B,gBAAgB,EAAE,MAAM,CAAC;QACzB,uBAAuB,EAAE,uBAAuB,CAAC;KAClD;IAOK,SAAS,CAAC,EACd,OAAO,EACP,iBAAiB,EACjB,SAAS,EACT,MAAM,GACP,EAAE;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,iBAAiB,EAAE,eAAe,EAAE,CAAC;QACrC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QACV,cAAc,EAAE,OAAO,CAAC;QACxB,YAAY,EAAE,eAAe,EAAE,CAAC;QAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CAmMH"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var _IncomingTransactionHelper_instances, _IncomingTransactionHelper_getNetworkState, _IncomingTransactionHelper_getEthQuery, _IncomingTransactionHelper_transactionLimit, _IncomingTransactionHelper_remoteTransactionSource, _IncomingTransactionHelper_updateSmartContractProperty, _IncomingTransactionHelper_getLatestBlockNumber, _IncomingTransactionHelper_isToSmartContract, _IncomingTransactionHelper_sortTransactionsByTime, _IncomingTransactionHelper_reconcileTransactions, _IncomingTransactionHelper_getNewTransactions, _IncomingTransactionHelper_getUpdatedTransactions, _IncomingTransactionHelper_isTransactionOutdated, _IncomingTransactionHelper_isStatusOutdated, _IncomingTransactionHelper_isGasDataOutdated;
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.IncomingTransactionHelper = void 0;
25
+ const controller_utils_1 = require("@metamask/controller-utils");
26
+ const SUPPORTED_NETWORK_IDS = [
27
+ '1',
28
+ '5',
29
+ '11155111', // Sepolia
30
+ ];
31
+ class IncomingTransactionHelper {
32
+ constructor({ getNetworkState, getEthQuery, transactionLimit, remoteTransactionSource, }) {
33
+ _IncomingTransactionHelper_instances.add(this);
34
+ _IncomingTransactionHelper_getNetworkState.set(this, void 0);
35
+ _IncomingTransactionHelper_getEthQuery.set(this, void 0);
36
+ _IncomingTransactionHelper_transactionLimit.set(this, void 0);
37
+ _IncomingTransactionHelper_remoteTransactionSource.set(this, void 0);
38
+ __classPrivateFieldSet(this, _IncomingTransactionHelper_getNetworkState, getNetworkState, "f");
39
+ __classPrivateFieldSet(this, _IncomingTransactionHelper_getEthQuery, getEthQuery, "f");
40
+ __classPrivateFieldSet(this, _IncomingTransactionHelper_transactionLimit, transactionLimit, "f");
41
+ __classPrivateFieldSet(this, _IncomingTransactionHelper_remoteTransactionSource, remoteTransactionSource, "f");
42
+ }
43
+ reconcile({ address, localTransactions, fromBlock, apiKey, }) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const { providerConfig, networkId: currentNetworkId } = __classPrivateFieldGet(this, _IncomingTransactionHelper_getNetworkState, "f").call(this);
46
+ const { chainId: currentChainId, type: networkType } = providerConfig;
47
+ if (currentNetworkId === null ||
48
+ !SUPPORTED_NETWORK_IDS.includes(currentNetworkId)) {
49
+ return { updateRequired: false, transactions: [] };
50
+ }
51
+ const remoteTransactions = yield __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").fetchTransactions({
52
+ address,
53
+ networkType,
54
+ limit: __classPrivateFieldGet(this, _IncomingTransactionHelper_transactionLimit, "f"),
55
+ currentChainId,
56
+ currentNetworkId,
57
+ fromBlock,
58
+ apiKey,
59
+ });
60
+ const [updateRequired, transactions] = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_reconcileTransactions).call(this, localTransactions, remoteTransactions);
61
+ __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, transactions);
62
+ const latestBlockNumber = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getLatestBlockNumber).call(this, transactions, address, currentChainId, currentNetworkId);
63
+ yield __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_updateSmartContractProperty).call(this, transactions);
64
+ return { updateRequired, transactions, latestBlockNumber };
65
+ });
66
+ }
67
+ }
68
+ exports.IncomingTransactionHelper = IncomingTransactionHelper;
69
+ _IncomingTransactionHelper_getNetworkState = new WeakMap(), _IncomingTransactionHelper_getEthQuery = new WeakMap(), _IncomingTransactionHelper_transactionLimit = new WeakMap(), _IncomingTransactionHelper_remoteTransactionSource = new WeakMap(), _IncomingTransactionHelper_instances = new WeakSet(), _IncomingTransactionHelper_updateSmartContractProperty = function _IncomingTransactionHelper_updateSmartContractProperty(transactions) {
70
+ return __awaiter(this, void 0, void 0, function* () {
71
+ yield Promise.all(transactions.map((tx) => __awaiter(this, void 0, void 0, function* () {
72
+ var _a;
73
+ (_a = tx.toSmartContract) !== null && _a !== void 0 ? _a : (tx.toSmartContract = yield __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_isToSmartContract).call(this, tx.transaction));
74
+ })));
75
+ });
76
+ }, _IncomingTransactionHelper_getLatestBlockNumber = function _IncomingTransactionHelper_getLatestBlockNumber(transactions, address, currentChainId, currentNetworkId) {
77
+ var _a;
78
+ let latestBlockNumber;
79
+ for (const tx of transactions) {
80
+ const onCurrentChain = tx.chainId === currentChainId ||
81
+ (!tx.chainId && tx.networkID === currentNetworkId);
82
+ const toCurrentAccount = ((_a = tx.transaction.to) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === address.toLowerCase();
83
+ const currentBlockNumberValue = tx.blockNumber
84
+ ? parseInt(tx.blockNumber, 10)
85
+ : -1;
86
+ const latestBlockNumberValue = latestBlockNumber
87
+ ? parseInt(latestBlockNumber, 10)
88
+ : -1;
89
+ if (onCurrentChain &&
90
+ toCurrentAccount &&
91
+ latestBlockNumberValue < currentBlockNumberValue) {
92
+ latestBlockNumber = tx.blockNumber;
93
+ }
94
+ }
95
+ return latestBlockNumber;
96
+ }, _IncomingTransactionHelper_isToSmartContract = function _IncomingTransactionHelper_isToSmartContract(transaction) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ // Contract Deploy
99
+ if (!transaction.to) {
100
+ return false;
101
+ }
102
+ // Send
103
+ if (transaction.data === '0x') {
104
+ return false;
105
+ }
106
+ const ethQuery = __classPrivateFieldGet(this, _IncomingTransactionHelper_getEthQuery, "f").call(this);
107
+ const code = yield (0, controller_utils_1.query)(ethQuery, 'getCode', [transaction.to]);
108
+ return (0, controller_utils_1.isSmartContractCode)(code);
109
+ });
110
+ }, _IncomingTransactionHelper_sortTransactionsByTime = function _IncomingTransactionHelper_sortTransactionsByTime(transactions) {
111
+ transactions.sort((a, b) => (a.time < b.time ? -1 : 1));
112
+ }, _IncomingTransactionHelper_reconcileTransactions = function _IncomingTransactionHelper_reconcileTransactions(localTxs, remoteTxs) {
113
+ const updatedTxs = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getUpdatedTransactions).call(this, remoteTxs, localTxs);
114
+ const newTxs = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getNewTransactions).call(this, remoteTxs, localTxs);
115
+ const updatedLocalTxs = localTxs.map((tx) => {
116
+ const txIdx = updatedTxs.findIndex(({ transactionHash }) => transactionHash === tx.transactionHash);
117
+ return txIdx === -1 ? tx : updatedTxs[txIdx];
118
+ });
119
+ const updateRequired = newTxs.length > 0 || updatedTxs.length > 0;
120
+ const transactions = [...newTxs, ...updatedLocalTxs];
121
+ return [updateRequired, transactions];
122
+ }, _IncomingTransactionHelper_getNewTransactions = function _IncomingTransactionHelper_getNewTransactions(remoteTxs, localTxs) {
123
+ return remoteTxs.filter((tx) => {
124
+ const alreadyInTransactions = localTxs.find(({ transactionHash }) => transactionHash === tx.transactionHash);
125
+ return !alreadyInTransactions;
126
+ });
127
+ }, _IncomingTransactionHelper_getUpdatedTransactions = function _IncomingTransactionHelper_getUpdatedTransactions(remoteTxs, localTxs) {
128
+ return remoteTxs.filter((remoteTx) => {
129
+ const isTxOutdated = localTxs.find((localTx) => {
130
+ return (remoteTx.transactionHash === localTx.transactionHash &&
131
+ __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_isTransactionOutdated).call(this, remoteTx, localTx));
132
+ });
133
+ return isTxOutdated;
134
+ });
135
+ }, _IncomingTransactionHelper_isTransactionOutdated = function _IncomingTransactionHelper_isTransactionOutdated(remoteTx, localTx) {
136
+ const statusOutdated = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_isStatusOutdated).call(this, remoteTx.transactionHash, localTx.transactionHash, remoteTx.status, localTx.status);
137
+ const gasDataOutdated = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_isGasDataOutdated).call(this, remoteTx.transaction.gasUsed, localTx.transaction.gasUsed);
138
+ return statusOutdated || gasDataOutdated;
139
+ }, _IncomingTransactionHelper_isStatusOutdated = function _IncomingTransactionHelper_isStatusOutdated(remoteTxHash, localTxHash, remoteTxStatus, localTxStatus) {
140
+ return remoteTxHash === localTxHash && remoteTxStatus !== localTxStatus;
141
+ }, _IncomingTransactionHelper_isGasDataOutdated = function _IncomingTransactionHelper_isGasDataOutdated(remoteGasUsed, localGasUsed) {
142
+ return remoteGasUsed !== localGasUsed;
143
+ };
144
+ //# sourceMappingURL=IncomingTransactionHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IncomingTransactionHelper.js","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { isSmartContractCode, query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type { NetworkState } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type {\n RemoteTransactionSource,\n Transaction,\n TransactionMeta,\n TransactionStatus,\n} from './types';\n\nconst SUPPORTED_NETWORK_IDS = [\n '1', // Mainnet\n '5', // Goerli\n '11155111', // Sepolia\n];\n\nexport class IncomingTransactionHelper {\n #getNetworkState: () => NetworkState;\n\n #getEthQuery: () => EthQuery;\n\n #transactionLimit: number;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n constructor({\n getNetworkState,\n getEthQuery,\n transactionLimit,\n remoteTransactionSource,\n }: {\n getNetworkState: () => NetworkState;\n getEthQuery: () => EthQuery;\n transactionLimit: number;\n remoteTransactionSource: RemoteTransactionSource;\n }) {\n this.#getNetworkState = getNetworkState;\n this.#getEthQuery = getEthQuery;\n this.#transactionLimit = transactionLimit;\n this.#remoteTransactionSource = remoteTransactionSource;\n }\n\n async reconcile({\n address,\n localTransactions,\n fromBlock,\n apiKey,\n }: {\n address: string;\n localTransactions: TransactionMeta[];\n fromBlock?: string;\n apiKey?: string;\n }): Promise<{\n updateRequired: boolean;\n transactions: TransactionMeta[];\n latestBlockNumber?: string;\n }> {\n const { providerConfig, networkId: currentNetworkId } =\n this.#getNetworkState();\n const { chainId: currentChainId, type: networkType } = providerConfig;\n\n if (\n currentNetworkId === null ||\n !SUPPORTED_NETWORK_IDS.includes(currentNetworkId)\n ) {\n return { updateRequired: false, transactions: [] };\n }\n\n const remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address,\n networkType,\n limit: this.#transactionLimit,\n currentChainId,\n currentNetworkId,\n fromBlock,\n apiKey,\n });\n\n const [updateRequired, transactions] = this.#reconcileTransactions(\n localTransactions,\n remoteTransactions,\n );\n\n this.#sortTransactionsByTime(transactions);\n\n const latestBlockNumber = this.#getLatestBlockNumber(\n transactions,\n address,\n currentChainId,\n currentNetworkId,\n );\n\n await this.#updateSmartContractProperty(transactions);\n\n return { updateRequired, transactions, latestBlockNumber };\n }\n\n async #updateSmartContractProperty(transactions: TransactionMeta[]) {\n await Promise.all(\n transactions.map(async (tx) => {\n tx.toSmartContract ??= await this.#isToSmartContract(tx.transaction);\n }),\n );\n }\n\n #getLatestBlockNumber(\n transactions: TransactionMeta[],\n address: string,\n currentChainId: Hex,\n currentNetworkId: string,\n ): string | undefined {\n let latestBlockNumber: string | undefined;\n\n for (const tx of transactions) {\n const onCurrentChain =\n tx.chainId === currentChainId ||\n (!tx.chainId && tx.networkID === currentNetworkId);\n\n const toCurrentAccount =\n tx.transaction.to?.toLowerCase() === address.toLowerCase();\n\n const currentBlockNumberValue = tx.blockNumber\n ? parseInt(tx.blockNumber, 10)\n : -1;\n\n const latestBlockNumberValue = latestBlockNumber\n ? parseInt(latestBlockNumber, 10)\n : -1;\n\n if (\n onCurrentChain &&\n toCurrentAccount &&\n latestBlockNumberValue < currentBlockNumberValue\n ) {\n latestBlockNumber = tx.blockNumber;\n }\n }\n\n return latestBlockNumber;\n }\n\n async #isToSmartContract(transaction: Transaction): Promise<boolean> {\n // Contract Deploy\n if (!transaction.to) {\n return false;\n }\n\n // Send\n if (transaction.data === '0x') {\n return false;\n }\n\n const ethQuery = this.#getEthQuery();\n const code = await query(ethQuery, 'getCode', [transaction.to]);\n\n return isSmartContractCode(code);\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #reconcileTransactions(\n localTxs: TransactionMeta[],\n remoteTxs: TransactionMeta[],\n ): [boolean, TransactionMeta[]] {\n const updatedTxs: TransactionMeta[] = this.#getUpdatedTransactions(\n remoteTxs,\n localTxs,\n );\n\n const newTxs: TransactionMeta[] = this.#getNewTransactions(\n remoteTxs,\n localTxs,\n );\n\n const updatedLocalTxs = localTxs.map((tx: TransactionMeta) => {\n const txIdx = updatedTxs.findIndex(\n ({ transactionHash }) => transactionHash === tx.transactionHash,\n );\n return txIdx === -1 ? tx : updatedTxs[txIdx];\n });\n\n const updateRequired = newTxs.length > 0 || updatedTxs.length > 0;\n const transactions = [...newTxs, ...updatedLocalTxs];\n\n return [updateRequired, transactions];\n }\n\n #getNewTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((tx) => {\n const alreadyInTransactions = localTxs.find(\n ({ transactionHash }) => transactionHash === tx.transactionHash,\n );\n return !alreadyInTransactions;\n });\n }\n\n #getUpdatedTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((remoteTx) => {\n const isTxOutdated = localTxs.find((localTx) => {\n return (\n remoteTx.transactionHash === localTx.transactionHash &&\n this.#isTransactionOutdated(remoteTx, localTx)\n );\n });\n return isTxOutdated;\n });\n }\n\n #isTransactionOutdated(\n remoteTx: TransactionMeta,\n localTx: TransactionMeta,\n ): boolean {\n const statusOutdated = this.#isStatusOutdated(\n remoteTx.transactionHash,\n localTx.transactionHash,\n remoteTx.status,\n localTx.status,\n );\n\n const gasDataOutdated = this.#isGasDataOutdated(\n remoteTx.transaction.gasUsed,\n localTx.transaction.gasUsed,\n );\n\n return statusOutdated || gasDataOutdated;\n }\n\n #isStatusOutdated(\n remoteTxHash: string | undefined,\n localTxHash: string | undefined,\n remoteTxStatus: TransactionStatus,\n localTxStatus: TransactionStatus,\n ): boolean {\n return remoteTxHash === localTxHash && remoteTxStatus !== localTxStatus;\n }\n\n #isGasDataOutdated(\n remoteGasUsed: string | undefined,\n localGasUsed: string | undefined,\n ): boolean {\n return remoteGasUsed !== localGasUsed;\n }\n}\n"]}
@@ -1,12 +1,13 @@
1
1
  /// <reference types="node" />
2
- import { EventEmitter } from 'events';
3
- import Common from '@ethereumjs/common';
4
- import { TypedTransaction } from '@ethereumjs/tx';
5
- import type { Hex } from '@metamask/utils';
6
- import { BaseController, BaseConfig, BaseState, RestrictedControllerMessenger } from '@metamask/base-controller';
2
+ import { Hardfork, Common } from '@ethereumjs/common';
3
+ import type { TypedTransaction } from '@ethereumjs/tx';
4
+ import type { AddApprovalRequest } from '@metamask/approval-controller';
5
+ import type { BaseConfig, BaseState, RestrictedControllerMessenger } from '@metamask/base-controller';
6
+ import { BaseController } from '@metamask/base-controller';
7
7
  import type { BlockTracker, NetworkState, Provider } from '@metamask/network-controller';
8
- import { AddApprovalRequest } from '@metamask/approval-controller';
9
- export declare const HARDFORK = "london";
8
+ import { EventEmitter } from 'events';
9
+ import type { Transaction, TransactionMeta, WalletDevice } from './types';
10
+ export declare const HARDFORK = Hardfork.London;
10
11
  /**
11
12
  * @type Result
12
13
  * @property result - Promise resolving to a new transaction hash
@@ -25,35 +26,6 @@ export interface FetchAllOptions {
25
26
  fromBlock?: string;
26
27
  etherscanApiKey?: string;
27
28
  }
28
- /**
29
- * @type Transaction
30
- *
31
- * Transaction representation
32
- * @property chainId - Network ID as per EIP-155
33
- * @property data - Data to pass with this transaction
34
- * @property from - Address to send this transaction from
35
- * @property gas - Gas to send with this transaction
36
- * @property gasPrice - Price of gas with this transaction
37
- * @property gasUsed - Gas used in the transaction
38
- * @property nonce - Unique number to prevent replay attacks
39
- * @property to - Address to send this transaction to
40
- * @property value - Value associated with this transaction
41
- */
42
- export interface Transaction {
43
- chainId?: Hex;
44
- data?: string;
45
- from: string;
46
- gas?: string;
47
- gasPrice?: string;
48
- gasUsed?: string;
49
- nonce?: string;
50
- to?: string;
51
- value?: string;
52
- maxFeePerGas?: string;
53
- maxPriorityFeePerGas?: string;
54
- estimatedBaseFee?: string;
55
- estimateGasError?: string;
56
- }
57
29
  export interface GasPriceValue {
58
30
  gasPrice: string;
59
31
  }
@@ -61,115 +33,6 @@ export interface FeeMarketEIP1559Values {
61
33
  maxFeePerGas: string;
62
34
  maxPriorityFeePerGas: string;
63
35
  }
64
- /**
65
- * The status of the transaction. Each status represents the state of the transaction internally
66
- * in the wallet. Some of these correspond with the state of the transaction on the network, but
67
- * some are wallet-specific.
68
- */
69
- export declare enum TransactionStatus {
70
- approved = "approved",
71
- cancelled = "cancelled",
72
- confirmed = "confirmed",
73
- failed = "failed",
74
- rejected = "rejected",
75
- signed = "signed",
76
- submitted = "submitted",
77
- unapproved = "unapproved"
78
- }
79
- /**
80
- * Options for wallet device.
81
- */
82
- export declare enum WalletDevice {
83
- MM_MOBILE = "metamask_mobile",
84
- MM_EXTENSION = "metamask_extension",
85
- OTHER = "other_device"
86
- }
87
- declare type TransactionMetaBase = {
88
- isTransfer?: boolean;
89
- transferInformation?: {
90
- symbol: string;
91
- contractAddress: string;
92
- decimals: number;
93
- };
94
- id: string;
95
- networkID?: string;
96
- chainId?: Hex;
97
- origin?: string;
98
- rawTransaction?: string;
99
- time: number;
100
- toSmartContract?: boolean;
101
- transaction: Transaction;
102
- transactionHash?: string;
103
- blockNumber?: string;
104
- deviceConfirmedOn?: WalletDevice;
105
- verifiedOnBlockchain?: boolean;
106
- };
107
- /**
108
- * @type TransactionMeta
109
- *
110
- * TransactionMeta representation
111
- * @property error - Synthesized error information for failed transactions
112
- * @property id - Generated UUID associated with this transaction
113
- * @property networkID - Network code as per EIP-155 for this transaction
114
- * @property origin - Origin this transaction was sent from
115
- * @property deviceConfirmedOn - string to indicate what device the transaction was confirmed
116
- * @property rawTransaction - Hex representation of the underlying transaction
117
- * @property status - String status of this transaction
118
- * @property time - Timestamp associated with this transaction
119
- * @property toSmartContract - Whether transaction recipient is a smart contract
120
- * @property transaction - Underlying Transaction object
121
- * @property transactionHash - Hash of a successful transaction
122
- * @property blockNumber - Number of the block where the transaction has been included
123
- */
124
- export declare type TransactionMeta = ({
125
- status: Exclude<TransactionStatus, TransactionStatus.failed>;
126
- } & TransactionMetaBase) | ({
127
- status: TransactionStatus.failed;
128
- error: Error;
129
- } & TransactionMetaBase);
130
- /**
131
- * @type EtherscanTransactionMeta
132
- *
133
- * EtherscanTransactionMeta representation
134
- * @property blockNumber - Number of the block where the transaction has been included
135
- * @property timeStamp - Timestamp associated with this transaction
136
- * @property hash - Hash of a successful transaction
137
- * @property nonce - Nonce of the transaction
138
- * @property blockHash - Hash of the block where the transaction has been included
139
- * @property transactionIndex - Etherscan internal index for this transaction
140
- * @property from - Address to send this transaction from
141
- * @property to - Address to send this transaction to
142
- * @property gas - Gas to send with this transaction
143
- * @property gasPrice - Price of gas with this transaction
144
- * @property isError - Synthesized error information for failed transactions
145
- * @property txreceipt_status - Receipt status for this transaction
146
- * @property input - input of the transaction
147
- * @property contractAddress - Address of the contract
148
- * @property cumulativeGasUsed - Amount of gas used
149
- * @property confirmations - Number of confirmations
150
- */
151
- export interface EtherscanTransactionMeta {
152
- blockNumber: string;
153
- timeStamp: string;
154
- hash: string;
155
- nonce: string;
156
- blockHash: string;
157
- transactionIndex: string;
158
- from: string;
159
- to: string;
160
- value: string;
161
- gas: string;
162
- gasPrice: string;
163
- cumulativeGasUsed: string;
164
- gasUsed: string;
165
- isError: string;
166
- txreceipt_status: string;
167
- input: string;
168
- contractAddress: string;
169
- confirmations: string;
170
- tokenDecimal: string;
171
- tokenSymbol: string;
172
- }
173
36
  /**
174
37
  * @type TransactionConfig
175
38
  *
@@ -232,26 +95,16 @@ export declare type TransactionControllerMessenger = RestrictedControllerMesseng
232
95
  */
233
96
  export declare class TransactionController extends BaseController<TransactionConfig, TransactionState> {
234
97
  private ethQuery;
235
- private nonceTracker;
98
+ private readonly nonceTracker;
236
99
  private registry;
237
- private provider;
100
+ private readonly provider;
238
101
  private handle?;
239
- private mutex;
240
- private getNetworkState;
241
- private messagingSystem;
102
+ private readonly mutex;
103
+ private readonly getNetworkState;
104
+ private readonly messagingSystem;
105
+ private readonly incomingTransactionHelper;
242
106
  private failTransaction;
243
107
  private registryLookup;
244
- /**
245
- * Normalizes the transaction information from etherscan
246
- * to be compatible with the TransactionMeta interface.
247
- *
248
- * @param txMeta - The transaction.
249
- * @param currentNetworkID - The current network ID.
250
- * @param currentChainId - The current chain ID.
251
- * @returns The normalized transaction.
252
- */
253
- private normalizeTx;
254
- private normalizeTokenTx;
255
108
  /**
256
109
  * EventEmitter instance used to listen to specific transactional events
257
110
  */
@@ -439,59 +292,6 @@ export declare class TransactionController extends BaseController<TransactionCon
439
292
  * @returns Whether the transaction has failed.
440
293
  */
441
294
  private checkTxReceiptStatusIsFailed;
442
- /**
443
- * Method to verify the state of transactions using Etherscan as a source of truth.
444
- *
445
- * @param remoteTxs - Transactions to reconcile that are from a remote source.
446
- * @param localTxs - Transactions to reconcile that are local.
447
- * @returns A tuple containing a boolean indicating whether or not an update was required, and the updated transaction.
448
- */
449
- private etherscanTransactionStateReconciler;
450
- /**
451
- * Get all transactions that are in the remote transactions array
452
- * but not in the local transactions array.
453
- *
454
- * @param remoteTxs - Array of transactions from remote source.
455
- * @param localTxs - Array of transactions stored locally.
456
- * @returns The new transactions.
457
- */
458
- private getNewTransactions;
459
- /**
460
- * Get all the transactions that are locally outdated with respect
461
- * to a remote source (etherscan or blockchain). The returned array
462
- * contains the transactions with the updated data.
463
- *
464
- * @param remoteTxs - Array of transactions from remote source.
465
- * @param localTxs - Array of transactions stored locally.
466
- * @returns The updated transactions.
467
- */
468
- private getUpdatedTransactions;
469
- /**
470
- * Verifies if a local transaction is outdated with respect to the remote transaction.
471
- *
472
- * @param remoteTx - The remote transaction from Etherscan.
473
- * @param localTx - The local transaction.
474
- * @returns Whether the transaction is outdated.
475
- */
476
- private isTransactionOutdated;
477
- /**
478
- * Verifies if the status of a local transaction is outdated with respect to the remote transaction.
479
- *
480
- * @param remoteTxHash - Remote transaction hash.
481
- * @param localTxHash - Local transaction hash.
482
- * @param remoteTxStatus - Remote transaction status.
483
- * @param localTxStatus - Local transaction status.
484
- * @returns Whether the status is outdated.
485
- */
486
- private isStatusOutdated;
487
- /**
488
- * Verifies if the gas data of a local transaction is outdated with respect to the remote transaction.
489
- *
490
- * @param remoteGasUsed - Remote gas used in the transaction.
491
- * @param localGasUsed - Local gas used in the transaction.
492
- * @returns Whether the gas data is outdated.
493
- */
494
- private isGasDataOutdated;
495
295
  private requestApproval;
496
296
  private getTransaction;
497
297
  private getApprovalId;