@metamask-previews/transaction-controller 38.3.0-preview-7692db0d → 38.3.0-preview-de5d2fda

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.
Files changed (83) hide show
  1. package/dist/TransactionController.cjs +44 -47
  2. package/dist/TransactionController.cjs.map +1 -1
  3. package/dist/TransactionController.d.cts +8 -8
  4. package/dist/TransactionController.d.cts.map +1 -1
  5. package/dist/TransactionController.d.mts +8 -8
  6. package/dist/TransactionController.d.mts.map +1 -1
  7. package/dist/TransactionController.mjs +44 -47
  8. package/dist/TransactionController.mjs.map +1 -1
  9. package/dist/api/accounts-api.cjs +61 -0
  10. package/dist/api/accounts-api.cjs.map +1 -0
  11. package/dist/api/accounts-api.d.cts +56 -0
  12. package/dist/api/accounts-api.d.cts.map +1 -0
  13. package/dist/api/accounts-api.d.mts +56 -0
  14. package/dist/api/accounts-api.d.mts.map +1 -0
  15. package/dist/api/accounts-api.mjs +56 -0
  16. package/dist/api/accounts-api.mjs.map +1 -0
  17. package/dist/helpers/AccountsApiRemoteTransactionSource.cjs +135 -0
  18. package/dist/helpers/AccountsApiRemoteTransactionSource.cjs.map +1 -0
  19. package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts +11 -0
  20. package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts.map +1 -0
  21. package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts +11 -0
  22. package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts.map +1 -0
  23. package/dist/helpers/AccountsApiRemoteTransactionSource.mjs +135 -0
  24. package/dist/helpers/AccountsApiRemoteTransactionSource.mjs.map +1 -0
  25. package/dist/helpers/IncomingTransactionHelper.cjs +96 -134
  26. package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
  27. package/dist/helpers/IncomingTransactionHelper.d.cts +7 -12
  28. package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
  29. package/dist/helpers/IncomingTransactionHelper.d.mts +7 -12
  30. package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
  31. package/dist/helpers/IncomingTransactionHelper.mjs +96 -134
  32. package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
  33. package/dist/helpers/MultichainTrackingHelper.cjs +3 -66
  34. package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -1
  35. package/dist/helpers/MultichainTrackingHelper.d.cts +1 -14
  36. package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -1
  37. package/dist/helpers/MultichainTrackingHelper.d.mts +1 -14
  38. package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -1
  39. package/dist/helpers/MultichainTrackingHelper.mjs +3 -66
  40. package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
  41. package/dist/helpers/PendingTransactionTracker.cjs +7 -9
  42. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
  43. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
  44. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
  45. package/dist/helpers/PendingTransactionTracker.mjs +7 -9
  46. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +1 -2
  49. package/dist/index.d.cts.map +1 -1
  50. package/dist/index.d.mts +1 -2
  51. package/dist/index.d.mts.map +1 -1
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/types.cjs.map +1 -1
  54. package/dist/types.d.cts +7 -8
  55. package/dist/types.d.cts.map +1 -1
  56. package/dist/types.d.mts +7 -8
  57. package/dist/types.d.mts.map +1 -1
  58. package/dist/types.mjs.map +1 -1
  59. package/package.json +1 -1
  60. package/dist/helpers/EtherscanRemoteTransactionSource.cjs +0 -157
  61. package/dist/helpers/EtherscanRemoteTransactionSource.cjs.map +0 -1
  62. package/dist/helpers/EtherscanRemoteTransactionSource.d.cts +0 -16
  63. package/dist/helpers/EtherscanRemoteTransactionSource.d.cts.map +0 -1
  64. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts +0 -16
  65. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts.map +0 -1
  66. package/dist/helpers/EtherscanRemoteTransactionSource.mjs +0 -157
  67. package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +0 -1
  68. package/dist/helpers/TransactionPoller.cjs +0 -133
  69. package/dist/helpers/TransactionPoller.cjs.map +0 -1
  70. package/dist/helpers/TransactionPoller.d.cts +0 -31
  71. package/dist/helpers/TransactionPoller.d.cts.map +0 -1
  72. package/dist/helpers/TransactionPoller.d.mts +0 -31
  73. package/dist/helpers/TransactionPoller.d.mts.map +0 -1
  74. package/dist/helpers/TransactionPoller.mjs +0 -130
  75. package/dist/helpers/TransactionPoller.mjs.map +0 -1
  76. package/dist/utils/etherscan.cjs +0 -115
  77. package/dist/utils/etherscan.cjs.map +0 -1
  78. package/dist/utils/etherscan.d.cts +0 -74
  79. package/dist/utils/etherscan.d.cts.map +0 -1
  80. package/dist/utils/etherscan.d.mts +0 -74
  81. package/dist/utils/etherscan.d.mts.map +0 -1
  82. package/dist/utils/etherscan.mjs +0 -109
  83. package/dist/utils/etherscan.mjs.map +0 -1
@@ -1,31 +0,0 @@
1
- import type { BlockTracker } from "@metamask/network-controller";
2
- import type { TransactionMeta } from "../types.mjs";
3
- export declare const ACCELERATED_COUNT_MAX = 5;
4
- export declare const ACCELERATED_INTERVAL: number;
5
- /**
6
- * Helper class to orchestrate when to poll pending transactions.
7
- * Initially starts polling via a timeout chain every 2 seconds up to 5 times.
8
- * Following that, it will poll on every new block via the block tracker.
9
- */
10
- export declare class TransactionPoller {
11
- #private;
12
- constructor(blockTracker: BlockTracker);
13
- /**
14
- * Start the poller with a listener that will be called on every interval.
15
- * @param listener - The listener to call on every interval.
16
- */
17
- start(listener: (latestBlockNumber: string) => Promise<void>): void;
18
- /**
19
- * Stop the poller.
20
- * Remove all timeouts and block tracker listeners.
21
- */
22
- stop(): void;
23
- /**
24
- * Notify the poller of the pending transactions being monitored.
25
- * This will reset to the accelerated polling and reset the count
26
- * when new transactions are added or removed.
27
- * @param pendingTransactions - The pending transactions to poll.
28
- */
29
- setPendingTransactions(pendingTransactions: TransactionMeta[]): void;
30
- }
31
- //# sourceMappingURL=TransactionPoller.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TransactionPoller.d.mts","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AAKjE,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAEhD,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAI7C;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAehB,YAAY,EAAE,YAAY;IAItC;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAa5D;;;OAGG;IACH,IAAI;IAgBJ;;;;;OAKG;IACH,sBAAsB,CAAC,mBAAmB,EAAE,eAAe,EAAE;CAwF9D"}
@@ -1,130 +0,0 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- 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");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _TransactionPoller_instances, _TransactionPoller_acceleratedCount, _TransactionPoller_blockTracker, _TransactionPoller_blockTrackerListener, _TransactionPoller_listener, _TransactionPoller_pendingTransactions, _TransactionPoller_running, _TransactionPoller_timeout, _TransactionPoller_queue, _TransactionPoller_interval, _TransactionPoller_stopTimeout, _TransactionPoller_stopBlockTracker;
13
- import { createModuleLogger } from "@metamask/utils";
14
- import $lodash from "lodash";
15
- const { isEqual } = $lodash;
16
- import { projectLogger } from "../logger.mjs";
17
- export const ACCELERATED_COUNT_MAX = 5;
18
- export const ACCELERATED_INTERVAL = 1000 * 2; // 2 Seconds
19
- const log = createModuleLogger(projectLogger, 'transaction-poller');
20
- /**
21
- * Helper class to orchestrate when to poll pending transactions.
22
- * Initially starts polling via a timeout chain every 2 seconds up to 5 times.
23
- * Following that, it will poll on every new block via the block tracker.
24
- */
25
- export class TransactionPoller {
26
- constructor(blockTracker) {
27
- _TransactionPoller_instances.add(this);
28
- _TransactionPoller_acceleratedCount.set(this, 0);
29
- _TransactionPoller_blockTracker.set(this, void 0);
30
- _TransactionPoller_blockTrackerListener.set(this, void 0);
31
- _TransactionPoller_listener.set(this, void 0);
32
- _TransactionPoller_pendingTransactions.set(this, void 0);
33
- _TransactionPoller_running.set(this, false);
34
- _TransactionPoller_timeout.set(this, void 0);
35
- __classPrivateFieldSet(this, _TransactionPoller_blockTracker, blockTracker, "f");
36
- }
37
- /**
38
- * Start the poller with a listener that will be called on every interval.
39
- * @param listener - The listener to call on every interval.
40
- */
41
- start(listener) {
42
- if (__classPrivateFieldGet(this, _TransactionPoller_running, "f")) {
43
- return;
44
- }
45
- __classPrivateFieldSet(this, _TransactionPoller_listener, listener, "f");
46
- __classPrivateFieldSet(this, _TransactionPoller_running, true, "f");
47
- __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_queue).call(this);
48
- log('Started');
49
- }
50
- /**
51
- * Stop the poller.
52
- * Remove all timeouts and block tracker listeners.
53
- */
54
- stop() {
55
- if (!__classPrivateFieldGet(this, _TransactionPoller_running, "f")) {
56
- return;
57
- }
58
- __classPrivateFieldSet(this, _TransactionPoller_running, false, "f");
59
- __classPrivateFieldSet(this, _TransactionPoller_listener, undefined, "f");
60
- __classPrivateFieldSet(this, _TransactionPoller_acceleratedCount, 0, "f");
61
- __classPrivateFieldSet(this, _TransactionPoller_pendingTransactions, undefined, "f");
62
- __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_stopTimeout).call(this);
63
- __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_stopBlockTracker).call(this);
64
- log('Stopped');
65
- }
66
- /**
67
- * Notify the poller of the pending transactions being monitored.
68
- * This will reset to the accelerated polling and reset the count
69
- * when new transactions are added or removed.
70
- * @param pendingTransactions - The pending transactions to poll.
71
- */
72
- setPendingTransactions(pendingTransactions) {
73
- const currentPendingTransactionIds = (__classPrivateFieldGet(this, _TransactionPoller_pendingTransactions, "f") ?? []).map((tx) => tx.id);
74
- __classPrivateFieldSet(this, _TransactionPoller_pendingTransactions, pendingTransactions, "f");
75
- const newPendingTransactionIds = pendingTransactions.map((tx) => tx.id);
76
- const hasUpdatedIds = !isEqual(currentPendingTransactionIds, newPendingTransactionIds);
77
- if (!__classPrivateFieldGet(this, _TransactionPoller_running, "f") || !hasUpdatedIds) {
78
- return;
79
- }
80
- log('Detected new pending transactions', newPendingTransactionIds);
81
- __classPrivateFieldSet(this, _TransactionPoller_acceleratedCount, 0, "f");
82
- if (__classPrivateFieldGet(this, _TransactionPoller_blockTrackerListener, "f")) {
83
- __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_stopBlockTracker).call(this);
84
- __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_queue).call(this);
85
- }
86
- }
87
- }
88
- _TransactionPoller_acceleratedCount = new WeakMap(), _TransactionPoller_blockTracker = new WeakMap(), _TransactionPoller_blockTrackerListener = new WeakMap(), _TransactionPoller_listener = new WeakMap(), _TransactionPoller_pendingTransactions = new WeakMap(), _TransactionPoller_running = new WeakMap(), _TransactionPoller_timeout = new WeakMap(), _TransactionPoller_instances = new WeakSet(), _TransactionPoller_queue = function _TransactionPoller_queue() {
89
- if (!__classPrivateFieldGet(this, _TransactionPoller_running, "f")) {
90
- return;
91
- }
92
- if (__classPrivateFieldGet(this, _TransactionPoller_acceleratedCount, "f") >= ACCELERATED_COUNT_MAX) {
93
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
94
- __classPrivateFieldSet(this, _TransactionPoller_blockTrackerListener, (latestBlockNumber) => __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_interval).call(this, false, latestBlockNumber), "f");
95
- __classPrivateFieldGet(this, _TransactionPoller_blockTracker, "f").on('latest', __classPrivateFieldGet(this, _TransactionPoller_blockTrackerListener, "f"));
96
- log('Added block tracker listener');
97
- return;
98
- }
99
- __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_stopTimeout).call(this);
100
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
101
- __classPrivateFieldSet(this, _TransactionPoller_timeout, setTimeout(async () => {
102
- await __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_interval).call(this, true);
103
- __classPrivateFieldGet(this, _TransactionPoller_instances, "m", _TransactionPoller_queue).call(this);
104
- }, ACCELERATED_INTERVAL), "f");
105
- }, _TransactionPoller_interval = async function _TransactionPoller_interval(isAccelerated, latestBlockNumber) {
106
- if (isAccelerated) {
107
- log('Accelerated interval', __classPrivateFieldGet(this, _TransactionPoller_acceleratedCount, "f") + 1);
108
- }
109
- else {
110
- log('Block tracker interval', latestBlockNumber);
111
- }
112
- const latestBlockNumberFinal = latestBlockNumber ?? (await __classPrivateFieldGet(this, _TransactionPoller_blockTracker, "f").getLatestBlock());
113
- await __classPrivateFieldGet(this, _TransactionPoller_listener, "f")?.call(this, latestBlockNumberFinal);
114
- if (isAccelerated && __classPrivateFieldGet(this, _TransactionPoller_running, "f")) {
115
- __classPrivateFieldSet(this, _TransactionPoller_acceleratedCount, __classPrivateFieldGet(this, _TransactionPoller_acceleratedCount, "f") + 1, "f");
116
- }
117
- }, _TransactionPoller_stopTimeout = function _TransactionPoller_stopTimeout() {
118
- if (!__classPrivateFieldGet(this, _TransactionPoller_timeout, "f")) {
119
- return;
120
- }
121
- clearTimeout(__classPrivateFieldGet(this, _TransactionPoller_timeout, "f"));
122
- __classPrivateFieldSet(this, _TransactionPoller_timeout, undefined, "f");
123
- }, _TransactionPoller_stopBlockTracker = function _TransactionPoller_stopBlockTracker() {
124
- if (!__classPrivateFieldGet(this, _TransactionPoller_blockTrackerListener, "f")) {
125
- return;
126
- }
127
- __classPrivateFieldGet(this, _TransactionPoller_blockTracker, "f").removeListener('latest', __classPrivateFieldGet(this, _TransactionPoller_blockTrackerListener, "f"));
128
- __classPrivateFieldSet(this, _TransactionPoller_blockTrackerListener, undefined, "f");
129
- };
130
- //# sourceMappingURL=TransactionPoller.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TransactionPoller.mjs","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BlockTracker } from '@metamask/network-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionMeta } from '../types';\n\nexport const ACCELERATED_COUNT_MAX = 5;\nexport const ACCELERATED_INTERVAL = 1000 * 2; // 2 Seconds\n\nconst log = createModuleLogger(projectLogger, 'transaction-poller');\n\n/**\n * Helper class to orchestrate when to poll pending transactions.\n * Initially starts polling via a timeout chain every 2 seconds up to 5 times.\n * Following that, it will poll on every new block via the block tracker.\n */\nexport class TransactionPoller {\n #acceleratedCount = 0;\n\n #blockTracker: BlockTracker;\n\n #blockTrackerListener?: (latestBlockNumber: string) => void;\n\n #listener?: (latestBlockNumber: string) => Promise<void>;\n\n #pendingTransactions?: TransactionMeta[];\n\n #running = false;\n\n #timeout?: NodeJS.Timeout;\n\n constructor(blockTracker: BlockTracker) {\n this.#blockTracker = blockTracker;\n }\n\n /**\n * Start the poller with a listener that will be called on every interval.\n * @param listener - The listener to call on every interval.\n */\n start(listener: (latestBlockNumber: string) => Promise<void>) {\n if (this.#running) {\n return;\n }\n\n this.#listener = listener;\n this.#running = true;\n\n this.#queue();\n\n log('Started');\n }\n\n /**\n * Stop the poller.\n * Remove all timeouts and block tracker listeners.\n */\n stop() {\n if (!this.#running) {\n return;\n }\n\n this.#running = false;\n this.#listener = undefined;\n this.#acceleratedCount = 0;\n this.#pendingTransactions = undefined;\n\n this.#stopTimeout();\n this.#stopBlockTracker();\n\n log('Stopped');\n }\n\n /**\n * Notify the poller of the pending transactions being monitored.\n * This will reset to the accelerated polling and reset the count\n * when new transactions are added or removed.\n * @param pendingTransactions - The pending transactions to poll.\n */\n setPendingTransactions(pendingTransactions: TransactionMeta[]) {\n const currentPendingTransactionIds = (this.#pendingTransactions ?? []).map(\n (tx) => tx.id,\n );\n\n this.#pendingTransactions = pendingTransactions;\n\n const newPendingTransactionIds = pendingTransactions.map((tx) => tx.id);\n\n const hasUpdatedIds = !isEqual(\n currentPendingTransactionIds,\n newPendingTransactionIds,\n );\n\n if (!this.#running || !hasUpdatedIds) {\n return;\n }\n\n log('Detected new pending transactions', newPendingTransactionIds);\n\n this.#acceleratedCount = 0;\n\n if (this.#blockTrackerListener) {\n this.#stopBlockTracker();\n this.#queue();\n }\n }\n\n #queue() {\n if (!this.#running) {\n return;\n }\n\n if (this.#acceleratedCount >= ACCELERATED_COUNT_MAX) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTrackerListener = (latestBlockNumber) =>\n this.#interval(false, latestBlockNumber);\n\n this.#blockTracker.on('latest', this.#blockTrackerListener);\n\n log('Added block tracker listener');\n\n return;\n }\n\n this.#stopTimeout();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(async () => {\n await this.#interval(true);\n this.#queue();\n }, ACCELERATED_INTERVAL);\n }\n\n async #interval(isAccelerated: boolean, latestBlockNumber?: string) {\n if (isAccelerated) {\n log('Accelerated interval', this.#acceleratedCount + 1);\n } else {\n log('Block tracker interval', latestBlockNumber);\n }\n\n const latestBlockNumberFinal =\n latestBlockNumber ?? (await this.#blockTracker.getLatestBlock());\n\n await this.#listener?.(latestBlockNumberFinal);\n\n if (isAccelerated && this.#running) {\n this.#acceleratedCount += 1;\n }\n }\n\n #stopTimeout() {\n if (!this.#timeout) {\n return;\n }\n\n clearTimeout(this.#timeout);\n this.#timeout = undefined;\n }\n\n #stopBlockTracker() {\n if (!this.#blockTrackerListener) {\n return;\n }\n\n this.#blockTracker.removeListener('latest', this.#blockTrackerListener);\n this.#blockTrackerListener = undefined;\n }\n}\n"]}
@@ -1,115 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getEtherscanApiHost = exports.fetchEtherscanTokenTransactions = exports.fetchEtherscanTransactions = void 0;
4
- const controller_utils_1 = require("@metamask/controller-utils");
5
- const constants_1 = require("../constants.cjs");
6
- const logger_1 = require("../logger.cjs");
7
- /**
8
- * Retrieves transaction data from Etherscan.
9
- *
10
- * @param request - Configuration required to fetch transactions.
11
- * @param request.address - Address to retrieve transactions for.
12
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
13
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
14
- * @param request.fromBlock - Block number to start fetching transactions from.
15
- * @param request.limit - Number of transactions to retrieve.
16
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
17
- */
18
- async function fetchEtherscanTransactions({ address, apiKey, chainId, fromBlock, limit, }) {
19
- return await fetchTransactions('txlist', {
20
- address,
21
- apiKey,
22
- chainId,
23
- fromBlock,
24
- limit,
25
- });
26
- }
27
- exports.fetchEtherscanTransactions = fetchEtherscanTransactions;
28
- /**
29
- * Retrieves token transaction data from Etherscan.
30
- *
31
- * @param request - Configuration required to fetch token transactions.
32
- * @param request.address - Address to retrieve token transactions for.
33
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
34
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
35
- * @param request.fromBlock - Block number to start fetching token transactions from.
36
- * @param request.limit - Number of token transactions to retrieve.
37
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
38
- */
39
- async function fetchEtherscanTokenTransactions({ address, apiKey, chainId, fromBlock, limit, }) {
40
- return await fetchTransactions('tokentx', {
41
- address,
42
- apiKey,
43
- chainId,
44
- fromBlock,
45
- limit,
46
- });
47
- }
48
- exports.fetchEtherscanTokenTransactions = fetchEtherscanTokenTransactions;
49
- /**
50
- * Retrieves transaction data from Etherscan from a specific endpoint.
51
- *
52
- * @param action - The Etherscan endpoint to use.
53
- * @param options - Options bag.
54
- * @param options.address - Address to retrieve transactions for.
55
- * @param options.apiKey - Etherscan API key to prevent rate limiting.
56
- * @param options.chainId - Current chain ID used to determine subdomain and domain.
57
- * @param options.fromBlock - Block number to start fetching transactions from.
58
- * @param options.limit - Number of transactions to retrieve.
59
- * @returns An object containing the request status and an array of transaction data.
60
- */
61
- async function fetchTransactions(action, { address, apiKey, chainId, fromBlock, limit, }) {
62
- const urlParams = {
63
- module: 'account',
64
- address,
65
- startBlock: fromBlock?.toString(),
66
- offset: limit?.toString(),
67
- sort: 'desc',
68
- };
69
- const etherscanTxUrl = getEtherscanApiUrl(chainId, {
70
- ...urlParams,
71
- action,
72
- apikey: apiKey,
73
- });
74
- (0, logger_1.incomingTransactionsLogger)('Sending Etherscan request', etherscanTxUrl);
75
- const response = (await (0, controller_utils_1.handleFetch)(etherscanTxUrl));
76
- return response;
77
- }
78
- /**
79
- * Return a URL that can be used to fetch data from Etherscan.
80
- *
81
- * @param chainId - Current chain ID used to determine subdomain and domain.
82
- * @param urlParams - The parameters used to construct the URL.
83
- * @returns URL to access Etherscan data.
84
- */
85
- function getEtherscanApiUrl(chainId, urlParams) {
86
- const apiUrl = getEtherscanApiHost(chainId);
87
- let url = `${apiUrl}/api?`;
88
- for (const paramKey of Object.keys(urlParams)) {
89
- const value = urlParams[paramKey];
90
- if (!value) {
91
- continue;
92
- }
93
- url += `${paramKey}=${value}&`;
94
- }
95
- url += 'tag=latest&page=1';
96
- return url;
97
- }
98
- /**
99
- * Return the host url used to fetch data from Etherscan.
100
- *
101
- * @param chainId - Current chain ID used to determine subdomain and domain.
102
- * @returns host URL to access Etherscan data.
103
- */
104
- function getEtherscanApiHost(chainId) {
105
- // @ts-expect-error We account for `chainId` not being a property below
106
- const networkInfo = constants_1.ETHERSCAN_SUPPORTED_NETWORKS[chainId];
107
- if (!networkInfo) {
108
- throw new Error(`Etherscan does not support chain with ID: ${chainId}`);
109
- }
110
- // TODO: Either fix this lint violation or explain why it's necessary to ignore.
111
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
112
- return `https://${networkInfo.subdomain}.${networkInfo.domain}`;
113
- }
114
- exports.getEtherscanApiHost = getEtherscanApiHost;
115
- //# sourceMappingURL=etherscan.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"etherscan.cjs","sourceRoot":"","sources":["../../src/utils/etherscan.ts"],"names":[],"mappings":";;;AAAA,iEAAyD;AAGzD,gDAA4D;AAC5D,0CAA8D;AAsE9D;;;;;;;;;;GAUG;AACI,KAAK,UAAU,0BAA0B,CAAC,EAC/C,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACuB;IAG5B,OAAO,MAAM,iBAAiB,CAAC,QAAQ,EAAE;QACvC,OAAO;QACP,MAAM;QACN,OAAO;QACP,SAAS;QACT,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAhBD,gEAgBC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,+BAA+B,CAAC,EACpD,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACuB;IAG5B,OAAO,MAAM,iBAAiB,CAAC,SAAS,EAAE;QACxC,OAAO;QACP,MAAM;QACN,OAAO;QACP,SAAS;QACT,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAhBD,0EAgBC;AAED;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,iBAAiB,CAG9B,MAAc,EACd,EACE,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GAON;IAED,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,SAAS;QACjB,OAAO;QACP,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE;QACjC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;QACzB,IAAI,EAAE,MAAM;KACb,CAAC;IAEF,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,EAAE;QACjD,GAAG,SAAS;QACZ,MAAM;QACN,MAAM,EAAE,MAAM;KACf,CAAC,CAAC;IAEH,IAAA,mCAAG,EAAC,2BAA2B,EAAE,cAAc,CAAC,CAAC;IAEjD,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAA,8BAAW,EACjC,cAAc,CACf,CAA+C,CAAC;IAEjD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CACzB,OAAY,EACZ,SAA6C;IAE7C,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,GAAG,GAAG,GAAG,MAAM,OAAO,CAAC;IAE3B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;QAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,EAAE;YACV,SAAS;SACV;QAED,GAAG,IAAI,GAAG,QAAQ,IAAI,KAAK,GAAG,CAAC;KAChC;IAED,GAAG,IAAI,mBAAmB,CAAC;IAE3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,OAAY;IAC9C,uEAAuE;IACvE,MAAM,WAAW,GAAG,wCAA4B,CAAC,OAAO,CAAC,CAAC;IAE1D,IAAI,CAAC,WAAW,EAAE;QAChB,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,EAAE,CAAC,CAAC;KACzE;IAED,gFAAgF;IAChF,4EAA4E;IAC5E,OAAO,WAAW,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;AAClE,CAAC;AAXD,kDAWC","sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from '../constants';\nimport { incomingTransactionsLogger as log } from '../logger';\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionMetaBase {\n blockNumber: string;\n blockHash: string;\n confirmations: string;\n contractAddress: string;\n cumulativeGasUsed: string;\n from: string;\n gas: string;\n gasPrice: string;\n gasUsed: string;\n hash: string;\n nonce: string;\n timeStamp: string;\n to: string;\n transactionIndex: string;\n value: string;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionMeta extends EtherscanTransactionMetaBase {\n functionName: string;\n input: string;\n isError: string;\n methodId: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n txreceipt_status: string;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTokenTransactionMeta\n extends EtherscanTransactionMetaBase {\n tokenDecimal: string;\n tokenName: string;\n tokenSymbol: string;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionResponse<\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n T extends EtherscanTransactionMetaBase,\n> {\n status: '0' | '1';\n message?: string;\n result: string | T[];\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionRequest {\n address: string;\n apiKey?: string;\n chainId: Hex;\n fromBlock?: number;\n limit?: number;\n}\n\n/**\n * Retrieves transaction data from Etherscan.\n *\n * @param request - Configuration required to fetch transactions.\n * @param request.address - Address to retrieve transactions for.\n * @param request.apiKey - Etherscan API key to prevent rate limiting.\n * @param request.chainId - Current chain ID used to determine subdomain and domain.\n * @param request.fromBlock - Block number to start fetching transactions from.\n * @param request.limit - Number of transactions to retrieve.\n * @returns An Etherscan response object containing the request status and an array of token transaction data.\n */\nexport async function fetchEtherscanTransactions({\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTransactionMeta>\n> {\n return await fetchTransactions('txlist', {\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n });\n}\n\n/**\n * Retrieves token transaction data from Etherscan.\n *\n * @param request - Configuration required to fetch token transactions.\n * @param request.address - Address to retrieve token transactions for.\n * @param request.apiKey - Etherscan API key to prevent rate limiting.\n * @param request.chainId - Current chain ID used to determine subdomain and domain.\n * @param request.fromBlock - Block number to start fetching token transactions from.\n * @param request.limit - Number of token transactions to retrieve.\n * @returns An Etherscan response object containing the request status and an array of token transaction data.\n */\nexport async function fetchEtherscanTokenTransactions({\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTokenTransactionMeta>\n> {\n return await fetchTransactions('tokentx', {\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n });\n}\n\n/**\n * Retrieves transaction data from Etherscan from a specific endpoint.\n *\n * @param action - The Etherscan endpoint to use.\n * @param options - Options bag.\n * @param options.address - Address to retrieve transactions for.\n * @param options.apiKey - Etherscan API key to prevent rate limiting.\n * @param options.chainId - Current chain ID used to determine subdomain and domain.\n * @param options.fromBlock - Block number to start fetching transactions from.\n * @param options.limit - Number of transactions to retrieve.\n * @returns An object containing the request status and an array of transaction data.\n */\nasync function fetchTransactions<\n ResponseData extends EtherscanTransactionMetaBase,\n>(\n action: string,\n {\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n }: {\n address: string;\n apiKey?: string;\n chainId: Hex;\n fromBlock?: number;\n limit?: number;\n },\n): Promise<EtherscanTransactionResponse<ResponseData>> {\n const urlParams = {\n module: 'account',\n address,\n startBlock: fromBlock?.toString(),\n offset: limit?.toString(),\n sort: 'desc',\n };\n\n const etherscanTxUrl = getEtherscanApiUrl(chainId, {\n ...urlParams,\n action,\n apikey: apiKey,\n });\n\n log('Sending Etherscan request', etherscanTxUrl);\n\n const response = (await handleFetch(\n etherscanTxUrl,\n )) as EtherscanTransactionResponse<ResponseData>;\n\n return response;\n}\n\n/**\n * Return a URL that can be used to fetch data from Etherscan.\n *\n * @param chainId - Current chain ID used to determine subdomain and domain.\n * @param urlParams - The parameters used to construct the URL.\n * @returns URL to access Etherscan data.\n */\nfunction getEtherscanApiUrl(\n chainId: Hex,\n urlParams: Record<string, string | undefined>,\n): string {\n const apiUrl = getEtherscanApiHost(chainId);\n let url = `${apiUrl}/api?`;\n\n for (const paramKey of Object.keys(urlParams)) {\n const value = urlParams[paramKey];\n\n if (!value) {\n continue;\n }\n\n url += `${paramKey}=${value}&`;\n }\n\n url += 'tag=latest&page=1';\n\n return url;\n}\n\n/**\n * Return the host url used to fetch data from Etherscan.\n *\n * @param chainId - Current chain ID used to determine subdomain and domain.\n * @returns host URL to access Etherscan data.\n */\nexport function getEtherscanApiHost(chainId: Hex) {\n // @ts-expect-error We account for `chainId` not being a property below\n const networkInfo = ETHERSCAN_SUPPORTED_NETWORKS[chainId];\n\n if (!networkInfo) {\n throw new Error(`Etherscan does not support chain with ID: ${chainId}`);\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://${networkInfo.subdomain}.${networkInfo.domain}`;\n}\n"]}
@@ -1,74 +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
- apiKey?: string;
39
- chainId: Hex;
40
- fromBlock?: number;
41
- limit?: number;
42
- }
43
- /**
44
- * Retrieves transaction data from Etherscan.
45
- *
46
- * @param request - Configuration required to fetch transactions.
47
- * @param request.address - Address to retrieve transactions for.
48
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
49
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
50
- * @param request.fromBlock - Block number to start fetching transactions from.
51
- * @param request.limit - Number of transactions to retrieve.
52
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
53
- */
54
- export declare function fetchEtherscanTransactions({ address, apiKey, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTransactionMeta>>;
55
- /**
56
- * Retrieves token transaction data from Etherscan.
57
- *
58
- * @param request - Configuration required to fetch token transactions.
59
- * @param request.address - Address to retrieve token transactions for.
60
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
61
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
62
- * @param request.fromBlock - Block number to start fetching token transactions from.
63
- * @param request.limit - Number of token transactions to retrieve.
64
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
65
- */
66
- export declare function fetchEtherscanTokenTransactions({ address, apiKey, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTokenTransactionMeta>>;
67
- /**
68
- * Return the host url used to fetch data from Etherscan.
69
- *
70
- * @param chainId - Current chain ID used to determine subdomain and domain.
71
- * @returns host URL to access Etherscan data.
72
- */
73
- export declare function getEtherscanApiHost(chainId: Hex): string;
74
- //# sourceMappingURL=etherscan.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"etherscan.d.cts","sourceRoot":"","sources":["../../src/utils/etherscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAQ3C,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;AAKD,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;IAGjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAKD,MAAM,WAAW,6BACf,SAAQ,4BAA4B;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAKD,MAAM,WAAW,4BAA4B,CAG3C,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;AAKD,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAAC,EAC/C,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,wBAAwB,CAAC,CACvD,CAQA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,6BAA6B,CAAC,CAC5D,CAQA;AAoFD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,GAAG,UAW/C"}
@@ -1,74 +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
- apiKey?: string;
39
- chainId: Hex;
40
- fromBlock?: number;
41
- limit?: number;
42
- }
43
- /**
44
- * Retrieves transaction data from Etherscan.
45
- *
46
- * @param request - Configuration required to fetch transactions.
47
- * @param request.address - Address to retrieve transactions for.
48
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
49
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
50
- * @param request.fromBlock - Block number to start fetching transactions from.
51
- * @param request.limit - Number of transactions to retrieve.
52
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
53
- */
54
- export declare function fetchEtherscanTransactions({ address, apiKey, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTransactionMeta>>;
55
- /**
56
- * Retrieves token transaction data from Etherscan.
57
- *
58
- * @param request - Configuration required to fetch token transactions.
59
- * @param request.address - Address to retrieve token transactions for.
60
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
61
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
62
- * @param request.fromBlock - Block number to start fetching token transactions from.
63
- * @param request.limit - Number of token transactions to retrieve.
64
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
65
- */
66
- export declare function fetchEtherscanTokenTransactions({ address, apiKey, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTokenTransactionMeta>>;
67
- /**
68
- * Return the host url used to fetch data from Etherscan.
69
- *
70
- * @param chainId - Current chain ID used to determine subdomain and domain.
71
- * @returns host URL to access Etherscan data.
72
- */
73
- export declare function getEtherscanApiHost(chainId: Hex): string;
74
- //# sourceMappingURL=etherscan.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"etherscan.d.mts","sourceRoot":"","sources":["../../src/utils/etherscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAQ3C,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;AAKD,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;IAGjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAKD,MAAM,WAAW,6BACf,SAAQ,4BAA4B;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAKD,MAAM,WAAW,4BAA4B,CAG3C,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;AAKD,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAAC,EAC/C,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,wBAAwB,CAAC,CACvD,CAQA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,6BAA6B,CAAC,CAC5D,CAQA;AAoFD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,GAAG,UAW/C"}
@@ -1,109 +0,0 @@
1
- import { handleFetch } from "@metamask/controller-utils";
2
- import { ETHERSCAN_SUPPORTED_NETWORKS } from "../constants.mjs";
3
- import { incomingTransactionsLogger as log } from "../logger.mjs";
4
- /**
5
- * Retrieves transaction data from Etherscan.
6
- *
7
- * @param request - Configuration required to fetch transactions.
8
- * @param request.address - Address to retrieve transactions for.
9
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
10
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
11
- * @param request.fromBlock - Block number to start fetching transactions from.
12
- * @param request.limit - Number of transactions to retrieve.
13
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
14
- */
15
- export async function fetchEtherscanTransactions({ address, apiKey, chainId, fromBlock, limit, }) {
16
- return await fetchTransactions('txlist', {
17
- address,
18
- apiKey,
19
- chainId,
20
- fromBlock,
21
- limit,
22
- });
23
- }
24
- /**
25
- * Retrieves token transaction data from Etherscan.
26
- *
27
- * @param request - Configuration required to fetch token transactions.
28
- * @param request.address - Address to retrieve token transactions for.
29
- * @param request.apiKey - Etherscan API key to prevent rate limiting.
30
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
31
- * @param request.fromBlock - Block number to start fetching token transactions from.
32
- * @param request.limit - Number of token transactions to retrieve.
33
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
34
- */
35
- export async function fetchEtherscanTokenTransactions({ address, apiKey, chainId, fromBlock, limit, }) {
36
- return await fetchTransactions('tokentx', {
37
- address,
38
- apiKey,
39
- chainId,
40
- fromBlock,
41
- limit,
42
- });
43
- }
44
- /**
45
- * Retrieves transaction data from Etherscan from a specific endpoint.
46
- *
47
- * @param action - The Etherscan endpoint to use.
48
- * @param options - Options bag.
49
- * @param options.address - Address to retrieve transactions for.
50
- * @param options.apiKey - Etherscan API key to prevent rate limiting.
51
- * @param options.chainId - Current chain ID used to determine subdomain and domain.
52
- * @param options.fromBlock - Block number to start fetching transactions from.
53
- * @param options.limit - Number of transactions to retrieve.
54
- * @returns An object containing the request status and an array of transaction data.
55
- */
56
- async function fetchTransactions(action, { address, apiKey, chainId, fromBlock, limit, }) {
57
- const urlParams = {
58
- module: 'account',
59
- address,
60
- startBlock: fromBlock?.toString(),
61
- offset: limit?.toString(),
62
- sort: 'desc',
63
- };
64
- const etherscanTxUrl = getEtherscanApiUrl(chainId, {
65
- ...urlParams,
66
- action,
67
- apikey: apiKey,
68
- });
69
- log('Sending Etherscan request', etherscanTxUrl);
70
- const response = (await handleFetch(etherscanTxUrl));
71
- return response;
72
- }
73
- /**
74
- * Return a URL that can be used to fetch data from Etherscan.
75
- *
76
- * @param chainId - Current chain ID used to determine subdomain and domain.
77
- * @param urlParams - The parameters used to construct the URL.
78
- * @returns URL to access Etherscan data.
79
- */
80
- function getEtherscanApiUrl(chainId, urlParams) {
81
- const apiUrl = getEtherscanApiHost(chainId);
82
- let url = `${apiUrl}/api?`;
83
- for (const paramKey of Object.keys(urlParams)) {
84
- const value = urlParams[paramKey];
85
- if (!value) {
86
- continue;
87
- }
88
- url += `${paramKey}=${value}&`;
89
- }
90
- url += 'tag=latest&page=1';
91
- return url;
92
- }
93
- /**
94
- * Return the host url used to fetch data from Etherscan.
95
- *
96
- * @param chainId - Current chain ID used to determine subdomain and domain.
97
- * @returns host URL to access Etherscan data.
98
- */
99
- export function getEtherscanApiHost(chainId) {
100
- // @ts-expect-error We account for `chainId` not being a property below
101
- const networkInfo = ETHERSCAN_SUPPORTED_NETWORKS[chainId];
102
- if (!networkInfo) {
103
- throw new Error(`Etherscan does not support chain with ID: ${chainId}`);
104
- }
105
- // TODO: Either fix this lint violation or explain why it's necessary to ignore.
106
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
107
- return `https://${networkInfo.subdomain}.${networkInfo.domain}`;
108
- }
109
- //# sourceMappingURL=etherscan.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"etherscan.mjs","sourceRoot":"","sources":["../../src/utils/etherscan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mCAAmC;AAGzD,OAAO,EAAE,4BAA4B,EAAE,yBAAqB;AAC5D,OAAO,EAAE,0BAA0B,IAAI,GAAG,EAAE,sBAAkB;AAsE9D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,EAC/C,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACuB;IAG5B,OAAO,MAAM,iBAAiB,CAAC,QAAQ,EAAE;QACvC,OAAO;QACP,MAAM;QACN,OAAO;QACP,SAAS;QACT,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,EACpD,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GACuB;IAG5B,OAAO,MAAM,iBAAiB,CAAC,SAAS,EAAE;QACxC,OAAO;QACP,MAAM;QACN,OAAO;QACP,SAAS;QACT,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,iBAAiB,CAG9B,MAAc,EACd,EACE,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,GAON;IAED,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,SAAS;QACjB,OAAO;QACP,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE;QACjC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;QACzB,IAAI,EAAE,MAAM;KACb,CAAC;IAEF,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,EAAE;QACjD,GAAG,SAAS;QACZ,MAAM;QACN,MAAM,EAAE,MAAM;KACf,CAAC,CAAC;IAEH,GAAG,CAAC,2BAA2B,EAAE,cAAc,CAAC,CAAC;IAEjD,MAAM,QAAQ,GAAG,CAAC,MAAM,WAAW,CACjC,cAAc,CACf,CAA+C,CAAC;IAEjD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CACzB,OAAY,EACZ,SAA6C;IAE7C,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,GAAG,GAAG,GAAG,MAAM,OAAO,CAAC;IAE3B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;QAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,EAAE;YACV,SAAS;SACV;QAED,GAAG,IAAI,GAAG,QAAQ,IAAI,KAAK,GAAG,CAAC;KAChC;IAED,GAAG,IAAI,mBAAmB,CAAC;IAE3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAY;IAC9C,uEAAuE;IACvE,MAAM,WAAW,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC;IAE1D,IAAI,CAAC,WAAW,EAAE;QAChB,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,EAAE,CAAC,CAAC;KACzE;IAED,gFAAgF;IAChF,4EAA4E;IAC5E,OAAO,WAAW,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;AAClE,CAAC","sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from '../constants';\nimport { incomingTransactionsLogger as log } from '../logger';\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionMetaBase {\n blockNumber: string;\n blockHash: string;\n confirmations: string;\n contractAddress: string;\n cumulativeGasUsed: string;\n from: string;\n gas: string;\n gasPrice: string;\n gasUsed: string;\n hash: string;\n nonce: string;\n timeStamp: string;\n to: string;\n transactionIndex: string;\n value: string;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionMeta extends EtherscanTransactionMetaBase {\n functionName: string;\n input: string;\n isError: string;\n methodId: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n txreceipt_status: string;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTokenTransactionMeta\n extends EtherscanTransactionMetaBase {\n tokenDecimal: string;\n tokenName: string;\n tokenSymbol: string;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionResponse<\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n T extends EtherscanTransactionMetaBase,\n> {\n status: '0' | '1';\n message?: string;\n result: string | T[];\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionRequest {\n address: string;\n apiKey?: string;\n chainId: Hex;\n fromBlock?: number;\n limit?: number;\n}\n\n/**\n * Retrieves transaction data from Etherscan.\n *\n * @param request - Configuration required to fetch transactions.\n * @param request.address - Address to retrieve transactions for.\n * @param request.apiKey - Etherscan API key to prevent rate limiting.\n * @param request.chainId - Current chain ID used to determine subdomain and domain.\n * @param request.fromBlock - Block number to start fetching transactions from.\n * @param request.limit - Number of transactions to retrieve.\n * @returns An Etherscan response object containing the request status and an array of token transaction data.\n */\nexport async function fetchEtherscanTransactions({\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTransactionMeta>\n> {\n return await fetchTransactions('txlist', {\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n });\n}\n\n/**\n * Retrieves token transaction data from Etherscan.\n *\n * @param request - Configuration required to fetch token transactions.\n * @param request.address - Address to retrieve token transactions for.\n * @param request.apiKey - Etherscan API key to prevent rate limiting.\n * @param request.chainId - Current chain ID used to determine subdomain and domain.\n * @param request.fromBlock - Block number to start fetching token transactions from.\n * @param request.limit - Number of token transactions to retrieve.\n * @returns An Etherscan response object containing the request status and an array of token transaction data.\n */\nexport async function fetchEtherscanTokenTransactions({\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTokenTransactionMeta>\n> {\n return await fetchTransactions('tokentx', {\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n });\n}\n\n/**\n * Retrieves transaction data from Etherscan from a specific endpoint.\n *\n * @param action - The Etherscan endpoint to use.\n * @param options - Options bag.\n * @param options.address - Address to retrieve transactions for.\n * @param options.apiKey - Etherscan API key to prevent rate limiting.\n * @param options.chainId - Current chain ID used to determine subdomain and domain.\n * @param options.fromBlock - Block number to start fetching transactions from.\n * @param options.limit - Number of transactions to retrieve.\n * @returns An object containing the request status and an array of transaction data.\n */\nasync function fetchTransactions<\n ResponseData extends EtherscanTransactionMetaBase,\n>(\n action: string,\n {\n address,\n apiKey,\n chainId,\n fromBlock,\n limit,\n }: {\n address: string;\n apiKey?: string;\n chainId: Hex;\n fromBlock?: number;\n limit?: number;\n },\n): Promise<EtherscanTransactionResponse<ResponseData>> {\n const urlParams = {\n module: 'account',\n address,\n startBlock: fromBlock?.toString(),\n offset: limit?.toString(),\n sort: 'desc',\n };\n\n const etherscanTxUrl = getEtherscanApiUrl(chainId, {\n ...urlParams,\n action,\n apikey: apiKey,\n });\n\n log('Sending Etherscan request', etherscanTxUrl);\n\n const response = (await handleFetch(\n etherscanTxUrl,\n )) as EtherscanTransactionResponse<ResponseData>;\n\n return response;\n}\n\n/**\n * Return a URL that can be used to fetch data from Etherscan.\n *\n * @param chainId - Current chain ID used to determine subdomain and domain.\n * @param urlParams - The parameters used to construct the URL.\n * @returns URL to access Etherscan data.\n */\nfunction getEtherscanApiUrl(\n chainId: Hex,\n urlParams: Record<string, string | undefined>,\n): string {\n const apiUrl = getEtherscanApiHost(chainId);\n let url = `${apiUrl}/api?`;\n\n for (const paramKey of Object.keys(urlParams)) {\n const value = urlParams[paramKey];\n\n if (!value) {\n continue;\n }\n\n url += `${paramKey}=${value}&`;\n }\n\n url += 'tag=latest&page=1';\n\n return url;\n}\n\n/**\n * Return the host url used to fetch data from Etherscan.\n *\n * @param chainId - Current chain ID used to determine subdomain and domain.\n * @returns host URL to access Etherscan data.\n */\nexport function getEtherscanApiHost(chainId: Hex) {\n // @ts-expect-error We account for `chainId` not being a property below\n const networkInfo = ETHERSCAN_SUPPORTED_NETWORKS[chainId];\n\n if (!networkInfo) {\n throw new Error(`Etherscan does not support chain with ID: ${chainId}`);\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://${networkInfo.subdomain}.${networkInfo.domain}`;\n}\n"]}