@metamask/transaction-controller 23.1.0 → 25.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/CHANGELOG.md +134 -1
  2. package/dist/TransactionController.js +38 -1816
  3. package/dist/TransactionController.js.map +1 -1
  4. package/dist/TransactionController.mjs +39 -0
  5. package/dist/TransactionController.mjs.map +1 -0
  6. package/dist/chunk-2K7J3EY3.mjs +170 -0
  7. package/dist/chunk-2K7J3EY3.mjs.map +1 -0
  8. package/dist/chunk-5XBULBP2.js +399 -0
  9. package/dist/chunk-5XBULBP2.js.map +1 -0
  10. package/dist/chunk-6MYNWYJK.mjs +158 -0
  11. package/dist/chunk-6MYNWYJK.mjs.map +1 -0
  12. package/dist/chunk-7APMBUKB.js +158 -0
  13. package/dist/chunk-7APMBUKB.js.map +1 -0
  14. package/dist/chunk-7LXE4KHV.js +40 -0
  15. package/dist/chunk-7LXE4KHV.js.map +1 -0
  16. package/dist/chunk-7MZ57ILQ.mjs +62 -0
  17. package/dist/chunk-7MZ57ILQ.mjs.map +1 -0
  18. package/dist/chunk-BJEESIBE.js +2313 -0
  19. package/dist/chunk-BJEESIBE.js.map +1 -0
  20. package/dist/chunk-C67QD5PV.mjs +320 -0
  21. package/dist/chunk-C67QD5PV.mjs.map +1 -0
  22. package/dist/chunk-DE3MZYVY.mjs +2313 -0
  23. package/dist/chunk-DE3MZYVY.mjs.map +1 -0
  24. package/dist/chunk-DEKM6PVG.mjs +46 -0
  25. package/dist/chunk-DEKM6PVG.mjs.map +1 -0
  26. package/dist/chunk-DQP6X25N.mjs +208 -0
  27. package/dist/chunk-DQP6X25N.mjs.map +1 -0
  28. package/dist/chunk-DTDTOMTB.js +238 -0
  29. package/dist/chunk-DTDTOMTB.js.map +1 -0
  30. package/dist/chunk-DTEDYRTL.js +242 -0
  31. package/dist/chunk-DTEDYRTL.js.map +1 -0
  32. package/dist/chunk-EQ3RRHB7.mjs +211 -0
  33. package/dist/chunk-EQ3RRHB7.mjs.map +1 -0
  34. package/dist/chunk-FDJPXQTF.js +46 -0
  35. package/dist/chunk-FDJPXQTF.js.map +1 -0
  36. package/dist/chunk-FRKQ3Z2L.mjs +40 -0
  37. package/dist/chunk-FRKQ3Z2L.mjs.map +1 -0
  38. package/dist/chunk-FS7FRO7B.mjs +90 -0
  39. package/dist/chunk-FS7FRO7B.mjs.map +1 -0
  40. package/dist/chunk-GKTIFXPN.js +170 -0
  41. package/dist/chunk-GKTIFXPN.js.map +1 -0
  42. package/dist/chunk-H4M66BA3.js +62 -0
  43. package/dist/chunk-H4M66BA3.js.map +1 -0
  44. package/dist/chunk-HPNXIKFY.js +76 -0
  45. package/dist/chunk-HPNXIKFY.js.map +1 -0
  46. package/dist/chunk-HS277C77.js +75 -0
  47. package/dist/chunk-HS277C77.js.map +1 -0
  48. package/dist/chunk-I5YZ7QUK.js +121 -0
  49. package/dist/chunk-I5YZ7QUK.js.map +1 -0
  50. package/dist/chunk-IC233ZQS.js +211 -0
  51. package/dist/chunk-IC233ZQS.js.map +1 -0
  52. package/dist/chunk-IUBAETUH.js +137 -0
  53. package/dist/chunk-IUBAETUH.js.map +1 -0
  54. package/dist/chunk-J56A7UCK.mjs +123 -0
  55. package/dist/chunk-J56A7UCK.mjs.map +1 -0
  56. package/dist/chunk-JR6HDRNV.mjs +242 -0
  57. package/dist/chunk-JR6HDRNV.mjs.map +1 -0
  58. package/dist/chunk-JRBREX22.mjs +75 -0
  59. package/dist/chunk-JRBREX22.mjs.map +1 -0
  60. package/dist/chunk-JRQHIBG5.mjs +399 -0
  61. package/dist/chunk-JRQHIBG5.mjs.map +1 -0
  62. package/dist/chunk-LM4NUNMT.mjs +76 -0
  63. package/dist/chunk-LM4NUNMT.mjs.map +1 -0
  64. package/dist/chunk-M7455RU7.js +320 -0
  65. package/dist/chunk-M7455RU7.js.map +1 -0
  66. package/dist/chunk-MHM5LRRF.mjs +122 -0
  67. package/dist/chunk-MHM5LRRF.mjs.map +1 -0
  68. package/dist/chunk-NHRBO3LU.mjs +50 -0
  69. package/dist/chunk-NHRBO3LU.mjs.map +1 -0
  70. package/dist/chunk-NM6OYEPP.mjs +182 -0
  71. package/dist/chunk-NM6OYEPP.mjs.map +1 -0
  72. package/dist/chunk-NUOBUW7C.js +85 -0
  73. package/dist/chunk-NUOBUW7C.js.map +1 -0
  74. package/dist/chunk-QP75SWIQ.js +53 -0
  75. package/dist/chunk-QP75SWIQ.js.map +1 -0
  76. package/dist/chunk-RI6MVJJN.js +122 -0
  77. package/dist/chunk-RI6MVJJN.js.map +1 -0
  78. package/dist/chunk-S6VGOPUY.js +14 -0
  79. package/dist/chunk-S6VGOPUY.js.map +1 -0
  80. package/dist/chunk-UGFBA4GV.js +123 -0
  81. package/dist/chunk-UGFBA4GV.js.map +1 -0
  82. package/dist/chunk-UKYY2RVS.mjs +137 -0
  83. package/dist/chunk-UKYY2RVS.mjs.map +1 -0
  84. package/dist/chunk-UM4ORJ5B.mjs +121 -0
  85. package/dist/chunk-UM4ORJ5B.mjs.map +1 -0
  86. package/dist/chunk-UQQWZT6C.mjs +14 -0
  87. package/dist/chunk-UQQWZT6C.mjs.map +1 -0
  88. package/dist/chunk-VH47Q6TS.js +182 -0
  89. package/dist/chunk-VH47Q6TS.js.map +1 -0
  90. package/dist/chunk-XGRAHX6T.mjs +53 -0
  91. package/dist/chunk-XGRAHX6T.mjs.map +1 -0
  92. package/dist/chunk-XUI43LEZ.mjs +30 -0
  93. package/dist/chunk-XUI43LEZ.mjs.map +1 -0
  94. package/dist/chunk-Y734U4V6.mjs +85 -0
  95. package/dist/chunk-Y734U4V6.mjs.map +1 -0
  96. package/dist/chunk-Y7ENNK7L.mjs +238 -0
  97. package/dist/chunk-Y7ENNK7L.mjs.map +1 -0
  98. package/dist/chunk-Z4BLTVTB.js +30 -0
  99. package/dist/chunk-Z4BLTVTB.js.map +1 -0
  100. package/dist/chunk-ZCQRDZ36.js +208 -0
  101. package/dist/chunk-ZCQRDZ36.js.map +1 -0
  102. package/dist/chunk-ZJLZSFOZ.js +90 -0
  103. package/dist/chunk-ZJLZSFOZ.js.map +1 -0
  104. package/dist/chunk-ZNZEJDOE.js +50 -0
  105. package/dist/chunk-ZNZEJDOE.js.map +1 -0
  106. package/dist/constants.js +15 -110
  107. package/dist/constants.js.map +1 -1
  108. package/dist/constants.mjs +16 -0
  109. package/dist/constants.mjs.map +1 -0
  110. package/dist/gas-flows/DefaultGasFeeFlow.js +14 -77
  111. package/dist/gas-flows/DefaultGasFeeFlow.js.map +1 -1
  112. package/dist/gas-flows/DefaultGasFeeFlow.mjs +15 -0
  113. package/dist/gas-flows/DefaultGasFeeFlow.mjs.map +1 -0
  114. package/dist/gas-flows/LineaGasFeeFlow.js +15 -110
  115. package/dist/gas-flows/LineaGasFeeFlow.js.map +1 -1
  116. package/dist/gas-flows/LineaGasFeeFlow.mjs +16 -0
  117. package/dist/gas-flows/LineaGasFeeFlow.mjs.map +1 -0
  118. package/dist/helpers/EtherscanRemoteTransactionSource.js +11 -145
  119. package/dist/helpers/EtherscanRemoteTransactionSource.js.map +1 -1
  120. package/dist/helpers/EtherscanRemoteTransactionSource.mjs +12 -0
  121. package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +1 -0
  122. package/dist/helpers/GasFeePoller.js +10 -143
  123. package/dist/helpers/GasFeePoller.js.map +1 -1
  124. package/dist/helpers/GasFeePoller.mjs +11 -0
  125. package/dist/helpers/GasFeePoller.mjs.map +1 -0
  126. package/dist/helpers/IncomingTransactionHelper.js +8 -205
  127. package/dist/helpers/IncomingTransactionHelper.js.map +1 -1
  128. package/dist/helpers/IncomingTransactionHelper.mjs +9 -0
  129. package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -0
  130. package/dist/helpers/MultichainTrackingHelper.js +12 -291
  131. package/dist/helpers/MultichainTrackingHelper.js.map +1 -1
  132. package/dist/helpers/MultichainTrackingHelper.mjs +13 -0
  133. package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -0
  134. package/dist/helpers/PendingTransactionTracker.js +9 -360
  135. package/dist/helpers/PendingTransactionTracker.js.map +1 -1
  136. package/dist/helpers/PendingTransactionTracker.mjs +10 -0
  137. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -0
  138. package/dist/index.js +56 -25
  139. package/dist/index.js.map +1 -1
  140. package/dist/index.mjs +57 -0
  141. package/dist/index.mjs.map +1 -0
  142. package/dist/logger.js +11 -8
  143. package/dist/logger.js.map +1 -1
  144. package/dist/logger.mjs +12 -0
  145. package/dist/logger.mjs.map +1 -0
  146. package/dist/tsconfig.build.tsbuildinfo +1 -0
  147. package/dist/{TransactionController.d.ts → types/TransactionController.d.ts} +235 -46
  148. package/dist/types/TransactionController.d.ts.map +1 -0
  149. package/dist/{constants.d.ts → types/constants.d.ts} +8 -3
  150. package/dist/types/constants.d.ts.map +1 -0
  151. package/dist/types/gas-flows/DefaultGasFeeFlow.d.ts.map +1 -0
  152. package/dist/types/gas-flows/LineaGasFeeFlow.d.ts.map +1 -0
  153. package/dist/types/helpers/EtherscanRemoteTransactionSource.d.ts.map +1 -0
  154. package/dist/types/helpers/GasFeePoller.d.ts.map +1 -0
  155. package/dist/types/helpers/IncomingTransactionHelper.d.ts.map +1 -0
  156. package/dist/types/helpers/MultichainTrackingHelper.d.ts.map +1 -0
  157. package/dist/types/helpers/PendingTransactionTracker.d.ts.map +1 -0
  158. package/dist/types/index.d.ts +9 -0
  159. package/dist/types/index.d.ts.map +1 -0
  160. package/dist/types/logger.d.ts.map +1 -0
  161. package/dist/{types.d.ts → types/types.d.ts} +63 -65
  162. package/dist/types/types.d.ts.map +1 -0
  163. package/dist/types/utils/etherscan.d.ts.map +1 -0
  164. package/dist/types/utils/external-transactions.d.ts.map +1 -0
  165. package/dist/types/utils/gas-fees.d.ts.map +1 -0
  166. package/dist/types/utils/gas-flow.d.ts.map +1 -0
  167. package/dist/types/utils/gas.d.ts.map +1 -0
  168. package/dist/types/utils/history.d.ts +20 -0
  169. package/dist/types/utils/history.d.ts.map +1 -0
  170. package/dist/types/utils/nonce.d.ts.map +1 -0
  171. package/dist/types/utils/simulation-api.d.ts +99 -0
  172. package/dist/types/utils/simulation-api.d.ts.map +1 -0
  173. package/dist/types/utils/simulation.d.ts +21 -0
  174. package/dist/types/utils/simulation.d.ts.map +1 -0
  175. package/dist/{utils → types/utils}/swaps.d.ts +8 -5
  176. package/dist/types/utils/swaps.d.ts.map +1 -0
  177. package/dist/types/utils/transaction-type.d.ts.map +1 -0
  178. package/dist/{utils → types/utils}/utils.d.ts +9 -1
  179. package/dist/types/utils/utils.d.ts.map +1 -0
  180. package/dist/types/utils/validation.d.ts.map +1 -0
  181. package/dist/types.js +19 -170
  182. package/dist/types.js.map +1 -1
  183. package/dist/types.mjs +20 -0
  184. package/dist/types.mjs.map +1 -0
  185. package/dist/utils/etherscan.js +13 -118
  186. package/dist/utils/etherscan.js.map +1 -1
  187. package/dist/utils/etherscan.mjs +14 -0
  188. package/dist/utils/etherscan.mjs.map +1 -0
  189. package/dist/utils/external-transactions.js +8 -35
  190. package/dist/utils/external-transactions.js.map +1 -1
  191. package/dist/utils/external-transactions.mjs +9 -0
  192. package/dist/utils/external-transactions.mjs.map +1 -0
  193. package/dist/utils/gas-fees.js +15 -200
  194. package/dist/utils/gas-fees.js.map +1 -1
  195. package/dist/utils/gas-fees.mjs +16 -0
  196. package/dist/utils/gas-fees.mjs.map +1 -0
  197. package/dist/utils/gas-flow.js +10 -52
  198. package/dist/utils/gas-flow.js.map +1 -1
  199. package/dist/utils/gas-flow.mjs +11 -0
  200. package/dist/utils/gas-flow.mjs.map +1 -0
  201. package/dist/utils/gas.js +19 -133
  202. package/dist/utils/gas.js.map +1 -1
  203. package/dist/utils/gas.mjs +20 -0
  204. package/dist/utils/gas.mjs.map +1 -0
  205. package/dist/utils/history.js +9 -83
  206. package/dist/utils/history.js.map +1 -1
  207. package/dist/utils/history.mjs +10 -0
  208. package/dist/utils/history.mjs.map +1 -0
  209. package/dist/utils/nonce.js +10 -76
  210. package/dist/utils/nonce.js.map +1 -1
  211. package/dist/utils/nonce.mjs +11 -0
  212. package/dist/utils/nonce.mjs.map +1 -0
  213. package/dist/utils/simulation-api.js +10 -0
  214. package/dist/utils/simulation-api.js.map +1 -0
  215. package/dist/utils/simulation-api.mjs +10 -0
  216. package/dist/utils/simulation-api.mjs.map +1 -0
  217. package/dist/utils/simulation.js +12 -0
  218. package/dist/utils/simulation.js.map +1 -0
  219. package/dist/utils/simulation.mjs +12 -0
  220. package/dist/utils/simulation.mjs.map +1 -0
  221. package/dist/utils/swaps.js +23 -256
  222. package/dist/utils/swaps.js.map +1 -1
  223. package/dist/utils/swaps.mjs +24 -0
  224. package/dist/utils/swaps.mjs.map +1 -0
  225. package/dist/utils/transaction-type.js +10 -120
  226. package/dist/utils/transaction-type.js.map +1 -1
  227. package/dist/utils/transaction-type.mjs +11 -0
  228. package/dist/utils/transaction-type.mjs.map +1 -0
  229. package/dist/utils/utils.js +32 -146
  230. package/dist/utils/utils.js.map +1 -1
  231. package/dist/utils/utils.mjs +33 -0
  232. package/dist/utils/utils.mjs.map +1 -0
  233. package/dist/utils/validation.js +11 -258
  234. package/dist/utils/validation.js.map +1 -1
  235. package/dist/utils/validation.mjs +12 -0
  236. package/dist/utils/validation.mjs.map +1 -0
  237. package/package.json +21 -9
  238. package/dist/TransactionController.d.ts.map +0 -1
  239. package/dist/constants.d.ts.map +0 -1
  240. package/dist/gas-flows/DefaultGasFeeFlow.d.ts.map +0 -1
  241. package/dist/gas-flows/LineaGasFeeFlow.d.ts.map +0 -1
  242. package/dist/helpers/EtherscanRemoteTransactionSource.d.ts.map +0 -1
  243. package/dist/helpers/GasFeePoller.d.ts.map +0 -1
  244. package/dist/helpers/IncomingTransactionHelper.d.ts.map +0 -1
  245. package/dist/helpers/MultichainTrackingHelper.d.ts.map +0 -1
  246. package/dist/helpers/PendingTransactionTracker.d.ts.map +0 -1
  247. package/dist/index.d.ts +0 -7
  248. package/dist/index.d.ts.map +0 -1
  249. package/dist/logger.d.ts.map +0 -1
  250. package/dist/types.d.ts.map +0 -1
  251. package/dist/utils/etherscan.d.ts.map +0 -1
  252. package/dist/utils/external-transactions.d.ts.map +0 -1
  253. package/dist/utils/gas-fees.d.ts.map +0 -1
  254. package/dist/utils/gas-flow.d.ts.map +0 -1
  255. package/dist/utils/gas.d.ts.map +0 -1
  256. package/dist/utils/history.d.ts +0 -15
  257. package/dist/utils/history.d.ts.map +0 -1
  258. package/dist/utils/nonce.d.ts.map +0 -1
  259. package/dist/utils/swaps.d.ts.map +0 -1
  260. package/dist/utils/transaction-type.d.ts.map +0 -1
  261. package/dist/utils/utils.d.ts.map +0 -1
  262. package/dist/utils/validation.d.ts.map +0 -1
  263. /package/dist/{gas-flows → types/gas-flows}/DefaultGasFeeFlow.d.ts +0 -0
  264. /package/dist/{gas-flows → types/gas-flows}/LineaGasFeeFlow.d.ts +0 -0
  265. /package/dist/{helpers → types/helpers}/EtherscanRemoteTransactionSource.d.ts +0 -0
  266. /package/dist/{helpers → types/helpers}/GasFeePoller.d.ts +0 -0
  267. /package/dist/{helpers → types/helpers}/IncomingTransactionHelper.d.ts +0 -0
  268. /package/dist/{helpers → types/helpers}/MultichainTrackingHelper.d.ts +0 -0
  269. /package/dist/{helpers → types/helpers}/PendingTransactionTracker.d.ts +0 -0
  270. /package/dist/{logger.d.ts → types/logger.d.ts} +0 -0
  271. /package/dist/{utils → types/utils}/etherscan.d.ts +0 -0
  272. /package/dist/{utils → types/utils}/external-transactions.d.ts +0 -0
  273. /package/dist/{utils → types/utils}/gas-fees.d.ts +0 -0
  274. /package/dist/{utils → types/utils}/gas-flow.d.ts +0 -0
  275. /package/dist/{utils → types/utils}/gas.d.ts +0 -0
  276. /package/dist/{utils → types/utils}/nonce.d.ts +0 -0
  277. /package/dist/{utils → types/utils}/transaction-type.d.ts +0 -0
  278. /package/dist/{utils → types/utils}/validation.d.ts +0 -0
@@ -0,0 +1,85 @@
1
+ import {
2
+ ETHERSCAN_SUPPORTED_NETWORKS
3
+ } from "./chunk-MHM5LRRF.mjs";
4
+ import {
5
+ incomingTransactionsLogger
6
+ } from "./chunk-UQQWZT6C.mjs";
7
+
8
+ // src/utils/etherscan.ts
9
+ import { handleFetch } from "@metamask/controller-utils";
10
+ async function fetchEtherscanTransactions({
11
+ address,
12
+ chainId,
13
+ fromBlock,
14
+ limit
15
+ }) {
16
+ return await fetchTransactions("txlist", {
17
+ address,
18
+ chainId,
19
+ fromBlock,
20
+ limit
21
+ });
22
+ }
23
+ async function fetchEtherscanTokenTransactions({
24
+ address,
25
+ chainId,
26
+ fromBlock,
27
+ limit
28
+ }) {
29
+ return await fetchTransactions("tokentx", {
30
+ address,
31
+ chainId,
32
+ fromBlock,
33
+ limit
34
+ });
35
+ }
36
+ async function fetchTransactions(action, {
37
+ address,
38
+ chainId,
39
+ fromBlock,
40
+ limit
41
+ }) {
42
+ const urlParams = {
43
+ module: "account",
44
+ address,
45
+ startBlock: fromBlock?.toString(),
46
+ offset: limit?.toString(),
47
+ sort: "desc"
48
+ };
49
+ const etherscanTxUrl = getEtherscanApiUrl(chainId, {
50
+ ...urlParams,
51
+ action
52
+ });
53
+ incomingTransactionsLogger("Sending Etherscan request", etherscanTxUrl);
54
+ const response = await handleFetch(
55
+ etherscanTxUrl
56
+ );
57
+ return response;
58
+ }
59
+ function getEtherscanApiUrl(chainId, urlParams) {
60
+ const apiUrl = getEtherscanApiHost(chainId);
61
+ let url = `${apiUrl}/api?`;
62
+ for (const paramKey of Object.keys(urlParams)) {
63
+ const value = urlParams[paramKey];
64
+ if (!value) {
65
+ continue;
66
+ }
67
+ url += `${paramKey}=${value}&`;
68
+ }
69
+ url += "tag=latest&page=1";
70
+ return url;
71
+ }
72
+ function getEtherscanApiHost(chainId) {
73
+ const networkInfo = ETHERSCAN_SUPPORTED_NETWORKS[chainId];
74
+ if (!networkInfo) {
75
+ throw new Error(`Etherscan does not support chain with ID: ${chainId}`);
76
+ }
77
+ return `https://${networkInfo.subdomain}.${networkInfo.domain}`;
78
+ }
79
+
80
+ export {
81
+ fetchEtherscanTransactions,
82
+ fetchEtherscanTokenTransactions,
83
+ getEtherscanApiHost
84
+ };
85
+ //# sourceMappingURL=chunk-Y734U4V6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/etherscan.ts"],"sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from '../constants';\nimport { incomingTransactionsLogger as log } from '../logger';\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionMetaBase {\n blockNumber: string;\n blockHash: string;\n confirmations: string;\n contractAddress: string;\n cumulativeGasUsed: string;\n from: string;\n gas: string;\n gasPrice: string;\n gasUsed: string;\n hash: string;\n nonce: string;\n timeStamp: string;\n to: string;\n transactionIndex: string;\n value: string;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface EtherscanTransactionMeta extends EtherscanTransactionMetaBase {\n functionName: string;\n input: string;\n isError: string;\n methodId: string;\n 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 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 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.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 chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTransactionMeta>\n> {\n return await fetchTransactions('txlist', {\n address,\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.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 chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTokenTransactionMeta>\n> {\n return await fetchTransactions('tokentx', {\n address,\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.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<T extends EtherscanTransactionMetaBase>(\n action: string,\n {\n address,\n chainId,\n fromBlock,\n limit,\n }: {\n address: string;\n chainId: Hex;\n fromBlock?: number;\n limit?: number;\n },\n): Promise<EtherscanTransactionResponse<T>> {\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 });\n\n log('Sending Etherscan request', etherscanTxUrl);\n\n const response = (await handleFetch(\n etherscanTxUrl,\n )) as EtherscanTransactionResponse<T>;\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 return `https://${networkInfo.subdomain}.${networkInfo.domain}`;\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,mBAAmB;AA+E5B,eAAsB,2BAA2B;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEE;AACA,SAAO,MAAM,kBAAkB,UAAU;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAYA,eAAsB,gCAAgC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEE;AACA,SAAO,MAAM,kBAAkB,WAAW;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAaA,eAAe,kBACb,QACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAM0C;AAC1C,QAAM,YAAY;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,IACA,YAAY,WAAW,SAAS;AAAA,IAChC,QAAQ,OAAO,SAAS;AAAA,IACxB,MAAM;AAAA,EACR;AAEA,QAAM,iBAAiB,mBAAmB,SAAS;AAAA,IACjD,GAAG;AAAA,IACH;AAAA,EACF,CAAC;AAED,6BAAI,6BAA6B,cAAc;AAE/C,QAAM,WAAY,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AASA,SAAS,mBACP,SACA,WACQ;AACR,QAAM,SAAS,oBAAoB,OAAO;AAC1C,MAAI,MAAM,GAAG,MAAM;AAEnB,aAAW,YAAY,OAAO,KAAK,SAAS,GAAG;AAC7C,UAAM,QAAQ,UAAU,QAAQ;AAEhC,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,WAAO,GAAG,QAAQ,IAAI,KAAK;AAAA,EAC7B;AAEA,SAAO;AAEP,SAAO;AACT;AAQO,SAAS,oBAAoB,SAAc;AAEhD,QAAM,cAAc,6BAA6B,OAAO;AAExD,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,6CAA6C,OAAO,EAAE;AAAA,EACxE;AAEA,SAAO,WAAW,YAAY,SAAS,IAAI,YAAY,MAAM;AAC/D;","names":[]}
@@ -0,0 +1,238 @@
1
+ import {
2
+ incomingTransactionsLogger
3
+ } from "./chunk-UQQWZT6C.mjs";
4
+ import {
5
+ __privateAdd,
6
+ __privateGet,
7
+ __privateMethod,
8
+ __privateSet
9
+ } from "./chunk-XUI43LEZ.mjs";
10
+
11
+ // src/helpers/IncomingTransactionHelper.ts
12
+ import { Mutex } from "async-mutex";
13
+ import EventEmitter from "events";
14
+ var RECENT_HISTORY_BLOCK_RANGE = 10;
15
+ var UPDATE_CHECKS = [
16
+ (txMeta) => txMeta.status,
17
+ (txMeta) => txMeta.txParams.gasUsed
18
+ ];
19
+ var _blockTracker, _getCurrentAccount, _getLastFetchedBlockNumbers, _getLocalTransactions, _getChainId, _isEnabled, _isRunning, _mutex, _onLatestBlock, _queryEntireHistory, _remoteTransactionSource, _transactionLimit, _updateTransactions, _sortTransactionsByTime, sortTransactionsByTime_fn, _getNewTransactions, getNewTransactions_fn, _getUpdatedTransactions, getUpdatedTransactions_fn, _isTransactionOutdated, isTransactionOutdated_fn, _getLastFetchedBlockNumberDec, getLastFetchedBlockNumberDec_fn, _getFromBlock, getFromBlock_fn, _updateLastFetchedBlockNumber, updateLastFetchedBlockNumber_fn, _getBlockNumberKey, getBlockNumberKey_fn, _canStart, canStart_fn;
20
+ var IncomingTransactionHelper = class {
21
+ constructor({
22
+ blockTracker,
23
+ getCurrentAccount,
24
+ getLastFetchedBlockNumbers,
25
+ getLocalTransactions,
26
+ getChainId,
27
+ isEnabled,
28
+ queryEntireHistory,
29
+ remoteTransactionSource,
30
+ transactionLimit,
31
+ updateTransactions
32
+ }) {
33
+ __privateAdd(this, _sortTransactionsByTime);
34
+ __privateAdd(this, _getNewTransactions);
35
+ __privateAdd(this, _getUpdatedTransactions);
36
+ __privateAdd(this, _isTransactionOutdated);
37
+ __privateAdd(this, _getLastFetchedBlockNumberDec);
38
+ __privateAdd(this, _getFromBlock);
39
+ __privateAdd(this, _updateLastFetchedBlockNumber);
40
+ __privateAdd(this, _getBlockNumberKey);
41
+ __privateAdd(this, _canStart);
42
+ __privateAdd(this, _blockTracker, void 0);
43
+ __privateAdd(this, _getCurrentAccount, void 0);
44
+ __privateAdd(this, _getLastFetchedBlockNumbers, void 0);
45
+ __privateAdd(this, _getLocalTransactions, void 0);
46
+ __privateAdd(this, _getChainId, void 0);
47
+ __privateAdd(this, _isEnabled, void 0);
48
+ __privateAdd(this, _isRunning, void 0);
49
+ __privateAdd(this, _mutex, new Mutex());
50
+ __privateAdd(this, _onLatestBlock, void 0);
51
+ __privateAdd(this, _queryEntireHistory, void 0);
52
+ __privateAdd(this, _remoteTransactionSource, void 0);
53
+ __privateAdd(this, _transactionLimit, void 0);
54
+ __privateAdd(this, _updateTransactions, void 0);
55
+ this.hub = new EventEmitter();
56
+ __privateSet(this, _blockTracker, blockTracker);
57
+ __privateSet(this, _getCurrentAccount, getCurrentAccount);
58
+ __privateSet(this, _getLastFetchedBlockNumbers, getLastFetchedBlockNumbers);
59
+ __privateSet(this, _getLocalTransactions, getLocalTransactions || (() => []));
60
+ __privateSet(this, _getChainId, getChainId);
61
+ __privateSet(this, _isEnabled, isEnabled ?? (() => true));
62
+ __privateSet(this, _isRunning, false);
63
+ __privateSet(this, _queryEntireHistory, queryEntireHistory ?? true);
64
+ __privateSet(this, _remoteTransactionSource, remoteTransactionSource);
65
+ __privateSet(this, _transactionLimit, transactionLimit);
66
+ __privateSet(this, _updateTransactions, updateTransactions ?? false);
67
+ __privateSet(this, _onLatestBlock, async (blockNumberHex) => {
68
+ try {
69
+ await this.update(blockNumberHex);
70
+ } catch (error) {
71
+ console.error("Error while checking incoming transactions", error);
72
+ }
73
+ });
74
+ }
75
+ start() {
76
+ if (__privateGet(this, _isRunning)) {
77
+ return;
78
+ }
79
+ if (!__privateMethod(this, _canStart, canStart_fn).call(this)) {
80
+ return;
81
+ }
82
+ __privateGet(this, _blockTracker).addListener("latest", __privateGet(this, _onLatestBlock));
83
+ __privateSet(this, _isRunning, true);
84
+ }
85
+ stop() {
86
+ __privateGet(this, _blockTracker).removeListener("latest", __privateGet(this, _onLatestBlock));
87
+ __privateSet(this, _isRunning, false);
88
+ }
89
+ async update(latestBlockNumberHex) {
90
+ const releaseLock = await __privateGet(this, _mutex).acquire();
91
+ incomingTransactionsLogger("Checking for incoming transactions");
92
+ try {
93
+ if (!__privateMethod(this, _canStart, canStart_fn).call(this)) {
94
+ return;
95
+ }
96
+ const latestBlockNumber = parseInt(
97
+ latestBlockNumberHex || await __privateGet(this, _blockTracker).getLatestBlock(),
98
+ 16
99
+ );
100
+ const additionalLastFetchedKeys = __privateGet(this, _remoteTransactionSource).getLastBlockVariations?.() ?? [];
101
+ const fromBlock = __privateMethod(this, _getFromBlock, getFromBlock_fn).call(this, latestBlockNumber);
102
+ const address = __privateGet(this, _getCurrentAccount).call(this);
103
+ const currentChainId = __privateGet(this, _getChainId).call(this);
104
+ let remoteTransactions = [];
105
+ try {
106
+ remoteTransactions = await __privateGet(this, _remoteTransactionSource).fetchTransactions({
107
+ address,
108
+ currentChainId,
109
+ fromBlock,
110
+ limit: __privateGet(this, _transactionLimit)
111
+ });
112
+ } catch (error) {
113
+ incomingTransactionsLogger("Error while fetching remote transactions", error);
114
+ return;
115
+ }
116
+ if (!__privateGet(this, _updateTransactions)) {
117
+ remoteTransactions = remoteTransactions.filter(
118
+ (tx) => tx.txParams.to?.toLowerCase() === address.toLowerCase()
119
+ );
120
+ }
121
+ const localTransactions = !__privateGet(this, _updateTransactions) ? [] : __privateGet(this, _getLocalTransactions).call(this);
122
+ const newTransactions = __privateMethod(this, _getNewTransactions, getNewTransactions_fn).call(this, remoteTransactions, localTransactions);
123
+ const updatedTransactions = __privateMethod(this, _getUpdatedTransactions, getUpdatedTransactions_fn).call(this, remoteTransactions, localTransactions);
124
+ if (newTransactions.length > 0 || updatedTransactions.length > 0) {
125
+ __privateMethod(this, _sortTransactionsByTime, sortTransactionsByTime_fn).call(this, newTransactions);
126
+ __privateMethod(this, _sortTransactionsByTime, sortTransactionsByTime_fn).call(this, updatedTransactions);
127
+ incomingTransactionsLogger("Found incoming transactions", {
128
+ new: newTransactions,
129
+ updated: updatedTransactions
130
+ });
131
+ this.hub.emit("transactions", {
132
+ added: newTransactions,
133
+ updated: updatedTransactions
134
+ });
135
+ }
136
+ __privateMethod(this, _updateLastFetchedBlockNumber, updateLastFetchedBlockNumber_fn).call(this, remoteTransactions, additionalLastFetchedKeys);
137
+ } finally {
138
+ releaseLock();
139
+ }
140
+ }
141
+ };
142
+ _blockTracker = new WeakMap();
143
+ _getCurrentAccount = new WeakMap();
144
+ _getLastFetchedBlockNumbers = new WeakMap();
145
+ _getLocalTransactions = new WeakMap();
146
+ _getChainId = new WeakMap();
147
+ _isEnabled = new WeakMap();
148
+ _isRunning = new WeakMap();
149
+ _mutex = new WeakMap();
150
+ _onLatestBlock = new WeakMap();
151
+ _queryEntireHistory = new WeakMap();
152
+ _remoteTransactionSource = new WeakMap();
153
+ _transactionLimit = new WeakMap();
154
+ _updateTransactions = new WeakMap();
155
+ _sortTransactionsByTime = new WeakSet();
156
+ sortTransactionsByTime_fn = function(transactions) {
157
+ transactions.sort((a, b) => a.time < b.time ? -1 : 1);
158
+ };
159
+ _getNewTransactions = new WeakSet();
160
+ getNewTransactions_fn = function(remoteTxs, localTxs) {
161
+ return remoteTxs.filter(
162
+ (tx) => !localTxs.some(({ hash }) => hash === tx.hash)
163
+ );
164
+ };
165
+ _getUpdatedTransactions = new WeakSet();
166
+ getUpdatedTransactions_fn = function(remoteTxs, localTxs) {
167
+ return remoteTxs.filter(
168
+ (remoteTx) => localTxs.some(
169
+ (localTx) => remoteTx.hash === localTx.hash && __privateMethod(this, _isTransactionOutdated, isTransactionOutdated_fn).call(this, remoteTx, localTx)
170
+ )
171
+ );
172
+ };
173
+ _isTransactionOutdated = new WeakSet();
174
+ isTransactionOutdated_fn = function(remoteTx, localTx) {
175
+ return UPDATE_CHECKS.some(
176
+ (getValue) => getValue(remoteTx) !== getValue(localTx)
177
+ );
178
+ };
179
+ _getLastFetchedBlockNumberDec = new WeakSet();
180
+ getLastFetchedBlockNumberDec_fn = function() {
181
+ const additionalLastFetchedKeys = __privateGet(this, _remoteTransactionSource).getLastBlockVariations?.() ?? [];
182
+ const lastFetchedKey = __privateMethod(this, _getBlockNumberKey, getBlockNumberKey_fn).call(this, additionalLastFetchedKeys);
183
+ const lastFetchedBlockNumbers = __privateGet(this, _getLastFetchedBlockNumbers).call(this);
184
+ return lastFetchedBlockNumbers[lastFetchedKey];
185
+ };
186
+ _getFromBlock = new WeakSet();
187
+ getFromBlock_fn = function(latestBlockNumber) {
188
+ const lastFetchedBlockNumber = __privateMethod(this, _getLastFetchedBlockNumberDec, getLastFetchedBlockNumberDec_fn).call(this);
189
+ if (lastFetchedBlockNumber) {
190
+ return lastFetchedBlockNumber + 1;
191
+ }
192
+ return __privateGet(this, _queryEntireHistory) ? void 0 : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;
193
+ };
194
+ _updateLastFetchedBlockNumber = new WeakSet();
195
+ updateLastFetchedBlockNumber_fn = function(remoteTxs, additionalKeys) {
196
+ let lastFetchedBlockNumber = -1;
197
+ for (const tx of remoteTxs) {
198
+ const currentBlockNumberValue = tx.blockNumber ? parseInt(tx.blockNumber, 10) : -1;
199
+ lastFetchedBlockNumber = Math.max(
200
+ lastFetchedBlockNumber,
201
+ currentBlockNumberValue
202
+ );
203
+ }
204
+ if (lastFetchedBlockNumber === -1) {
205
+ return;
206
+ }
207
+ const lastFetchedKey = __privateMethod(this, _getBlockNumberKey, getBlockNumberKey_fn).call(this, additionalKeys);
208
+ const lastFetchedBlockNumbers = __privateGet(this, _getLastFetchedBlockNumbers).call(this);
209
+ const previousValue = lastFetchedBlockNumbers[lastFetchedKey];
210
+ if (previousValue >= lastFetchedBlockNumber) {
211
+ return;
212
+ }
213
+ this.hub.emit("updatedLastFetchedBlockNumbers", {
214
+ lastFetchedBlockNumbers: {
215
+ ...lastFetchedBlockNumbers,
216
+ [lastFetchedKey]: lastFetchedBlockNumber
217
+ },
218
+ blockNumber: lastFetchedBlockNumber
219
+ });
220
+ };
221
+ _getBlockNumberKey = new WeakSet();
222
+ getBlockNumberKey_fn = function(additionalKeys) {
223
+ const currentChainId = __privateGet(this, _getChainId).call(this);
224
+ const currentAccount = __privateGet(this, _getCurrentAccount).call(this)?.toLowerCase();
225
+ return [currentChainId, currentAccount, ...additionalKeys].join("#");
226
+ };
227
+ _canStart = new WeakSet();
228
+ canStart_fn = function() {
229
+ const isEnabled = __privateGet(this, _isEnabled).call(this);
230
+ const currentChainId = __privateGet(this, _getChainId).call(this);
231
+ const isSupportedNetwork = __privateGet(this, _remoteTransactionSource).isSupportedNetwork(currentChainId);
232
+ return isEnabled && isSupportedNetwork;
233
+ };
234
+
235
+ export {
236
+ IncomingTransactionHelper
237
+ };
238
+ //# sourceMappingURL=chunk-Y7ENNK7L.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/helpers/IncomingTransactionHelper.ts"],"sourcesContent":["import type { BlockTracker } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport EventEmitter from 'events';\n\nimport { incomingTransactionsLogger as log } from '../logger';\nimport type { RemoteTransactionSource, TransactionMeta } from '../types';\n\nconst RECENT_HISTORY_BLOCK_RANGE = 10;\n\n// TODO: Replace `any` with type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst UPDATE_CHECKS: ((txMeta: TransactionMeta) => any)[] = [\n (txMeta) => txMeta.status,\n (txMeta) => txMeta.txParams.gasUsed,\n];\n\n/**\n * Configuration options for the IncomingTransactionHelper\n *\n * @property includeTokenTransfers - Whether or not to include ERC20 token transfers.\n * @property isEnabled - Whether or not incoming transaction retrieval is enabled.\n * @property queryEntireHistory - Whether to initially query the entire transaction history or only recent blocks.\n * @property updateTransactions - Whether to update local transactions using remote transaction data.\n */\nexport type IncomingTransactionOptions = {\n includeTokenTransfers?: boolean;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n updateTransactions?: boolean;\n};\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #getCurrentAccount: () => string;\n\n #getLastFetchedBlockNumbers: () => Record<string, number>;\n\n #getLocalTransactions: () => TransactionMeta[];\n\n #getChainId: () => Hex;\n\n #isEnabled: () => boolean;\n\n #isRunning: boolean;\n\n #mutex = new Mutex();\n\n #onLatestBlock: (blockNumberHex: Hex) => Promise<void>;\n\n #queryEntireHistory: boolean;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n #transactionLimit?: number;\n\n #updateTransactions: boolean;\n\n constructor({\n blockTracker,\n getCurrentAccount,\n getLastFetchedBlockNumbers,\n getLocalTransactions,\n getChainId,\n isEnabled,\n queryEntireHistory,\n remoteTransactionSource,\n transactionLimit,\n updateTransactions,\n }: {\n blockTracker: BlockTracker;\n getCurrentAccount: () => string;\n getLastFetchedBlockNumbers: () => Record<string, number>;\n getLocalTransactions?: () => TransactionMeta[];\n getChainId: () => Hex;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n remoteTransactionSource: RemoteTransactionSource;\n transactionLimit?: number;\n updateTransactions?: boolean;\n }) {\n this.hub = new EventEmitter();\n\n this.#blockTracker = blockTracker;\n this.#getCurrentAccount = getCurrentAccount;\n this.#getLastFetchedBlockNumbers = getLastFetchedBlockNumbers;\n this.#getLocalTransactions = getLocalTransactions || (() => []);\n this.#getChainId = getChainId;\n this.#isEnabled = isEnabled ?? (() => true);\n this.#isRunning = false;\n this.#queryEntireHistory = queryEntireHistory ?? true;\n this.#remoteTransactionSource = remoteTransactionSource;\n this.#transactionLimit = transactionLimit;\n this.#updateTransactions = updateTransactions ?? false;\n\n // Using a property instead of a method to provide a listener reference\n // with the correct scope that we can remove later if stopped.\n this.#onLatestBlock = async (blockNumberHex: Hex) => {\n try {\n await this.update(blockNumberHex);\n } catch (error) {\n console.error('Error while checking incoming transactions', error);\n }\n };\n }\n\n start() {\n if (this.#isRunning) {\n return;\n }\n\n if (!this.#canStart()) {\n return;\n }\n\n this.#blockTracker.addListener('latest', this.#onLatestBlock);\n this.#isRunning = true;\n }\n\n stop() {\n this.#blockTracker.removeListener('latest', this.#onLatestBlock);\n this.#isRunning = false;\n }\n\n async update(latestBlockNumberHex?: Hex): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n log('Checking for incoming transactions');\n\n try {\n if (!this.#canStart()) {\n return;\n }\n\n const latestBlockNumber = parseInt(\n latestBlockNumberHex || (await this.#blockTracker.getLatestBlock()),\n 16,\n );\n\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n\n const fromBlock = this.#getFromBlock(latestBlockNumber);\n const address = this.#getCurrentAccount();\n const currentChainId = this.#getChainId();\n\n let remoteTransactions = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address,\n currentChainId,\n fromBlock,\n limit: this.#transactionLimit,\n });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n log('Error while fetching remote transactions', error);\n return;\n }\n if (!this.#updateTransactions) {\n remoteTransactions = remoteTransactions.filter(\n (tx) => tx.txParams.to?.toLowerCase() === address.toLowerCase(),\n );\n }\n\n const localTransactions = !this.#updateTransactions\n ? []\n : this.#getLocalTransactions();\n\n const newTransactions = this.#getNewTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n const updatedTransactions = this.#getUpdatedTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n if (newTransactions.length > 0 || updatedTransactions.length > 0) {\n this.#sortTransactionsByTime(newTransactions);\n this.#sortTransactionsByTime(updatedTransactions);\n\n log('Found incoming transactions', {\n new: newTransactions,\n updated: updatedTransactions,\n });\n\n this.hub.emit('transactions', {\n added: newTransactions,\n updated: updatedTransactions,\n });\n }\n this.#updateLastFetchedBlockNumber(\n remoteTransactions,\n additionalLastFetchedKeys,\n );\n } finally {\n releaseLock();\n }\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #getNewTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter(\n (tx) => !localTxs.some(({ hash }) => hash === tx.hash),\n );\n }\n\n #getUpdatedTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((remoteTx) =>\n localTxs.some(\n (localTx) =>\n remoteTx.hash === localTx.hash &&\n this.#isTransactionOutdated(remoteTx, localTx),\n ),\n );\n }\n\n #isTransactionOutdated(\n remoteTx: TransactionMeta,\n localTx: TransactionMeta,\n ): boolean {\n return UPDATE_CHECKS.some(\n (getValue) => getValue(remoteTx) !== getValue(localTx),\n );\n }\n\n #getLastFetchedBlockNumberDec(): number {\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n const lastFetchedKey = this.#getBlockNumberKey(additionalLastFetchedKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n return lastFetchedBlockNumbers[lastFetchedKey];\n }\n\n #getFromBlock(latestBlockNumber: number): number | undefined {\n const lastFetchedBlockNumber = this.#getLastFetchedBlockNumberDec();\n\n if (lastFetchedBlockNumber) {\n return lastFetchedBlockNumber + 1;\n }\n\n return this.#queryEntireHistory\n ? undefined\n : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;\n }\n\n #updateLastFetchedBlockNumber(\n remoteTxs: TransactionMeta[],\n additionalKeys: string[],\n ) {\n let lastFetchedBlockNumber = -1;\n\n for (const tx of remoteTxs) {\n const currentBlockNumberValue = tx.blockNumber\n ? parseInt(tx.blockNumber, 10)\n : -1;\n\n lastFetchedBlockNumber = Math.max(\n lastFetchedBlockNumber,\n currentBlockNumberValue,\n );\n }\n\n if (lastFetchedBlockNumber === -1) {\n return;\n }\n\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n const previousValue = lastFetchedBlockNumbers[lastFetchedKey];\n\n if (previousValue >= lastFetchedBlockNumber) {\n return;\n }\n\n this.hub.emit('updatedLastFetchedBlockNumbers', {\n lastFetchedBlockNumbers: {\n ...lastFetchedBlockNumbers,\n [lastFetchedKey]: lastFetchedBlockNumber,\n },\n blockNumber: lastFetchedBlockNumber,\n });\n }\n\n #getBlockNumberKey(additionalKeys: string[]): string {\n const currentChainId = this.#getChainId();\n const currentAccount = this.#getCurrentAccount()?.toLowerCase();\n\n return [currentChainId, currentAccount, ...additionalKeys].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const currentChainId = this.#getChainId();\n\n const isSupportedNetwork =\n this.#remoteTransactionSource.isSupportedNetwork(currentChainId);\n\n return isEnabled && isSupportedNetwork;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,30 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var __accessCheck = (obj, member, msg) => {
2
+ if (!member.has(obj))
3
+ throw TypeError("Cannot " + msg);
4
+ };
5
+ var __privateGet = (obj, member, getter) => {
6
+ __accessCheck(obj, member, "read from private field");
7
+ return getter ? getter.call(obj) : member.get(obj);
8
+ };
9
+ var __privateAdd = (obj, member, value) => {
10
+ if (member.has(obj))
11
+ throw TypeError("Cannot add the same private member more than once");
12
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
13
+ };
14
+ var __privateSet = (obj, member, value, setter) => {
15
+ __accessCheck(obj, member, "write to private field");
16
+ setter ? setter.call(obj, value) : member.set(obj, value);
17
+ return value;
18
+ };
19
+ var __privateMethod = (obj, member, method) => {
20
+ __accessCheck(obj, member, "access private method");
21
+ return method;
22
+ };
23
+
24
+
25
+
26
+
27
+
28
+
29
+ exports.__privateGet = __privateGet; exports.__privateAdd = __privateAdd; exports.__privateSet = __privateSet; exports.__privateMethod = __privateMethod;
30
+ //# sourceMappingURL=chunk-Z4BLTVTB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":""}
@@ -0,0 +1,208 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkIC233ZQSjs = require('./chunk-IC233ZQS.js');
4
+
5
+
6
+ var _chunkH4M66BA3js = require('./chunk-H4M66BA3.js');
7
+
8
+
9
+ var _chunkS6VGOPUYjs = require('./chunk-S6VGOPUY.js');
10
+
11
+ // src/utils/gas-fees.ts
12
+
13
+
14
+
15
+
16
+
17
+ var _controllerutils = require('@metamask/controller-utils');
18
+ var _utils = require('@metamask/utils');
19
+ var log = _utils.createModuleLogger.call(void 0, _chunkS6VGOPUYjs.projectLogger, "gas-fees");
20
+ async function updateGasFees(request) {
21
+ const { txMeta } = request;
22
+ const initialParams = { ...txMeta.txParams };
23
+ const isSwap = _chunkIC233ZQSjs.SWAP_TRANSACTION_TYPES.includes(
24
+ txMeta.type
25
+ );
26
+ const savedGasFees = isSwap ? void 0 : request.getSavedGasFees(txMeta.chainId);
27
+ const suggestedGasFees = await getSuggestedGasFees(request);
28
+ log("Suggested gas fees", suggestedGasFees);
29
+ const getGasFeeRequest = {
30
+ ...request,
31
+ initialParams,
32
+ savedGasFees,
33
+ suggestedGasFees
34
+ };
35
+ txMeta.txParams.maxFeePerGas = getMaxFeePerGas(getGasFeeRequest);
36
+ txMeta.txParams.maxPriorityFeePerGas = getMaxPriorityFeePerGas(getGasFeeRequest);
37
+ txMeta.txParams.gasPrice = getGasPrice(getGasFeeRequest);
38
+ txMeta.userFeeLevel = getUserFeeLevel(getGasFeeRequest);
39
+ log("Updated gas fee properties", {
40
+ maxFeePerGas: txMeta.txParams.maxFeePerGas,
41
+ maxPriorityFeePerGas: txMeta.txParams.maxPriorityFeePerGas,
42
+ gasPrice: txMeta.txParams.gasPrice
43
+ });
44
+ if (txMeta.txParams.maxFeePerGas || txMeta.txParams.maxPriorityFeePerGas) {
45
+ delete txMeta.txParams.gasPrice;
46
+ }
47
+ if (txMeta.txParams.gasPrice) {
48
+ delete txMeta.txParams.maxFeePerGas;
49
+ delete txMeta.txParams.maxPriorityFeePerGas;
50
+ }
51
+ updateDefaultGasEstimates(txMeta);
52
+ }
53
+ function gweiDecimalToWeiHex(value) {
54
+ return _controllerutils.toHex.call(void 0, _controllerutils.gweiDecToWEIBN.call(void 0, value));
55
+ }
56
+ function getMaxFeePerGas(request) {
57
+ const { savedGasFees, eip1559, initialParams, suggestedGasFees } = request;
58
+ if (!eip1559) {
59
+ return void 0;
60
+ }
61
+ if (savedGasFees) {
62
+ const maxFeePerGas = gweiDecimalToWeiHex(savedGasFees.maxBaseFee);
63
+ log("Using maxFeePerGas from savedGasFees", maxFeePerGas);
64
+ return maxFeePerGas;
65
+ }
66
+ if (initialParams.maxFeePerGas) {
67
+ log("Using maxFeePerGas from request", initialParams.maxFeePerGas);
68
+ return initialParams.maxFeePerGas;
69
+ }
70
+ if (initialParams.gasPrice && !initialParams.maxPriorityFeePerGas) {
71
+ log(
72
+ "Setting maxFeePerGas to gasPrice from request",
73
+ initialParams.gasPrice
74
+ );
75
+ return initialParams.gasPrice;
76
+ }
77
+ if (suggestedGasFees.maxFeePerGas) {
78
+ log("Using suggested maxFeePerGas", suggestedGasFees.maxFeePerGas);
79
+ return suggestedGasFees.maxFeePerGas;
80
+ }
81
+ if (suggestedGasFees.gasPrice) {
82
+ log(
83
+ "Setting maxFeePerGas to suggested gasPrice",
84
+ suggestedGasFees.gasPrice
85
+ );
86
+ return suggestedGasFees.gasPrice;
87
+ }
88
+ log("maxFeePerGas not set");
89
+ return void 0;
90
+ }
91
+ function getMaxPriorityFeePerGas(request) {
92
+ const { eip1559, initialParams, savedGasFees, suggestedGasFees, txMeta } = request;
93
+ if (!eip1559) {
94
+ return void 0;
95
+ }
96
+ if (savedGasFees) {
97
+ const maxPriorityFeePerGas = gweiDecimalToWeiHex(savedGasFees.priorityFee);
98
+ log(
99
+ "Using maxPriorityFeePerGas from savedGasFees.priorityFee",
100
+ maxPriorityFeePerGas
101
+ );
102
+ return maxPriorityFeePerGas;
103
+ }
104
+ if (initialParams.maxPriorityFeePerGas) {
105
+ log(
106
+ "Using maxPriorityFeePerGas from request",
107
+ initialParams.maxPriorityFeePerGas
108
+ );
109
+ return initialParams.maxPriorityFeePerGas;
110
+ }
111
+ if (initialParams.gasPrice && !initialParams.maxFeePerGas) {
112
+ log(
113
+ "Setting maxPriorityFeePerGas to gasPrice from request",
114
+ initialParams.gasPrice
115
+ );
116
+ return initialParams.gasPrice;
117
+ }
118
+ if (suggestedGasFees.maxPriorityFeePerGas) {
119
+ log(
120
+ "Using suggested maxPriorityFeePerGas",
121
+ suggestedGasFees.maxPriorityFeePerGas
122
+ );
123
+ return suggestedGasFees.maxPriorityFeePerGas;
124
+ }
125
+ if (txMeta.txParams.maxFeePerGas) {
126
+ log(
127
+ "Setting maxPriorityFeePerGas to maxFeePerGas",
128
+ txMeta.txParams.maxFeePerGas
129
+ );
130
+ return txMeta.txParams.maxFeePerGas;
131
+ }
132
+ log("maxPriorityFeePerGas not set");
133
+ return void 0;
134
+ }
135
+ function getGasPrice(request) {
136
+ const { eip1559, initialParams, suggestedGasFees } = request;
137
+ if (eip1559) {
138
+ return void 0;
139
+ }
140
+ if (initialParams.gasPrice) {
141
+ log("Using gasPrice from request", initialParams.gasPrice);
142
+ return initialParams.gasPrice;
143
+ }
144
+ if (suggestedGasFees.maxFeePerGas) {
145
+ log("Using suggested maxFeePerGas", suggestedGasFees.maxFeePerGas);
146
+ return suggestedGasFees.maxFeePerGas;
147
+ }
148
+ if (suggestedGasFees.gasPrice) {
149
+ log("Using suggested gasPrice", suggestedGasFees.gasPrice);
150
+ return suggestedGasFees.gasPrice;
151
+ }
152
+ log("gasPrice not set");
153
+ return void 0;
154
+ }
155
+ function getUserFeeLevel(request) {
156
+ const { eip1559, initialParams, savedGasFees, suggestedGasFees, txMeta } = request;
157
+ if (!eip1559) {
158
+ return void 0;
159
+ }
160
+ if (savedGasFees) {
161
+ return "custom" /* CUSTOM */;
162
+ }
163
+ if (!initialParams.maxFeePerGas && !initialParams.maxPriorityFeePerGas && initialParams.gasPrice) {
164
+ return txMeta.origin === _controllerutils.ORIGIN_METAMASK ? "custom" /* CUSTOM */ : "dappSuggested" /* DAPP_SUGGESTED */;
165
+ }
166
+ if (!initialParams.maxFeePerGas && !initialParams.maxPriorityFeePerGas && suggestedGasFees.maxFeePerGas && suggestedGasFees.maxPriorityFeePerGas) {
167
+ return "medium" /* MEDIUM */;
168
+ }
169
+ if (txMeta.origin === _controllerutils.ORIGIN_METAMASK) {
170
+ return "medium" /* MEDIUM */;
171
+ }
172
+ return "dappSuggested" /* DAPP_SUGGESTED */;
173
+ }
174
+ function updateDefaultGasEstimates(txMeta) {
175
+ if (!txMeta.defaultGasEstimates) {
176
+ txMeta.defaultGasEstimates = {};
177
+ }
178
+ txMeta.defaultGasEstimates.maxFeePerGas = txMeta.txParams.maxFeePerGas;
179
+ txMeta.defaultGasEstimates.maxPriorityFeePerGas = txMeta.txParams.maxPriorityFeePerGas;
180
+ txMeta.defaultGasEstimates.gasPrice = txMeta.txParams.gasPrice;
181
+ txMeta.defaultGasEstimates.estimateType = txMeta.userFeeLevel;
182
+ }
183
+ async function getSuggestedGasFees(request) {
184
+ const { eip1559, ethQuery, gasFeeFlows, getGasFeeEstimates, txMeta } = request;
185
+ if (!eip1559 && txMeta.txParams.gasPrice || eip1559 && txMeta.txParams.maxFeePerGas && txMeta.txParams.maxPriorityFeePerGas) {
186
+ return {};
187
+ }
188
+ const gasFeeFlow = _chunkH4M66BA3js.getGasFeeFlow.call(void 0, txMeta, gasFeeFlows);
189
+ try {
190
+ const response = await gasFeeFlow.getGasFees({
191
+ ethQuery,
192
+ getGasFeeControllerEstimates: getGasFeeEstimates,
193
+ transactionMeta: txMeta
194
+ });
195
+ return response.estimates.medium;
196
+ } catch (error) {
197
+ log("Failed to get suggested gas fees", error);
198
+ }
199
+ const gasPriceDecimal = await _controllerutils.query.call(void 0, ethQuery, "gasPrice");
200
+ const gasPrice = gasPriceDecimal ? _utils.add0x.call(void 0, gasPriceDecimal.toString(16)) : void 0;
201
+ return { gasPrice };
202
+ }
203
+
204
+
205
+
206
+
207
+ exports.updateGasFees = updateGasFees; exports.gweiDecimalToWeiHex = gweiDecimalToWeiHex;
208
+ //# sourceMappingURL=chunk-ZCQRDZ36.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/gas-fees.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable jsdoc/require-jsdoc */\n\nimport {\n ORIGIN_METAMASK,\n gweiDecToWEIBN,\n query,\n toHex,\n} from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { Hex } from '@metamask/utils';\nimport { add0x, createModuleLogger } from '@metamask/utils';\n\nimport { projectLogger } from '../logger';\nimport type {\n SavedGasFees,\n TransactionParams,\n TransactionMeta,\n TransactionType,\n GasFeeFlow,\n} from '../types';\nimport { UserFeeLevel } from '../types';\nimport { getGasFeeFlow } from './gas-flow';\nimport { SWAP_TRANSACTION_TYPES } from './swaps';\n\nexport type UpdateGasFeesRequest = {\n eip1559: boolean;\n ethQuery: EthQuery;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getSavedGasFees: (chainId: Hex) => SavedGasFees | undefined;\n txMeta: TransactionMeta;\n};\n\nexport type GetGasFeeRequest = UpdateGasFeesRequest & {\n initialParams: TransactionParams;\n savedGasFees?: SavedGasFees;\n suggestedGasFees: SuggestedGasFees;\n};\n\ntype SuggestedGasFees = {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n gasPrice?: string;\n};\n\nconst log = createModuleLogger(projectLogger, 'gas-fees');\n\nexport async function updateGasFees(request: UpdateGasFeesRequest) {\n const { txMeta } = request;\n const initialParams = { ...txMeta.txParams };\n\n const isSwap = SWAP_TRANSACTION_TYPES.includes(\n txMeta.type as TransactionType,\n );\n const savedGasFees = isSwap\n ? undefined\n : request.getSavedGasFees(txMeta.chainId);\n\n const suggestedGasFees = await getSuggestedGasFees(request);\n\n log('Suggested gas fees', suggestedGasFees);\n\n const getGasFeeRequest: GetGasFeeRequest = {\n ...request,\n initialParams,\n savedGasFees,\n suggestedGasFees,\n };\n\n txMeta.txParams.maxFeePerGas = getMaxFeePerGas(getGasFeeRequest);\n\n txMeta.txParams.maxPriorityFeePerGas =\n getMaxPriorityFeePerGas(getGasFeeRequest);\n\n txMeta.txParams.gasPrice = getGasPrice(getGasFeeRequest);\n txMeta.userFeeLevel = getUserFeeLevel(getGasFeeRequest);\n\n log('Updated gas fee properties', {\n maxFeePerGas: txMeta.txParams.maxFeePerGas,\n maxPriorityFeePerGas: txMeta.txParams.maxPriorityFeePerGas,\n gasPrice: txMeta.txParams.gasPrice,\n });\n\n if (txMeta.txParams.maxFeePerGas || txMeta.txParams.maxPriorityFeePerGas) {\n delete txMeta.txParams.gasPrice;\n }\n\n if (txMeta.txParams.gasPrice) {\n delete txMeta.txParams.maxFeePerGas;\n delete txMeta.txParams.maxPriorityFeePerGas;\n }\n\n updateDefaultGasEstimates(txMeta);\n}\n\nexport function gweiDecimalToWeiHex(value: string) {\n return toHex(gweiDecToWEIBN(value));\n}\n\nfunction getMaxFeePerGas(request: GetGasFeeRequest): string | undefined {\n const { savedGasFees, eip1559, initialParams, suggestedGasFees } = request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n const maxFeePerGas = gweiDecimalToWeiHex(savedGasFees.maxBaseFee as string);\n log('Using maxFeePerGas from savedGasFees', maxFeePerGas);\n return maxFeePerGas;\n }\n\n if (initialParams.maxFeePerGas) {\n log('Using maxFeePerGas from request', initialParams.maxFeePerGas);\n return initialParams.maxFeePerGas;\n }\n\n if (initialParams.gasPrice && !initialParams.maxPriorityFeePerGas) {\n log(\n 'Setting maxFeePerGas to gasPrice from request',\n initialParams.gasPrice,\n );\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxFeePerGas) {\n log('Using suggested maxFeePerGas', suggestedGasFees.maxFeePerGas);\n return suggestedGasFees.maxFeePerGas;\n }\n\n if (suggestedGasFees.gasPrice) {\n log(\n 'Setting maxFeePerGas to suggested gasPrice',\n suggestedGasFees.gasPrice,\n );\n return suggestedGasFees.gasPrice;\n }\n\n log('maxFeePerGas not set');\n return undefined;\n}\n\nfunction getMaxPriorityFeePerGas(\n request: GetGasFeeRequest,\n): string | undefined {\n const { eip1559, initialParams, savedGasFees, suggestedGasFees, txMeta } =\n request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n const maxPriorityFeePerGas = gweiDecimalToWeiHex(savedGasFees.priorityFee);\n log(\n 'Using maxPriorityFeePerGas from savedGasFees.priorityFee',\n maxPriorityFeePerGas,\n );\n return maxPriorityFeePerGas;\n }\n\n if (initialParams.maxPriorityFeePerGas) {\n log(\n 'Using maxPriorityFeePerGas from request',\n initialParams.maxPriorityFeePerGas,\n );\n return initialParams.maxPriorityFeePerGas;\n }\n\n if (initialParams.gasPrice && !initialParams.maxFeePerGas) {\n log(\n 'Setting maxPriorityFeePerGas to gasPrice from request',\n initialParams.gasPrice,\n );\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxPriorityFeePerGas) {\n log(\n 'Using suggested maxPriorityFeePerGas',\n suggestedGasFees.maxPriorityFeePerGas,\n );\n return suggestedGasFees.maxPriorityFeePerGas;\n }\n\n if (txMeta.txParams.maxFeePerGas) {\n log(\n 'Setting maxPriorityFeePerGas to maxFeePerGas',\n txMeta.txParams.maxFeePerGas,\n );\n return txMeta.txParams.maxFeePerGas;\n }\n\n log('maxPriorityFeePerGas not set');\n return undefined;\n}\n\nfunction getGasPrice(request: GetGasFeeRequest): string | undefined {\n const { eip1559, initialParams, suggestedGasFees } = request;\n\n if (eip1559) {\n return undefined;\n }\n\n if (initialParams.gasPrice) {\n log('Using gasPrice from request', initialParams.gasPrice);\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxFeePerGas) {\n log('Using suggested maxFeePerGas', suggestedGasFees.maxFeePerGas);\n return suggestedGasFees.maxFeePerGas;\n }\n\n if (suggestedGasFees.gasPrice) {\n log('Using suggested gasPrice', suggestedGasFees.gasPrice);\n return suggestedGasFees.gasPrice;\n }\n\n log('gasPrice not set');\n return undefined;\n}\n\nfunction getUserFeeLevel(request: GetGasFeeRequest): UserFeeLevel | undefined {\n const { eip1559, initialParams, savedGasFees, suggestedGasFees, txMeta } =\n request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n return UserFeeLevel.CUSTOM;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n initialParams.gasPrice\n ) {\n return txMeta.origin === ORIGIN_METAMASK\n ? UserFeeLevel.CUSTOM\n : UserFeeLevel.DAPP_SUGGESTED;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n suggestedGasFees.maxFeePerGas &&\n suggestedGasFees.maxPriorityFeePerGas\n ) {\n return UserFeeLevel.MEDIUM;\n }\n\n if (txMeta.origin === ORIGIN_METAMASK) {\n return UserFeeLevel.MEDIUM;\n }\n\n return UserFeeLevel.DAPP_SUGGESTED;\n}\n\nfunction updateDefaultGasEstimates(txMeta: TransactionMeta) {\n if (!txMeta.defaultGasEstimates) {\n txMeta.defaultGasEstimates = {};\n }\n\n txMeta.defaultGasEstimates.maxFeePerGas = txMeta.txParams.maxFeePerGas;\n\n txMeta.defaultGasEstimates.maxPriorityFeePerGas =\n txMeta.txParams.maxPriorityFeePerGas;\n\n txMeta.defaultGasEstimates.gasPrice = txMeta.txParams.gasPrice;\n txMeta.defaultGasEstimates.estimateType = txMeta.userFeeLevel;\n}\n\nasync function getSuggestedGasFees(\n request: UpdateGasFeesRequest,\n): Promise<SuggestedGasFees> {\n const { eip1559, ethQuery, gasFeeFlows, getGasFeeEstimates, txMeta } =\n request;\n\n if (\n (!eip1559 && txMeta.txParams.gasPrice) ||\n (eip1559 &&\n txMeta.txParams.maxFeePerGas &&\n txMeta.txParams.maxPriorityFeePerGas)\n ) {\n return {};\n }\n\n const gasFeeFlow = getGasFeeFlow(txMeta, gasFeeFlows) as GasFeeFlow;\n\n try {\n const response = await gasFeeFlow.getGasFees({\n ethQuery,\n getGasFeeControllerEstimates: getGasFeeEstimates,\n transactionMeta: txMeta,\n });\n\n return response.estimates.medium;\n } catch (error) {\n log('Failed to get suggested gas fees', error);\n }\n\n const gasPriceDecimal = (await query(ethQuery, 'gasPrice')) as number;\n\n const gasPrice = gasPriceDecimal\n ? add0x(gasPriceDecimal.toString(16))\n : undefined;\n\n return { gasPrice };\n}\n"]}