@metamask/transaction-controller 18.2.0 → 18.3.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.
- package/CHANGELOG.md +362 -0
- package/dist/TransactionController.d.ts +8 -4
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +15 -3
- package/dist/TransactionController.js.map +1 -1
- package/package.json +2 -2
- package/dist/EtherscanRemoteTransactionSource.d.ts +0 -15
- package/dist/EtherscanRemoteTransactionSource.d.ts.map +0 -1
- package/dist/EtherscanRemoteTransactionSource.js +0 -122
- package/dist/EtherscanRemoteTransactionSource.js.map +0 -1
- package/dist/IncomingTransactionHelper.d.ts +0 -25
- package/dist/IncomingTransactionHelper.d.ts.map +0 -1
- package/dist/IncomingTransactionHelper.js +0 -198
- package/dist/IncomingTransactionHelper.js.map +0 -1
- package/dist/etherscan.d.ts +0 -64
- package/dist/etherscan.d.ts.map +0 -1
- package/dist/etherscan.js +0 -109
- package/dist/etherscan.js.map +0 -1
- package/dist/external-transactions.d.ts +0 -10
- package/dist/external-transactions.d.ts.map +0 -1
- package/dist/external-transactions.js +0 -36
- package/dist/external-transactions.js.map +0 -1
- package/dist/history.d.ts +0 -15
- package/dist/history.d.ts.map +0 -1
- package/dist/history.js +0 -75
- package/dist/history.js.map +0 -1
- package/dist/mocks/txsMock.d.ts +0 -64
- package/dist/mocks/txsMock.d.ts.map +0 -1
- package/dist/mocks/txsMock.js +0 -515
- package/dist/mocks/txsMock.js.map +0 -1
- package/dist/transaction-type.d.ts +0 -14
- package/dist/transaction-type.d.ts.map +0 -1
- package/dist/transaction-type.js +0 -114
- package/dist/transaction-type.js.map +0 -1
- package/dist/utils.d.ts +0 -72
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -235
- package/dist/utils.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/transaction-controller",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.3.0",
|
|
4
4
|
"description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -77,4 +77,4 @@
|
|
|
77
77
|
"access": "public",
|
|
78
78
|
"registry": "https://registry.npmjs.org/"
|
|
79
79
|
}
|
|
80
|
-
}
|
|
80
|
+
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Hex } from '@metamask/utils';
|
|
2
|
-
import type { RemoteTransactionSource, RemoteTransactionSourceRequest, TransactionMeta } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* A RemoteTransactionSource that fetches transaction data from Etherscan.
|
|
5
|
-
*/
|
|
6
|
-
export declare class EtherscanRemoteTransactionSource implements RemoteTransactionSource {
|
|
7
|
-
#private;
|
|
8
|
-
constructor({ includeTokenTransfers, }?: {
|
|
9
|
-
includeTokenTransfers?: boolean;
|
|
10
|
-
});
|
|
11
|
-
isSupportedNetwork(chainId: Hex): boolean;
|
|
12
|
-
getLastBlockVariations(): string[];
|
|
13
|
-
fetchTransactions(request: RemoteTransactionSourceRequest): Promise<TransactionMeta[]>;
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=EtherscanRemoteTransactionSource.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EtherscanRemoteTransactionSource.d.ts","sourceRoot":"","sources":["../src/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAiB3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;gBAMtB,EACV,qBAAqB,GACtB,GAAE;QAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAO;IAK3C,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIzC,sBAAsB,IAAI,MAAM,EAAE;IAI5B,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAkI9B"}
|
|
@@ -1,122 +0,0 @@
|
|
|
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 _EtherscanRemoteTransactionSource_instances, _EtherscanRemoteTransactionSource_includeTokenTransfers, _EtherscanRemoteTransactionSource_isTokenRequestPending, _EtherscanRemoteTransactionSource_fetchNormalTransactions, _EtherscanRemoteTransactionSource_fetchTokenTransactions, _EtherscanRemoteTransactionSource_getResponseTransactions, _EtherscanRemoteTransactionSource_normalizeTransaction, _EtherscanRemoteTransactionSource_normalizeTokenTransaction, _EtherscanRemoteTransactionSource_normalizeTransactionBase;
|
|
23
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.EtherscanRemoteTransactionSource = void 0;
|
|
25
|
-
const controller_utils_1 = require("@metamask/controller-utils");
|
|
26
|
-
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
27
|
-
const uuid_1 = require("uuid");
|
|
28
|
-
const constants_1 = require("./constants");
|
|
29
|
-
const etherscan_1 = require("./etherscan");
|
|
30
|
-
const logger_1 = require("./logger");
|
|
31
|
-
const types_1 = require("./types");
|
|
32
|
-
/**
|
|
33
|
-
* A RemoteTransactionSource that fetches transaction data from Etherscan.
|
|
34
|
-
*/
|
|
35
|
-
class EtherscanRemoteTransactionSource {
|
|
36
|
-
constructor({ includeTokenTransfers, } = {}) {
|
|
37
|
-
_EtherscanRemoteTransactionSource_instances.add(this);
|
|
38
|
-
_EtherscanRemoteTransactionSource_includeTokenTransfers.set(this, void 0);
|
|
39
|
-
_EtherscanRemoteTransactionSource_isTokenRequestPending.set(this, void 0);
|
|
40
|
-
_EtherscanRemoteTransactionSource_fetchNormalTransactions.set(this, (request, etherscanRequest) => __awaiter(this, void 0, void 0, function* () {
|
|
41
|
-
const { currentChainId } = request;
|
|
42
|
-
const etherscanTransactions = yield (0, etherscan_1.fetchEtherscanTransactions)(etherscanRequest);
|
|
43
|
-
return __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_getResponseTransactions).call(this, etherscanTransactions).map((tx) => __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransaction).call(this, tx, currentChainId));
|
|
44
|
-
}));
|
|
45
|
-
_EtherscanRemoteTransactionSource_fetchTokenTransactions.set(this, (request, etherscanRequest) => __awaiter(this, void 0, void 0, function* () {
|
|
46
|
-
const { currentChainId } = request;
|
|
47
|
-
const etherscanTransactions = yield (0, etherscan_1.fetchEtherscanTokenTransactions)(etherscanRequest);
|
|
48
|
-
return __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_getResponseTransactions).call(this, etherscanTransactions).map((tx) => __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTokenTransaction).call(this, tx, currentChainId));
|
|
49
|
-
}));
|
|
50
|
-
__classPrivateFieldSet(this, _EtherscanRemoteTransactionSource_includeTokenTransfers, includeTokenTransfers !== null && includeTokenTransfers !== void 0 ? includeTokenTransfers : true, "f");
|
|
51
|
-
__classPrivateFieldSet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, false, "f");
|
|
52
|
-
}
|
|
53
|
-
isSupportedNetwork(chainId) {
|
|
54
|
-
return Object.keys(constants_1.ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);
|
|
55
|
-
}
|
|
56
|
-
getLastBlockVariations() {
|
|
57
|
-
return [__classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f") ? 'token' : 'normal'];
|
|
58
|
-
}
|
|
59
|
-
fetchTransactions(request) {
|
|
60
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
-
const etherscanRequest = Object.assign(Object.assign({}, request), { chainId: request.currentChainId });
|
|
62
|
-
const transactions = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f")
|
|
63
|
-
? yield __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_fetchTokenTransactions, "f").call(this, request, etherscanRequest)
|
|
64
|
-
: yield __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_fetchNormalTransactions, "f").call(this, request, etherscanRequest);
|
|
65
|
-
if (__classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_includeTokenTransfers, "f")) {
|
|
66
|
-
__classPrivateFieldSet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, !__classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f"), "f");
|
|
67
|
-
}
|
|
68
|
-
return transactions;
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
exports.EtherscanRemoteTransactionSource = EtherscanRemoteTransactionSource;
|
|
73
|
-
_EtherscanRemoteTransactionSource_includeTokenTransfers = new WeakMap(), _EtherscanRemoteTransactionSource_isTokenRequestPending = new WeakMap(), _EtherscanRemoteTransactionSource_fetchNormalTransactions = new WeakMap(), _EtherscanRemoteTransactionSource_fetchTokenTransactions = new WeakMap(), _EtherscanRemoteTransactionSource_instances = new WeakSet(), _EtherscanRemoteTransactionSource_getResponseTransactions = function _EtherscanRemoteTransactionSource_getResponseTransactions(response) {
|
|
74
|
-
let result = response.result;
|
|
75
|
-
if (response.status === '0') {
|
|
76
|
-
result = [];
|
|
77
|
-
if (response.result.length) {
|
|
78
|
-
(0, logger_1.incomingTransactionsLogger)('Ignored Etherscan request error', {
|
|
79
|
-
message: response.result,
|
|
80
|
-
type: __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f") ? 'token' : 'normal',
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
85
|
-
}, _EtherscanRemoteTransactionSource_normalizeTransaction = function _EtherscanRemoteTransactionSource_normalizeTransaction(txMeta, currentChainId) {
|
|
86
|
-
const base = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransactionBase).call(this, txMeta, currentChainId);
|
|
87
|
-
return Object.assign(Object.assign(Object.assign({}, base), { txParams: Object.assign(Object.assign({}, base.txParams), { data: txMeta.input }) }), (txMeta.isError === '0'
|
|
88
|
-
? { status: types_1.TransactionStatus.confirmed }
|
|
89
|
-
: {
|
|
90
|
-
error: new Error('Transaction failed'),
|
|
91
|
-
status: types_1.TransactionStatus.failed,
|
|
92
|
-
}));
|
|
93
|
-
}, _EtherscanRemoteTransactionSource_normalizeTokenTransaction = function _EtherscanRemoteTransactionSource_normalizeTokenTransaction(txMeta, currentChainId) {
|
|
94
|
-
const base = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransactionBase).call(this, txMeta, currentChainId);
|
|
95
|
-
return Object.assign(Object.assign({}, base), { isTransfer: true, transferInformation: {
|
|
96
|
-
contractAddress: txMeta.contractAddress,
|
|
97
|
-
decimals: Number(txMeta.tokenDecimal),
|
|
98
|
-
symbol: txMeta.tokenSymbol,
|
|
99
|
-
} });
|
|
100
|
-
}, _EtherscanRemoteTransactionSource_normalizeTransactionBase = function _EtherscanRemoteTransactionSource_normalizeTransactionBase(txMeta, currentChainId) {
|
|
101
|
-
const time = parseInt(txMeta.timeStamp, 10) * 1000;
|
|
102
|
-
return {
|
|
103
|
-
blockNumber: txMeta.blockNumber,
|
|
104
|
-
chainId: currentChainId,
|
|
105
|
-
hash: txMeta.hash,
|
|
106
|
-
id: (0, uuid_1.v1)({ msecs: time }),
|
|
107
|
-
status: types_1.TransactionStatus.confirmed,
|
|
108
|
-
time,
|
|
109
|
-
txParams: {
|
|
110
|
-
chainId: currentChainId,
|
|
111
|
-
from: txMeta.from,
|
|
112
|
-
gas: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gas)),
|
|
113
|
-
gasPrice: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasPrice)),
|
|
114
|
-
gasUsed: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasUsed)),
|
|
115
|
-
nonce: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.nonce)),
|
|
116
|
-
to: txMeta.to,
|
|
117
|
-
value: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.value)),
|
|
118
|
-
},
|
|
119
|
-
verifiedOnBlockchain: false,
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
//# sourceMappingURL=EtherscanRemoteTransactionSource.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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 { ETHERSCAN_SUPPORTED_NETWORKS } from './constants';\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n EtherscanTransactionRequest,\n EtherscanTransactionResponse,\n} from './etherscan';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from './etherscan';\nimport { incomingTransactionsLogger as log } from './logger';\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 #includeTokenTransfers: boolean;\n\n #isTokenRequestPending: boolean;\n\n constructor({\n includeTokenTransfers,\n }: { includeTokenTransfers?: boolean } = {}) {\n this.#includeTokenTransfers = includeTokenTransfers ?? true;\n this.#isTokenRequestPending = false;\n }\n\n isSupportedNetwork(chainId: Hex): boolean {\n return Object.keys(ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);\n }\n\n getLastBlockVariations(): string[] {\n return [this.#isTokenRequestPending ? 'token' : 'normal'];\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const etherscanRequest: EtherscanTransactionRequest = {\n ...request,\n chainId: request.currentChainId,\n };\n\n const transactions = this.#isTokenRequestPending\n ? await this.#fetchTokenTransactions(request, etherscanRequest)\n : await this.#fetchNormalTransactions(request, etherscanRequest);\n\n if (this.#includeTokenTransfers) {\n this.#isTokenRequestPending = !this.#isTokenRequestPending;\n }\n\n return transactions;\n }\n\n #fetchNormalTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTransaction(tx, currentChainId),\n );\n };\n\n #fetchTokenTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTokenTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTokenTransaction(tx, currentChainId),\n );\n };\n\n #getResponseTransactions<T extends EtherscanTransactionMetaBase>(\n response: EtherscanTransactionResponse<T>,\n ): T[] {\n let result = response.result as T[];\n\n if (response.status === '0') {\n result = [];\n\n if (response.result.length) {\n log('Ignored Etherscan request error', {\n message: response.result,\n type: this.#isTokenRequestPending ? 'token' : 'normal',\n });\n }\n }\n\n return result;\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n txParams: {\n ...base.txParams,\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 currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\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 currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n hash: txMeta.hash,\n id: random({ msecs: time }),\n status: TransactionStatus.confirmed,\n time,\n txParams: {\n chainId: currentChainId,\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 verifiedOnBlockchain: false,\n };\n }\n}\n"]}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import type { BlockTracker, NetworkState } from '@metamask/network-controller';
|
|
3
|
-
import type { Hex } from '@metamask/utils';
|
|
4
|
-
import EventEmitter from 'events';
|
|
5
|
-
import type { RemoteTransactionSource, TransactionMeta } from './types';
|
|
6
|
-
export declare class IncomingTransactionHelper {
|
|
7
|
-
#private;
|
|
8
|
-
hub: EventEmitter;
|
|
9
|
-
constructor({ blockTracker, getCurrentAccount, getLastFetchedBlockNumbers, getLocalTransactions, getNetworkState, isEnabled, queryEntireHistory, remoteTransactionSource, transactionLimit, updateTransactions, }: {
|
|
10
|
-
blockTracker: BlockTracker;
|
|
11
|
-
getCurrentAccount: () => string;
|
|
12
|
-
getLastFetchedBlockNumbers: () => Record<string, number>;
|
|
13
|
-
getLocalTransactions?: () => TransactionMeta[];
|
|
14
|
-
getNetworkState: () => NetworkState;
|
|
15
|
-
isEnabled?: () => boolean;
|
|
16
|
-
queryEntireHistory?: boolean;
|
|
17
|
-
remoteTransactionSource: RemoteTransactionSource;
|
|
18
|
-
transactionLimit?: number;
|
|
19
|
-
updateTransactions?: boolean;
|
|
20
|
-
});
|
|
21
|
-
start(): void;
|
|
22
|
-
stop(): void;
|
|
23
|
-
update(latestBlockNumberHex?: Hex): Promise<void>;
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=IncomingTransactionHelper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IncomingTransactionHelper.d.ts","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,YAAY,MAAM,QAAQ,CAAC;AAGlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AASxE,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBA4BN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,eAAe,EAAE,MAAM,YAAY,CAAC;QACpC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;IA0BD,KAAK;IAaL,IAAI;IAKE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAmMxD"}
|
|
@@ -1,198 +0,0 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
-
};
|
|
25
|
-
var _IncomingTransactionHelper_instances, _IncomingTransactionHelper_blockTracker, _IncomingTransactionHelper_getCurrentAccount, _IncomingTransactionHelper_getLastFetchedBlockNumbers, _IncomingTransactionHelper_getLocalTransactions, _IncomingTransactionHelper_getNetworkState, _IncomingTransactionHelper_isEnabled, _IncomingTransactionHelper_isRunning, _IncomingTransactionHelper_mutex, _IncomingTransactionHelper_onLatestBlock, _IncomingTransactionHelper_queryEntireHistory, _IncomingTransactionHelper_remoteTransactionSource, _IncomingTransactionHelper_transactionLimit, _IncomingTransactionHelper_updateTransactions, _IncomingTransactionHelper_sortTransactionsByTime, _IncomingTransactionHelper_getNewTransactions, _IncomingTransactionHelper_getUpdatedTransactions, _IncomingTransactionHelper_isTransactionOutdated, _IncomingTransactionHelper_getFromBlock, _IncomingTransactionHelper_updateLastFetchedBlockNumber, _IncomingTransactionHelper_getBlockNumberKey, _IncomingTransactionHelper_canStart, _IncomingTransactionHelper_getCurrentChainId;
|
|
26
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.IncomingTransactionHelper = void 0;
|
|
28
|
-
const async_mutex_1 = require("async-mutex");
|
|
29
|
-
const events_1 = __importDefault(require("events"));
|
|
30
|
-
const logger_1 = require("./logger");
|
|
31
|
-
const RECENT_HISTORY_BLOCK_RANGE = 10;
|
|
32
|
-
const UPDATE_CHECKS = [
|
|
33
|
-
(txMeta) => txMeta.status,
|
|
34
|
-
(txMeta) => txMeta.txParams.gasUsed,
|
|
35
|
-
];
|
|
36
|
-
class IncomingTransactionHelper {
|
|
37
|
-
constructor({ blockTracker, getCurrentAccount, getLastFetchedBlockNumbers, getLocalTransactions, getNetworkState, isEnabled, queryEntireHistory, remoteTransactionSource, transactionLimit, updateTransactions, }) {
|
|
38
|
-
_IncomingTransactionHelper_instances.add(this);
|
|
39
|
-
_IncomingTransactionHelper_blockTracker.set(this, void 0);
|
|
40
|
-
_IncomingTransactionHelper_getCurrentAccount.set(this, void 0);
|
|
41
|
-
_IncomingTransactionHelper_getLastFetchedBlockNumbers.set(this, void 0);
|
|
42
|
-
_IncomingTransactionHelper_getLocalTransactions.set(this, void 0);
|
|
43
|
-
_IncomingTransactionHelper_getNetworkState.set(this, void 0);
|
|
44
|
-
_IncomingTransactionHelper_isEnabled.set(this, void 0);
|
|
45
|
-
_IncomingTransactionHelper_isRunning.set(this, void 0);
|
|
46
|
-
_IncomingTransactionHelper_mutex.set(this, new async_mutex_1.Mutex());
|
|
47
|
-
_IncomingTransactionHelper_onLatestBlock.set(this, void 0);
|
|
48
|
-
_IncomingTransactionHelper_queryEntireHistory.set(this, void 0);
|
|
49
|
-
_IncomingTransactionHelper_remoteTransactionSource.set(this, void 0);
|
|
50
|
-
_IncomingTransactionHelper_transactionLimit.set(this, void 0);
|
|
51
|
-
_IncomingTransactionHelper_updateTransactions.set(this, void 0);
|
|
52
|
-
this.hub = new events_1.default();
|
|
53
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_blockTracker, blockTracker, "f");
|
|
54
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_getCurrentAccount, getCurrentAccount, "f");
|
|
55
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, getLastFetchedBlockNumbers, "f");
|
|
56
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_getLocalTransactions, getLocalTransactions || (() => []), "f");
|
|
57
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_getNetworkState, getNetworkState, "f");
|
|
58
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_isEnabled, isEnabled !== null && isEnabled !== void 0 ? isEnabled : (() => true), "f");
|
|
59
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
|
|
60
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_queryEntireHistory, queryEntireHistory !== null && queryEntireHistory !== void 0 ? queryEntireHistory : true, "f");
|
|
61
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_remoteTransactionSource, remoteTransactionSource, "f");
|
|
62
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_transactionLimit, transactionLimit, "f");
|
|
63
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_updateTransactions, updateTransactions !== null && updateTransactions !== void 0 ? updateTransactions : false, "f");
|
|
64
|
-
// Using a property instead of a method to provide a listener reference
|
|
65
|
-
// with the correct scope that we can remove later if stopped.
|
|
66
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_onLatestBlock, (blockNumberHex) => __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
try {
|
|
68
|
-
yield this.update(blockNumberHex);
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
console.error('Error while checking incoming transactions', error);
|
|
72
|
-
}
|
|
73
|
-
}), "f");
|
|
74
|
-
}
|
|
75
|
-
start() {
|
|
76
|
-
if (__classPrivateFieldGet(this, _IncomingTransactionHelper_isRunning, "f")) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").addListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
|
|
83
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, true, "f");
|
|
84
|
-
}
|
|
85
|
-
stop() {
|
|
86
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").removeListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
|
|
87
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
|
|
88
|
-
}
|
|
89
|
-
update(latestBlockNumberHex) {
|
|
90
|
-
var _a, _b, _c;
|
|
91
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
const releaseLock = yield __classPrivateFieldGet(this, _IncomingTransactionHelper_mutex, "f").acquire();
|
|
93
|
-
(0, logger_1.incomingTransactionsLogger)('Checking for incoming transactions');
|
|
94
|
-
try {
|
|
95
|
-
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const latestBlockNumber = parseInt(latestBlockNumberHex || (yield __classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").getLatestBlock()), 16);
|
|
99
|
-
const additionalLastFetchedKeys = (_c = (_b = (_a = __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f")).getLastBlockVariations) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
|
|
100
|
-
const fromBlock = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getFromBlock).call(this, latestBlockNumber, additionalLastFetchedKeys);
|
|
101
|
-
const address = __classPrivateFieldGet(this, _IncomingTransactionHelper_getCurrentAccount, "f").call(this);
|
|
102
|
-
const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getCurrentChainId).call(this);
|
|
103
|
-
let remoteTransactions = [];
|
|
104
|
-
try {
|
|
105
|
-
remoteTransactions =
|
|
106
|
-
yield __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").fetchTransactions({
|
|
107
|
-
address,
|
|
108
|
-
currentChainId,
|
|
109
|
-
fromBlock,
|
|
110
|
-
limit: __classPrivateFieldGet(this, _IncomingTransactionHelper_transactionLimit, "f"),
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
(0, logger_1.incomingTransactionsLogger)('Error while fetching remote transactions', error);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_updateTransactions, "f")) {
|
|
118
|
-
remoteTransactions = remoteTransactions.filter((tx) => { var _a; return ((_a = tx.txParams.to) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === address.toLowerCase(); });
|
|
119
|
-
}
|
|
120
|
-
const localTransactions = !__classPrivateFieldGet(this, _IncomingTransactionHelper_updateTransactions, "f")
|
|
121
|
-
? []
|
|
122
|
-
: __classPrivateFieldGet(this, _IncomingTransactionHelper_getLocalTransactions, "f").call(this);
|
|
123
|
-
const newTransactions = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getNewTransactions).call(this, remoteTransactions, localTransactions);
|
|
124
|
-
const updatedTransactions = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getUpdatedTransactions).call(this, remoteTransactions, localTransactions);
|
|
125
|
-
if (newTransactions.length > 0 || updatedTransactions.length > 0) {
|
|
126
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, newTransactions);
|
|
127
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, updatedTransactions);
|
|
128
|
-
(0, logger_1.incomingTransactionsLogger)('Found incoming transactions', {
|
|
129
|
-
new: newTransactions,
|
|
130
|
-
updated: updatedTransactions,
|
|
131
|
-
});
|
|
132
|
-
this.hub.emit('transactions', {
|
|
133
|
-
added: newTransactions,
|
|
134
|
-
updated: updatedTransactions,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_updateLastFetchedBlockNumber).call(this, remoteTransactions, additionalLastFetchedKeys);
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
releaseLock();
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
exports.IncomingTransactionHelper = IncomingTransactionHelper;
|
|
146
|
-
_IncomingTransactionHelper_blockTracker = new WeakMap(), _IncomingTransactionHelper_getCurrentAccount = new WeakMap(), _IncomingTransactionHelper_getLastFetchedBlockNumbers = new WeakMap(), _IncomingTransactionHelper_getLocalTransactions = new WeakMap(), _IncomingTransactionHelper_getNetworkState = new WeakMap(), _IncomingTransactionHelper_isEnabled = new WeakMap(), _IncomingTransactionHelper_isRunning = new WeakMap(), _IncomingTransactionHelper_mutex = new WeakMap(), _IncomingTransactionHelper_onLatestBlock = new WeakMap(), _IncomingTransactionHelper_queryEntireHistory = new WeakMap(), _IncomingTransactionHelper_remoteTransactionSource = new WeakMap(), _IncomingTransactionHelper_transactionLimit = new WeakMap(), _IncomingTransactionHelper_updateTransactions = new WeakMap(), _IncomingTransactionHelper_instances = new WeakSet(), _IncomingTransactionHelper_sortTransactionsByTime = function _IncomingTransactionHelper_sortTransactionsByTime(transactions) {
|
|
147
|
-
transactions.sort((a, b) => (a.time < b.time ? -1 : 1));
|
|
148
|
-
}, _IncomingTransactionHelper_getNewTransactions = function _IncomingTransactionHelper_getNewTransactions(remoteTxs, localTxs) {
|
|
149
|
-
return remoteTxs.filter((tx) => !localTxs.some(({ hash }) => hash === tx.hash));
|
|
150
|
-
}, _IncomingTransactionHelper_getUpdatedTransactions = function _IncomingTransactionHelper_getUpdatedTransactions(remoteTxs, localTxs) {
|
|
151
|
-
return remoteTxs.filter((remoteTx) => localTxs.some((localTx) => remoteTx.hash === localTx.hash &&
|
|
152
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_isTransactionOutdated).call(this, remoteTx, localTx)));
|
|
153
|
-
}, _IncomingTransactionHelper_isTransactionOutdated = function _IncomingTransactionHelper_isTransactionOutdated(remoteTx, localTx) {
|
|
154
|
-
return UPDATE_CHECKS.some((getValue) => getValue(remoteTx) !== getValue(localTx));
|
|
155
|
-
}, _IncomingTransactionHelper_getFromBlock = function _IncomingTransactionHelper_getFromBlock(latestBlockNumber, additionalKeys) {
|
|
156
|
-
const lastFetchedKey = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getBlockNumberKey).call(this, additionalKeys);
|
|
157
|
-
const lastFetchedBlockNumber = __classPrivateFieldGet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, "f").call(this)[lastFetchedKey];
|
|
158
|
-
if (lastFetchedBlockNumber) {
|
|
159
|
-
return lastFetchedBlockNumber + 1;
|
|
160
|
-
}
|
|
161
|
-
return __classPrivateFieldGet(this, _IncomingTransactionHelper_queryEntireHistory, "f")
|
|
162
|
-
? undefined
|
|
163
|
-
: latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;
|
|
164
|
-
}, _IncomingTransactionHelper_updateLastFetchedBlockNumber = function _IncomingTransactionHelper_updateLastFetchedBlockNumber(remoteTxs, additionalKeys) {
|
|
165
|
-
let lastFetchedBlockNumber = -1;
|
|
166
|
-
for (const tx of remoteTxs) {
|
|
167
|
-
const currentBlockNumberValue = tx.blockNumber
|
|
168
|
-
? parseInt(tx.blockNumber, 10)
|
|
169
|
-
: -1;
|
|
170
|
-
lastFetchedBlockNumber = Math.max(lastFetchedBlockNumber, currentBlockNumberValue);
|
|
171
|
-
}
|
|
172
|
-
if (lastFetchedBlockNumber === -1) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
const lastFetchedKey = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getBlockNumberKey).call(this, additionalKeys);
|
|
176
|
-
const lastFetchedBlockNumbers = __classPrivateFieldGet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, "f").call(this);
|
|
177
|
-
const previousValue = lastFetchedBlockNumbers[lastFetchedKey];
|
|
178
|
-
if (previousValue >= lastFetchedBlockNumber) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
lastFetchedBlockNumbers[lastFetchedKey] = lastFetchedBlockNumber;
|
|
182
|
-
this.hub.emit('updatedLastFetchedBlockNumbers', {
|
|
183
|
-
lastFetchedBlockNumbers,
|
|
184
|
-
blockNumber: lastFetchedBlockNumber,
|
|
185
|
-
});
|
|
186
|
-
}, _IncomingTransactionHelper_getBlockNumberKey = function _IncomingTransactionHelper_getBlockNumberKey(additionalKeys) {
|
|
187
|
-
const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getCurrentChainId).call(this);
|
|
188
|
-
const currentAccount = __classPrivateFieldGet(this, _IncomingTransactionHelper_getCurrentAccount, "f").call(this).toLowerCase();
|
|
189
|
-
return [currentChainId, currentAccount, ...additionalKeys].join('#');
|
|
190
|
-
}, _IncomingTransactionHelper_canStart = function _IncomingTransactionHelper_canStart() {
|
|
191
|
-
const isEnabled = __classPrivateFieldGet(this, _IncomingTransactionHelper_isEnabled, "f").call(this);
|
|
192
|
-
const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getCurrentChainId).call(this);
|
|
193
|
-
const isSupportedNetwork = __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").isSupportedNetwork(currentChainId);
|
|
194
|
-
return isEnabled && isSupportedNetwork;
|
|
195
|
-
}, _IncomingTransactionHelper_getCurrentChainId = function _IncomingTransactionHelper_getCurrentChainId() {
|
|
196
|
-
return __classPrivateFieldGet(this, _IncomingTransactionHelper_getNetworkState, "f").call(this).providerConfig.chainId;
|
|
197
|
-
};
|
|
198
|
-
//# sourceMappingURL=IncomingTransactionHelper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IncomingTransactionHelper.js","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BlockTracker, NetworkState } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport EventEmitter from 'events';\n\nimport { incomingTransactionsLogger as log } from './logger';\nimport type { RemoteTransactionSource, TransactionMeta } from './types';\n\nconst RECENT_HISTORY_BLOCK_RANGE = 10;\n\nconst UPDATE_CHECKS: ((txMeta: TransactionMeta) => any)[] = [\n (txMeta) => txMeta.status,\n (txMeta) => txMeta.txParams.gasUsed,\n];\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #getCurrentAccount: () => string;\n\n #getLastFetchedBlockNumbers: () => Record<string, number>;\n\n #getLocalTransactions: () => TransactionMeta[];\n\n #getNetworkState: () => NetworkState;\n\n #isEnabled: () => boolean;\n\n #isRunning: boolean;\n\n #mutex = new Mutex();\n\n #onLatestBlock: (blockNumberHex: Hex) => Promise<void>;\n\n #queryEntireHistory: boolean;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n #transactionLimit?: number;\n\n #updateTransactions: boolean;\n\n constructor({\n blockTracker,\n getCurrentAccount,\n getLastFetchedBlockNumbers,\n getLocalTransactions,\n getNetworkState,\n isEnabled,\n queryEntireHistory,\n remoteTransactionSource,\n transactionLimit,\n updateTransactions,\n }: {\n blockTracker: BlockTracker;\n getCurrentAccount: () => string;\n getLastFetchedBlockNumbers: () => Record<string, number>;\n getLocalTransactions?: () => TransactionMeta[];\n getNetworkState: () => NetworkState;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n remoteTransactionSource: RemoteTransactionSource;\n transactionLimit?: number;\n updateTransactions?: boolean;\n }) {\n this.hub = new EventEmitter();\n\n this.#blockTracker = blockTracker;\n this.#getCurrentAccount = getCurrentAccount;\n this.#getLastFetchedBlockNumbers = getLastFetchedBlockNumbers;\n this.#getLocalTransactions = getLocalTransactions || (() => []);\n this.#getNetworkState = getNetworkState;\n this.#isEnabled = isEnabled ?? (() => true);\n this.#isRunning = false;\n this.#queryEntireHistory = queryEntireHistory ?? true;\n this.#remoteTransactionSource = remoteTransactionSource;\n this.#transactionLimit = transactionLimit;\n this.#updateTransactions = updateTransactions ?? false;\n\n // Using a property instead of a method to provide a listener reference\n // with the correct scope that we can remove later if stopped.\n this.#onLatestBlock = async (blockNumberHex: Hex) => {\n try {\n await this.update(blockNumberHex);\n } catch (error) {\n console.error('Error while checking incoming transactions', error);\n }\n };\n }\n\n start() {\n if (this.#isRunning) {\n return;\n }\n\n if (!this.#canStart()) {\n return;\n }\n\n this.#blockTracker.addListener('latest', this.#onLatestBlock);\n this.#isRunning = true;\n }\n\n stop() {\n this.#blockTracker.removeListener('latest', this.#onLatestBlock);\n this.#isRunning = false;\n }\n\n async update(latestBlockNumberHex?: Hex): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n log('Checking for incoming transactions');\n\n try {\n if (!this.#canStart()) {\n return;\n }\n\n const latestBlockNumber = parseInt(\n latestBlockNumberHex || (await this.#blockTracker.getLatestBlock()),\n 16,\n );\n\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n\n const fromBlock = this.#getFromBlock(\n latestBlockNumber,\n additionalLastFetchedKeys,\n );\n\n const address = this.#getCurrentAccount();\n const currentChainId = this.#getCurrentChainId();\n\n let remoteTransactions = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address,\n currentChainId,\n fromBlock,\n limit: this.#transactionLimit,\n });\n } catch (error: any) {\n log('Error while fetching remote transactions', error);\n return;\n }\n\n if (!this.#updateTransactions) {\n remoteTransactions = remoteTransactions.filter(\n (tx) => tx.txParams.to?.toLowerCase() === address.toLowerCase(),\n );\n }\n\n const localTransactions = !this.#updateTransactions\n ? []\n : this.#getLocalTransactions();\n\n const newTransactions = this.#getNewTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n const updatedTransactions = this.#getUpdatedTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n if (newTransactions.length > 0 || updatedTransactions.length > 0) {\n this.#sortTransactionsByTime(newTransactions);\n this.#sortTransactionsByTime(updatedTransactions);\n\n log('Found incoming transactions', {\n new: newTransactions,\n updated: updatedTransactions,\n });\n\n this.hub.emit('transactions', {\n added: newTransactions,\n updated: updatedTransactions,\n });\n }\n\n this.#updateLastFetchedBlockNumber(\n remoteTransactions,\n additionalLastFetchedKeys,\n );\n } finally {\n releaseLock();\n }\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #getNewTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter(\n (tx) => !localTxs.some(({ hash }) => hash === tx.hash),\n );\n }\n\n #getUpdatedTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((remoteTx) =>\n localTxs.some(\n (localTx) =>\n remoteTx.hash === localTx.hash &&\n this.#isTransactionOutdated(remoteTx, localTx),\n ),\n );\n }\n\n #isTransactionOutdated(\n remoteTx: TransactionMeta,\n localTx: TransactionMeta,\n ): boolean {\n return UPDATE_CHECKS.some(\n (getValue) => getValue(remoteTx) !== getValue(localTx),\n );\n }\n\n #getFromBlock(\n latestBlockNumber: number,\n additionalKeys: string[],\n ): number | undefined {\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n\n const lastFetchedBlockNumber =\n this.#getLastFetchedBlockNumbers()[lastFetchedKey];\n\n if (lastFetchedBlockNumber) {\n return lastFetchedBlockNumber + 1;\n }\n\n return this.#queryEntireHistory\n ? undefined\n : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;\n }\n\n #updateLastFetchedBlockNumber(\n remoteTxs: TransactionMeta[],\n additionalKeys: string[],\n ) {\n let lastFetchedBlockNumber = -1;\n\n for (const tx of remoteTxs) {\n const currentBlockNumberValue = tx.blockNumber\n ? parseInt(tx.blockNumber, 10)\n : -1;\n\n lastFetchedBlockNumber = Math.max(\n lastFetchedBlockNumber,\n currentBlockNumberValue,\n );\n }\n\n if (lastFetchedBlockNumber === -1) {\n return;\n }\n\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n const previousValue = lastFetchedBlockNumbers[lastFetchedKey];\n\n if (previousValue >= lastFetchedBlockNumber) {\n return;\n }\n\n lastFetchedBlockNumbers[lastFetchedKey] = lastFetchedBlockNumber;\n\n this.hub.emit('updatedLastFetchedBlockNumbers', {\n lastFetchedBlockNumbers,\n blockNumber: lastFetchedBlockNumber,\n });\n }\n\n #getBlockNumberKey(additionalKeys: string[]): string {\n const currentChainId = this.#getCurrentChainId();\n const currentAccount = this.#getCurrentAccount().toLowerCase();\n\n return [currentChainId, currentAccount, ...additionalKeys].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const currentChainId = this.#getCurrentChainId();\n\n const isSupportedNetwork =\n this.#remoteTransactionSource.isSupportedNetwork(currentChainId);\n\n return isEnabled && isSupportedNetwork;\n }\n\n #getCurrentChainId(): Hex {\n return this.#getNetworkState().providerConfig.chainId;\n }\n}\n"]}
|
package/dist/etherscan.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { Hex } from '@metamask/utils';
|
|
2
|
-
export interface EtherscanTransactionMetaBase {
|
|
3
|
-
blockNumber: string;
|
|
4
|
-
blockHash: string;
|
|
5
|
-
confirmations: string;
|
|
6
|
-
contractAddress: string;
|
|
7
|
-
cumulativeGasUsed: string;
|
|
8
|
-
from: string;
|
|
9
|
-
gas: string;
|
|
10
|
-
gasPrice: string;
|
|
11
|
-
gasUsed: string;
|
|
12
|
-
hash: string;
|
|
13
|
-
nonce: string;
|
|
14
|
-
timeStamp: string;
|
|
15
|
-
to: string;
|
|
16
|
-
transactionIndex: string;
|
|
17
|
-
value: string;
|
|
18
|
-
}
|
|
19
|
-
export interface EtherscanTransactionMeta extends EtherscanTransactionMetaBase {
|
|
20
|
-
functionName: string;
|
|
21
|
-
input: string;
|
|
22
|
-
isError: string;
|
|
23
|
-
methodId: string;
|
|
24
|
-
txreceipt_status: string;
|
|
25
|
-
}
|
|
26
|
-
export interface EtherscanTokenTransactionMeta extends EtherscanTransactionMetaBase {
|
|
27
|
-
tokenDecimal: string;
|
|
28
|
-
tokenName: string;
|
|
29
|
-
tokenSymbol: string;
|
|
30
|
-
}
|
|
31
|
-
export interface EtherscanTransactionResponse<T extends EtherscanTransactionMetaBase> {
|
|
32
|
-
status: '0' | '1';
|
|
33
|
-
message?: string;
|
|
34
|
-
result: string | T[];
|
|
35
|
-
}
|
|
36
|
-
export interface EtherscanTransactionRequest {
|
|
37
|
-
address: string;
|
|
38
|
-
chainId: Hex;
|
|
39
|
-
fromBlock?: number;
|
|
40
|
-
limit?: number;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Retrieves transaction data from Etherscan.
|
|
44
|
-
*
|
|
45
|
-
* @param request - Configuration required to fetch transactions.
|
|
46
|
-
* @param request.address - Address to retrieve transactions for.
|
|
47
|
-
* @param request.chainId - Current chain ID used to determine subdomain and domain.
|
|
48
|
-
* @param request.fromBlock - Block number to start fetching transactions from.
|
|
49
|
-
* @param request.limit - Number of transactions to retrieve.
|
|
50
|
-
* @returns An Etherscan response object containing the request status and an array of token transaction data.
|
|
51
|
-
*/
|
|
52
|
-
export declare function fetchEtherscanTransactions({ address, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTransactionMeta>>;
|
|
53
|
-
/**
|
|
54
|
-
* Retrieves token transaction data from Etherscan.
|
|
55
|
-
*
|
|
56
|
-
* @param request - Configuration required to fetch token transactions.
|
|
57
|
-
* @param request.address - Address to retrieve token transactions for.
|
|
58
|
-
* @param request.chainId - Current chain ID used to determine subdomain and domain.
|
|
59
|
-
* @param request.fromBlock - Block number to start fetching token transactions from.
|
|
60
|
-
* @param request.limit - Number of token transactions to retrieve.
|
|
61
|
-
* @returns An Etherscan response object containing the request status and an array of token transaction data.
|
|
62
|
-
*/
|
|
63
|
-
export declare function fetchEtherscanTokenTransactions({ address, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTokenTransactionMeta>>;
|
|
64
|
-
//# sourceMappingURL=etherscan.d.ts.map
|
package/dist/etherscan.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"etherscan.d.ts","sourceRoot":"","sources":["../src/etherscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAK3C,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAyB,SAAQ,4BAA4B;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,6BACf,SAAQ,4BAA4B;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B,CAC3C,CAAC,SAAS,4BAA4B;IAEtC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAAC,EAC/C,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,wBAAwB,CAAC,CACvD,CAOA;AAED;;;;;;;;;GASG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,6BAA6B,CAAC,CAC5D,CAOA"}
|
package/dist/etherscan.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.fetchEtherscanTokenTransactions = exports.fetchEtherscanTransactions = void 0;
|
|
13
|
-
const controller_utils_1 = require("@metamask/controller-utils");
|
|
14
|
-
const constants_1 = require("./constants");
|
|
15
|
-
const logger_1 = require("./logger");
|
|
16
|
-
/**
|
|
17
|
-
* Retrieves transaction data from Etherscan.
|
|
18
|
-
*
|
|
19
|
-
* @param request - Configuration required to fetch transactions.
|
|
20
|
-
* @param request.address - Address to retrieve transactions for.
|
|
21
|
-
* @param request.chainId - Current chain ID used to determine subdomain and domain.
|
|
22
|
-
* @param request.fromBlock - Block number to start fetching transactions from.
|
|
23
|
-
* @param request.limit - Number of transactions to retrieve.
|
|
24
|
-
* @returns An Etherscan response object containing the request status and an array of token transaction data.
|
|
25
|
-
*/
|
|
26
|
-
function fetchEtherscanTransactions({ address, chainId, fromBlock, limit, }) {
|
|
27
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
-
return yield fetchTransactions('txlist', {
|
|
29
|
-
address,
|
|
30
|
-
chainId,
|
|
31
|
-
fromBlock,
|
|
32
|
-
limit,
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
exports.fetchEtherscanTransactions = fetchEtherscanTransactions;
|
|
37
|
-
/**
|
|
38
|
-
* Retrieves token transaction data from Etherscan.
|
|
39
|
-
*
|
|
40
|
-
* @param request - Configuration required to fetch token transactions.
|
|
41
|
-
* @param request.address - Address to retrieve token transactions for.
|
|
42
|
-
* @param request.chainId - Current chain ID used to determine subdomain and domain.
|
|
43
|
-
* @param request.fromBlock - Block number to start fetching token transactions from.
|
|
44
|
-
* @param request.limit - Number of token transactions to retrieve.
|
|
45
|
-
* @returns An Etherscan response object containing the request status and an array of token transaction data.
|
|
46
|
-
*/
|
|
47
|
-
function fetchEtherscanTokenTransactions({ address, chainId, fromBlock, limit, }) {
|
|
48
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
return yield fetchTransactions('tokentx', {
|
|
50
|
-
address,
|
|
51
|
-
chainId,
|
|
52
|
-
fromBlock,
|
|
53
|
-
limit,
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
exports.fetchEtherscanTokenTransactions = fetchEtherscanTokenTransactions;
|
|
58
|
-
/**
|
|
59
|
-
* Retrieves transaction data from Etherscan from a specific endpoint.
|
|
60
|
-
*
|
|
61
|
-
* @param action - The Etherscan endpoint to use.
|
|
62
|
-
* @param options - Options bag.
|
|
63
|
-
* @param options.address - Address to retrieve transactions for.
|
|
64
|
-
* @param options.chainId - Current chain ID used to determine subdomain and domain.
|
|
65
|
-
* @param options.fromBlock - Block number to start fetching transactions from.
|
|
66
|
-
* @param options.limit - Number of transactions to retrieve.
|
|
67
|
-
* @returns An object containing the request status and an array of transaction data.
|
|
68
|
-
*/
|
|
69
|
-
function fetchTransactions(action, { address, chainId, fromBlock, limit, }) {
|
|
70
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
const urlParams = {
|
|
72
|
-
module: 'account',
|
|
73
|
-
address,
|
|
74
|
-
startBlock: fromBlock === null || fromBlock === void 0 ? void 0 : fromBlock.toString(),
|
|
75
|
-
offset: limit === null || limit === void 0 ? void 0 : limit.toString(),
|
|
76
|
-
sort: 'desc',
|
|
77
|
-
};
|
|
78
|
-
const etherscanTxUrl = getEtherscanApiUrl(chainId, Object.assign(Object.assign({}, urlParams), { action }));
|
|
79
|
-
(0, logger_1.incomingTransactionsLogger)('Sending Etherscan request', etherscanTxUrl);
|
|
80
|
-
const response = (yield (0, controller_utils_1.handleFetch)(etherscanTxUrl));
|
|
81
|
-
return response;
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Return a URL that can be used to fetch data from Etherscan.
|
|
86
|
-
*
|
|
87
|
-
* @param chainId - Current chain ID used to determine subdomain and domain.
|
|
88
|
-
* @param urlParams - The parameters used to construct the URL.
|
|
89
|
-
* @returns URL to access Etherscan data.
|
|
90
|
-
*/
|
|
91
|
-
function getEtherscanApiUrl(chainId, urlParams) {
|
|
92
|
-
const networkInfo = constants_1.ETHERSCAN_SUPPORTED_NETWORKS[chainId];
|
|
93
|
-
if (!networkInfo) {
|
|
94
|
-
throw new Error(`Etherscan does not support chain with ID: ${chainId}`);
|
|
95
|
-
}
|
|
96
|
-
const apiUrl = `https://${networkInfo.subdomain}.${networkInfo.domain}`;
|
|
97
|
-
let url = `${apiUrl}/api?`;
|
|
98
|
-
// eslint-disable-next-line guard-for-in
|
|
99
|
-
for (const paramKey in urlParams) {
|
|
100
|
-
const value = urlParams[paramKey];
|
|
101
|
-
if (!value) {
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
url += `${paramKey}=${value}&`;
|
|
105
|
-
}
|
|
106
|
-
url += 'tag=latest&page=1';
|
|
107
|
-
return url;
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=etherscan.js.map
|