@metamask-previews/transaction-controller 39.1.0-preview-fd7ad7de → 40.0.0-preview-e6722625
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 +8 -1
- package/dist/TransactionController.cjs +47 -44
- package/dist/TransactionController.cjs.map +1 -1
- package/dist/TransactionController.d.cts +8 -8
- package/dist/TransactionController.d.cts.map +1 -1
- package/dist/TransactionController.d.mts +8 -8
- package/dist/TransactionController.d.mts.map +1 -1
- package/dist/TransactionController.mjs +47 -44
- package/dist/TransactionController.mjs.map +1 -1
- package/dist/constants.cjs +85 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +84 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +84 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +84 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/helpers/EtherscanRemoteTransactionSource.cjs +157 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.cjs.map +1 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.d.cts +16 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.d.cts.map +1 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.d.mts +16 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.d.mts.map +1 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.mjs +157 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +1 -0
- package/dist/helpers/IncomingTransactionHelper.cjs +137 -87
- package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.cts +12 -7
- package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.mts +12 -7
- package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.mjs +137 -87
- package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.cjs +66 -3
- package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.d.cts +14 -1
- package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.d.mts +14 -1
- package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.mjs +66 -3
- package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +8 -11
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +8 -11
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/etherscan.cjs +115 -0
- package/dist/utils/etherscan.cjs.map +1 -0
- package/dist/utils/etherscan.d.cts +74 -0
- package/dist/utils/etherscan.d.cts.map +1 -0
- package/dist/utils/etherscan.d.mts +74 -0
- package/dist/utils/etherscan.d.mts.map +1 -0
- package/dist/utils/etherscan.mjs +109 -0
- package/dist/utils/etherscan.mjs.map +1 -0
- package/package.json +3 -3
- package/dist/api/accounts-api.cjs +0 -66
- package/dist/api/accounts-api.cjs.map +0 -1
- package/dist/api/accounts-api.d.cts +0 -56
- package/dist/api/accounts-api.d.cts.map +0 -1
- package/dist/api/accounts-api.d.mts +0 -56
- package/dist/api/accounts-api.d.mts.map +0 -1
- package/dist/api/accounts-api.mjs +0 -61
- package/dist/api/accounts-api.mjs.map +0 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.cjs +0 -132
- package/dist/helpers/AccountsApiRemoteTransactionSource.cjs.map +0 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts +0 -11
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts.map +0 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts +0 -11
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts.map +0 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.mjs +0 -132
- package/dist/helpers/AccountsApiRemoteTransactionSource.mjs.map +0 -1
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { AccountsController } from "@metamask/accounts-controller";
|
|
3
|
+
import type { BlockTracker } from "@metamask/network-controller";
|
|
3
4
|
import type { Hex } from "@metamask/utils";
|
|
4
5
|
import EventEmitter from "events";
|
|
5
|
-
import type { RemoteTransactionSource } from "../types.mjs";
|
|
6
|
+
import type { RemoteTransactionSource, TransactionMeta } from "../types.mjs";
|
|
6
7
|
/**
|
|
7
8
|
* Configuration options for the IncomingTransactionHelper
|
|
8
9
|
*
|
|
9
10
|
* @property includeTokenTransfers - Whether or not to include ERC20 token transfers.
|
|
10
11
|
* @property isEnabled - Whether or not incoming transaction retrieval is enabled.
|
|
12
|
+
* @property queryEntireHistory - Whether to initially query the entire transaction history or only recent blocks.
|
|
13
|
+
* @property updateTransactions - Whether to update local transactions using remote transaction data.
|
|
11
14
|
*/
|
|
12
15
|
export type IncomingTransactionOptions = {
|
|
13
16
|
includeTokenTransfers?: boolean;
|
|
14
17
|
isEnabled?: () => boolean;
|
|
18
|
+
queryEntireHistory?: boolean;
|
|
19
|
+
updateTransactions?: boolean;
|
|
15
20
|
};
|
|
16
21
|
export declare class IncomingTransactionHelper {
|
|
17
22
|
#private;
|
|
18
23
|
hub: EventEmitter;
|
|
19
|
-
constructor({ getCurrentAccount,
|
|
24
|
+
constructor({ blockTracker, getCurrentAccount, getLastFetchedBlockNumbers, getLocalTransactions, getChainId, isEnabled, queryEntireHistory, remoteTransactionSource, transactionLimit, updateTransactions, }: {
|
|
25
|
+
blockTracker: BlockTracker;
|
|
20
26
|
getCurrentAccount: () => ReturnType<AccountsController['getSelectedAccount']>;
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
getLastFetchedBlockNumbers: () => Record<string, number>;
|
|
28
|
+
getLocalTransactions?: () => TransactionMeta[];
|
|
29
|
+
getChainId: () => Hex;
|
|
23
30
|
isEnabled?: () => boolean;
|
|
24
31
|
queryEntireHistory?: boolean;
|
|
25
32
|
remoteTransactionSource: RemoteTransactionSource;
|
|
@@ -28,8 +35,6 @@ export declare class IncomingTransactionHelper {
|
|
|
28
35
|
});
|
|
29
36
|
start(): void;
|
|
30
37
|
stop(): void;
|
|
31
|
-
update(
|
|
32
|
-
isInterval?: boolean;
|
|
33
|
-
}): Promise<void>;
|
|
38
|
+
update(latestBlockNumberHex?: Hex): Promise<void>;
|
|
34
39
|
}
|
|
35
40
|
//# sourceMappingURL=IncomingTransactionHelper.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IncomingTransactionHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sCAAsC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"IncomingTransactionHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sCAAsC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAWzE;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBA8BN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,UAAU,CACjC,kBAAkB,CAAC,oBAAoB,CAAC,CACzC,CAAC;QACF,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,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;IAeL,IAAI;IAOE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CA+LxD"}
|
|
@@ -9,30 +9,55 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _IncomingTransactionHelper_instances, _IncomingTransactionHelper_getCurrentAccount,
|
|
12
|
+
var _IncomingTransactionHelper_instances, _IncomingTransactionHelper_blockTracker, _IncomingTransactionHelper_getCurrentAccount, _IncomingTransactionHelper_getLastFetchedBlockNumbers, _IncomingTransactionHelper_getLocalTransactions, _IncomingTransactionHelper_getChainId, _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_getLastFetchedBlockNumberDec, _IncomingTransactionHelper_getFromBlock, _IncomingTransactionHelper_updateLastFetchedBlockNumber, _IncomingTransactionHelper_getBlockNumberKey, _IncomingTransactionHelper_canStart;
|
|
13
|
+
import { Mutex } from "async-mutex";
|
|
13
14
|
import EventEmitter from "events";
|
|
14
15
|
import { incomingTransactionsLogger as log } from "../logger.mjs";
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
const RECENT_HISTORY_BLOCK_RANGE = 10;
|
|
17
|
+
// TODO: Replace `any` with type
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
const UPDATE_CHECKS = [
|
|
20
|
+
(txMeta) => txMeta.status,
|
|
21
|
+
(txMeta) => txMeta.txParams.gasUsed,
|
|
22
|
+
];
|
|
17
23
|
export class IncomingTransactionHelper {
|
|
18
|
-
constructor({ getCurrentAccount,
|
|
24
|
+
constructor({ blockTracker, getCurrentAccount, getLastFetchedBlockNumbers, getLocalTransactions, getChainId, isEnabled, queryEntireHistory, remoteTransactionSource, transactionLimit, updateTransactions, }) {
|
|
19
25
|
_IncomingTransactionHelper_instances.add(this);
|
|
26
|
+
_IncomingTransactionHelper_blockTracker.set(this, void 0);
|
|
20
27
|
_IncomingTransactionHelper_getCurrentAccount.set(this, void 0);
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
_IncomingTransactionHelper_getLastFetchedBlockNumbers.set(this, void 0);
|
|
29
|
+
_IncomingTransactionHelper_getLocalTransactions.set(this, void 0);
|
|
30
|
+
_IncomingTransactionHelper_getChainId.set(this, void 0);
|
|
23
31
|
_IncomingTransactionHelper_isEnabled.set(this, void 0);
|
|
24
32
|
_IncomingTransactionHelper_isRunning.set(this, void 0);
|
|
33
|
+
_IncomingTransactionHelper_mutex.set(this, new Mutex());
|
|
34
|
+
_IncomingTransactionHelper_onLatestBlock.set(this, void 0);
|
|
35
|
+
_IncomingTransactionHelper_queryEntireHistory.set(this, void 0);
|
|
25
36
|
_IncomingTransactionHelper_remoteTransactionSource.set(this, void 0);
|
|
26
|
-
_IncomingTransactionHelper_timeoutId.set(this, void 0);
|
|
27
37
|
_IncomingTransactionHelper_transactionLimit.set(this, void 0);
|
|
38
|
+
_IncomingTransactionHelper_updateTransactions.set(this, void 0);
|
|
28
39
|
this.hub = new EventEmitter();
|
|
40
|
+
__classPrivateFieldSet(this, _IncomingTransactionHelper_blockTracker, blockTracker, "f");
|
|
29
41
|
__classPrivateFieldSet(this, _IncomingTransactionHelper_getCurrentAccount, getCurrentAccount, "f");
|
|
30
|
-
__classPrivateFieldSet(this,
|
|
31
|
-
__classPrivateFieldSet(this,
|
|
42
|
+
__classPrivateFieldSet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, getLastFetchedBlockNumbers, "f");
|
|
43
|
+
__classPrivateFieldSet(this, _IncomingTransactionHelper_getLocalTransactions, getLocalTransactions || (() => []), "f");
|
|
44
|
+
__classPrivateFieldSet(this, _IncomingTransactionHelper_getChainId, getChainId, "f");
|
|
32
45
|
__classPrivateFieldSet(this, _IncomingTransactionHelper_isEnabled, isEnabled ?? (() => true), "f");
|
|
33
46
|
__classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
|
|
47
|
+
__classPrivateFieldSet(this, _IncomingTransactionHelper_queryEntireHistory, queryEntireHistory ?? true, "f");
|
|
34
48
|
__classPrivateFieldSet(this, _IncomingTransactionHelper_remoteTransactionSource, remoteTransactionSource, "f");
|
|
35
49
|
__classPrivateFieldSet(this, _IncomingTransactionHelper_transactionLimit, transactionLimit, "f");
|
|
50
|
+
__classPrivateFieldSet(this, _IncomingTransactionHelper_updateTransactions, updateTransactions ?? false, "f");
|
|
51
|
+
// Using a property instead of a method to provide a listener reference
|
|
52
|
+
// with the correct scope that we can remove later if stopped.
|
|
53
|
+
__classPrivateFieldSet(this, _IncomingTransactionHelper_onLatestBlock, async (blockNumberHex) => {
|
|
54
|
+
try {
|
|
55
|
+
await this.update(blockNumberHex);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('Error while checking incoming transactions', error);
|
|
59
|
+
}
|
|
60
|
+
}, "f");
|
|
36
61
|
}
|
|
37
62
|
start() {
|
|
38
63
|
if (__classPrivateFieldGet(this, _IncomingTransactionHelper_isRunning, "f")) {
|
|
@@ -41,102 +66,127 @@ export class IncomingTransactionHelper {
|
|
|
41
66
|
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
|
|
42
67
|
return;
|
|
43
68
|
}
|
|
69
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
44
70
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
45
|
-
|
|
71
|
+
__classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").addListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
|
|
46
72
|
__classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, true, "f");
|
|
47
|
-
log('Started polling');
|
|
48
73
|
}
|
|
49
74
|
stop() {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_isRunning, "f")) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
75
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
77
|
+
__classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").removeListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
|
|
56
78
|
__classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
|
|
57
|
-
log('Stopped polling');
|
|
58
79
|
}
|
|
59
|
-
async update(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
});
|
|
63
|
-
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const account = __classPrivateFieldGet(this, _IncomingTransactionHelper_getCurrentAccount, "f").call(this);
|
|
67
|
-
const chainIds = __classPrivateFieldGet(this, _IncomingTransactionHelper_getChainIds, "f").call(this);
|
|
68
|
-
const startTimestampByChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getStartTimestampByChainId).call(this, chainIds);
|
|
69
|
-
const endTimestamp = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getTimestampSeconds).call(this, Date.now());
|
|
70
|
-
let remoteTransactions = [];
|
|
80
|
+
async update(latestBlockNumberHex) {
|
|
81
|
+
const releaseLock = await __classPrivateFieldGet(this, _IncomingTransactionHelper_mutex, "f").acquire();
|
|
82
|
+
log('Checking for incoming transactions');
|
|
71
83
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const latestBlockNumber = parseInt(latestBlockNumberHex || (await __classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").getLatestBlock()), 16);
|
|
88
|
+
const additionalLastFetchedKeys = __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").getLastBlockVariations?.() ?? [];
|
|
89
|
+
const fromBlock = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getFromBlock).call(this, latestBlockNumber);
|
|
90
|
+
const account = __classPrivateFieldGet(this, _IncomingTransactionHelper_getCurrentAccount, "f").call(this);
|
|
91
|
+
const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_getChainId, "f").call(this);
|
|
92
|
+
let remoteTransactions = [];
|
|
93
|
+
try {
|
|
94
|
+
remoteTransactions =
|
|
95
|
+
await __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").fetchTransactions({
|
|
96
|
+
address: account.address,
|
|
97
|
+
currentChainId,
|
|
98
|
+
fromBlock,
|
|
99
|
+
limit: __classPrivateFieldGet(this, _IncomingTransactionHelper_transactionLimit, "f"),
|
|
100
|
+
});
|
|
101
|
+
// TODO: Replace `any` with type
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
log('Error while fetching remote transactions', error);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_updateTransactions, "f")) {
|
|
109
|
+
const address = account.address.toLowerCase();
|
|
110
|
+
remoteTransactions = remoteTransactions.filter((tx) => tx.txParams.to?.toLowerCase() === address);
|
|
111
|
+
}
|
|
112
|
+
const localTransactions = !__classPrivateFieldGet(this, _IncomingTransactionHelper_updateTransactions, "f")
|
|
113
|
+
? []
|
|
114
|
+
: __classPrivateFieldGet(this, _IncomingTransactionHelper_getLocalTransactions, "f").call(this);
|
|
115
|
+
const newTransactions = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getNewTransactions).call(this, remoteTransactions, localTransactions);
|
|
116
|
+
const updatedTransactions = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getUpdatedTransactions).call(this, remoteTransactions, localTransactions);
|
|
117
|
+
if (newTransactions.length > 0 || updatedTransactions.length > 0) {
|
|
118
|
+
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, newTransactions);
|
|
119
|
+
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, updatedTransactions);
|
|
120
|
+
log('Found incoming transactions', {
|
|
121
|
+
new: newTransactions,
|
|
122
|
+
updated: updatedTransactions,
|
|
79
123
|
});
|
|
124
|
+
this.hub.emit('transactions', {
|
|
125
|
+
added: newTransactions,
|
|
126
|
+
updated: updatedTransactions,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_updateLastFetchedBlockNumber).call(this, remoteTransactions, additionalLastFetchedKeys);
|
|
80
130
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (remoteTransactions.length > 0) {
|
|
86
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, remoteTransactions);
|
|
87
|
-
log('Found incoming transactions', { remoteTransactions });
|
|
88
|
-
this.hub.emit('incoming-transactions', remoteTransactions);
|
|
89
|
-
}
|
|
90
|
-
for (const chainId of chainIds) {
|
|
91
|
-
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_updateLastFetchedTimestamp).call(this, chainId, endTimestamp);
|
|
131
|
+
finally {
|
|
132
|
+
releaseLock();
|
|
92
133
|
}
|
|
93
134
|
}
|
|
94
135
|
}
|
|
95
|
-
_IncomingTransactionHelper_getCurrentAccount = new WeakMap(),
|
|
96
|
-
|
|
97
|
-
|
|
136
|
+
_IncomingTransactionHelper_blockTracker = new WeakMap(), _IncomingTransactionHelper_getCurrentAccount = new WeakMap(), _IncomingTransactionHelper_getLastFetchedBlockNumbers = new WeakMap(), _IncomingTransactionHelper_getLocalTransactions = new WeakMap(), _IncomingTransactionHelper_getChainId = 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) {
|
|
137
|
+
transactions.sort((a, b) => (a.time < b.time ? -1 : 1));
|
|
138
|
+
}, _IncomingTransactionHelper_getNewTransactions = function _IncomingTransactionHelper_getNewTransactions(remoteTxs, localTxs) {
|
|
139
|
+
return remoteTxs.filter((tx) => !localTxs.some(({ hash }) => hash === tx.hash));
|
|
140
|
+
}, _IncomingTransactionHelper_getUpdatedTransactions = function _IncomingTransactionHelper_getUpdatedTransactions(remoteTxs, localTxs) {
|
|
141
|
+
return remoteTxs.filter((remoteTx) => localTxs.some((localTx) => remoteTx.hash === localTx.hash &&
|
|
142
|
+
__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_isTransactionOutdated).call(this, remoteTx, localTx)));
|
|
143
|
+
}, _IncomingTransactionHelper_isTransactionOutdated = function _IncomingTransactionHelper_isTransactionOutdated(remoteTx, localTx) {
|
|
144
|
+
return UPDATE_CHECKS.some((getValue) => getValue(remoteTx) !== getValue(localTx));
|
|
145
|
+
}, _IncomingTransactionHelper_getLastFetchedBlockNumberDec = function _IncomingTransactionHelper_getLastFetchedBlockNumberDec() {
|
|
146
|
+
const additionalLastFetchedKeys = __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").getLastBlockVariations?.() ?? [];
|
|
147
|
+
const lastFetchedKey = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getBlockNumberKey).call(this, additionalLastFetchedKeys);
|
|
148
|
+
const lastFetchedBlockNumbers = __classPrivateFieldGet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, "f").call(this);
|
|
149
|
+
return lastFetchedBlockNumbers[lastFetchedKey];
|
|
150
|
+
}, _IncomingTransactionHelper_getFromBlock = function _IncomingTransactionHelper_getFromBlock(latestBlockNumber) {
|
|
151
|
+
const lastFetchedBlockNumber = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getLastFetchedBlockNumberDec).call(this);
|
|
152
|
+
if (lastFetchedBlockNumber) {
|
|
153
|
+
return lastFetchedBlockNumber + 1;
|
|
98
154
|
}
|
|
99
|
-
|
|
100
|
-
|
|
155
|
+
return __classPrivateFieldGet(this, _IncomingTransactionHelper_queryEntireHistory, "f")
|
|
156
|
+
? undefined
|
|
157
|
+
: latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;
|
|
158
|
+
}, _IncomingTransactionHelper_updateLastFetchedBlockNumber = function _IncomingTransactionHelper_updateLastFetchedBlockNumber(remoteTxs, additionalKeys) {
|
|
159
|
+
let lastFetchedBlockNumber = -1;
|
|
160
|
+
for (const tx of remoteTxs) {
|
|
161
|
+
const currentBlockNumberValue = tx.blockNumber
|
|
162
|
+
? parseInt(tx.blockNumber, 10)
|
|
163
|
+
: -1;
|
|
164
|
+
lastFetchedBlockNumber = Math.max(lastFetchedBlockNumber, currentBlockNumberValue);
|
|
101
165
|
}
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
__classPrivateFieldSet(this, _IncomingTransactionHelper_timeoutId, setTimeout(() => __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_onInterval).call(this), INTERVAL), "f");
|
|
166
|
+
if (lastFetchedBlockNumber === -1) {
|
|
167
|
+
return;
|
|
105
168
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
const lastFetchedTimestamps = __classPrivateFieldGet(this, _IncomingTransactionHelper_getLastFetchedTimestamps, "f").call(this);
|
|
119
|
-
return lastFetchedTimestamps[lastFetchedKey];
|
|
120
|
-
}, _IncomingTransactionHelper_updateLastFetchedTimestamp = function _IncomingTransactionHelper_updateLastFetchedTimestamp(chainId, newTimestamp) {
|
|
121
|
-
const lastFetchedKey = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getTimestampKey).call(this, chainId);
|
|
122
|
-
log('Updating last fetched timestamp', {
|
|
123
|
-
key: lastFetchedKey,
|
|
124
|
-
timestamp: newTimestamp,
|
|
125
|
-
});
|
|
126
|
-
this.hub.emit('updated-last-fetched-timestamp', {
|
|
127
|
-
key: lastFetchedKey,
|
|
128
|
-
timestamp: newTimestamp,
|
|
169
|
+
const lastFetchedKey = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getBlockNumberKey).call(this, additionalKeys);
|
|
170
|
+
const lastFetchedBlockNumbers = __classPrivateFieldGet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, "f").call(this);
|
|
171
|
+
const previousValue = lastFetchedBlockNumbers[lastFetchedKey];
|
|
172
|
+
if (previousValue >= lastFetchedBlockNumber) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
this.hub.emit('updatedLastFetchedBlockNumbers', {
|
|
176
|
+
lastFetchedBlockNumbers: {
|
|
177
|
+
...lastFetchedBlockNumbers,
|
|
178
|
+
[lastFetchedKey]: lastFetchedBlockNumber,
|
|
179
|
+
},
|
|
180
|
+
blockNumber: lastFetchedBlockNumber,
|
|
129
181
|
});
|
|
130
|
-
},
|
|
182
|
+
}, _IncomingTransactionHelper_getBlockNumberKey = function _IncomingTransactionHelper_getBlockNumberKey(additionalKeys) {
|
|
183
|
+
const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_getChainId, "f").call(this);
|
|
131
184
|
const currentAccount = __classPrivateFieldGet(this, _IncomingTransactionHelper_getCurrentAccount, "f").call(this)?.address.toLowerCase();
|
|
132
|
-
return [
|
|
185
|
+
return [currentChainId, currentAccount, ...additionalKeys].join('#');
|
|
133
186
|
}, _IncomingTransactionHelper_canStart = function _IncomingTransactionHelper_canStart() {
|
|
134
187
|
const isEnabled = __classPrivateFieldGet(this, _IncomingTransactionHelper_isEnabled, "f").call(this);
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
return isEnabled && isAnyChainSupported;
|
|
139
|
-
}, _IncomingTransactionHelper_getTimestampSeconds = function _IncomingTransactionHelper_getTimestampSeconds(timestampMilliseconds) {
|
|
140
|
-
return Math.ceil(timestampMilliseconds / 1000);
|
|
188
|
+
const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_getChainId, "f").call(this);
|
|
189
|
+
const isSupportedNetwork = __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").isSupportedNetwork(currentChainId);
|
|
190
|
+
return isEnabled && isSupportedNetwork;
|
|
141
191
|
};
|
|
142
192
|
//# sourceMappingURL=IncomingTransactionHelper.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IncomingTransactionHelper.mjs","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,OAAO,YAAY,eAAe;AAElC,OAAO,EAAE,0BAA0B,IAAI,GAAG,EAAE,sBAAkB;AAc9D,MAAM,4BAA4B,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS;AACvE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,aAAa;AAEzC,MAAM,OAAO,yBAAyB;IAqBpC,YAAY,EACV,iBAAiB,EACjB,wBAAwB,EACxB,WAAW,EACX,SAAS,EACT,uBAAuB,EACvB,gBAAgB,GAYjB;;QApCD,+DAEE;QAEF,sEAAwD;QAExD,yDAA0B;QAE1B,uDAA0B;QAE1B,uDAAoB;QAEpB,qEAAkD;QAElD,uDAAqB;QAErB,8DAA2B;QAqBzB,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,EAAE,CAAC;QAE9B,uBAAA,IAAI,gDAAsB,iBAAiB,MAAA,CAAC;QAC5C,uBAAA,IAAI,uDAA6B,wBAAwB,MAAA,CAAC;QAC1D,uBAAA,IAAI,0CAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,wCAAc,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAA,CAAC;QAC5C,uBAAA,IAAI,wCAAc,KAAK,MAAA,CAAC;QACxB,uBAAA,IAAI,sDAA4B,uBAAuB,MAAA,CAAC;QACxD,uBAAA,IAAI,+CAAqB,gBAAgB,MAAA,CAAC;IAC5C,CAAC;IAED,KAAK;QACH,IAAI,uBAAA,IAAI,4CAAW,EAAE;YACnB,OAAO;SACR;QAED,IAAI,CAAC,uBAAA,IAAI,iFAAU,MAAd,IAAI,CAAY,EAAE;YACrB,OAAO;SACR;QAED,kEAAkE;QAClE,uBAAA,IAAI,wCAAc,UAAU,CAAC,GAAG,EAAE,CAAC,uBAAA,IAAI,mFAAY,MAAhB,IAAI,CAAc,EAAE,QAAQ,CAAC,MAAA,CAAC;QACjE,uBAAA,IAAI,wCAAc,IAAI,MAAA,CAAC;QAEvB,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACzB,CAAC;IAED,IAAI;QACF,IAAI,uBAAA,IAAI,4CAAW,EAAE;YACnB,YAAY,CAAC,uBAAA,IAAI,4CAAqB,CAAC,CAAC;SACzC;QAED,IAAI,CAAC,uBAAA,IAAI,4CAAW,EAAE;YACpB,OAAO;SACR;QAED,uBAAA,IAAI,wCAAc,KAAK,MAAA,CAAC;QAExB,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACzB,CAAC;IAeD,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,KAA+B,EAAE;QACxD,GAAG,CAAC,oCAAoC,EAAE;YACxC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC,uBAAA,IAAI,iFAAU,MAAd,IAAI,CAAY,EAAE;YACrB,OAAO;SACR;QAED,MAAM,OAAO,GAAG,uBAAA,IAAI,oDAAmB,MAAvB,IAAI,CAAqB,CAAC;QAC1C,MAAM,QAAQ,GAAG,uBAAA,IAAI,8CAAa,MAAjB,IAAI,CAAe,CAAC;QACrC,MAAM,uBAAuB,GAAG,uBAAA,IAAI,mGAA4B,MAAhC,IAAI,EAA6B,QAAQ,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,uBAAA,IAAI,4FAAqB,MAAzB,IAAI,EAAsB,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAE3D,IAAI,kBAAkB,GAAsB,EAAE,CAAC;QAE/C,IAAI;YACF,kBAAkB;gBAChB,MAAM,uBAAA,IAAI,0DAAyB,CAAC,iBAAiB,CAAC;oBACpD,OAAO,EAAE,OAAO,CAAC,OAAc;oBAC/B,QAAQ;oBACR,YAAY;oBACZ,KAAK,EAAE,uBAAA,IAAI,mDAAkB;oBAC7B,uBAAuB;iBACxB,CAAC,CAAC;SACN;QAAC,OAAO,KAAc,EAAE;YACvB,GAAG,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;YACvD,OAAO;SACR;QAED,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;YACjC,uBAAA,IAAI,+FAAwB,MAA5B,IAAI,EAAyB,kBAAkB,CAAC,CAAC;YAEjD,GAAG,CAAC,6BAA6B,EAAE,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAE3D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;SAC5D;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,uBAAA,IAAI,mGAA4B,MAAhC,IAAI,EAA6B,OAAO,EAAE,YAAY,CAAC,CAAC;SACzD;IACH,CAAC;CA4DF;4jBAlHC,KAAK;IACH,IAAI;QACF,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;KACzC;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;KACpE;IAED,IAAI,uBAAA,IAAI,4CAAW,EAAE;QACnB,kEAAkE;QAClE,uBAAA,IAAI,wCAAc,UAAU,CAAC,GAAG,EAAE,CAAC,uBAAA,IAAI,mFAAY,MAAhB,IAAI,CAAc,EAAE,QAAQ,CAAC,MAAA,CAAC;KAClE;AACH,CAAC,iHA6CuB,YAA+B;IACrD,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,yHAE2B,QAAe;IACzC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;QACtC,MAAM,oBAAoB,GAAG,uBAAA,IAAI,gGAAyB,MAA7B,IAAI,EAA0B,OAAO,CAAC,CAAC;QAEpE,MAAM,cAAc,GAAG,oBAAoB;YACzC,CAAC,CAAC,oBAAoB,GAAG,CAAC;YAC1B,CAAC,CAAC,uBAAA,IAAI,4FAAqB,MAAzB,IAAI,EAAsB,IAAI,CAAC,GAAG,EAAE,GAAG,4BAA4B,CAAC,CAAC;QAEzE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/C,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC,mHAEwB,OAAY;IACnC,MAAM,cAAc,GAAG,uBAAA,IAAI,wFAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,CAAC;IACtD,MAAM,qBAAqB,GAAG,uBAAA,IAAI,2DAA0B,MAA9B,IAAI,CAA4B,CAAC;IAC/D,OAAO,qBAAqB,CAAC,cAAc,CAAC,CAAC;AAC/C,CAAC,yHAE2B,OAAY,EAAE,YAAoB;IAC5D,MAAM,cAAc,GAAG,uBAAA,IAAI,wFAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,CAAC;IAEtD,GAAG,CAAC,iCAAiC,EAAE;QACrC,GAAG,EAAE,cAAc;QACnB,SAAS,EAAE,YAAY;KACxB,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gCAAgC,EAAE;QAC9C,GAAG,EAAE,cAAc;QACnB,SAAS,EAAE,YAAY;KACxB,CAAC,CAAC;AACL,CAAC,mGAEgB,OAAY;IAC3B,MAAM,cAAc,GAAG,uBAAA,IAAI,oDAAmB,MAAvB,IAAI,CAAqB,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;IACxE,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7C,CAAC;IAGC,MAAM,SAAS,GAAG,uBAAA,IAAI,4CAAW,MAAf,IAAI,CAAa,CAAC;IACpC,MAAM,QAAQ,GAAG,uBAAA,IAAI,8CAAa,MAAjB,IAAI,CAAe,CAAC;IAErC,MAAM,iBAAiB,GACrB,uBAAA,IAAI,0DAAyB,CAAC,kBAAkB,EAAE,CAAC;IAErD,MAAM,mBAAmB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACpD,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,CACpC,CAAC;IAEF,OAAO,SAAS,IAAI,mBAAmB,CAAC;AAC1C,CAAC,2GAEoB,qBAA6B;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import type { AccountsController } from '@metamask/accounts-controller';\nimport type { Hex } from '@metamask/utils';\nimport EventEmitter from 'events';\n\nimport { incomingTransactionsLogger as log } from '../logger';\nimport type { RemoteTransactionSource, TransactionMeta } from '../types';\n\n/**\n * Configuration options for the IncomingTransactionHelper\n *\n * @property includeTokenTransfers - Whether or not to include ERC20 token transfers.\n * @property isEnabled - Whether or not incoming transaction retrieval is enabled.\n */\nexport type IncomingTransactionOptions = {\n includeTokenTransfers?: boolean;\n isEnabled?: () => boolean;\n};\n\nconst FIRST_QUERY_HISTORY_DURATION = 1000 * 60 * 60 * 24 * 2; // 2 Days\nconst INTERVAL = 1000 * 30; // 30 Seconds\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n\n #getLastFetchedTimestamps: () => Record<string, number>;\n\n #getChainIds: () => Hex[];\n\n #isEnabled: () => boolean;\n\n #isRunning: boolean;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n #timeoutId?: unknown;\n\n #transactionLimit?: number;\n\n constructor({\n getCurrentAccount,\n getLastFetchedTimestamps,\n getChainIds,\n isEnabled,\n remoteTransactionSource,\n transactionLimit,\n }: {\n getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n getLastFetchedTimestamps: () => Record<string, number>;\n getChainIds: () => Hex[];\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n remoteTransactionSource: RemoteTransactionSource;\n transactionLimit?: number;\n updateTransactions?: boolean;\n }) {\n this.hub = new EventEmitter();\n\n this.#getCurrentAccount = getCurrentAccount;\n this.#getLastFetchedTimestamps = getLastFetchedTimestamps;\n this.#getChainIds = getChainIds;\n this.#isEnabled = isEnabled ?? (() => true);\n this.#isRunning = false;\n this.#remoteTransactionSource = remoteTransactionSource;\n this.#transactionLimit = transactionLimit;\n }\n\n start() {\n if (this.#isRunning) {\n return;\n }\n\n if (!this.#canStart()) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeoutId = setTimeout(() => this.#onInterval(), INTERVAL);\n this.#isRunning = true;\n\n log('Started polling');\n }\n\n stop() {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId as number);\n }\n\n if (!this.#isRunning) {\n return;\n }\n\n this.#isRunning = false;\n\n log('Stopped polling');\n }\n\n async #onInterval() {\n try {\n await this.update({ isInterval: true });\n } catch (error) {\n console.error('Error while checking incoming transactions', error);\n }\n\n if (this.#isRunning) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeoutId = setTimeout(() => this.#onInterval(), INTERVAL);\n }\n }\n\n async update({ isInterval }: { isInterval?: boolean } = {}): Promise<void> {\n log('Checking for incoming transactions', {\n isInterval: Boolean(isInterval),\n });\n\n if (!this.#canStart()) {\n return;\n }\n\n const account = this.#getCurrentAccount();\n const chainIds = this.#getChainIds();\n const startTimestampByChainId = this.#getStartTimestampByChainId(chainIds);\n const endTimestamp = this.#getTimestampSeconds(Date.now());\n\n let remoteTransactions: TransactionMeta[] = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address: account.address as Hex,\n chainIds,\n endTimestamp,\n limit: this.#transactionLimit,\n startTimestampByChainId,\n });\n } catch (error: unknown) {\n log('Error while fetching remote transactions', error);\n return;\n }\n\n if (remoteTransactions.length > 0) {\n this.#sortTransactionsByTime(remoteTransactions);\n\n log('Found incoming transactions', { remoteTransactions });\n\n this.hub.emit('incoming-transactions', remoteTransactions);\n }\n\n for (const chainId of chainIds) {\n this.#updateLastFetchedTimestamp(chainId, endTimestamp);\n }\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #getStartTimestampByChainId(chainIds: Hex[]): Record<Hex, number> {\n return chainIds.reduce((acc, chainId) => {\n const lastFetchedTimestamp = this.#getLastFetchedTimestamp(chainId);\n\n const startTimestamp = lastFetchedTimestamp\n ? lastFetchedTimestamp + 1\n : this.#getTimestampSeconds(Date.now() - FIRST_QUERY_HISTORY_DURATION);\n\n return { ...acc, [chainId]: startTimestamp };\n }, {});\n }\n\n #getLastFetchedTimestamp(chainId: Hex): number {\n const lastFetchedKey = this.#getTimestampKey(chainId);\n const lastFetchedTimestamps = this.#getLastFetchedTimestamps();\n return lastFetchedTimestamps[lastFetchedKey];\n }\n\n #updateLastFetchedTimestamp(chainId: Hex, newTimestamp: number) {\n const lastFetchedKey = this.#getTimestampKey(chainId);\n\n log('Updating last fetched timestamp', {\n key: lastFetchedKey,\n timestamp: newTimestamp,\n });\n\n this.hub.emit('updated-last-fetched-timestamp', {\n key: lastFetchedKey,\n timestamp: newTimestamp,\n });\n }\n\n #getTimestampKey(chainId: Hex): string {\n const currentAccount = this.#getCurrentAccount()?.address.toLowerCase();\n return [chainId, currentAccount].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const chainIds = this.#getChainIds();\n\n const supportedChainIds =\n this.#remoteTransactionSource.getSupportedChains();\n\n const isAnyChainSupported = chainIds.some((chainId) =>\n supportedChainIds.includes(chainId),\n );\n\n return isEnabled && isAnyChainSupported;\n }\n\n #getTimestampSeconds(timestampMilliseconds: number): number {\n return Math.ceil(timestampMilliseconds / 1000);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IncomingTransactionHelper.mjs","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountsController } from '@metamask/accounts-controller';\nimport type { BlockTracker } 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\n// TODO: Replace `any` with type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst UPDATE_CHECKS: ((txMeta: TransactionMeta) => any)[] = [\n (txMeta) => txMeta.status,\n (txMeta) => txMeta.txParams.gasUsed,\n];\n\n/**\n * Configuration options for the IncomingTransactionHelper\n *\n * @property includeTokenTransfers - Whether or not to include ERC20 token transfers.\n * @property isEnabled - Whether or not incoming transaction retrieval is enabled.\n * @property queryEntireHistory - Whether to initially query the entire transaction history or only recent blocks.\n * @property updateTransactions - Whether to update local transactions using remote transaction data.\n */\nexport type IncomingTransactionOptions = {\n includeTokenTransfers?: boolean;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n updateTransactions?: boolean;\n};\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n\n #getLastFetchedBlockNumbers: () => Record<string, number>;\n\n #getLocalTransactions: () => TransactionMeta[];\n\n #getChainId: () => Hex;\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 getChainId,\n isEnabled,\n queryEntireHistory,\n remoteTransactionSource,\n transactionLimit,\n updateTransactions,\n }: {\n blockTracker: BlockTracker;\n getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n getLastFetchedBlockNumbers: () => Record<string, number>;\n getLocalTransactions?: () => TransactionMeta[];\n getChainId: () => Hex;\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.#getChainId = getChainId;\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 // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTracker.addListener('latest', this.#onLatestBlock);\n this.#isRunning = true;\n }\n\n stop() {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\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(latestBlockNumber);\n const account = this.#getCurrentAccount();\n const currentChainId = this.#getChainId();\n\n let remoteTransactions = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address: account.address,\n currentChainId,\n fromBlock,\n limit: this.#transactionLimit,\n });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n log('Error while fetching remote transactions', error);\n return;\n }\n if (!this.#updateTransactions) {\n const address = account.address.toLowerCase();\n remoteTransactions = remoteTransactions.filter(\n (tx) => tx.txParams.to?.toLowerCase() === address,\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 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 #getLastFetchedBlockNumberDec(): number {\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n const lastFetchedKey = this.#getBlockNumberKey(additionalLastFetchedKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n return lastFetchedBlockNumbers[lastFetchedKey];\n }\n\n #getFromBlock(latestBlockNumber: number): number | undefined {\n const lastFetchedBlockNumber = this.#getLastFetchedBlockNumberDec();\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 this.hub.emit('updatedLastFetchedBlockNumbers', {\n lastFetchedBlockNumbers: {\n ...lastFetchedBlockNumbers,\n [lastFetchedKey]: lastFetchedBlockNumber,\n },\n blockNumber: lastFetchedBlockNumber,\n });\n }\n\n #getBlockNumberKey(additionalKeys: string[]): string {\n const currentChainId = this.#getChainId();\n const currentAccount = this.#getCurrentAccount()?.address.toLowerCase();\n\n return [currentChainId, currentAccount, ...additionalKeys].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const currentChainId = this.#getChainId();\n\n const isSupportedNetwork =\n this.#remoteTransactionSource.isSupportedNetwork(currentChainId);\n\n return isEnabled && isSupportedNetwork;\n }\n}\n"]}
|
|
@@ -13,32 +13,38 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _MultichainTrackingHelper_instances, _MultichainTrackingHelper_isMultichainEnabled, _MultichainTrackingHelper_provider, _MultichainTrackingHelper_nonceTracker, _MultichainTrackingHelper_findNetworkClientIdByChainId, _MultichainTrackingHelper_getNetworkClientById, _MultichainTrackingHelper_getNetworkClientRegistry, _MultichainTrackingHelper_removePendingTransactionTrackerListeners, _MultichainTrackingHelper_createNonceTracker, _MultichainTrackingHelper_createPendingTransactionTracker, _MultichainTrackingHelper_nonceMutexesByChainId, _MultichainTrackingHelper_trackingMap, _MultichainTrackingHelper_refreshTrackingMap, _MultichainTrackingHelper_stopTrackingByNetworkClientId, _MultichainTrackingHelper_startTrackingByNetworkClientId, _MultichainTrackingHelper_getNetworkClient;
|
|
16
|
+
var _MultichainTrackingHelper_instances, _MultichainTrackingHelper_isMultichainEnabled, _MultichainTrackingHelper_provider, _MultichainTrackingHelper_nonceTracker, _MultichainTrackingHelper_incomingTransactionOptions, _MultichainTrackingHelper_findNetworkClientIdByChainId, _MultichainTrackingHelper_getNetworkClientById, _MultichainTrackingHelper_getNetworkClientRegistry, _MultichainTrackingHelper_removeIncomingTransactionHelperListeners, _MultichainTrackingHelper_removePendingTransactionTrackerListeners, _MultichainTrackingHelper_createNonceTracker, _MultichainTrackingHelper_createIncomingTransactionHelper, _MultichainTrackingHelper_createPendingTransactionTracker, _MultichainTrackingHelper_nonceMutexesByChainId, _MultichainTrackingHelper_trackingMap, _MultichainTrackingHelper_etherscanRemoteTransactionSourcesMap, _MultichainTrackingHelper_refreshTrackingMap, _MultichainTrackingHelper_stopTrackingByNetworkClientId, _MultichainTrackingHelper_startTrackingByNetworkClientId, _MultichainTrackingHelper_refreshEtherscanRemoteTransactionSources, _MultichainTrackingHelper_getNetworkClient;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.MultichainTrackingHelper = void 0;
|
|
19
19
|
const eth_query_1 = __importDefault(require("@metamask/eth-query"));
|
|
20
20
|
const async_mutex_1 = require("async-mutex");
|
|
21
21
|
const logger_1 = require("../logger.cjs");
|
|
22
|
+
const EtherscanRemoteTransactionSource_1 = require("./EtherscanRemoteTransactionSource.cjs");
|
|
22
23
|
class MultichainTrackingHelper {
|
|
23
|
-
constructor({ isMultichainEnabled, provider, nonceTracker, findNetworkClientIdByChainId, getNetworkClientById, getNetworkClientRegistry, removePendingTransactionTrackerListeners, createNonceTracker, createPendingTransactionTracker, onNetworkStateChange, }) {
|
|
24
|
+
constructor({ isMultichainEnabled, provider, nonceTracker, incomingTransactionOptions, findNetworkClientIdByChainId, getNetworkClientById, getNetworkClientRegistry, removeIncomingTransactionHelperListeners, removePendingTransactionTrackerListeners, createNonceTracker, createIncomingTransactionHelper, createPendingTransactionTracker, onNetworkStateChange, }) {
|
|
24
25
|
_MultichainTrackingHelper_instances.add(this);
|
|
25
26
|
_MultichainTrackingHelper_isMultichainEnabled.set(this, void 0);
|
|
26
27
|
_MultichainTrackingHelper_provider.set(this, void 0);
|
|
27
28
|
_MultichainTrackingHelper_nonceTracker.set(this, void 0);
|
|
29
|
+
_MultichainTrackingHelper_incomingTransactionOptions.set(this, void 0);
|
|
28
30
|
_MultichainTrackingHelper_findNetworkClientIdByChainId.set(this, void 0);
|
|
29
31
|
_MultichainTrackingHelper_getNetworkClientById.set(this, void 0);
|
|
30
32
|
_MultichainTrackingHelper_getNetworkClientRegistry.set(this, void 0);
|
|
33
|
+
_MultichainTrackingHelper_removeIncomingTransactionHelperListeners.set(this, void 0);
|
|
31
34
|
_MultichainTrackingHelper_removePendingTransactionTrackerListeners.set(this, void 0);
|
|
32
35
|
_MultichainTrackingHelper_createNonceTracker.set(this, void 0);
|
|
36
|
+
_MultichainTrackingHelper_createIncomingTransactionHelper.set(this, void 0);
|
|
33
37
|
_MultichainTrackingHelper_createPendingTransactionTracker.set(this, void 0);
|
|
34
38
|
_MultichainTrackingHelper_nonceMutexesByChainId.set(this, new Map());
|
|
35
39
|
_MultichainTrackingHelper_trackingMap.set(this, new Map());
|
|
40
|
+
_MultichainTrackingHelper_etherscanRemoteTransactionSourcesMap.set(this, new Map());
|
|
36
41
|
this.checkForPendingTransactionAndStartPolling = () => {
|
|
37
42
|
for (const [, trackers] of __classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f")) {
|
|
38
43
|
trackers.pendingTransactionTracker.startIfPendingTransactions();
|
|
39
44
|
}
|
|
40
45
|
};
|
|
41
46
|
_MultichainTrackingHelper_refreshTrackingMap.set(this, (networkClients) => {
|
|
47
|
+
__classPrivateFieldGet(this, _MultichainTrackingHelper_refreshEtherscanRemoteTransactionSources, "f").call(this, networkClients);
|
|
42
48
|
const networkClientIds = Object.keys(networkClients);
|
|
43
49
|
const existingNetworkClientIds = Array.from(__classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").keys());
|
|
44
50
|
// Remove tracking for NetworkClientIds that no longer exist
|
|
@@ -52,14 +58,29 @@ class MultichainTrackingHelper {
|
|
|
52
58
|
__classPrivateFieldGet(this, _MultichainTrackingHelper_instances, "m", _MultichainTrackingHelper_startTrackingByNetworkClientId).call(this, id);
|
|
53
59
|
});
|
|
54
60
|
});
|
|
61
|
+
_MultichainTrackingHelper_refreshEtherscanRemoteTransactionSources.set(this, (networkClients) => {
|
|
62
|
+
// this will be prettier when we have consolidated network clients with a single chainId:
|
|
63
|
+
// check if there are still other network clients using the same chainId
|
|
64
|
+
// if not remove the etherscanRemoteTransaction source from the map
|
|
65
|
+
const chainIdsInRegistry = new Set();
|
|
66
|
+
Object.values(networkClients).forEach((networkClient) => chainIdsInRegistry.add(networkClient.configuration.chainId));
|
|
67
|
+
const existingChainIds = Array.from(__classPrivateFieldGet(this, _MultichainTrackingHelper_etherscanRemoteTransactionSourcesMap, "f").keys());
|
|
68
|
+
const chainIdsToRemove = existingChainIds.filter((chainId) => !chainIdsInRegistry.has(chainId));
|
|
69
|
+
chainIdsToRemove.forEach((chainId) => {
|
|
70
|
+
__classPrivateFieldGet(this, _MultichainTrackingHelper_etherscanRemoteTransactionSourcesMap, "f").delete(chainId);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
55
73
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_isMultichainEnabled, isMultichainEnabled, "f");
|
|
56
74
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_provider, provider, "f");
|
|
57
75
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_nonceTracker, nonceTracker, "f");
|
|
76
|
+
__classPrivateFieldSet(this, _MultichainTrackingHelper_incomingTransactionOptions, incomingTransactionOptions, "f");
|
|
58
77
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_findNetworkClientIdByChainId, findNetworkClientIdByChainId, "f");
|
|
59
78
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_getNetworkClientById, getNetworkClientById, "f");
|
|
60
79
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_getNetworkClientRegistry, getNetworkClientRegistry, "f");
|
|
80
|
+
__classPrivateFieldSet(this, _MultichainTrackingHelper_removeIncomingTransactionHelperListeners, removeIncomingTransactionHelperListeners, "f");
|
|
61
81
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_removePendingTransactionTrackerListeners, removePendingTransactionTrackerListeners, "f");
|
|
62
82
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_createNonceTracker, createNonceTracker, "f");
|
|
83
|
+
__classPrivateFieldSet(this, _MultichainTrackingHelper_createIncomingTransactionHelper, createIncomingTransactionHelper, "f");
|
|
63
84
|
__classPrivateFieldSet(this, _MultichainTrackingHelper_createPendingTransactionTracker, createPendingTransactionTracker, "f");
|
|
64
85
|
onNetworkStateChange((_, patches) => {
|
|
65
86
|
if (__classPrivateFieldGet(this, _MultichainTrackingHelper_isMultichainEnabled, "f")) {
|
|
@@ -163,6 +184,33 @@ class MultichainTrackingHelper {
|
|
|
163
184
|
throw err;
|
|
164
185
|
}
|
|
165
186
|
}
|
|
187
|
+
startIncomingTransactionPolling(networkClientIds = []) {
|
|
188
|
+
networkClientIds.forEach((networkClientId) => {
|
|
189
|
+
__classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").get(networkClientId)?.incomingTransactionHelper.start();
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
stopIncomingTransactionPolling(networkClientIds = []) {
|
|
193
|
+
networkClientIds.forEach((networkClientId) => {
|
|
194
|
+
__classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").get(networkClientId)?.incomingTransactionHelper.stop();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
stopAllIncomingTransactionPolling() {
|
|
198
|
+
for (const [, trackers] of __classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f")) {
|
|
199
|
+
trackers.incomingTransactionHelper.stop();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async updateIncomingTransactions(networkClientIds = []) {
|
|
203
|
+
const promises = await Promise.allSettled(networkClientIds.map(async (networkClientId) => {
|
|
204
|
+
return await __classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f")
|
|
205
|
+
.get(networkClientId)
|
|
206
|
+
?.incomingTransactionHelper.update();
|
|
207
|
+
}));
|
|
208
|
+
promises
|
|
209
|
+
.filter((result) => result.status === 'rejected')
|
|
210
|
+
.forEach((result) => {
|
|
211
|
+
(0, logger_1.incomingTransactionsLogger)('failed to update incoming transactions', result.reason);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
166
214
|
stopAllTracking() {
|
|
167
215
|
for (const [networkClientId] of __classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f")) {
|
|
168
216
|
__classPrivateFieldGet(this, _MultichainTrackingHelper_instances, "m", _MultichainTrackingHelper_stopTrackingByNetworkClientId).call(this, networkClientId);
|
|
@@ -170,11 +218,13 @@ class MultichainTrackingHelper {
|
|
|
170
218
|
}
|
|
171
219
|
}
|
|
172
220
|
exports.MultichainTrackingHelper = MultichainTrackingHelper;
|
|
173
|
-
_MultichainTrackingHelper_isMultichainEnabled = new WeakMap(), _MultichainTrackingHelper_provider = new WeakMap(), _MultichainTrackingHelper_nonceTracker = new WeakMap(), _MultichainTrackingHelper_findNetworkClientIdByChainId = new WeakMap(), _MultichainTrackingHelper_getNetworkClientById = new WeakMap(), _MultichainTrackingHelper_getNetworkClientRegistry = new WeakMap(), _MultichainTrackingHelper_removePendingTransactionTrackerListeners = new WeakMap(), _MultichainTrackingHelper_createNonceTracker = new WeakMap(), _MultichainTrackingHelper_createPendingTransactionTracker = new WeakMap(), _MultichainTrackingHelper_nonceMutexesByChainId = new WeakMap(), _MultichainTrackingHelper_trackingMap = new WeakMap(), _MultichainTrackingHelper_refreshTrackingMap = new WeakMap(), _MultichainTrackingHelper_instances = new WeakSet(), _MultichainTrackingHelper_stopTrackingByNetworkClientId = function _MultichainTrackingHelper_stopTrackingByNetworkClientId(networkClientId) {
|
|
221
|
+
_MultichainTrackingHelper_isMultichainEnabled = new WeakMap(), _MultichainTrackingHelper_provider = new WeakMap(), _MultichainTrackingHelper_nonceTracker = new WeakMap(), _MultichainTrackingHelper_incomingTransactionOptions = new WeakMap(), _MultichainTrackingHelper_findNetworkClientIdByChainId = new WeakMap(), _MultichainTrackingHelper_getNetworkClientById = new WeakMap(), _MultichainTrackingHelper_getNetworkClientRegistry = new WeakMap(), _MultichainTrackingHelper_removeIncomingTransactionHelperListeners = new WeakMap(), _MultichainTrackingHelper_removePendingTransactionTrackerListeners = new WeakMap(), _MultichainTrackingHelper_createNonceTracker = new WeakMap(), _MultichainTrackingHelper_createIncomingTransactionHelper = new WeakMap(), _MultichainTrackingHelper_createPendingTransactionTracker = new WeakMap(), _MultichainTrackingHelper_nonceMutexesByChainId = new WeakMap(), _MultichainTrackingHelper_trackingMap = new WeakMap(), _MultichainTrackingHelper_etherscanRemoteTransactionSourcesMap = new WeakMap(), _MultichainTrackingHelper_refreshTrackingMap = new WeakMap(), _MultichainTrackingHelper_refreshEtherscanRemoteTransactionSources = new WeakMap(), _MultichainTrackingHelper_instances = new WeakSet(), _MultichainTrackingHelper_stopTrackingByNetworkClientId = function _MultichainTrackingHelper_stopTrackingByNetworkClientId(networkClientId) {
|
|
174
222
|
const trackers = __classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").get(networkClientId);
|
|
175
223
|
if (trackers) {
|
|
176
224
|
trackers.pendingTransactionTracker.stop();
|
|
177
225
|
__classPrivateFieldGet(this, _MultichainTrackingHelper_removePendingTransactionTrackerListeners, "f").call(this, trackers.pendingTransactionTracker);
|
|
226
|
+
trackers.incomingTransactionHelper.stop();
|
|
227
|
+
__classPrivateFieldGet(this, _MultichainTrackingHelper_removeIncomingTransactionHelperListeners, "f").call(this, trackers.incomingTransactionHelper);
|
|
178
228
|
__classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").delete(networkClientId);
|
|
179
229
|
}
|
|
180
230
|
}, _MultichainTrackingHelper_startTrackingByNetworkClientId = function _MultichainTrackingHelper_startTrackingByNetworkClientId(networkClientId) {
|
|
@@ -183,11 +233,23 @@ _MultichainTrackingHelper_isMultichainEnabled = new WeakMap(), _MultichainTracki
|
|
|
183
233
|
return;
|
|
184
234
|
}
|
|
185
235
|
const { provider, blockTracker, configuration: { chainId }, } = __classPrivateFieldGet(this, _MultichainTrackingHelper_getNetworkClientById, "f").call(this, networkClientId);
|
|
236
|
+
let etherscanRemoteTransactionSource = __classPrivateFieldGet(this, _MultichainTrackingHelper_etherscanRemoteTransactionSourcesMap, "f").get(chainId);
|
|
237
|
+
if (!etherscanRemoteTransactionSource) {
|
|
238
|
+
etherscanRemoteTransactionSource = new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource({
|
|
239
|
+
includeTokenTransfers: __classPrivateFieldGet(this, _MultichainTrackingHelper_incomingTransactionOptions, "f").includeTokenTransfers,
|
|
240
|
+
});
|
|
241
|
+
__classPrivateFieldGet(this, _MultichainTrackingHelper_etherscanRemoteTransactionSourcesMap, "f").set(chainId, etherscanRemoteTransactionSource);
|
|
242
|
+
}
|
|
186
243
|
const nonceTracker = __classPrivateFieldGet(this, _MultichainTrackingHelper_createNonceTracker, "f").call(this, {
|
|
187
244
|
provider,
|
|
188
245
|
blockTracker,
|
|
189
246
|
chainId,
|
|
190
247
|
});
|
|
248
|
+
const incomingTransactionHelper = __classPrivateFieldGet(this, _MultichainTrackingHelper_createIncomingTransactionHelper, "f").call(this, {
|
|
249
|
+
blockTracker,
|
|
250
|
+
etherscanRemoteTransactionSource,
|
|
251
|
+
chainId,
|
|
252
|
+
});
|
|
191
253
|
const pendingTransactionTracker = __classPrivateFieldGet(this, _MultichainTrackingHelper_createPendingTransactionTracker, "f").call(this, {
|
|
192
254
|
provider,
|
|
193
255
|
blockTracker,
|
|
@@ -195,6 +257,7 @@ _MultichainTrackingHelper_isMultichainEnabled = new WeakMap(), _MultichainTracki
|
|
|
195
257
|
});
|
|
196
258
|
__classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").set(networkClientId, {
|
|
197
259
|
nonceTracker,
|
|
260
|
+
incomingTransactionHelper,
|
|
198
261
|
pendingTransactionTracker,
|
|
199
262
|
});
|
|
200
263
|
}, _MultichainTrackingHelper_getNetworkClient = function _MultichainTrackingHelper_getNetworkClient({ networkClientId, chainId, } = {}) {
|