@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
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAccountTransactionsAllPages = exports.getAccountTransactions = void 0;
4
+ const utils_1 = require("@metamask/utils");
5
+ const logger_1 = require("../logger.cjs");
6
+ const BASE_URL = `https://accounts.api.cx.metamask.io/v1/accounts/`;
7
+ const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'accounts-api');
8
+ /**
9
+ * Fetch account transactions from the accounts API.
10
+ * @param request - The request object.
11
+ * @returns The response object.
12
+ */
13
+ async function getAccountTransactions(request) {
14
+ const { address, chainIds, cursor, endTimestamp, startTimestamp } = request;
15
+ let url = `${BASE_URL}${address}/transactions`;
16
+ const params = [];
17
+ if (chainIds) {
18
+ const network = chainIds.join(',');
19
+ params.push(`networks=${network}`);
20
+ }
21
+ if (startTimestamp) {
22
+ params.push(`startTimestamp=${startTimestamp}`);
23
+ }
24
+ if (endTimestamp) {
25
+ params.push(`endTimestamp=${endTimestamp}`);
26
+ }
27
+ if (cursor) {
28
+ params.push(`cursor=${cursor}`);
29
+ }
30
+ if (params.length) {
31
+ url += `?${params.join('&')}`;
32
+ }
33
+ log('Getting account transactions', { request, url });
34
+ const response = await fetch(url);
35
+ const responseJson = await response.json();
36
+ log('Retrieved account transactions', responseJson);
37
+ return responseJson;
38
+ }
39
+ exports.getAccountTransactions = getAccountTransactions;
40
+ /**
41
+ * Fetch account transactions from the accounts API.
42
+ * Automatically fetches all pages.
43
+ * @param request - The request object.
44
+ * @returns An array of transaction objects.
45
+ */
46
+ async function getAccountTransactionsAllPages(request) {
47
+ const transactions = [];
48
+ let cursor;
49
+ let hasNextPage = true;
50
+ log('Getting account transactions from all pages', request);
51
+ while (hasNextPage) {
52
+ const response = await getAccountTransactions({ ...request, cursor });
53
+ transactions.push(...response.data);
54
+ cursor = response.pageInfo.cursor;
55
+ hasNextPage = response.pageInfo.hasNextPage;
56
+ }
57
+ log('Retrieved account transactions from all pages', transactions);
58
+ return transactions;
59
+ }
60
+ exports.getAccountTransactionsAllPages = getAccountTransactionsAllPages;
61
+ //# sourceMappingURL=accounts-api.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts-api.cjs","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":";;;AAAA,2CAA+D;AAE/D,0CAA0C;AA8C1C,MAAM,QAAQ,GAAG,kDAAkD,CAAC;AAEpE,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,cAAc,CAAC,CAAC;AAE9D;;;;GAIG;AACI,KAAK,UAAU,sBAAsB,CAC1C,OAAsC;IAEtC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAE5E,IAAI,GAAG,GAAG,GAAG,QAAQ,GAAG,OAAO,eAAe,CAAC;IAC/C,MAAM,MAAM,GAAG,EAAE,CAAC;IAElB,IAAI,QAAQ,EAAE;QACZ,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;KACpC;IAED,IAAI,cAAc,EAAE;QAClB,MAAM,CAAC,IAAI,CAAC,kBAAkB,cAAc,EAAE,CAAC,CAAC;KACjD;IAED,IAAI,YAAY,EAAE;QAChB,MAAM,CAAC,IAAI,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;KAC7C;IAED,IAAI,MAAM,EAAE;QACV,MAAM,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;KACjC;IAED,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;KAC/B;IAED,GAAG,CAAC,8BAA8B,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAEtD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAE3C,GAAG,CAAC,gCAAgC,EAAE,YAAY,CAAC,CAAC;IAEpD,OAAO,YAAY,CAAC;AACtB,CAAC;AArCD,wDAqCC;AAED;;;;;GAKG;AACI,KAAK,UAAU,8BAA8B,CAClD,OAAsC;IAEtC,MAAM,YAAY,GAAG,EAAE,CAAC;IAExB,IAAI,MAAM,CAAC;IACX,IAAI,WAAW,GAAG,IAAI,CAAC;IAEvB,GAAG,CAAC,6CAA6C,EAAE,OAAO,CAAC,CAAC;IAE5D,OAAO,WAAW,EAAE;QAClB,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACtE,YAAY,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEpC,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAClC,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;KAC7C;IAED,GAAG,CAAC,+CAA+C,EAAE,YAAY,CAAC,CAAC;IAEnE,OAAO,YAAY,CAAC;AACtB,CAAC;AArBD,wEAqBC","sourcesContent":["import { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport { projectLogger } from '../logger';\n\nexport type TransactionResponse = {\n hash: Hex;\n timestamp: string;\n chainId: number;\n blockNumber: number;\n blockHash: Hex;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: string;\n nonce: number;\n cumulativeGasUsed: number;\n methodId: null;\n value: string;\n to: string;\n from: string;\n isError: boolean;\n valueTransfers: {\n contractAddress: string;\n decimal: number;\n symbol: string;\n from: string;\n to: string;\n amount: string;\n }[];\n};\n\nexport type GetAccountTransactionsRequest = {\n address: Hex;\n chainIds?: Hex[];\n cursor?: string;\n endTimestamp?: number;\n startTimestamp?: number;\n};\n\nexport type GetAccountTransactionsResponse = {\n data: TransactionResponse[];\n pageInfo: {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n };\n};\n\nconst BASE_URL = `https://accounts.api.cx.metamask.io/v1/accounts/`;\n\nconst log = createModuleLogger(projectLogger, 'accounts-api');\n\n/**\n * Fetch account transactions from the accounts API.\n * @param request - The request object.\n * @returns The response object.\n */\nexport async function getAccountTransactions(\n request: GetAccountTransactionsRequest,\n): Promise<GetAccountTransactionsResponse> {\n const { address, chainIds, cursor, endTimestamp, startTimestamp } = request;\n\n let url = `${BASE_URL}${address}/transactions`;\n const params = [];\n\n if (chainIds) {\n const network = chainIds.join(',');\n params.push(`networks=${network}`);\n }\n\n if (startTimestamp) {\n params.push(`startTimestamp=${startTimestamp}`);\n }\n\n if (endTimestamp) {\n params.push(`endTimestamp=${endTimestamp}`);\n }\n\n if (cursor) {\n params.push(`cursor=${cursor}`);\n }\n\n if (params.length) {\n url += `?${params.join('&')}`;\n }\n\n log('Getting account transactions', { request, url });\n\n const response = await fetch(url);\n const responseJson = await response.json();\n\n log('Retrieved account transactions', responseJson);\n\n return responseJson;\n}\n\n/**\n * Fetch account transactions from the accounts API.\n * Automatically fetches all pages.\n * @param request - The request object.\n * @returns An array of transaction objects.\n */\nexport async function getAccountTransactionsAllPages(\n request: GetAccountTransactionsRequest,\n): Promise<TransactionResponse[]> {\n const transactions = [];\n\n let cursor;\n let hasNextPage = true;\n\n log('Getting account transactions from all pages', request);\n\n while (hasNextPage) {\n const response = await getAccountTransactions({ ...request, cursor });\n transactions.push(...response.data);\n\n cursor = response.pageInfo.cursor;\n hasNextPage = response.pageInfo.hasNextPage;\n }\n\n log('Retrieved account transactions from all pages', transactions);\n\n return transactions;\n}\n"]}
@@ -0,0 +1,56 @@
1
+ import { type Hex } from "@metamask/utils";
2
+ export type TransactionResponse = {
3
+ hash: Hex;
4
+ timestamp: string;
5
+ chainId: number;
6
+ blockNumber: number;
7
+ blockHash: Hex;
8
+ gas: number;
9
+ gasUsed: number;
10
+ gasPrice: string;
11
+ effectiveGasPrice: string;
12
+ nonce: number;
13
+ cumulativeGasUsed: number;
14
+ methodId: null;
15
+ value: string;
16
+ to: string;
17
+ from: string;
18
+ isError: boolean;
19
+ valueTransfers: {
20
+ contractAddress: string;
21
+ decimal: number;
22
+ symbol: string;
23
+ from: string;
24
+ to: string;
25
+ amount: string;
26
+ }[];
27
+ };
28
+ export type GetAccountTransactionsRequest = {
29
+ address: Hex;
30
+ chainIds?: Hex[];
31
+ cursor?: string;
32
+ endTimestamp?: number;
33
+ startTimestamp?: number;
34
+ };
35
+ export type GetAccountTransactionsResponse = {
36
+ data: TransactionResponse[];
37
+ pageInfo: {
38
+ count: number;
39
+ hasNextPage: boolean;
40
+ cursor?: string;
41
+ };
42
+ };
43
+ /**
44
+ * Fetch account transactions from the accounts API.
45
+ * @param request - The request object.
46
+ * @returns The response object.
47
+ */
48
+ export declare function getAccountTransactions(request: GetAccountTransactionsRequest): Promise<GetAccountTransactionsResponse>;
49
+ /**
50
+ * Fetch account transactions from the accounts API.
51
+ * Automatically fetches all pages.
52
+ * @param request - The request object.
53
+ * @returns An array of transaction objects.
54
+ */
55
+ export declare function getAccountTransactionsAllPages(request: GetAccountTransactionsRequest): Promise<TransactionResponse[]>;
56
+ //# sourceMappingURL=accounts-api.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts-api.d.cts","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,GAAG,EAAE,wBAAwB;AAI/D,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,GAAG,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,EAAE,CAAC;CACL,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,GAAG,CAAC;IACb,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,OAAO,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAMF;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,8BAA8B,CAAC,CAmCzC;AAED;;;;;GAKG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAmBhC"}
@@ -0,0 +1,56 @@
1
+ import { type Hex } from "@metamask/utils";
2
+ export type TransactionResponse = {
3
+ hash: Hex;
4
+ timestamp: string;
5
+ chainId: number;
6
+ blockNumber: number;
7
+ blockHash: Hex;
8
+ gas: number;
9
+ gasUsed: number;
10
+ gasPrice: string;
11
+ effectiveGasPrice: string;
12
+ nonce: number;
13
+ cumulativeGasUsed: number;
14
+ methodId: null;
15
+ value: string;
16
+ to: string;
17
+ from: string;
18
+ isError: boolean;
19
+ valueTransfers: {
20
+ contractAddress: string;
21
+ decimal: number;
22
+ symbol: string;
23
+ from: string;
24
+ to: string;
25
+ amount: string;
26
+ }[];
27
+ };
28
+ export type GetAccountTransactionsRequest = {
29
+ address: Hex;
30
+ chainIds?: Hex[];
31
+ cursor?: string;
32
+ endTimestamp?: number;
33
+ startTimestamp?: number;
34
+ };
35
+ export type GetAccountTransactionsResponse = {
36
+ data: TransactionResponse[];
37
+ pageInfo: {
38
+ count: number;
39
+ hasNextPage: boolean;
40
+ cursor?: string;
41
+ };
42
+ };
43
+ /**
44
+ * Fetch account transactions from the accounts API.
45
+ * @param request - The request object.
46
+ * @returns The response object.
47
+ */
48
+ export declare function getAccountTransactions(request: GetAccountTransactionsRequest): Promise<GetAccountTransactionsResponse>;
49
+ /**
50
+ * Fetch account transactions from the accounts API.
51
+ * Automatically fetches all pages.
52
+ * @param request - The request object.
53
+ * @returns An array of transaction objects.
54
+ */
55
+ export declare function getAccountTransactionsAllPages(request: GetAccountTransactionsRequest): Promise<TransactionResponse[]>;
56
+ //# sourceMappingURL=accounts-api.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts-api.d.mts","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,GAAG,EAAE,wBAAwB;AAI/D,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,GAAG,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,EAAE,CAAC;CACL,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,GAAG,CAAC;IACb,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,OAAO,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAMF;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,8BAA8B,CAAC,CAmCzC;AAED;;;;;GAKG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAmBhC"}
@@ -0,0 +1,56 @@
1
+ import { createModuleLogger } from "@metamask/utils";
2
+ import { projectLogger } from "../logger.mjs";
3
+ const BASE_URL = `https://accounts.api.cx.metamask.io/v1/accounts/`;
4
+ const log = createModuleLogger(projectLogger, 'accounts-api');
5
+ /**
6
+ * Fetch account transactions from the accounts API.
7
+ * @param request - The request object.
8
+ * @returns The response object.
9
+ */
10
+ export async function getAccountTransactions(request) {
11
+ const { address, chainIds, cursor, endTimestamp, startTimestamp } = request;
12
+ let url = `${BASE_URL}${address}/transactions`;
13
+ const params = [];
14
+ if (chainIds) {
15
+ const network = chainIds.join(',');
16
+ params.push(`networks=${network}`);
17
+ }
18
+ if (startTimestamp) {
19
+ params.push(`startTimestamp=${startTimestamp}`);
20
+ }
21
+ if (endTimestamp) {
22
+ params.push(`endTimestamp=${endTimestamp}`);
23
+ }
24
+ if (cursor) {
25
+ params.push(`cursor=${cursor}`);
26
+ }
27
+ if (params.length) {
28
+ url += `?${params.join('&')}`;
29
+ }
30
+ log('Getting account transactions', { request, url });
31
+ const response = await fetch(url);
32
+ const responseJson = await response.json();
33
+ log('Retrieved account transactions', responseJson);
34
+ return responseJson;
35
+ }
36
+ /**
37
+ * Fetch account transactions from the accounts API.
38
+ * Automatically fetches all pages.
39
+ * @param request - The request object.
40
+ * @returns An array of transaction objects.
41
+ */
42
+ export async function getAccountTransactionsAllPages(request) {
43
+ const transactions = [];
44
+ let cursor;
45
+ let hasNextPage = true;
46
+ log('Getting account transactions from all pages', request);
47
+ while (hasNextPage) {
48
+ const response = await getAccountTransactions({ ...request, cursor });
49
+ transactions.push(...response.data);
50
+ cursor = response.pageInfo.cursor;
51
+ hasNextPage = response.pageInfo.hasNextPage;
52
+ }
53
+ log('Retrieved account transactions from all pages', transactions);
54
+ return transactions;
55
+ }
56
+ //# sourceMappingURL=accounts-api.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts-api.mjs","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAY,wBAAwB;AAE/D,OAAO,EAAE,aAAa,EAAE,sBAAkB;AA8C1C,MAAM,QAAQ,GAAG,kDAAkD,CAAC;AAEpE,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AAE9D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAsC;IAEtC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAE5E,IAAI,GAAG,GAAG,GAAG,QAAQ,GAAG,OAAO,eAAe,CAAC;IAC/C,MAAM,MAAM,GAAG,EAAE,CAAC;IAElB,IAAI,QAAQ,EAAE;QACZ,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;KACpC;IAED,IAAI,cAAc,EAAE;QAClB,MAAM,CAAC,IAAI,CAAC,kBAAkB,cAAc,EAAE,CAAC,CAAC;KACjD;IAED,IAAI,YAAY,EAAE;QAChB,MAAM,CAAC,IAAI,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;KAC7C;IAED,IAAI,MAAM,EAAE;QACV,MAAM,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;KACjC;IAED,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;KAC/B;IAED,GAAG,CAAC,8BAA8B,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAEtD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAE3C,GAAG,CAAC,gCAAgC,EAAE,YAAY,CAAC,CAAC;IAEpD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,OAAsC;IAEtC,MAAM,YAAY,GAAG,EAAE,CAAC;IAExB,IAAI,MAAM,CAAC;IACX,IAAI,WAAW,GAAG,IAAI,CAAC;IAEvB,GAAG,CAAC,6CAA6C,EAAE,OAAO,CAAC,CAAC;IAE5D,OAAO,WAAW,EAAE;QAClB,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACtE,YAAY,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEpC,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAClC,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;KAC7C;IAED,GAAG,CAAC,+CAA+C,EAAE,YAAY,CAAC,CAAC;IAEnE,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport { projectLogger } from '../logger';\n\nexport type TransactionResponse = {\n hash: Hex;\n timestamp: string;\n chainId: number;\n blockNumber: number;\n blockHash: Hex;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: string;\n nonce: number;\n cumulativeGasUsed: number;\n methodId: null;\n value: string;\n to: string;\n from: string;\n isError: boolean;\n valueTransfers: {\n contractAddress: string;\n decimal: number;\n symbol: string;\n from: string;\n to: string;\n amount: string;\n }[];\n};\n\nexport type GetAccountTransactionsRequest = {\n address: Hex;\n chainIds?: Hex[];\n cursor?: string;\n endTimestamp?: number;\n startTimestamp?: number;\n};\n\nexport type GetAccountTransactionsResponse = {\n data: TransactionResponse[];\n pageInfo: {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n };\n};\n\nconst BASE_URL = `https://accounts.api.cx.metamask.io/v1/accounts/`;\n\nconst log = createModuleLogger(projectLogger, 'accounts-api');\n\n/**\n * Fetch account transactions from the accounts API.\n * @param request - The request object.\n * @returns The response object.\n */\nexport async function getAccountTransactions(\n request: GetAccountTransactionsRequest,\n): Promise<GetAccountTransactionsResponse> {\n const { address, chainIds, cursor, endTimestamp, startTimestamp } = request;\n\n let url = `${BASE_URL}${address}/transactions`;\n const params = [];\n\n if (chainIds) {\n const network = chainIds.join(',');\n params.push(`networks=${network}`);\n }\n\n if (startTimestamp) {\n params.push(`startTimestamp=${startTimestamp}`);\n }\n\n if (endTimestamp) {\n params.push(`endTimestamp=${endTimestamp}`);\n }\n\n if (cursor) {\n params.push(`cursor=${cursor}`);\n }\n\n if (params.length) {\n url += `?${params.join('&')}`;\n }\n\n log('Getting account transactions', { request, url });\n\n const response = await fetch(url);\n const responseJson = await response.json();\n\n log('Retrieved account transactions', responseJson);\n\n return responseJson;\n}\n\n/**\n * Fetch account transactions from the accounts API.\n * Automatically fetches all pages.\n * @param request - The request object.\n * @returns An array of transaction objects.\n */\nexport async function getAccountTransactionsAllPages(\n request: GetAccountTransactionsRequest,\n): Promise<TransactionResponse[]> {\n const transactions = [];\n\n let cursor;\n let hasNextPage = true;\n\n log('Getting account transactions from all pages', request);\n\n while (hasNextPage) {\n const response = await getAccountTransactions({ ...request, cursor });\n transactions.push(...response.data);\n\n cursor = response.pageInfo.cursor;\n hasNextPage = response.pageInfo.hasNextPage;\n }\n\n log('Retrieved account transactions from all pages', transactions);\n\n return transactions;\n}\n"]}
@@ -0,0 +1,135 @@
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_filterTransactions, _AccountsApiRemoteTransactionSource_normalizeTransaction, _AccountsApiRemoteTransactionSource_getTimestampSeconds;
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AccountsApiRemoteTransactionSource = 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
+ const 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 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
+ const incomingTransactions = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_filterTransactions).call(this, request, responseTransactions);
45
+ const normalizedTransactions = incomingTransactions.map((tx) => __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_normalizeTransaction).call(this, address, tx));
46
+ log('Filtered and normalized transactions', normalizedTransactions);
47
+ return normalizedTransactions;
48
+ }
49
+ }
50
+ exports.AccountsApiRemoteTransactionSource = AccountsApiRemoteTransactionSource;
51
+ _AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemoteTransactionSource_getTransactions = async function _AccountsApiRemoteTransactionSource_getTransactions(request) {
52
+ log('Fetching transactions', request);
53
+ const { address, chainIds: requestedChainIds, startTimestampByChainId, } = request;
54
+ const chainIds = requestedChainIds.filter((chainId) => SUPPORTED_CHAIN_IDS.includes(chainId));
55
+ const unsupportedChainIds = requestedChainIds.filter((chainId) => !chainIds.includes(chainId));
56
+ if (unsupportedChainIds.length) {
57
+ log('Ignoring unsupported chain IDs', unsupportedChainIds);
58
+ }
59
+ const startTimestamp = Math.min(...Object.values(startTimestampByChainId));
60
+ const endTimestamp = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTimestampSeconds).call(this, Date.now());
61
+ return await (0, accounts_api_1.getAccountTransactionsAllPages)({
62
+ address,
63
+ chainIds,
64
+ startTimestamp,
65
+ endTimestamp,
66
+ });
67
+ }, _AccountsApiRemoteTransactionSource_filterTransactions = function _AccountsApiRemoteTransactionSource_filterTransactions(request, responseTransactions) {
68
+ const { address, startTimestampByChainId, limit } = request;
69
+ const incomingTransactions = responseTransactions.filter((tx) => tx.to === address || tx.valueTransfers.some((vt) => vt.to === address));
70
+ log('Fetched incoming transactions from accounts API', incomingTransactions);
71
+ const incomingTransactionsMatchingTimestamp = incomingTransactions.filter((tx) => {
72
+ const chainId = `0x${tx.chainId.toString(16)}`;
73
+ const chainStartTimestamp = startTimestampByChainId[chainId];
74
+ const timestamp = new Date(tx.timestamp).getTime();
75
+ return timestamp >= chainStartTimestamp;
76
+ });
77
+ return incomingTransactionsMatchingTimestamp.slice(0, limit);
78
+ }, _AccountsApiRemoteTransactionSource_normalizeTransaction = function _AccountsApiRemoteTransactionSource_normalizeTransaction(address, responseTransaction) {
79
+ const blockNumber = String(responseTransaction.blockNumber);
80
+ const chainId = `0x${responseTransaction.chainId.toString(16)}`;
81
+ const { hash } = responseTransaction;
82
+ const time = new Date(responseTransaction.timestamp).getTime();
83
+ const id = (0, uuid_1.v1)({ msecs: time });
84
+ const { from } = responseTransaction;
85
+ const gas = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.gas));
86
+ const gasPrice = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.gasPrice));
87
+ const gasUsed = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.gasUsed));
88
+ const nonce = (0, controller_utils_1.BNToHex)(new bn_js_1.default(responseTransaction.nonce));
89
+ const type = types_1.TransactionType.incoming;
90
+ const verifiedOnBlockchain = false;
91
+ const status = responseTransaction.isError
92
+ ? types_1.TransactionStatus.failed
93
+ : types_1.TransactionStatus.confirmed;
94
+ const valueTransfer = responseTransaction.valueTransfers.find((vt) => vt.to === address);
95
+ const isTransfer = Boolean(valueTransfer);
96
+ const contractAddress = valueTransfer?.contractAddress;
97
+ const decimals = valueTransfer?.decimal;
98
+ const symbol = valueTransfer?.symbol;
99
+ const value = (0, controller_utils_1.BNToHex)(new bn_js_1.default(valueTransfer?.amount ?? responseTransaction.value));
100
+ const to = address;
101
+ return {
102
+ blockNumber,
103
+ chainId,
104
+ hash,
105
+ id,
106
+ status,
107
+ error: status === types_1.TransactionStatus.failed
108
+ ? new Error('Transaction failed')
109
+ : undefined,
110
+ time,
111
+ txParams: {
112
+ chainId,
113
+ from,
114
+ gas,
115
+ gasPrice,
116
+ gasUsed,
117
+ nonce,
118
+ to,
119
+ value,
120
+ },
121
+ type,
122
+ verifiedOnBlockchain,
123
+ isTransfer,
124
+ transferInformation: isTransfer
125
+ ? {
126
+ contractAddress,
127
+ decimals,
128
+ symbol,
129
+ }
130
+ : undefined,
131
+ };
132
+ }, _AccountsApiRemoteTransactionSource_getTimestampSeconds = function _AccountsApiRemoteTransactionSource_getTimestampSeconds(timestampMilliseconds) {
133
+ return Math.ceil(timestampMilliseconds / 1000);
134
+ };
135
+ //# sourceMappingURL=AccountsApiRemoteTransactionSource.cjs.map
@@ -0,0 +1 @@
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 { getAccountTransactionsAllPages } 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\nconst 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 const incomingTransactions = this.#filterTransactions(\n request,\n responseTransactions,\n );\n\n const normalizedTransactions = incomingTransactions.map((tx) =>\n this.#normalizeTransaction(address, tx),\n );\n\n log('Filtered and normalized transactions', normalizedTransactions);\n\n return normalizedTransactions;\n }\n\n async #getTransactions(request: RemoteTransactionSourceRequest) {\n log('Fetching transactions', request);\n\n const {\n address,\n chainIds: requestedChainIds,\n startTimestampByChainId,\n } = 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 startTimestamp = Math.min(...Object.values(startTimestampByChainId));\n const endTimestamp = this.#getTimestampSeconds(Date.now());\n\n return await getAccountTransactionsAllPages({\n address,\n chainIds,\n startTimestamp,\n endTimestamp,\n });\n }\n\n #filterTransactions(\n request: RemoteTransactionSourceRequest,\n responseTransactions: TransactionResponse[],\n ) {\n const { address, startTimestampByChainId, limit } = request;\n\n const incomingTransactions = responseTransactions.filter(\n (tx) =>\n tx.to === address || tx.valueTransfers.some((vt) => vt.to === address),\n );\n\n log(\n 'Fetched incoming transactions from accounts API',\n incomingTransactions,\n );\n\n const incomingTransactionsMatchingTimestamp = incomingTransactions.filter(\n (tx) => {\n const chainId = `0x${tx.chainId.toString(16)}` as Hex;\n const chainStartTimestamp = startTimestampByChainId[chainId];\n const timestamp = new Date(tx.timestamp).getTime();\n return timestamp >= chainStartTimestamp;\n },\n );\n\n return incomingTransactionsMatchingTimestamp.slice(0, limit);\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) => vt.to === address,\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 = address;\n\n return {\n blockNumber,\n chainId,\n hash,\n id,\n status,\n error:\n status === TransactionStatus.failed\n ? new Error('Transaction failed')\n : (undefined as unknown as TransactionError),\n time,\n txParams: {\n chainId,\n from,\n gas,\n gasPrice,\n gasUsed,\n nonce,\n to,\n value,\n },\n type,\n verifiedOnBlockchain,\n isTransfer,\n transferInformation: isTransfer\n ? {\n contractAddress,\n decimals,\n symbol,\n }\n : undefined,\n };\n }\n\n #getTimestampSeconds(timestampMilliseconds: number) {\n return Math.ceil(timestampMilliseconds / 1000);\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { Hex } from "@metamask/utils";
2
+ import type { RemoteTransactionSource, RemoteTransactionSourceRequest, TransactionMeta } from "../types.cjs";
3
+ /**
4
+ * A RemoteTransactionSource that fetches incoming transactions using the Accounts API.
5
+ */
6
+ export declare class AccountsApiRemoteTransactionSource implements RemoteTransactionSource {
7
+ #private;
8
+ getSupportedChains(): Hex[];
9
+ fetchTransactions(request: RemoteTransactionSourceRequest): Promise<TransactionMeta[]>;
10
+ }
11
+ //# sourceMappingURL=AccountsApiRemoteTransactionSource.d.cts.map
@@ -0,0 +1 @@
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;AAmBlB;;GAEG;AACH,qBAAa,kCACX,YAAW,uBAAuB;;IAElC,kBAAkB,IAAI,GAAG,EAAE;IAIrB,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAwJ9B"}
@@ -0,0 +1,11 @@
1
+ import type { Hex } from "@metamask/utils";
2
+ import type { RemoteTransactionSource, RemoteTransactionSourceRequest, TransactionMeta } from "../types.mjs";
3
+ /**
4
+ * A RemoteTransactionSource that fetches incoming transactions using the Accounts API.
5
+ */
6
+ export declare class AccountsApiRemoteTransactionSource implements RemoteTransactionSource {
7
+ #private;
8
+ getSupportedChains(): Hex[];
9
+ fetchTransactions(request: RemoteTransactionSourceRequest): Promise<TransactionMeta[]>;
10
+ }
11
+ //# sourceMappingURL=AccountsApiRemoteTransactionSource.d.mts.map
@@ -0,0 +1 @@
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;AAmBlB;;GAEG;AACH,qBAAa,kCACX,YAAW,uBAAuB;;IAElC,kBAAkB,IAAI,GAAG,EAAE;IAIrB,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAwJ9B"}
@@ -0,0 +1,135 @@
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_filterTransactions, _AccountsApiRemoteTransactionSource_normalizeTransaction, _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 { getAccountTransactionsAllPages } 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
+ 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
+ const incomingTransactions = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_filterTransactions).call(this, request, responseTransactions);
46
+ const normalizedTransactions = incomingTransactions.map((tx) => __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_normalizeTransaction).call(this, address, tx));
47
+ log('Filtered and normalized transactions', normalizedTransactions);
48
+ return normalizedTransactions;
49
+ }
50
+ }
51
+ _AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemoteTransactionSource_getTransactions = async function _AccountsApiRemoteTransactionSource_getTransactions(request) {
52
+ log('Fetching transactions', request);
53
+ const { address, chainIds: requestedChainIds, startTimestampByChainId, } = request;
54
+ const chainIds = requestedChainIds.filter((chainId) => SUPPORTED_CHAIN_IDS.includes(chainId));
55
+ const unsupportedChainIds = requestedChainIds.filter((chainId) => !chainIds.includes(chainId));
56
+ if (unsupportedChainIds.length) {
57
+ log('Ignoring unsupported chain IDs', unsupportedChainIds);
58
+ }
59
+ const startTimestamp = Math.min(...Object.values(startTimestampByChainId));
60
+ const endTimestamp = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTimestampSeconds).call(this, Date.now());
61
+ return await getAccountTransactionsAllPages({
62
+ address,
63
+ chainIds,
64
+ startTimestamp,
65
+ endTimestamp,
66
+ });
67
+ }, _AccountsApiRemoteTransactionSource_filterTransactions = function _AccountsApiRemoteTransactionSource_filterTransactions(request, responseTransactions) {
68
+ const { address, startTimestampByChainId, limit } = request;
69
+ const incomingTransactions = responseTransactions.filter((tx) => tx.to === address || tx.valueTransfers.some((vt) => vt.to === address));
70
+ log('Fetched incoming transactions from accounts API', incomingTransactions);
71
+ const incomingTransactionsMatchingTimestamp = incomingTransactions.filter((tx) => {
72
+ const chainId = `0x${tx.chainId.toString(16)}`;
73
+ const chainStartTimestamp = startTimestampByChainId[chainId];
74
+ const timestamp = new Date(tx.timestamp).getTime();
75
+ return timestamp >= chainStartTimestamp;
76
+ });
77
+ return incomingTransactionsMatchingTimestamp.slice(0, limit);
78
+ }, _AccountsApiRemoteTransactionSource_normalizeTransaction = function _AccountsApiRemoteTransactionSource_normalizeTransaction(address, responseTransaction) {
79
+ const blockNumber = String(responseTransaction.blockNumber);
80
+ const chainId = `0x${responseTransaction.chainId.toString(16)}`;
81
+ const { hash } = responseTransaction;
82
+ const time = new Date(responseTransaction.timestamp).getTime();
83
+ const id = random({ msecs: time });
84
+ const { from } = responseTransaction;
85
+ const gas = BNToHex(new BN(responseTransaction.gas));
86
+ const gasPrice = BNToHex(new BN(responseTransaction.gasPrice));
87
+ const gasUsed = BNToHex(new BN(responseTransaction.gasUsed));
88
+ const nonce = BNToHex(new BN(responseTransaction.nonce));
89
+ const type = TransactionType.incoming;
90
+ const verifiedOnBlockchain = false;
91
+ const status = responseTransaction.isError
92
+ ? TransactionStatus.failed
93
+ : TransactionStatus.confirmed;
94
+ const valueTransfer = responseTransaction.valueTransfers.find((vt) => vt.to === address);
95
+ const isTransfer = Boolean(valueTransfer);
96
+ const contractAddress = valueTransfer?.contractAddress;
97
+ const decimals = valueTransfer?.decimal;
98
+ const symbol = valueTransfer?.symbol;
99
+ const value = BNToHex(new BN(valueTransfer?.amount ?? responseTransaction.value));
100
+ const to = address;
101
+ return {
102
+ blockNumber,
103
+ chainId,
104
+ hash,
105
+ id,
106
+ status,
107
+ error: status === TransactionStatus.failed
108
+ ? new Error('Transaction failed')
109
+ : undefined,
110
+ time,
111
+ txParams: {
112
+ chainId,
113
+ from,
114
+ gas,
115
+ gasPrice,
116
+ gasUsed,
117
+ nonce,
118
+ to,
119
+ value,
120
+ },
121
+ type,
122
+ verifiedOnBlockchain,
123
+ isTransfer,
124
+ transferInformation: isTransfer
125
+ ? {
126
+ contractAddress,
127
+ decimals,
128
+ symbol,
129
+ }
130
+ : undefined,
131
+ };
132
+ }, _AccountsApiRemoteTransactionSource_getTimestampSeconds = function _AccountsApiRemoteTransactionSource_getTimestampSeconds(timestampMilliseconds) {
133
+ return Math.ceil(timestampMilliseconds / 1000);
134
+ };
135
+ //# sourceMappingURL=AccountsApiRemoteTransactionSource.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountsApiRemoteTransactionSource.mjs","sourceRoot":"","sources":["../../src/helpers/AccountsApiRemoteTransactionSource.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,mCAAmC;AAErD,OAAO,GAAE,cAAc;;AACvB,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,aAAa;AAMpC,OAAO,EAAE,8BAA8B,EAAE,gCAA4B;AACrE,OAAO,EAAE,SAAS,EAAE,yBAAqB;AACzC,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,sBAAkB;AAO3E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,qBAAiB;AAE9D,MAAM,mBAAmB,GAAU;IACjC,SAAS,CAAC,OAAO;IACjB,SAAS,CAAC,OAAO;IACjB,SAAS,CAAC,GAAG;IACb,SAAS,CAAC,aAAa;IACvB,SAAS,CAAC,IAAI;IACd,SAAS,CAAC,QAAQ;IAClB,SAAS,CAAC,QAAQ;IAClB,SAAS,CAAC,MAAM;CACjB,CAAC;AAEF,MAAM,GAAG,GAAG,kBAAkB,CAC5B,0BAA0B,EAC1B,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,kCAAkC;IAA/C;;IAiKA,CAAC;IA9JC,kBAAkB;QAChB,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,OAAuC;QAEvC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAE5B,MAAM,oBAAoB,GAAG,MAAM,uBAAA,IAAI,0GAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,CAAC;QAElE,MAAM,oBAAoB,GAAG,uBAAA,IAAI,6GAAoB,MAAxB,IAAI,EAC/B,OAAO,EACP,oBAAoB,CACrB,CAAC;QAEF,MAAM,sBAAsB,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAC7D,uBAAA,IAAI,+GAAsB,MAA1B,IAAI,EAAuB,OAAO,EAAE,EAAE,CAAC,CACxC,CAAC;QAEF,GAAG,CAAC,sCAAsC,EAAE,sBAAsB,CAAC,CAAC;QAEpE,OAAO,sBAAsB,CAAC;IAChC,CAAC;CAuIF;qHArIC,KAAK,8DAAkB,OAAuC;IAC5D,GAAG,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IAEtC,MAAM,EACJ,OAAO,EACP,QAAQ,EAAE,iBAAiB,EAC3B,uBAAuB,GACxB,GAAG,OAAO,CAAC;IAEZ,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CACpD,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,CACtC,CAAC;IAEF,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,MAAM,CAClD,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CACzC,CAAC;IAEF,IAAI,mBAAmB,CAAC,MAAM,EAAE;QAC9B,GAAG,CAAC,gCAAgC,EAAE,mBAAmB,CAAC,CAAC;KAC5D;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,uBAAA,IAAI,8GAAqB,MAAzB,IAAI,EAAsB,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAE3D,OAAO,MAAM,8BAA8B,CAAC;QAC1C,OAAO;QACP,QAAQ;QACR,cAAc;QACd,YAAY;KACb,CAAC,CAAC;AACL,CAAC,2HAGC,OAAuC,EACvC,oBAA2C;IAE3C,MAAM,EAAE,OAAO,EAAE,uBAAuB,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE5D,MAAM,oBAAoB,GAAG,oBAAoB,CAAC,MAAM,CACtD,CAAC,EAAE,EAAE,EAAE,CACL,EAAE,CAAC,EAAE,KAAK,OAAO,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CACzE,CAAC;IAEF,GAAG,CACD,iDAAiD,EACjD,oBAAoB,CACrB,CAAC;IAEF,MAAM,qCAAqC,GAAG,oBAAoB,CAAC,MAAM,CACvE,CAAC,EAAE,EAAE,EAAE;QACL,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAS,CAAC;QACtD,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QACnD,OAAO,SAAS,IAAI,mBAAmB,CAAC;IAC1C,CAAC,CACF,CAAC;IAEF,OAAO,qCAAqC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC/D,CAAC,+HAGC,OAAY,EACZ,mBAA8D;IAE9D,MAAM,WAAW,GAAG,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,KAAK,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAS,CAAC;IACvE,MAAM,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC;IACrC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC;IACtC,MAAM,oBAAoB,GAAG,KAAK,CAAC;IAEnC,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO;QACxC,CAAC,CAAC,iBAAiB,CAAC,MAAM;QAC1B,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC;IAEhC,MAAM,aAAa,GAAG,mBAAmB,CAAC,cAAc,CAAC,IAAI,CAC3D,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,OAAO,CAC1B,CAAC;IAEF,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,eAAe,GAAG,aAAa,EAAE,eAAyB,CAAC;IACjE,MAAM,QAAQ,GAAG,aAAa,EAAE,OAAiB,CAAC;IAClD,MAAM,MAAM,GAAG,aAAa,EAAE,MAAgB,CAAC;IAE/C,MAAM,KAAK,GAAG,OAAO,CACnB,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAC3D,CAAC;IAEF,MAAM,EAAE,GAAG,OAAO,CAAC;IAEnB,OAAO;QACL,WAAW;QACX,OAAO;QACP,IAAI;QACJ,EAAE;QACF,MAAM;QACN,KAAK,EACH,MAAM,KAAK,iBAAiB,CAAC,MAAM;YACjC,CAAC,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACjC,CAAC,CAAE,SAAyC;QAChD,IAAI;QACJ,QAAQ,EAAE;YACR,OAAO;YACP,IAAI;YACJ,GAAG;YACH,QAAQ;YACR,OAAO;YACP,KAAK;YACL,EAAE;YACF,KAAK;SACN;QACD,IAAI;QACJ,oBAAoB;QACpB,UAAU;QACV,mBAAmB,EAAE,UAAU;YAC7B,CAAC,CAAC;gBACE,eAAe;gBACf,QAAQ;gBACR,MAAM;aACP;YACH,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC,6HAEoB,qBAA6B;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;AACjD,CAAC","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 { getAccountTransactionsAllPages } 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\nconst 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 const incomingTransactions = this.#filterTransactions(\n request,\n responseTransactions,\n );\n\n const normalizedTransactions = incomingTransactions.map((tx) =>\n this.#normalizeTransaction(address, tx),\n );\n\n log('Filtered and normalized transactions', normalizedTransactions);\n\n return normalizedTransactions;\n }\n\n async #getTransactions(request: RemoteTransactionSourceRequest) {\n log('Fetching transactions', request);\n\n const {\n address,\n chainIds: requestedChainIds,\n startTimestampByChainId,\n } = 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 startTimestamp = Math.min(...Object.values(startTimestampByChainId));\n const endTimestamp = this.#getTimestampSeconds(Date.now());\n\n return await getAccountTransactionsAllPages({\n address,\n chainIds,\n startTimestamp,\n endTimestamp,\n });\n }\n\n #filterTransactions(\n request: RemoteTransactionSourceRequest,\n responseTransactions: TransactionResponse[],\n ) {\n const { address, startTimestampByChainId, limit } = request;\n\n const incomingTransactions = responseTransactions.filter(\n (tx) =>\n tx.to === address || tx.valueTransfers.some((vt) => vt.to === address),\n );\n\n log(\n 'Fetched incoming transactions from accounts API',\n incomingTransactions,\n );\n\n const incomingTransactionsMatchingTimestamp = incomingTransactions.filter(\n (tx) => {\n const chainId = `0x${tx.chainId.toString(16)}` as Hex;\n const chainStartTimestamp = startTimestampByChainId[chainId];\n const timestamp = new Date(tx.timestamp).getTime();\n return timestamp >= chainStartTimestamp;\n },\n );\n\n return incomingTransactionsMatchingTimestamp.slice(0, limit);\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) => vt.to === address,\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 = address;\n\n return {\n blockNumber,\n chainId,\n hash,\n id,\n status,\n error:\n status === TransactionStatus.failed\n ? new Error('Transaction failed')\n : (undefined as unknown as TransactionError),\n time,\n txParams: {\n chainId,\n from,\n gas,\n gasPrice,\n gasUsed,\n nonce,\n to,\n value,\n },\n type,\n verifiedOnBlockchain,\n isTransfer,\n transferInformation: isTransfer\n ? {\n contractAddress,\n decimals,\n symbol,\n }\n : undefined,\n };\n }\n\n #getTimestampSeconds(timestampMilliseconds: number) {\n return Math.ceil(timestampMilliseconds / 1000);\n }\n}\n"]}