@metamask-previews/transaction-controller 41.1.0-preview-9cfbf21f → 41.1.0-preview-73fa7bfb
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 +0 -23
- package/dist/TransactionController.cjs +51 -57
- package/dist/TransactionController.cjs.map +1 -1
- package/dist/TransactionController.d.cts +13 -72
- package/dist/TransactionController.d.cts.map +1 -1
- package/dist/TransactionController.d.mts +13 -72
- package/dist/TransactionController.d.mts.map +1 -1
- package/dist/TransactionController.mjs +51 -57
- package/dist/TransactionController.mjs.map +1 -1
- package/dist/api/accounts-api.cjs +3 -48
- package/dist/api/accounts-api.cjs.map +1 -1
- package/dist/api/accounts-api.d.cts +0 -49
- package/dist/api/accounts-api.d.cts.map +1 -1
- package/dist/api/accounts-api.d.mts +0 -49
- package/dist/api/accounts-api.d.mts.map +1 -1
- package/dist/api/accounts-api.mjs +2 -46
- package/dist/api/accounts-api.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 +158 -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 +158 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +1 -0
- package/dist/helpers/IncomingTransactionHelper.cjs +142 -90
- package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.cts +16 -10
- package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.mts +16 -10
- package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.mjs +143 -91
- package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.cjs +70 -23
- 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 +70 -23
- package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
- package/dist/index.cjs +2 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -2
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +14 -21
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +14 -21
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/etherscan.cjs +116 -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 +110 -0
- package/dist/utils/etherscan.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/helpers/AccountsApiRemoteTransactionSource.cjs +0 -183
- package/dist/helpers/AccountsApiRemoteTransactionSource.cjs.map +0 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts +0 -12
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts.map +0 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts +0 -12
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts.map +0 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.mjs +0 -183
- package/dist/helpers/AccountsApiRemoteTransactionSource.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
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,kBAAkB,EAAE,aAAa,EAAE,sBAAkB;AAE9D,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AAsE3D;;;;;;;;;;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,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAEvC,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 { createModuleLogger, projectLogger } from '../logger';\n\nconst log = createModuleLogger(projectLogger, 'etherscan');\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 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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/transaction-controller",
|
|
3
|
-
"version": "41.1.0-preview-
|
|
3
|
+
"version": "41.1.0-preview-73fa7bfb",
|
|
4
4
|
"description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@metamask/accounts-controller": "^20.0.1",
|
|
73
73
|
"@metamask/approval-controller": "^7.1.1",
|
|
74
74
|
"@metamask/auto-changelog": "^3.4.4",
|
|
75
|
-
"@metamask/eth-block-tracker": "^11.0.
|
|
75
|
+
"@metamask/eth-block-tracker": "^11.0.2",
|
|
76
76
|
"@metamask/eth-json-rpc-provider": "^4.1.6",
|
|
77
77
|
"@metamask/ethjs-provider-http": "^0.3.0",
|
|
78
78
|
"@metamask/gas-fee-controller": "^22.0.2",
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
-
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");
|
|
5
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
-
};
|
|
7
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
-
};
|
|
10
|
-
var _AccountsApiRemoteTransactionSource_instances, _AccountsApiRemoteTransactionSource_getTransactions, _AccountsApiRemoteTransactionSource_queryTransactions, _AccountsApiRemoteTransactionSource_filterTransactions, _AccountsApiRemoteTransactionSource_normalizeTransaction, _AccountsApiRemoteTransactionSource_getCacheKey, _AccountsApiRemoteTransactionSource_getCacheCursor, _AccountsApiRemoteTransactionSource_getTimestampSeconds;
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AccountsApiRemoteTransactionSource = exports.SUPPORTED_CHAIN_IDS = void 0;
|
|
13
|
-
const controller_utils_1 = require("@metamask/controller-utils");
|
|
14
|
-
const bn_js_1 = __importDefault(require("bn.js"));
|
|
15
|
-
const uuid_1 = require("uuid");
|
|
16
|
-
const accounts_api_1 = require("../api/accounts-api.cjs");
|
|
17
|
-
const constants_1 = require("../constants.cjs");
|
|
18
|
-
const logger_1 = require("../logger.cjs");
|
|
19
|
-
const types_1 = require("../types.cjs");
|
|
20
|
-
exports.SUPPORTED_CHAIN_IDS = [
|
|
21
|
-
constants_1.CHAIN_IDS.MAINNET,
|
|
22
|
-
constants_1.CHAIN_IDS.POLYGON,
|
|
23
|
-
constants_1.CHAIN_IDS.BSC,
|
|
24
|
-
constants_1.CHAIN_IDS.LINEA_MAINNET,
|
|
25
|
-
constants_1.CHAIN_IDS.BASE,
|
|
26
|
-
constants_1.CHAIN_IDS.OPTIMISM,
|
|
27
|
-
constants_1.CHAIN_IDS.ARBITRUM,
|
|
28
|
-
constants_1.CHAIN_IDS.SCROLL,
|
|
29
|
-
];
|
|
30
|
-
const log = (0, logger_1.createModuleLogger)(logger_1.incomingTransactionsLogger, 'accounts-api-source');
|
|
31
|
-
/**
|
|
32
|
-
* A RemoteTransactionSource that fetches incoming transactions using the Accounts API.
|
|
33
|
-
*/
|
|
34
|
-
class AccountsApiRemoteTransactionSource {
|
|
35
|
-
constructor() {
|
|
36
|
-
_AccountsApiRemoteTransactionSource_instances.add(this);
|
|
37
|
-
}
|
|
38
|
-
getSupportedChains() {
|
|
39
|
-
return exports.SUPPORTED_CHAIN_IDS;
|
|
40
|
-
}
|
|
41
|
-
async fetchTransactions(request) {
|
|
42
|
-
const { address } = request;
|
|
43
|
-
const responseTransactions = await __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTransactions).call(this, request);
|
|
44
|
-
log('Fetched transactions', responseTransactions.length, responseTransactions);
|
|
45
|
-
const normalizedTransactions = responseTransactions.map((tx) => __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_normalizeTransaction).call(this, address, tx));
|
|
46
|
-
log('Normalized transactions', normalizedTransactions);
|
|
47
|
-
const filteredTransactions = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_filterTransactions).call(this, request, normalizedTransactions);
|
|
48
|
-
log('Filtered transactions', filteredTransactions.length, filteredTransactions);
|
|
49
|
-
return filteredTransactions;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
exports.AccountsApiRemoteTransactionSource = AccountsApiRemoteTransactionSource;
|
|
53
|
-
_AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemoteTransactionSource_getTransactions = async function _AccountsApiRemoteTransactionSource_getTransactions(request) {
|
|
54
|
-
log('Getting transactions', request);
|
|
55
|
-
const { address, cache, chainIds: requestedChainIds } = request;
|
|
56
|
-
const chainIds = requestedChainIds.filter((chainId) => exports.SUPPORTED_CHAIN_IDS.includes(chainId));
|
|
57
|
-
const unsupportedChainIds = requestedChainIds.filter((chainId) => !chainIds.includes(chainId));
|
|
58
|
-
if (unsupportedChainIds.length) {
|
|
59
|
-
log('Ignoring unsupported chain IDs', unsupportedChainIds);
|
|
60
|
-
}
|
|
61
|
-
const cursor = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheCursor).call(this, cache, chainIds, address);
|
|
62
|
-
if (cursor) {
|
|
63
|
-
log('Using cached cursor', cursor);
|
|
64
|
-
}
|
|
65
|
-
return await __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_queryTransactions).call(this, request, chainIds, cursor);
|
|
66
|
-
}, _AccountsApiRemoteTransactionSource_queryTransactions = async function _AccountsApiRemoteTransactionSource_queryTransactions(request, chainIds, cursor) {
|
|
67
|
-
const { address, queryEntireHistory, updateCache } = request;
|
|
68
|
-
const transactions = [];
|
|
69
|
-
let hasNextPage = true;
|
|
70
|
-
let currentCursor = cursor;
|
|
71
|
-
let pageCount = 0;
|
|
72
|
-
const startTimestamp = queryEntireHistory || cursor
|
|
73
|
-
? undefined
|
|
74
|
-
: __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTimestampSeconds).call(this, Date.now());
|
|
75
|
-
while (hasNextPage) {
|
|
76
|
-
try {
|
|
77
|
-
const response = await (0, accounts_api_1.getAccountTransactions)({
|
|
78
|
-
address,
|
|
79
|
-
chainIds,
|
|
80
|
-
cursor: currentCursor,
|
|
81
|
-
sortDirection: 'ASC',
|
|
82
|
-
startTimestamp,
|
|
83
|
-
});
|
|
84
|
-
pageCount += 1;
|
|
85
|
-
if (response?.data) {
|
|
86
|
-
transactions.push(...response.data);
|
|
87
|
-
}
|
|
88
|
-
hasNextPage = response?.pageInfo?.hasNextPage;
|
|
89
|
-
currentCursor = response?.pageInfo?.cursor;
|
|
90
|
-
if (currentCursor) {
|
|
91
|
-
// eslint-disable-next-line no-loop-func
|
|
92
|
-
updateCache((cache) => {
|
|
93
|
-
const key = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheKey).call(this, chainIds, address);
|
|
94
|
-
cache[key] = currentCursor;
|
|
95
|
-
log('Updated cache', { key, newCursor: currentCursor });
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
log('Error while fetching transactions', error);
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
log('Queried transactions', { pageCount });
|
|
105
|
-
return transactions;
|
|
106
|
-
}, _AccountsApiRemoteTransactionSource_filterTransactions = function _AccountsApiRemoteTransactionSource_filterTransactions(request, transactions) {
|
|
107
|
-
const { address, includeTokenTransfers, updateTransactions } = request;
|
|
108
|
-
let filteredTransactions = transactions;
|
|
109
|
-
if (!updateTransactions) {
|
|
110
|
-
filteredTransactions = filteredTransactions.filter((tx) => tx.txParams.to === address);
|
|
111
|
-
}
|
|
112
|
-
if (!includeTokenTransfers) {
|
|
113
|
-
filteredTransactions = filteredTransactions.filter((tx) => !tx.isTransfer);
|
|
114
|
-
}
|
|
115
|
-
return filteredTransactions;
|
|
116
|
-
}, _AccountsApiRemoteTransactionSource_normalizeTransaction = function _AccountsApiRemoteTransactionSource_normalizeTransaction(address, responseTransaction) {
|
|
117
|
-
const blockNumber = String(responseTransaction.blockNumber);
|
|
118
|
-
const chainId = `0x${responseTransaction.chainId.toString(16)}`;
|
|
119
|
-
const { hash } = responseTransaction;
|
|
120
|
-
const time = new Date(responseTransaction.timestamp).getTime();
|
|
121
|
-
const id = (0, uuid_1.v1)({ msecs: time });
|
|
122
|
-
const { from } = responseTransaction;
|
|
123
|
-
const gas = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.gas));
|
|
124
|
-
const gasPrice = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.gasPrice));
|
|
125
|
-
const gasUsed = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.gasUsed));
|
|
126
|
-
const nonce = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.nonce));
|
|
127
|
-
const type = types_1.TransactionType.incoming;
|
|
128
|
-
const verifiedOnBlockchain = false;
|
|
129
|
-
const status = responseTransaction.isError
|
|
130
|
-
? types_1.TransactionStatus.failed
|
|
131
|
-
: types_1.TransactionStatus.confirmed;
|
|
132
|
-
const valueTransfer = responseTransaction.valueTransfers.find((vt) => vt.to.toLowerCase() === address.toLowerCase() && vt.contractAddress);
|
|
133
|
-
const isTransfer = Boolean(valueTransfer);
|
|
134
|
-
const contractAddress = valueTransfer?.contractAddress;
|
|
135
|
-
const decimals = valueTransfer?.decimal;
|
|
136
|
-
const symbol = valueTransfer?.symbol;
|
|
137
|
-
const value = (0, controller_utils_1.BNToHex)(new bn_js_1.default(valueTransfer?.amount ?? responseTransaction.value));
|
|
138
|
-
const to = valueTransfer ? address : responseTransaction.to;
|
|
139
|
-
const error = status === types_1.TransactionStatus.failed
|
|
140
|
-
? new Error('Transaction failed')
|
|
141
|
-
: undefined;
|
|
142
|
-
const transferInformation = isTransfer
|
|
143
|
-
? {
|
|
144
|
-
contractAddress,
|
|
145
|
-
decimals,
|
|
146
|
-
symbol,
|
|
147
|
-
}
|
|
148
|
-
: undefined;
|
|
149
|
-
return {
|
|
150
|
-
blockNumber,
|
|
151
|
-
chainId,
|
|
152
|
-
error,
|
|
153
|
-
hash,
|
|
154
|
-
id,
|
|
155
|
-
isTransfer,
|
|
156
|
-
// Populated by TransactionController when added to state
|
|
157
|
-
networkClientId: '',
|
|
158
|
-
status,
|
|
159
|
-
time,
|
|
160
|
-
toSmartContract: false,
|
|
161
|
-
transferInformation,
|
|
162
|
-
txParams: {
|
|
163
|
-
chainId,
|
|
164
|
-
from,
|
|
165
|
-
gas,
|
|
166
|
-
gasPrice,
|
|
167
|
-
gasUsed,
|
|
168
|
-
nonce,
|
|
169
|
-
to,
|
|
170
|
-
value,
|
|
171
|
-
},
|
|
172
|
-
type,
|
|
173
|
-
verifiedOnBlockchain,
|
|
174
|
-
};
|
|
175
|
-
}, _AccountsApiRemoteTransactionSource_getCacheKey = function _AccountsApiRemoteTransactionSource_getCacheKey(chainIds, address) {
|
|
176
|
-
return `accounts-api#${chainIds.join(',')}#${address}`;
|
|
177
|
-
}, _AccountsApiRemoteTransactionSource_getCacheCursor = function _AccountsApiRemoteTransactionSource_getCacheCursor(cache, chainIds, address) {
|
|
178
|
-
const key = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheKey).call(this, chainIds, address);
|
|
179
|
-
return cache[key];
|
|
180
|
-
}, _AccountsApiRemoteTransactionSource_getTimestampSeconds = function _AccountsApiRemoteTransactionSource_getTimestampSeconds(timestampMs) {
|
|
181
|
-
return Math.floor(timestampMs / 1000);
|
|
182
|
-
};
|
|
183
|
-
//# sourceMappingURL=AccountsApiRemoteTransactionSource.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AccountsApiRemoteTransactionSource.cjs","sourceRoot":"","sources":["../../src/helpers/AccountsApiRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport type {\n GetAccountTransactionsResponse,\n TransactionResponse,\n} from '../api/accounts-api';\nimport { getAccountTransactions } from '../api/accounts-api';\nimport { CHAIN_IDS } from '../constants';\nimport { createModuleLogger, incomingTransactionsLogger } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionError,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\nexport const SUPPORTED_CHAIN_IDS: Hex[] = [\n CHAIN_IDS.MAINNET,\n CHAIN_IDS.POLYGON,\n CHAIN_IDS.BSC,\n CHAIN_IDS.LINEA_MAINNET,\n CHAIN_IDS.BASE,\n CHAIN_IDS.OPTIMISM,\n CHAIN_IDS.ARBITRUM,\n CHAIN_IDS.SCROLL,\n];\n\nconst log = createModuleLogger(\n incomingTransactionsLogger,\n 'accounts-api-source',\n);\n\n/**\n * A RemoteTransactionSource that fetches incoming transactions using the Accounts API.\n */\nexport class AccountsApiRemoteTransactionSource\n implements RemoteTransactionSource\n{\n getSupportedChains(): Hex[] {\n return SUPPORTED_CHAIN_IDS;\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const { address } = request;\n\n const responseTransactions = await this.#getTransactions(request);\n\n log(\n 'Fetched transactions',\n responseTransactions.length,\n responseTransactions,\n );\n\n const normalizedTransactions = responseTransactions.map((tx) =>\n this.#normalizeTransaction(address, tx),\n );\n\n log('Normalized transactions', normalizedTransactions);\n\n const filteredTransactions = this.#filterTransactions(\n request,\n normalizedTransactions,\n );\n\n log(\n 'Filtered transactions',\n filteredTransactions.length,\n filteredTransactions,\n );\n\n return filteredTransactions;\n }\n\n async #getTransactions(request: RemoteTransactionSourceRequest) {\n log('Getting transactions', request);\n\n const { address, cache, chainIds: requestedChainIds } = request;\n\n const chainIds = requestedChainIds.filter((chainId) =>\n SUPPORTED_CHAIN_IDS.includes(chainId),\n );\n\n const unsupportedChainIds = requestedChainIds.filter(\n (chainId) => !chainIds.includes(chainId),\n );\n\n if (unsupportedChainIds.length) {\n log('Ignoring unsupported chain IDs', unsupportedChainIds);\n }\n\n const cursor = this.#getCacheCursor(cache, chainIds, address);\n\n if (cursor) {\n log('Using cached cursor', cursor);\n }\n\n return await this.#queryTransactions(request, chainIds, cursor);\n }\n\n async #queryTransactions(\n request: RemoteTransactionSourceRequest,\n chainIds: Hex[],\n cursor?: string,\n ): Promise<TransactionResponse[]> {\n const { address, queryEntireHistory, updateCache } = request;\n const transactions: TransactionResponse[] = [];\n\n let hasNextPage = true;\n let currentCursor = cursor;\n let pageCount = 0;\n\n const startTimestamp =\n queryEntireHistory || cursor\n ? undefined\n : this.#getTimestampSeconds(Date.now());\n\n while (hasNextPage) {\n try {\n const response = await getAccountTransactions({\n address,\n chainIds,\n cursor: currentCursor,\n sortDirection: 'ASC',\n startTimestamp,\n });\n\n pageCount += 1;\n\n if (response?.data) {\n transactions.push(...response.data);\n }\n\n hasNextPage = response?.pageInfo?.hasNextPage;\n currentCursor = response?.pageInfo?.cursor;\n\n if (currentCursor) {\n // eslint-disable-next-line no-loop-func\n updateCache((cache) => {\n const key = this.#getCacheKey(chainIds, address);\n cache[key] = currentCursor;\n\n log('Updated cache', { key, newCursor: currentCursor });\n });\n }\n } catch (error) {\n log('Error while fetching transactions', error);\n break;\n }\n }\n\n log('Queried transactions', { pageCount });\n\n return transactions;\n }\n\n #filterTransactions(\n request: RemoteTransactionSourceRequest,\n transactions: TransactionMeta[],\n ) {\n const { address, includeTokenTransfers, updateTransactions } = request;\n\n let filteredTransactions = transactions;\n\n if (!updateTransactions) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => tx.txParams.to === address,\n );\n }\n\n if (!includeTokenTransfers) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => !tx.isTransfer,\n );\n }\n\n return filteredTransactions;\n }\n\n #normalizeTransaction(\n address: Hex,\n responseTransaction: GetAccountTransactionsResponse['data'][0],\n ): TransactionMeta {\n const blockNumber = String(responseTransaction.blockNumber);\n const chainId = `0x${responseTransaction.chainId.toString(16)}` as Hex;\n const { hash } = responseTransaction;\n const time = new Date(responseTransaction.timestamp).getTime();\n const id = random({ msecs: time });\n const { from } = responseTransaction;\n const gas = BNToHex(new BN(responseTransaction.gas));\n const gasPrice = BNToHex(new BN(responseTransaction.gasPrice));\n const gasUsed = BNToHex(new BN(responseTransaction.gasUsed));\n const nonce = BNToHex(new BN(responseTransaction.nonce));\n const type = TransactionType.incoming;\n const verifiedOnBlockchain = false;\n\n const status = responseTransaction.isError\n ? TransactionStatus.failed\n : TransactionStatus.confirmed;\n\n const valueTransfer = responseTransaction.valueTransfers.find(\n (vt) =>\n vt.to.toLowerCase() === address.toLowerCase() && vt.contractAddress,\n );\n\n const isTransfer = Boolean(valueTransfer);\n const contractAddress = valueTransfer?.contractAddress as string;\n const decimals = valueTransfer?.decimal as number;\n const symbol = valueTransfer?.symbol as string;\n\n const value = BNToHex(\n new BN(valueTransfer?.amount ?? responseTransaction.value),\n );\n\n const to = valueTransfer ? address : responseTransaction.to;\n\n const error =\n status === TransactionStatus.failed\n ? new Error('Transaction failed')\n : (undefined as unknown as TransactionError);\n\n const transferInformation = isTransfer\n ? {\n contractAddress,\n decimals,\n symbol,\n }\n : undefined;\n\n return {\n blockNumber,\n chainId,\n error,\n hash,\n id,\n isTransfer,\n // Populated by TransactionController when added to state\n networkClientId: '',\n status,\n time,\n toSmartContract: false,\n transferInformation,\n txParams: {\n chainId,\n from,\n gas,\n gasPrice,\n gasUsed,\n nonce,\n to,\n value,\n },\n type,\n verifiedOnBlockchain,\n };\n }\n\n #getCacheKey(chainIds: Hex[], address: Hex): string {\n return `accounts-api#${chainIds.join(',')}#${address}`;\n }\n\n #getCacheCursor(\n cache: Record<string, unknown>,\n chainIds: Hex[],\n address: Hex,\n ): string | undefined {\n const key = this.#getCacheKey(chainIds, address);\n return cache[key] as string | undefined;\n }\n\n #getTimestampSeconds(timestampMs: number): number {\n return Math.floor(timestampMs / 1000);\n }\n}\n"]}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Hex } from "@metamask/utils";
|
|
2
|
-
import type { RemoteTransactionSource, RemoteTransactionSourceRequest, TransactionMeta } from "../types.cjs";
|
|
3
|
-
export declare const SUPPORTED_CHAIN_IDS: Hex[];
|
|
4
|
-
/**
|
|
5
|
-
* A RemoteTransactionSource that fetches incoming transactions using the Accounts API.
|
|
6
|
-
*/
|
|
7
|
-
export declare class AccountsApiRemoteTransactionSource implements RemoteTransactionSource {
|
|
8
|
-
#private;
|
|
9
|
-
getSupportedChains(): Hex[];
|
|
10
|
-
fetchTransactions(request: RemoteTransactionSourceRequest): Promise<TransactionMeta[]>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=AccountsApiRemoteTransactionSource.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AccountsApiRemoteTransactionSource.d.cts","sourceRoot":"","sources":["../../src/helpers/AccountsApiRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAW3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAE9B,eAAe,EAChB,qBAAiB;AAGlB,eAAO,MAAM,mBAAmB,EAAE,GAAG,EASpC,CAAC;AAOF;;GAEG;AACH,qBAAa,kCACX,YAAW,uBAAuB;;IAElC,kBAAkB,IAAI,GAAG,EAAE;IAIrB,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAsO9B"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Hex } from "@metamask/utils";
|
|
2
|
-
import type { RemoteTransactionSource, RemoteTransactionSourceRequest, TransactionMeta } from "../types.mjs";
|
|
3
|
-
export declare const SUPPORTED_CHAIN_IDS: Hex[];
|
|
4
|
-
/**
|
|
5
|
-
* A RemoteTransactionSource that fetches incoming transactions using the Accounts API.
|
|
6
|
-
*/
|
|
7
|
-
export declare class AccountsApiRemoteTransactionSource implements RemoteTransactionSource {
|
|
8
|
-
#private;
|
|
9
|
-
getSupportedChains(): Hex[];
|
|
10
|
-
fetchTransactions(request: RemoteTransactionSourceRequest): Promise<TransactionMeta[]>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=AccountsApiRemoteTransactionSource.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AccountsApiRemoteTransactionSource.d.mts","sourceRoot":"","sources":["../../src/helpers/AccountsApiRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAW3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAE9B,eAAe,EAChB,qBAAiB;AAGlB,eAAO,MAAM,mBAAmB,EAAE,GAAG,EASpC,CAAC;AAOF;;GAEG;AACH,qBAAa,kCACX,YAAW,uBAAuB;;IAElC,kBAAkB,IAAI,GAAG,EAAE;IAIrB,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAsO9B"}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
-
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");
|
|
4
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
-
};
|
|
6
|
-
var _AccountsApiRemoteTransactionSource_instances, _AccountsApiRemoteTransactionSource_getTransactions, _AccountsApiRemoteTransactionSource_queryTransactions, _AccountsApiRemoteTransactionSource_filterTransactions, _AccountsApiRemoteTransactionSource_normalizeTransaction, _AccountsApiRemoteTransactionSource_getCacheKey, _AccountsApiRemoteTransactionSource_getCacheCursor, _AccountsApiRemoteTransactionSource_getTimestampSeconds;
|
|
7
|
-
function $importDefault(module) {
|
|
8
|
-
if (module?.__esModule) {
|
|
9
|
-
return module.default;
|
|
10
|
-
}
|
|
11
|
-
return module;
|
|
12
|
-
}
|
|
13
|
-
import { BNToHex } from "@metamask/controller-utils";
|
|
14
|
-
import $BN from "bn.js";
|
|
15
|
-
const BN = $importDefault($BN);
|
|
16
|
-
import { v1 as random } from "uuid";
|
|
17
|
-
import { getAccountTransactions } from "../api/accounts-api.mjs";
|
|
18
|
-
import { CHAIN_IDS } from "../constants.mjs";
|
|
19
|
-
import { createModuleLogger, incomingTransactionsLogger } from "../logger.mjs";
|
|
20
|
-
import { TransactionStatus, TransactionType } from "../types.mjs";
|
|
21
|
-
export const SUPPORTED_CHAIN_IDS = [
|
|
22
|
-
CHAIN_IDS.MAINNET,
|
|
23
|
-
CHAIN_IDS.POLYGON,
|
|
24
|
-
CHAIN_IDS.BSC,
|
|
25
|
-
CHAIN_IDS.LINEA_MAINNET,
|
|
26
|
-
CHAIN_IDS.BASE,
|
|
27
|
-
CHAIN_IDS.OPTIMISM,
|
|
28
|
-
CHAIN_IDS.ARBITRUM,
|
|
29
|
-
CHAIN_IDS.SCROLL,
|
|
30
|
-
];
|
|
31
|
-
const log = createModuleLogger(incomingTransactionsLogger, 'accounts-api-source');
|
|
32
|
-
/**
|
|
33
|
-
* A RemoteTransactionSource that fetches incoming transactions using the Accounts API.
|
|
34
|
-
*/
|
|
35
|
-
export class AccountsApiRemoteTransactionSource {
|
|
36
|
-
constructor() {
|
|
37
|
-
_AccountsApiRemoteTransactionSource_instances.add(this);
|
|
38
|
-
}
|
|
39
|
-
getSupportedChains() {
|
|
40
|
-
return SUPPORTED_CHAIN_IDS;
|
|
41
|
-
}
|
|
42
|
-
async fetchTransactions(request) {
|
|
43
|
-
const { address } = request;
|
|
44
|
-
const responseTransactions = await __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTransactions).call(this, request);
|
|
45
|
-
log('Fetched transactions', responseTransactions.length, responseTransactions);
|
|
46
|
-
const normalizedTransactions = responseTransactions.map((tx) => __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_normalizeTransaction).call(this, address, tx));
|
|
47
|
-
log('Normalized transactions', normalizedTransactions);
|
|
48
|
-
const filteredTransactions = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_filterTransactions).call(this, request, normalizedTransactions);
|
|
49
|
-
log('Filtered transactions', filteredTransactions.length, filteredTransactions);
|
|
50
|
-
return filteredTransactions;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
_AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemoteTransactionSource_getTransactions = async function _AccountsApiRemoteTransactionSource_getTransactions(request) {
|
|
54
|
-
log('Getting transactions', request);
|
|
55
|
-
const { address, cache, chainIds: requestedChainIds } = request;
|
|
56
|
-
const chainIds = requestedChainIds.filter((chainId) => SUPPORTED_CHAIN_IDS.includes(chainId));
|
|
57
|
-
const unsupportedChainIds = requestedChainIds.filter((chainId) => !chainIds.includes(chainId));
|
|
58
|
-
if (unsupportedChainIds.length) {
|
|
59
|
-
log('Ignoring unsupported chain IDs', unsupportedChainIds);
|
|
60
|
-
}
|
|
61
|
-
const cursor = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheCursor).call(this, cache, chainIds, address);
|
|
62
|
-
if (cursor) {
|
|
63
|
-
log('Using cached cursor', cursor);
|
|
64
|
-
}
|
|
65
|
-
return await __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_queryTransactions).call(this, request, chainIds, cursor);
|
|
66
|
-
}, _AccountsApiRemoteTransactionSource_queryTransactions = async function _AccountsApiRemoteTransactionSource_queryTransactions(request, chainIds, cursor) {
|
|
67
|
-
const { address, queryEntireHistory, updateCache } = request;
|
|
68
|
-
const transactions = [];
|
|
69
|
-
let hasNextPage = true;
|
|
70
|
-
let currentCursor = cursor;
|
|
71
|
-
let pageCount = 0;
|
|
72
|
-
const startTimestamp = queryEntireHistory || cursor
|
|
73
|
-
? undefined
|
|
74
|
-
: __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTimestampSeconds).call(this, Date.now());
|
|
75
|
-
while (hasNextPage) {
|
|
76
|
-
try {
|
|
77
|
-
const response = await getAccountTransactions({
|
|
78
|
-
address,
|
|
79
|
-
chainIds,
|
|
80
|
-
cursor: currentCursor,
|
|
81
|
-
sortDirection: 'ASC',
|
|
82
|
-
startTimestamp,
|
|
83
|
-
});
|
|
84
|
-
pageCount += 1;
|
|
85
|
-
if (response?.data) {
|
|
86
|
-
transactions.push(...response.data);
|
|
87
|
-
}
|
|
88
|
-
hasNextPage = response?.pageInfo?.hasNextPage;
|
|
89
|
-
currentCursor = response?.pageInfo?.cursor;
|
|
90
|
-
if (currentCursor) {
|
|
91
|
-
// eslint-disable-next-line no-loop-func
|
|
92
|
-
updateCache((cache) => {
|
|
93
|
-
const key = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheKey).call(this, chainIds, address);
|
|
94
|
-
cache[key] = currentCursor;
|
|
95
|
-
log('Updated cache', { key, newCursor: currentCursor });
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
log('Error while fetching transactions', error);
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
log('Queried transactions', { pageCount });
|
|
105
|
-
return transactions;
|
|
106
|
-
}, _AccountsApiRemoteTransactionSource_filterTransactions = function _AccountsApiRemoteTransactionSource_filterTransactions(request, transactions) {
|
|
107
|
-
const { address, includeTokenTransfers, updateTransactions } = request;
|
|
108
|
-
let filteredTransactions = transactions;
|
|
109
|
-
if (!updateTransactions) {
|
|
110
|
-
filteredTransactions = filteredTransactions.filter((tx) => tx.txParams.to === address);
|
|
111
|
-
}
|
|
112
|
-
if (!includeTokenTransfers) {
|
|
113
|
-
filteredTransactions = filteredTransactions.filter((tx) => !tx.isTransfer);
|
|
114
|
-
}
|
|
115
|
-
return filteredTransactions;
|
|
116
|
-
}, _AccountsApiRemoteTransactionSource_normalizeTransaction = function _AccountsApiRemoteTransactionSource_normalizeTransaction(address, responseTransaction) {
|
|
117
|
-
const blockNumber = String(responseTransaction.blockNumber);
|
|
118
|
-
const chainId = `0x${responseTransaction.chainId.toString(16)}`;
|
|
119
|
-
const { hash } = responseTransaction;
|
|
120
|
-
const time = new Date(responseTransaction.timestamp).getTime();
|
|
121
|
-
const id = random({ msecs: time });
|
|
122
|
-
const { from } = responseTransaction;
|
|
123
|
-
const gas = BNToHex(new BN(responseTransaction.gas));
|
|
124
|
-
const gasPrice = BNToHex(new BN(responseTransaction.gasPrice));
|
|
125
|
-
const gasUsed = BNToHex(new BN(responseTransaction.gasUsed));
|
|
126
|
-
const nonce = BNToHex(new BN(responseTransaction.nonce));
|
|
127
|
-
const type = TransactionType.incoming;
|
|
128
|
-
const verifiedOnBlockchain = false;
|
|
129
|
-
const status = responseTransaction.isError
|
|
130
|
-
? TransactionStatus.failed
|
|
131
|
-
: TransactionStatus.confirmed;
|
|
132
|
-
const valueTransfer = responseTransaction.valueTransfers.find((vt) => vt.to.toLowerCase() === address.toLowerCase() && vt.contractAddress);
|
|
133
|
-
const isTransfer = Boolean(valueTransfer);
|
|
134
|
-
const contractAddress = valueTransfer?.contractAddress;
|
|
135
|
-
const decimals = valueTransfer?.decimal;
|
|
136
|
-
const symbol = valueTransfer?.symbol;
|
|
137
|
-
const value = BNToHex(new BN(valueTransfer?.amount ?? responseTransaction.value));
|
|
138
|
-
const to = valueTransfer ? address : responseTransaction.to;
|
|
139
|
-
const error = status === TransactionStatus.failed
|
|
140
|
-
? new Error('Transaction failed')
|
|
141
|
-
: undefined;
|
|
142
|
-
const transferInformation = isTransfer
|
|
143
|
-
? {
|
|
144
|
-
contractAddress,
|
|
145
|
-
decimals,
|
|
146
|
-
symbol,
|
|
147
|
-
}
|
|
148
|
-
: undefined;
|
|
149
|
-
return {
|
|
150
|
-
blockNumber,
|
|
151
|
-
chainId,
|
|
152
|
-
error,
|
|
153
|
-
hash,
|
|
154
|
-
id,
|
|
155
|
-
isTransfer,
|
|
156
|
-
// Populated by TransactionController when added to state
|
|
157
|
-
networkClientId: '',
|
|
158
|
-
status,
|
|
159
|
-
time,
|
|
160
|
-
toSmartContract: false,
|
|
161
|
-
transferInformation,
|
|
162
|
-
txParams: {
|
|
163
|
-
chainId,
|
|
164
|
-
from,
|
|
165
|
-
gas,
|
|
166
|
-
gasPrice,
|
|
167
|
-
gasUsed,
|
|
168
|
-
nonce,
|
|
169
|
-
to,
|
|
170
|
-
value,
|
|
171
|
-
},
|
|
172
|
-
type,
|
|
173
|
-
verifiedOnBlockchain,
|
|
174
|
-
};
|
|
175
|
-
}, _AccountsApiRemoteTransactionSource_getCacheKey = function _AccountsApiRemoteTransactionSource_getCacheKey(chainIds, address) {
|
|
176
|
-
return `accounts-api#${chainIds.join(',')}#${address}`;
|
|
177
|
-
}, _AccountsApiRemoteTransactionSource_getCacheCursor = function _AccountsApiRemoteTransactionSource_getCacheCursor(cache, chainIds, address) {
|
|
178
|
-
const key = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheKey).call(this, chainIds, address);
|
|
179
|
-
return cache[key];
|
|
180
|
-
}, _AccountsApiRemoteTransactionSource_getTimestampSeconds = function _AccountsApiRemoteTransactionSource_getTimestampSeconds(timestampMs) {
|
|
181
|
-
return Math.floor(timestampMs / 1000);
|
|
182
|
-
};
|
|
183
|
-
//# sourceMappingURL=AccountsApiRemoteTransactionSource.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AccountsApiRemoteTransactionSource.mjs","sourceRoot":"","sources":["../../src/helpers/AccountsApiRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport type {\n GetAccountTransactionsResponse,\n TransactionResponse,\n} from '../api/accounts-api';\nimport { getAccountTransactions } from '../api/accounts-api';\nimport { CHAIN_IDS } from '../constants';\nimport { createModuleLogger, incomingTransactionsLogger } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionError,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\nexport const SUPPORTED_CHAIN_IDS: Hex[] = [\n CHAIN_IDS.MAINNET,\n CHAIN_IDS.POLYGON,\n CHAIN_IDS.BSC,\n CHAIN_IDS.LINEA_MAINNET,\n CHAIN_IDS.BASE,\n CHAIN_IDS.OPTIMISM,\n CHAIN_IDS.ARBITRUM,\n CHAIN_IDS.SCROLL,\n];\n\nconst log = createModuleLogger(\n incomingTransactionsLogger,\n 'accounts-api-source',\n);\n\n/**\n * A RemoteTransactionSource that fetches incoming transactions using the Accounts API.\n */\nexport class AccountsApiRemoteTransactionSource\n implements RemoteTransactionSource\n{\n getSupportedChains(): Hex[] {\n return SUPPORTED_CHAIN_IDS;\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const { address } = request;\n\n const responseTransactions = await this.#getTransactions(request);\n\n log(\n 'Fetched transactions',\n responseTransactions.length,\n responseTransactions,\n );\n\n const normalizedTransactions = responseTransactions.map((tx) =>\n this.#normalizeTransaction(address, tx),\n );\n\n log('Normalized transactions', normalizedTransactions);\n\n const filteredTransactions = this.#filterTransactions(\n request,\n normalizedTransactions,\n );\n\n log(\n 'Filtered transactions',\n filteredTransactions.length,\n filteredTransactions,\n );\n\n return filteredTransactions;\n }\n\n async #getTransactions(request: RemoteTransactionSourceRequest) {\n log('Getting transactions', request);\n\n const { address, cache, chainIds: requestedChainIds } = request;\n\n const chainIds = requestedChainIds.filter((chainId) =>\n SUPPORTED_CHAIN_IDS.includes(chainId),\n );\n\n const unsupportedChainIds = requestedChainIds.filter(\n (chainId) => !chainIds.includes(chainId),\n );\n\n if (unsupportedChainIds.length) {\n log('Ignoring unsupported chain IDs', unsupportedChainIds);\n }\n\n const cursor = this.#getCacheCursor(cache, chainIds, address);\n\n if (cursor) {\n log('Using cached cursor', cursor);\n }\n\n return await this.#queryTransactions(request, chainIds, cursor);\n }\n\n async #queryTransactions(\n request: RemoteTransactionSourceRequest,\n chainIds: Hex[],\n cursor?: string,\n ): Promise<TransactionResponse[]> {\n const { address, queryEntireHistory, updateCache } = request;\n const transactions: TransactionResponse[] = [];\n\n let hasNextPage = true;\n let currentCursor = cursor;\n let pageCount = 0;\n\n const startTimestamp =\n queryEntireHistory || cursor\n ? undefined\n : this.#getTimestampSeconds(Date.now());\n\n while (hasNextPage) {\n try {\n const response = await getAccountTransactions({\n address,\n chainIds,\n cursor: currentCursor,\n sortDirection: 'ASC',\n startTimestamp,\n });\n\n pageCount += 1;\n\n if (response?.data) {\n transactions.push(...response.data);\n }\n\n hasNextPage = response?.pageInfo?.hasNextPage;\n currentCursor = response?.pageInfo?.cursor;\n\n if (currentCursor) {\n // eslint-disable-next-line no-loop-func\n updateCache((cache) => {\n const key = this.#getCacheKey(chainIds, address);\n cache[key] = currentCursor;\n\n log('Updated cache', { key, newCursor: currentCursor });\n });\n }\n } catch (error) {\n log('Error while fetching transactions', error);\n break;\n }\n }\n\n log('Queried transactions', { pageCount });\n\n return transactions;\n }\n\n #filterTransactions(\n request: RemoteTransactionSourceRequest,\n transactions: TransactionMeta[],\n ) {\n const { address, includeTokenTransfers, updateTransactions } = request;\n\n let filteredTransactions = transactions;\n\n if (!updateTransactions) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => tx.txParams.to === address,\n );\n }\n\n if (!includeTokenTransfers) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => !tx.isTransfer,\n );\n }\n\n return filteredTransactions;\n }\n\n #normalizeTransaction(\n address: Hex,\n responseTransaction: GetAccountTransactionsResponse['data'][0],\n ): TransactionMeta {\n const blockNumber = String(responseTransaction.blockNumber);\n const chainId = `0x${responseTransaction.chainId.toString(16)}` as Hex;\n const { hash } = responseTransaction;\n const time = new Date(responseTransaction.timestamp).getTime();\n const id = random({ msecs: time });\n const { from } = responseTransaction;\n const gas = BNToHex(new BN(responseTransaction.gas));\n const gasPrice = BNToHex(new BN(responseTransaction.gasPrice));\n const gasUsed = BNToHex(new BN(responseTransaction.gasUsed));\n const nonce = BNToHex(new BN(responseTransaction.nonce));\n const type = TransactionType.incoming;\n const verifiedOnBlockchain = false;\n\n const status = responseTransaction.isError\n ? TransactionStatus.failed\n : TransactionStatus.confirmed;\n\n const valueTransfer = responseTransaction.valueTransfers.find(\n (vt) =>\n vt.to.toLowerCase() === address.toLowerCase() && vt.contractAddress,\n );\n\n const isTransfer = Boolean(valueTransfer);\n const contractAddress = valueTransfer?.contractAddress as string;\n const decimals = valueTransfer?.decimal as number;\n const symbol = valueTransfer?.symbol as string;\n\n const value = BNToHex(\n new BN(valueTransfer?.amount ?? responseTransaction.value),\n );\n\n const to = valueTransfer ? address : responseTransaction.to;\n\n const error =\n status === TransactionStatus.failed\n ? new Error('Transaction failed')\n : (undefined as unknown as TransactionError);\n\n const transferInformation = isTransfer\n ? {\n contractAddress,\n decimals,\n symbol,\n }\n : undefined;\n\n return {\n blockNumber,\n chainId,\n error,\n hash,\n id,\n isTransfer,\n // Populated by TransactionController when added to state\n networkClientId: '',\n status,\n time,\n toSmartContract: false,\n transferInformation,\n txParams: {\n chainId,\n from,\n gas,\n gasPrice,\n gasUsed,\n nonce,\n to,\n value,\n },\n type,\n verifiedOnBlockchain,\n };\n }\n\n #getCacheKey(chainIds: Hex[], address: Hex): string {\n return `accounts-api#${chainIds.join(',')}#${address}`;\n }\n\n #getCacheCursor(\n cache: Record<string, unknown>,\n chainIds: Hex[],\n address: Hex,\n ): string | undefined {\n const key = this.#getCacheKey(chainIds, address);\n return cache[key] as string | undefined;\n }\n\n #getTimestampSeconds(timestampMs: number): number {\n return Math.floor(timestampMs / 1000);\n }\n}\n"]}
|