@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,182 @@
1
+ import {
2
+ isEIP1559Transaction
3
+ } from "./chunk-J56A7UCK.mjs";
4
+
5
+ // src/utils/validation.ts
6
+ import { Interface } from "@ethersproject/abi";
7
+ import { ORIGIN_METAMASK, isValidHexAddress } from "@metamask/controller-utils";
8
+ import { abiERC20 } from "@metamask/metamask-eth-abis";
9
+ import { providerErrors, rpcErrors } from "@metamask/rpc-errors";
10
+ async function validateTransactionOrigin(permittedAddresses, selectedAddress, from, origin) {
11
+ if (origin === ORIGIN_METAMASK) {
12
+ if (from !== selectedAddress) {
13
+ throw rpcErrors.internal({
14
+ message: `Internally initiated transaction is using invalid account.`,
15
+ data: {
16
+ origin,
17
+ fromAddress: from,
18
+ selectedAddress
19
+ }
20
+ });
21
+ }
22
+ return;
23
+ }
24
+ if (!permittedAddresses.includes(from)) {
25
+ throw providerErrors.unauthorized({ data: { origin } });
26
+ }
27
+ }
28
+ function validateTxParams(txParams, isEIP1559Compatible = true) {
29
+ validateEIP1559Compatibility(txParams, isEIP1559Compatible);
30
+ validateParamFrom(txParams.from);
31
+ validateParamRecipient(txParams);
32
+ validateParamValue(txParams.value);
33
+ validateParamData(txParams.data);
34
+ validateParamChainId(txParams.chainId);
35
+ validateGasFeeParams(txParams);
36
+ }
37
+ function validateEIP1559Compatibility(txParams, isEIP1559Compatible) {
38
+ if (isEIP1559Transaction(txParams) && !isEIP1559Compatible) {
39
+ throw rpcErrors.invalidParams(
40
+ "Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559"
41
+ );
42
+ }
43
+ }
44
+ function validateParamValue(value) {
45
+ if (value !== void 0) {
46
+ if (value.includes("-")) {
47
+ throw rpcErrors.invalidParams(
48
+ `Invalid transaction value "${value}": not a positive number.`
49
+ );
50
+ }
51
+ if (value.includes(".")) {
52
+ throw rpcErrors.invalidParams(
53
+ `Invalid transaction value "${value}": number must be in wei.`
54
+ );
55
+ }
56
+ const intValue = parseInt(value, 10);
57
+ const isValid = Number.isFinite(intValue) && !Number.isNaN(intValue) && !isNaN(Number(value)) && Number.isSafeInteger(intValue);
58
+ if (!isValid) {
59
+ throw rpcErrors.invalidParams(
60
+ `Invalid transaction value ${value}: number must be a valid number.`
61
+ );
62
+ }
63
+ }
64
+ }
65
+ function validateParamRecipient(txParams) {
66
+ if (txParams.to === "0x" || txParams.to === void 0) {
67
+ if (txParams.data) {
68
+ delete txParams.to;
69
+ } else {
70
+ throw rpcErrors.invalidParams(`Invalid "to" address.`);
71
+ }
72
+ } else if (txParams.to !== void 0 && !isValidHexAddress(txParams.to)) {
73
+ throw rpcErrors.invalidParams(`Invalid "to" address.`);
74
+ }
75
+ }
76
+ function validateParamFrom(from) {
77
+ if (!from || typeof from !== "string") {
78
+ throw rpcErrors.invalidParams(
79
+ `Invalid "from" address ${from}: not a string.`
80
+ );
81
+ }
82
+ if (!isValidHexAddress(from)) {
83
+ throw rpcErrors.invalidParams('Invalid "from" address.');
84
+ }
85
+ }
86
+ function validateParamData(value) {
87
+ if (value) {
88
+ const ERC20Interface = new Interface(abiERC20);
89
+ try {
90
+ ERC20Interface.parseTransaction({ data: value });
91
+ } catch (error) {
92
+ if (error.message.match(/BUFFER_OVERRUN/u)) {
93
+ throw rpcErrors.invalidParams(
94
+ "Invalid transaction params: data out-of-bounds, BUFFER_OVERRUN."
95
+ );
96
+ }
97
+ }
98
+ }
99
+ }
100
+ function validateParamChainId(chainId) {
101
+ if (chainId !== void 0 && typeof chainId !== "number" && typeof chainId !== "string") {
102
+ throw rpcErrors.invalidParams(
103
+ `Invalid transaction params: chainId is not a Number or hex string. got: (${chainId})`
104
+ );
105
+ }
106
+ }
107
+ function validateGasFeeParams(txParams) {
108
+ if (txParams.gasPrice) {
109
+ ensureProperTransactionEnvelopeTypeProvided(txParams, "gasPrice");
110
+ ensureMutuallyExclusiveFieldsNotProvided(
111
+ txParams,
112
+ "gasPrice",
113
+ "maxFeePerGas"
114
+ );
115
+ ensureMutuallyExclusiveFieldsNotProvided(
116
+ txParams,
117
+ "gasPrice",
118
+ "maxPriorityFeePerGas"
119
+ );
120
+ ensureFieldIsString(txParams, "gasPrice");
121
+ }
122
+ if (txParams.maxFeePerGas) {
123
+ ensureProperTransactionEnvelopeTypeProvided(txParams, "maxFeePerGas");
124
+ ensureMutuallyExclusiveFieldsNotProvided(
125
+ txParams,
126
+ "maxFeePerGas",
127
+ "gasPrice"
128
+ );
129
+ ensureFieldIsString(txParams, "maxFeePerGas");
130
+ }
131
+ if (txParams.maxPriorityFeePerGas) {
132
+ ensureProperTransactionEnvelopeTypeProvided(
133
+ txParams,
134
+ "maxPriorityFeePerGas"
135
+ );
136
+ ensureMutuallyExclusiveFieldsNotProvided(
137
+ txParams,
138
+ "maxPriorityFeePerGas",
139
+ "gasPrice"
140
+ );
141
+ ensureFieldIsString(txParams, "maxPriorityFeePerGas");
142
+ }
143
+ }
144
+ function ensureProperTransactionEnvelopeTypeProvided(txParams, field) {
145
+ switch (field) {
146
+ case "maxFeePerGas":
147
+ case "maxPriorityFeePerGas":
148
+ if (txParams.type && txParams.type !== "0x2" /* feeMarket */) {
149
+ throw rpcErrors.invalidParams(
150
+ `Invalid transaction envelope type: specified type "${txParams.type}" but including maxFeePerGas and maxPriorityFeePerGas requires type: "${"0x2" /* feeMarket */}"`
151
+ );
152
+ }
153
+ break;
154
+ case "gasPrice":
155
+ default:
156
+ if (txParams.type && txParams.type === "0x2" /* feeMarket */) {
157
+ throw rpcErrors.invalidParams(
158
+ `Invalid transaction envelope type: specified type "${txParams.type}" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas`
159
+ );
160
+ }
161
+ }
162
+ }
163
+ function ensureMutuallyExclusiveFieldsNotProvided(txParams, fieldBeingValidated, mutuallyExclusiveField) {
164
+ if (typeof txParams[mutuallyExclusiveField] !== "undefined") {
165
+ throw rpcErrors.invalidParams(
166
+ `Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`
167
+ );
168
+ }
169
+ }
170
+ function ensureFieldIsString(txParams, field) {
171
+ if (typeof txParams[field] !== "string") {
172
+ throw rpcErrors.invalidParams(
173
+ `Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`
174
+ );
175
+ }
176
+ }
177
+
178
+ export {
179
+ validateTransactionOrigin,
180
+ validateTxParams
181
+ };
182
+ //# sourceMappingURL=chunk-NM6OYEPP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/validation.ts"],"sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, isValidHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\n\nimport { TransactionEnvelopeType, type TransactionParams } from '../types';\nimport { isEIP1559Transaction } from './utils';\n\ntype GasFieldsToValidate = 'gasPrice' | 'maxFeePerGas' | 'maxPriorityFeePerGas';\n\n/**\n * Validates whether a transaction initiated by a specific 'from' address is permitted by the origin.\n *\n * @param permittedAddresses - The permitted accounts for the given origin.\n * @param selectedAddress - The currently selected Ethereum address in the wallet.\n * @param from - The address from which the transaction is initiated.\n * @param origin - The origin or source of the transaction.\n * @throws Throws an error if the transaction is not permitted.\n */\nexport async function validateTransactionOrigin(\n permittedAddresses: string[],\n selectedAddress: string,\n from: string,\n origin: string,\n) {\n if (origin === ORIGIN_METAMASK) {\n // Ensure the 'from' address matches the currently selected address\n if (from !== selectedAddress) {\n throw rpcErrors.internal({\n message: `Internally initiated transaction is using invalid account.`,\n data: {\n origin,\n fromAddress: from,\n selectedAddress,\n },\n });\n }\n return;\n }\n\n // Check if the origin has permissions to initiate transactions from the specified address\n if (!permittedAddresses.includes(from)) {\n throw providerErrors.unauthorized({ data: { origin } });\n }\n}\n\n/**\n * Validates the transaction params for required properties and throws in\n * the event of any validation error.\n *\n * @param txParams - Transaction params object to validate.\n * @param isEIP1559Compatible - whether or not the current network supports EIP-1559 transactions.\n */\nexport function validateTxParams(\n txParams: TransactionParams,\n isEIP1559Compatible = true,\n) {\n validateEIP1559Compatibility(txParams, isEIP1559Compatible);\n validateParamFrom(txParams.from);\n validateParamRecipient(txParams);\n validateParamValue(txParams.value);\n validateParamData(txParams.data);\n validateParamChainId(txParams.chainId);\n validateGasFeeParams(txParams);\n}\n\n/**\n * Validates EIP-1559 compatibility for transaction creation.\n *\n * @param txParams - The transaction parameters to validate.\n * @param isEIP1559Compatible - Indicates if the current network supports EIP-1559.\n * @throws Throws invalid params if the transaction specifies EIP-1559 but the network does not support it.\n */\nfunction validateEIP1559Compatibility(\n txParams: TransactionParams,\n isEIP1559Compatible: boolean,\n) {\n if (isEIP1559Transaction(txParams) && !isEIP1559Compatible) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559',\n );\n }\n}\n\n/**\n * Validates value property, ensuring it is a valid positive integer number\n * denominated in wei.\n *\n * @param value - The value to validate, expressed as a string.\n * @throws Throws an error if the value is not a valid positive integer\n * number denominated in wei.\n * - If the value contains a hyphen (-), it is considered invalid.\n * - If the value contains a decimal point (.), it is considered invalid.\n * - If the value is not a finite number, is NaN, or is not a safe integer, it is considered invalid.\n */\nfunction validateParamValue(value?: string) {\n if (value !== undefined) {\n if (value.includes('-')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": not a positive number.`,\n );\n }\n\n if (value.includes('.')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": number must be in wei.`,\n );\n }\n const intValue = parseInt(value, 10);\n const isValid =\n Number.isFinite(intValue) &&\n !Number.isNaN(intValue) &&\n !isNaN(Number(value)) &&\n Number.isSafeInteger(intValue);\n if (!isValid) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value ${value}: number must be a valid number.`,\n );\n }\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param txParams - The transaction parameters object to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamRecipient(txParams: TransactionParams) {\n if (txParams.to === '0x' || txParams.to === undefined) {\n if (txParams.data) {\n delete txParams.to;\n } else {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n } else if (txParams.to !== undefined && !isValidHexAddress(txParams.to)) {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param from - The from property to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamFrom(from: string) {\n if (!from || typeof from !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid \"from\" address ${from}: not a string.`,\n );\n }\n if (!isValidHexAddress(from)) {\n throw rpcErrors.invalidParams('Invalid \"from\" address.');\n }\n}\n\n/**\n * Validates input data for transactions.\n *\n * @param value - The input data to validate.\n * @throws Throws invalid params if the input data is invalid.\n */\nfunction validateParamData(value?: string) {\n if (value) {\n const ERC20Interface = new Interface(abiERC20);\n try {\n ERC20Interface.parseTransaction({ data: value });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error.message.match(/BUFFER_OVERRUN/u)) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: data out-of-bounds, BUFFER_OVERRUN.',\n );\n }\n }\n }\n}\n\n/**\n * Validates chainId type.\n *\n * @param chainId - The chainId to validate.\n */\nfunction validateParamChainId(chainId: number | string | undefined) {\n if (\n chainId !== undefined &&\n typeof chainId !== 'number' &&\n typeof chainId !== 'string'\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: chainId is not a Number or hex string. got: (${chainId})`,\n );\n }\n}\n\n/**\n * Validates gas values.\n *\n * @param txParams - The transaction parameters to validate.\n */\nfunction validateGasFeeParams(txParams: TransactionParams) {\n if (txParams.gasPrice) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'gasPrice');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxPriorityFeePerGas',\n );\n ensureFieldIsString(txParams, 'gasPrice');\n }\n\n if (txParams.maxFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'maxFeePerGas');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsString(txParams, 'maxFeePerGas');\n }\n\n if (txParams.maxPriorityFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(\n txParams,\n 'maxPriorityFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxPriorityFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsString(txParams, 'maxPriorityFeePerGas');\n }\n}\n\n/**\n * Ensures that the provided txParams has the proper 'type' specified for the\n * given field, if it is provided. If types do not match throws an\n * invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {ethErrors.rpc.invalidParams} Throws if type does not match the\n * expectations for provided field.\n */\nfunction ensureProperTransactionEnvelopeTypeProvided(\n txParams: TransactionParams,\n field: GasFieldsToValidate,\n) {\n switch (field) {\n case 'maxFeePerGas':\n case 'maxPriorityFeePerGas':\n if (\n txParams.type &&\n txParams.type !== TransactionEnvelopeType.feeMarket\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${txParams.type}\" but including maxFeePerGas and maxPriorityFeePerGas requires type: \"${TransactionEnvelopeType.feeMarket}\"`,\n );\n }\n break;\n case 'gasPrice':\n default:\n if (\n txParams.type &&\n txParams.type === TransactionEnvelopeType.feeMarket\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${txParams.type}\" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas`,\n );\n }\n }\n}\n\n/**\n * Given two fields, ensure that the second field is not included in txParams,\n * and if it is throw an invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param fieldBeingValidated - The current field being validated\n * @param mutuallyExclusiveField - The field to ensure is not provided\n * @throws {ethErrors.rpc.invalidParams} Throws if mutuallyExclusiveField is\n * present in txParams.\n */\nfunction ensureMutuallyExclusiveFieldsNotProvided(\n txParams: TransactionParams,\n fieldBeingValidated: GasFieldsToValidate,\n mutuallyExclusiveField: GasFieldsToValidate,\n) {\n if (typeof txParams[mutuallyExclusiveField] !== 'undefined') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`,\n );\n }\n}\n\n/**\n * Ensures that the provided value for field is a string, throws an\n * invalidParams error if field is not a string.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {rpcErrors.invalidParams} Throws if field is not a string\n */\nfunction ensureFieldIsString(\n txParams: TransactionParams,\n field: GasFieldsToValidate,\n) {\n if (typeof txParams[field] !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`,\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,85 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkRI6MVJJNjs = require('./chunk-RI6MVJJN.js');
4
+
5
+
6
+ var _chunkS6VGOPUYjs = require('./chunk-S6VGOPUY.js');
7
+
8
+ // src/utils/etherscan.ts
9
+ var _controllerutils = require('@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
+ _chunkS6VGOPUYjs.incomingTransactionsLogger.call(void 0, "Sending Etherscan request", etherscanTxUrl);
54
+ const response = await _controllerutils.handleFetch.call(void 0,
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 = _chunkRI6MVJJNjs.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
+
81
+
82
+
83
+
84
+ exports.fetchEtherscanTransactions = fetchEtherscanTransactions; exports.fetchEtherscanTokenTransactions = fetchEtherscanTokenTransactions; exports.getEtherscanApiHost = getEtherscanApiHost;
85
+ //# sourceMappingURL=chunk-NUOBUW7C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/etherscan.ts"],"names":[],"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","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"]}
@@ -0,0 +1,53 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/utils/history.ts
2
+ var _fastjsonpatch = require('fast-json-patch'); var _fastjsonpatch2 = _interopRequireDefault(_fastjsonpatch);
3
+ var _lodash = require('lodash');
4
+ function addInitialHistorySnapshot(transactionMeta) {
5
+ const snapshot = snapshotFromTransactionMeta(transactionMeta);
6
+ return _lodash.merge.call(void 0, {}, transactionMeta, { history: [snapshot] });
7
+ }
8
+ function updateTransactionHistory(transactionMeta, note) {
9
+ if (!transactionMeta.history) {
10
+ return transactionMeta;
11
+ }
12
+ const currentState = snapshotFromTransactionMeta(transactionMeta);
13
+ const previousState = replayHistory(transactionMeta.history);
14
+ const historyEntry = generateHistoryEntry(previousState, currentState, note);
15
+ if (historyEntry.length > 0) {
16
+ return _lodash.merge.call(void 0, {}, transactionMeta, {
17
+ history: [...transactionMeta.history, historyEntry]
18
+ });
19
+ }
20
+ return transactionMeta;
21
+ }
22
+ function generateHistoryEntry(previousState, currentState, note) {
23
+ const historyOperationsEntry = _fastjsonpatch2.default.compare(
24
+ previousState,
25
+ currentState
26
+ );
27
+ if (historyOperationsEntry[0]) {
28
+ if (note) {
29
+ historyOperationsEntry[0].note = note;
30
+ }
31
+ historyOperationsEntry[0].timestamp = Date.now();
32
+ }
33
+ return historyOperationsEntry;
34
+ }
35
+ function replayHistory(transactionHistory) {
36
+ const shortHistory = _lodash.cloneDeep.call(void 0, transactionHistory);
37
+ return shortHistory.reduce(
38
+ // TODO: Replace `any` with type
39
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+ (val, entry) => _fastjsonpatch2.default.applyPatch(val, entry).newDocument
41
+ );
42
+ }
43
+ function snapshotFromTransactionMeta(transactionMeta) {
44
+ const snapshot = { ...transactionMeta };
45
+ delete snapshot.history;
46
+ return _lodash.cloneDeep.call(void 0, snapshot);
47
+ }
48
+
49
+
50
+
51
+
52
+ exports.addInitialHistorySnapshot = addInitialHistorySnapshot; exports.updateTransactionHistory = updateTransactionHistory;
53
+ //# sourceMappingURL=chunk-QP75SWIQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/history.ts"],"names":[],"mappings":";AAAA,OAAO,gBAAgB;AACvB,SAAS,WAAW,aAAa;AAe1B,SAAS,0BACd,iBACiB;AACjB,QAAM,WAAW,4BAA4B,eAAe;AAC5D,SAAO,MAAM,CAAC,GAAG,iBAAiB,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC;AAC3D;AAWO,SAAS,yBACd,iBACA,MACiB;AACjB,MAAI,CAAC,gBAAgB,SAAS;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,4BAA4B,eAAe;AAChE,QAAM,gBAAgB,cAAc,gBAAgB,OAAO;AAC3D,QAAM,eAAe,qBAAqB,eAAe,cAAc,IAAI;AAE3E,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,MAAM,CAAC,GAAG,iBAAiB;AAAA,MAChC,SAAS,CAAC,GAAG,gBAAgB,SAAS,YAAY;AAAA,IACpD,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAUA,SAAS,qBAGP,eACA,cACA,MACyB;AACzB,QAAM,yBAAyB,WAAW;AAAA,IACxC;AAAA,IACA;AAAA,EACF;AAEA,MAAI,uBAAuB,CAAC,GAAG;AAC7B,QAAI,MAAM;AACR,6BAAuB,CAAC,EAAE,OAAO;AAAA,IACnC;AACA,2BAAuB,CAAC,EAAE,YAAY,KAAK,IAAI;AAAA,EACjD;AACA,SAAO;AACT;AAQA,SAAS,cACP,oBACiB;AACjB,QAAM,eAAe,UAAU,kBAAkB;AACjD,SAAO,aAAa;AAAA;AAAA;AAAA,IAGlB,CAAC,KAAK,UAAe,WAAW,WAAW,KAAK,KAAK,EAAE;AAAA,EACzD;AACF;AAQA,SAAS,4BACP,iBACiB;AACjB,QAAM,WAAW,EAAE,GAAG,gBAAgB;AACtC,SAAO,SAAS;AAChB,SAAO,UAAU,QAAQ;AAC3B","sourcesContent":["import jsonDiffer from 'fast-json-patch';\nimport { cloneDeep, merge } from 'lodash';\n\nimport type {\n TransactionHistory,\n TransactionHistoryEntry,\n TransactionMeta,\n} from '../types';\n\n/**\n * Build a new version of the provided transaction with an initial history\n * entry, which is just a snapshot of the transaction.\n *\n * @param transactionMeta - TransactionMeta to add initial history snapshot to.\n * @returns A copy of `transactionMeta` with a new `history` property.\n */\nexport function addInitialHistorySnapshot(\n transactionMeta: TransactionMeta,\n): TransactionMeta {\n const snapshot = snapshotFromTransactionMeta(transactionMeta);\n return merge({}, transactionMeta, { history: [snapshot] });\n}\n\n/**\n * Builds a new version of the transaction with a new history entry if\n * it has a `history` property, or just returns the transaction.\n *\n * @param transactionMeta - TransactionMeta to add history entry to.\n * @param note - Note to add to history entry.\n * @returns A copy of `transactionMeta` with a new `history` entry if it has an\n * existing non-empty `history` array.\n */\nexport function updateTransactionHistory(\n transactionMeta: TransactionMeta,\n note: string,\n): TransactionMeta {\n if (!transactionMeta.history) {\n return transactionMeta;\n }\n\n const currentState = snapshotFromTransactionMeta(transactionMeta);\n const previousState = replayHistory(transactionMeta.history);\n const historyEntry = generateHistoryEntry(previousState, currentState, note);\n\n if (historyEntry.length > 0) {\n return merge({}, transactionMeta, {\n history: [...transactionMeta.history, historyEntry],\n });\n }\n return transactionMeta;\n}\n\n/**\n * Generates a history entry from the previous and new transaction metadata.\n *\n * @param previousState - The previous transaction metadata.\n * @param currentState - The new transaction metadata.\n * @param note - A note for the transaction metada update.\n * @returns An array of history operation.\n */\nfunction generateHistoryEntry(\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n previousState: any,\n currentState: TransactionMeta,\n note: string,\n): TransactionHistoryEntry {\n const historyOperationsEntry = jsonDiffer.compare(\n previousState,\n currentState,\n ) as TransactionHistoryEntry;\n // Add a note to the first operation, since it breaks if we append it to the entry\n if (historyOperationsEntry[0]) {\n if (note) {\n historyOperationsEntry[0].note = note;\n }\n historyOperationsEntry[0].timestamp = Date.now();\n }\n return historyOperationsEntry;\n}\n\n/**\n * Recovers previous transactionMeta from passed history array.\n *\n * @param transactionHistory - The transaction metadata to replay.\n * @returns The transaction metadata.\n */\nfunction replayHistory(\n transactionHistory: TransactionHistory,\n): TransactionMeta {\n const shortHistory = cloneDeep(transactionHistory);\n return shortHistory.reduce(\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (val, entry: any) => jsonDiffer.applyPatch(val, entry).newDocument,\n ) as TransactionMeta;\n}\n\n/**\n * Clone the transaction meta data without the history property.\n *\n * @param transactionMeta - The transaction metadata to snapshot.\n * @returns A deep clone of transaction metadata without history property.\n */\nfunction snapshotFromTransactionMeta(\n transactionMeta: TransactionMeta,\n): TransactionMeta {\n const snapshot = { ...transactionMeta };\n delete snapshot.history;\n return cloneDeep(snapshot);\n}\n"]}
@@ -0,0 +1,122 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/constants.ts
2
+ var CHAIN_IDS = {
3
+ MAINNET: "0x1",
4
+ GOERLI: "0x5",
5
+ BSC: "0x38",
6
+ BSC_TESTNET: "0x61",
7
+ OPTIMISM: "0xa",
8
+ OPTIMISM_SEPOLIA: "0xaa37dc",
9
+ POLYGON: "0x89",
10
+ POLYGON_TESTNET: "0x13881",
11
+ AVALANCHE: "0xa86a",
12
+ AVALANCHE_TESTNET: "0xa869",
13
+ FANTOM: "0xfa",
14
+ FANTOM_TESTNET: "0xfa2",
15
+ SEPOLIA: "0xaa36a7",
16
+ LINEA_GOERLI: "0xe704",
17
+ LINEA_SEPOLIA: "0xe705",
18
+ LINEA_MAINNET: "0xe708",
19
+ MOONBEAM: "0x504",
20
+ MOONBEAM_TESTNET: "0x507",
21
+ MOONRIVER: "0x505",
22
+ GNOSIS: "0x64",
23
+ ARBITRUM: "0xa4b1",
24
+ ZKSYNC_ERA: "0x144"
25
+ };
26
+ var DEFAULT_ETHERSCAN_DOMAIN = "etherscan.io";
27
+ var DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX = "api";
28
+ var ETHERSCAN_SUPPORTED_NETWORKS = {
29
+ [CHAIN_IDS.GOERLI]: {
30
+ domain: DEFAULT_ETHERSCAN_DOMAIN,
31
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-goerli`
32
+ },
33
+ [CHAIN_IDS.MAINNET]: {
34
+ domain: DEFAULT_ETHERSCAN_DOMAIN,
35
+ subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX
36
+ },
37
+ [CHAIN_IDS.SEPOLIA]: {
38
+ domain: DEFAULT_ETHERSCAN_DOMAIN,
39
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-sepolia`
40
+ },
41
+ [CHAIN_IDS.LINEA_GOERLI]: {
42
+ domain: "lineascan.build",
43
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-goerli`
44
+ },
45
+ [CHAIN_IDS.LINEA_SEPOLIA]: {
46
+ domain: "lineascan.build",
47
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-sepolia`
48
+ },
49
+ [CHAIN_IDS.LINEA_MAINNET]: {
50
+ domain: "lineascan.build",
51
+ subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX
52
+ },
53
+ [CHAIN_IDS.BSC]: {
54
+ domain: "bscscan.com",
55
+ subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX
56
+ },
57
+ [CHAIN_IDS.BSC_TESTNET]: {
58
+ domain: "bscscan.com",
59
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-testnet`
60
+ },
61
+ [CHAIN_IDS.OPTIMISM]: {
62
+ domain: DEFAULT_ETHERSCAN_DOMAIN,
63
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-optimistic`
64
+ },
65
+ [CHAIN_IDS.OPTIMISM_SEPOLIA]: {
66
+ domain: DEFAULT_ETHERSCAN_DOMAIN,
67
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-sepolia-optimistic`
68
+ },
69
+ [CHAIN_IDS.POLYGON]: {
70
+ domain: "polygonscan.com",
71
+ subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX
72
+ },
73
+ [CHAIN_IDS.POLYGON_TESTNET]: {
74
+ domain: "polygonscan.com",
75
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-mumbai`
76
+ },
77
+ [CHAIN_IDS.AVALANCHE]: {
78
+ domain: "snowtrace.io",
79
+ subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX
80
+ },
81
+ [CHAIN_IDS.AVALANCHE_TESTNET]: {
82
+ domain: "snowtrace.io",
83
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-testnet`
84
+ },
85
+ [CHAIN_IDS.FANTOM]: {
86
+ domain: "ftmscan.com",
87
+ subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX
88
+ },
89
+ [CHAIN_IDS.FANTOM_TESTNET]: {
90
+ domain: "ftmscan.com",
91
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-testnet`
92
+ },
93
+ [CHAIN_IDS.MOONBEAM]: {
94
+ domain: "moonscan.io",
95
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-moonbeam`
96
+ },
97
+ [CHAIN_IDS.MOONBEAM_TESTNET]: {
98
+ domain: "moonscan.io",
99
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-moonbase`
100
+ },
101
+ [CHAIN_IDS.MOONRIVER]: {
102
+ domain: "moonscan.io",
103
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-moonriver`
104
+ },
105
+ [CHAIN_IDS.GNOSIS]: {
106
+ domain: "gnosisscan.io",
107
+ subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-gnosis`
108
+ }
109
+ };
110
+ var GAS_BUFFER_CHAIN_OVERRIDES = {
111
+ [CHAIN_IDS.OPTIMISM]: 1,
112
+ [CHAIN_IDS.OPTIMISM_SEPOLIA]: 1
113
+ };
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+ exports.CHAIN_IDS = CHAIN_IDS; exports.DEFAULT_ETHERSCAN_DOMAIN = DEFAULT_ETHERSCAN_DOMAIN; exports.DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX = DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX; exports.ETHERSCAN_SUPPORTED_NETWORKS = ETHERSCAN_SUPPORTED_NETWORKS; exports.GAS_BUFFER_CHAIN_OVERRIDES = GAS_BUFFER_CHAIN_OVERRIDES;
122
+ //# sourceMappingURL=chunk-RI6MVJJN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants.ts"],"names":[],"mappings":"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","sourcesContent":["export const CHAIN_IDS = {\n MAINNET: '0x1',\n GOERLI: '0x5',\n BSC: '0x38',\n BSC_TESTNET: '0x61',\n OPTIMISM: '0xa',\n OPTIMISM_SEPOLIA: '0xaa37dc',\n POLYGON: '0x89',\n POLYGON_TESTNET: '0x13881',\n AVALANCHE: '0xa86a',\n AVALANCHE_TESTNET: '0xa869',\n FANTOM: '0xfa',\n FANTOM_TESTNET: '0xfa2',\n SEPOLIA: '0xaa36a7',\n LINEA_GOERLI: '0xe704',\n LINEA_SEPOLIA: '0xe705',\n LINEA_MAINNET: '0xe708',\n MOONBEAM: '0x504',\n MOONBEAM_TESTNET: '0x507',\n MOONRIVER: '0x505',\n GNOSIS: '0x64',\n ARBITRUM: '0xa4b1',\n ZKSYNC_ERA: '0x144',\n} as const;\n\nexport const DEFAULT_ETHERSCAN_DOMAIN = 'etherscan.io';\nexport const DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX = 'api';\n\nexport const ETHERSCAN_SUPPORTED_NETWORKS = {\n [CHAIN_IDS.GOERLI]: {\n domain: DEFAULT_ETHERSCAN_DOMAIN,\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-goerli`,\n },\n [CHAIN_IDS.MAINNET]: {\n domain: DEFAULT_ETHERSCAN_DOMAIN,\n subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX,\n },\n [CHAIN_IDS.SEPOLIA]: {\n domain: DEFAULT_ETHERSCAN_DOMAIN,\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-sepolia`,\n },\n [CHAIN_IDS.LINEA_GOERLI]: {\n domain: 'lineascan.build',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-goerli`,\n },\n [CHAIN_IDS.LINEA_SEPOLIA]: {\n domain: 'lineascan.build',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-sepolia`,\n },\n [CHAIN_IDS.LINEA_MAINNET]: {\n domain: 'lineascan.build',\n subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX,\n },\n [CHAIN_IDS.BSC]: {\n domain: 'bscscan.com',\n subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX,\n },\n [CHAIN_IDS.BSC_TESTNET]: {\n domain: 'bscscan.com',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-testnet`,\n },\n [CHAIN_IDS.OPTIMISM]: {\n domain: DEFAULT_ETHERSCAN_DOMAIN,\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-optimistic`,\n },\n [CHAIN_IDS.OPTIMISM_SEPOLIA]: {\n domain: DEFAULT_ETHERSCAN_DOMAIN,\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-sepolia-optimistic`,\n },\n [CHAIN_IDS.POLYGON]: {\n domain: 'polygonscan.com',\n subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX,\n },\n [CHAIN_IDS.POLYGON_TESTNET]: {\n domain: 'polygonscan.com',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-mumbai`,\n },\n [CHAIN_IDS.AVALANCHE]: {\n domain: 'snowtrace.io',\n subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX,\n },\n [CHAIN_IDS.AVALANCHE_TESTNET]: {\n domain: 'snowtrace.io',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-testnet`,\n },\n [CHAIN_IDS.FANTOM]: {\n domain: 'ftmscan.com',\n subdomain: DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX,\n },\n [CHAIN_IDS.FANTOM_TESTNET]: {\n domain: 'ftmscan.com',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-testnet`,\n },\n [CHAIN_IDS.MOONBEAM]: {\n domain: 'moonscan.io',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-moonbeam`,\n },\n [CHAIN_IDS.MOONBEAM_TESTNET]: {\n domain: 'moonscan.io',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-moonbase`,\n },\n [CHAIN_IDS.MOONRIVER]: {\n domain: 'moonscan.io',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-moonriver`,\n },\n [CHAIN_IDS.GNOSIS]: {\n domain: 'gnosisscan.io',\n subdomain: `${DEFAULT_ETHERSCAN_SUBDOMAIN_PREFIX}-gnosis`,\n },\n};\n\nexport const GAS_BUFFER_CHAIN_OVERRIDES = {\n [CHAIN_IDS.OPTIMISM]: 1,\n [CHAIN_IDS.OPTIMISM_SEPOLIA]: 1,\n};\n"]}
@@ -0,0 +1,14 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/logger.ts
2
+ var _utils = require('@metamask/utils');
3
+ var projectLogger = _utils.createProjectLogger.call(void 0, "transaction-controller");
4
+ var incomingTransactionsLogger = _utils.createModuleLogger.call(void 0,
5
+ projectLogger,
6
+ "incoming-transactions"
7
+ );
8
+
9
+
10
+
11
+
12
+
13
+ exports.createModuleLogger = _utils.createModuleLogger; exports.projectLogger = projectLogger; exports.incomingTransactionsLogger = incomingTransactionsLogger;
14
+ //# sourceMappingURL=chunk-S6VGOPUY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logger.ts"],"names":[],"mappings":";AAEA,SAAS,qBAAqB,0BAA0B;AAEjD,IAAM,gBAAgB,oBAAoB,wBAAwB;AAElE,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AACF","sourcesContent":["/* istanbul ignore file */\n\nimport { createProjectLogger, createModuleLogger } from '@metamask/utils';\n\nexport const projectLogger = createProjectLogger('transaction-controller');\n\nexport const incomingTransactionsLogger = createModuleLogger(\n projectLogger,\n 'incoming-transactions',\n);\n\nexport { createModuleLogger };\n"]}
@@ -0,0 +1,123 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/utils/utils.ts
2
+ var _controllerutils = require('@metamask/controller-utils');
3
+
4
+
5
+
6
+
7
+ var _utils = require('@metamask/utils');
8
+ var ESTIMATE_GAS_ERROR = "eth_estimateGas rpc method error";
9
+ var NORMALIZERS = {
10
+ data: (data) => _utils.add0x.call(void 0, padHexToEvenLength(data)),
11
+ from: (from) => _utils.add0x.call(void 0, from).toLowerCase(),
12
+ gas: (gas) => _utils.add0x.call(void 0, gas),
13
+ gasLimit: (gas) => _utils.add0x.call(void 0, gas),
14
+ gasPrice: (gasPrice) => _utils.add0x.call(void 0, gasPrice),
15
+ nonce: (nonce) => _utils.add0x.call(void 0, nonce),
16
+ to: (to) => _utils.add0x.call(void 0, to).toLowerCase(),
17
+ value: (value) => _utils.add0x.call(void 0, value),
18
+ maxFeePerGas: (maxFeePerGas) => _utils.add0x.call(void 0, maxFeePerGas),
19
+ maxPriorityFeePerGas: (maxPriorityFeePerGas) => _utils.add0x.call(void 0, maxPriorityFeePerGas),
20
+ estimatedBaseFee: (maxPriorityFeePerGas) => _utils.add0x.call(void 0, maxPriorityFeePerGas),
21
+ type: (type) => _utils.add0x.call(void 0, type)
22
+ };
23
+ function normalizeTransactionParams(txParams) {
24
+ const normalizedTxParams = { from: "" };
25
+ for (const key of _utils.getKnownPropertyNames.call(void 0, NORMALIZERS)) {
26
+ if (txParams[key]) {
27
+ normalizedTxParams[key] = NORMALIZERS[key](txParams[key]);
28
+ }
29
+ }
30
+ if (!normalizedTxParams.value) {
31
+ normalizedTxParams.value = "0x0";
32
+ }
33
+ return normalizedTxParams;
34
+ }
35
+ function isEIP1559Transaction(txParams) {
36
+ const hasOwnProp = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
37
+ return hasOwnProp(txParams, "maxFeePerGas") && hasOwnProp(txParams, "maxPriorityFeePerGas");
38
+ }
39
+ var validateGasValues = (gasValues) => {
40
+ Object.keys(gasValues).forEach((key) => {
41
+ const value = gasValues[key];
42
+ if (typeof value !== "string" || !_utils.isStrictHexString.call(void 0, value)) {
43
+ throw new TypeError(
44
+ `expected hex string for ${key} but received: ${value}`
45
+ );
46
+ }
47
+ });
48
+ };
49
+ var isFeeMarketEIP1559Values = (gasValues) => gasValues?.maxFeePerGas !== void 0 || gasValues?.maxPriorityFeePerGas !== void 0;
50
+ var isGasPriceValue = (gasValues) => gasValues?.gasPrice !== void 0;
51
+ var getIncreasedPriceHex = (value, rate) => _utils.add0x.call(void 0, `${parseInt(`${value * rate}`, 10).toString(16)}`);
52
+ var getIncreasedPriceFromExisting = (value, rate) => {
53
+ return getIncreasedPriceHex(_controllerutils.convertHexToDecimal.call(void 0, value), rate);
54
+ };
55
+ function validateMinimumIncrease(proposed, min) {
56
+ const proposedDecimal = _controllerutils.convertHexToDecimal.call(void 0, proposed);
57
+ const minDecimal = _controllerutils.convertHexToDecimal.call(void 0, min);
58
+ if (proposedDecimal >= minDecimal) {
59
+ return proposed;
60
+ }
61
+ const errorMsg = `The proposed value: ${proposedDecimal} should meet or exceed the minimum value: ${minDecimal}`;
62
+ throw new Error(errorMsg);
63
+ }
64
+ function validateIfTransactionUnapproved(transactionMeta, fnName) {
65
+ if (transactionMeta?.status !== "unapproved" /* unapproved */) {
66
+ throw new Error(
67
+ `TransactionsController: Can only call ${fnName} on an unapproved transaction.
68
+ Current tx status: ${transactionMeta?.status}`
69
+ );
70
+ }
71
+ }
72
+ function normalizeTxError(error) {
73
+ return {
74
+ name: error.name,
75
+ message: error.message,
76
+ stack: error.stack,
77
+ code: error.code,
78
+ rpc: isJsonCompatible(error.value) ? error.value : void 0
79
+ };
80
+ }
81
+ function normalizeGasFeeValues(gasFeeValues) {
82
+ const normalize = (value) => typeof value === "string" ? _utils.add0x.call(void 0, value) : value;
83
+ if ("gasPrice" in gasFeeValues) {
84
+ return {
85
+ gasPrice: normalize(gasFeeValues.gasPrice)
86
+ };
87
+ }
88
+ return {
89
+ maxFeePerGas: normalize(gasFeeValues.maxFeePerGas),
90
+ maxPriorityFeePerGas: normalize(gasFeeValues.maxPriorityFeePerGas)
91
+ };
92
+ }
93
+ function isJsonCompatible(value) {
94
+ try {
95
+ JSON.parse(JSON.stringify(value));
96
+ return true;
97
+ } catch {
98
+ return false;
99
+ }
100
+ }
101
+ function padHexToEvenLength(hex) {
102
+ const prefix = hex.toLowerCase().startsWith("0x") ? hex.slice(0, 2) : "";
103
+ const data = prefix ? hex.slice(2) : hex;
104
+ const evenData = data.length % 2 === 0 ? data : `0${data}`;
105
+ return prefix + evenData;
106
+ }
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+ exports.ESTIMATE_GAS_ERROR = ESTIMATE_GAS_ERROR; exports.normalizeTransactionParams = normalizeTransactionParams; exports.isEIP1559Transaction = isEIP1559Transaction; exports.validateGasValues = validateGasValues; exports.isFeeMarketEIP1559Values = isFeeMarketEIP1559Values; exports.isGasPriceValue = isGasPriceValue; exports.getIncreasedPriceHex = getIncreasedPriceHex; exports.getIncreasedPriceFromExisting = getIncreasedPriceFromExisting; exports.validateMinimumIncrease = validateMinimumIncrease; exports.validateIfTransactionUnapproved = validateIfTransactionUnapproved; exports.normalizeTxError = normalizeTxError; exports.normalizeGasFeeValues = normalizeGasFeeValues; exports.padHexToEvenLength = padHexToEvenLength;
123
+ //# sourceMappingURL=chunk-UGFBA4GV.js.map