@metamask/transaction-controller 36.1.0 → 37.1.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 (480) hide show
  1. package/CHANGELOG.md +47 -1
  2. package/dist/TransactionController.cjs +2071 -0
  3. package/dist/TransactionController.cjs.map +1 -0
  4. package/dist/{types/TransactionController.d.ts → TransactionController.d.cts} +19 -26
  5. package/dist/TransactionController.d.cts.map +1 -0
  6. package/dist/TransactionController.d.mts +828 -0
  7. package/dist/TransactionController.d.mts.map +1 -0
  8. package/dist/TransactionController.mjs +2072 -44
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/constants.cjs +170 -0
  11. package/dist/constants.cjs.map +1 -0
  12. package/dist/{types/constants.d.ts → constants.d.cts} +1 -1
  13. package/dist/constants.d.cts.map +1 -0
  14. package/dist/constants.d.mts +143 -0
  15. package/dist/constants.d.mts.map +1 -0
  16. package/dist/constants.mjs +165 -18
  17. package/dist/constants.mjs.map +1 -1
  18. package/dist/errors.cjs +30 -0
  19. package/dist/{chunk-HMOSP33F.js.map → errors.cjs.map} +1 -1
  20. package/dist/{types/errors.d.ts → errors.d.cts} +2 -2
  21. package/dist/errors.d.cts.map +1 -0
  22. package/dist/errors.d.mts +15 -0
  23. package/dist/errors.d.mts.map +1 -0
  24. package/dist/errors.mjs +22 -14
  25. package/dist/errors.mjs.map +1 -1
  26. package/dist/gas-flows/DefaultGasFeeFlow.cjs +87 -0
  27. package/dist/gas-flows/DefaultGasFeeFlow.cjs.map +1 -0
  28. package/dist/{types/gas-flows/DefaultGasFeeFlow.d.ts → gas-flows/DefaultGasFeeFlow.d.cts} +2 -2
  29. package/dist/gas-flows/DefaultGasFeeFlow.d.cts.map +1 -0
  30. package/dist/gas-flows/DefaultGasFeeFlow.d.mts +10 -0
  31. package/dist/gas-flows/DefaultGasFeeFlow.d.mts.map +1 -0
  32. package/dist/gas-flows/DefaultGasFeeFlow.mjs +81 -13
  33. package/dist/gas-flows/DefaultGasFeeFlow.mjs.map +1 -1
  34. package/dist/gas-flows/LineaGasFeeFlow.cjs +102 -0
  35. package/dist/gas-flows/LineaGasFeeFlow.cjs.map +1 -0
  36. package/dist/{types/gas-flows/LineaGasFeeFlow.d.ts → gas-flows/LineaGasFeeFlow.d.cts} +2 -2
  37. package/dist/gas-flows/LineaGasFeeFlow.d.cts.map +1 -0
  38. package/dist/gas-flows/LineaGasFeeFlow.d.mts +12 -0
  39. package/dist/gas-flows/LineaGasFeeFlow.d.mts.map +1 -0
  40. package/dist/gas-flows/LineaGasFeeFlow.mjs +96 -14
  41. package/dist/gas-flows/LineaGasFeeFlow.mjs.map +1 -1
  42. package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs +29 -0
  43. package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs.map +1 -0
  44. package/dist/{types/gas-flows/OptimismLayer1GasFeeFlow.d.ts → gas-flows/OptimismLayer1GasFeeFlow.d.cts} +3 -3
  45. package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.cts.map +1 -0
  46. package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts +10 -0
  47. package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts.map +1 -0
  48. package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs +24 -10
  49. package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs.map +1 -1
  50. package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs +92 -0
  51. package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs.map +1 -0
  52. package/dist/{types/gas-flows/OracleLayer1GasFeeFlow.d.ts → gas-flows/OracleLayer1GasFeeFlow.d.cts} +3 -3
  53. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts.map +1 -0
  54. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts +12 -0
  55. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts.map +1 -0
  56. package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs +88 -7
  57. package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs.map +1 -1
  58. package/dist/gas-flows/ScrollLayer1GasFeeFlow.cjs +21 -0
  59. package/dist/gas-flows/ScrollLayer1GasFeeFlow.cjs.map +1 -0
  60. package/dist/{types/gas-flows/ScrollLayer1GasFeeFlow.d.ts → gas-flows/ScrollLayer1GasFeeFlow.d.cts} +3 -3
  61. package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.cts.map +1 -0
  62. package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.mts +10 -0
  63. package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.mts.map +1 -0
  64. package/dist/gas-flows/ScrollLayer1GasFeeFlow.mjs +16 -10
  65. package/dist/gas-flows/ScrollLayer1GasFeeFlow.mjs.map +1 -1
  66. package/dist/gas-flows/TestGasFeeFlow.cjs +73 -0
  67. package/dist/{chunk-FMRLPVFZ.mjs.map → gas-flows/TestGasFeeFlow.cjs.map} +1 -1
  68. package/dist/{types/gas-flows/TestGasFeeFlow.d.ts → gas-flows/TestGasFeeFlow.d.cts} +2 -2
  69. package/dist/gas-flows/TestGasFeeFlow.d.cts.map +1 -0
  70. package/dist/gas-flows/TestGasFeeFlow.d.mts +12 -0
  71. package/dist/gas-flows/TestGasFeeFlow.d.mts.map +1 -0
  72. package/dist/gas-flows/TestGasFeeFlow.mjs +67 -7
  73. package/dist/gas-flows/TestGasFeeFlow.mjs.map +1 -1
  74. package/dist/helpers/EtherscanRemoteTransactionSource.cjs +149 -0
  75. package/dist/helpers/EtherscanRemoteTransactionSource.cjs.map +1 -0
  76. package/dist/{types/helpers/EtherscanRemoteTransactionSource.d.ts → helpers/EtherscanRemoteTransactionSource.d.cts} +3 -3
  77. package/dist/helpers/EtherscanRemoteTransactionSource.d.cts.map +1 -0
  78. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts +15 -0
  79. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts.map +1 -0
  80. package/dist/helpers/EtherscanRemoteTransactionSource.mjs +147 -10
  81. package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +1 -1
  82. package/dist/helpers/GasFeePoller.cjs +185 -0
  83. package/dist/helpers/GasFeePoller.cjs.map +1 -0
  84. package/dist/{types/helpers/GasFeePoller.d.ts → helpers/GasFeePoller.d.cts} +7 -7
  85. package/dist/helpers/GasFeePoller.d.cts.map +1 -0
  86. package/dist/helpers/GasFeePoller.d.mts +35 -0
  87. package/dist/helpers/GasFeePoller.d.mts.map +1 -0
  88. package/dist/helpers/GasFeePoller.mjs +183 -10
  89. package/dist/helpers/GasFeePoller.mjs.map +1 -1
  90. package/dist/helpers/IncomingTransactionHelper.cjs +199 -0
  91. package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -0
  92. package/dist/{types/helpers/IncomingTransactionHelper.d.ts → helpers/IncomingTransactionHelper.d.cts} +6 -6
  93. package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -0
  94. package/dist/helpers/IncomingTransactionHelper.d.mts +40 -0
  95. package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -0
  96. package/dist/helpers/IncomingTransactionHelper.mjs +190 -7
  97. package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
  98. package/dist/helpers/MultichainTrackingHelper.cjs +284 -0
  99. package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -0
  100. package/dist/{types/helpers/MultichainTrackingHelper.d.ts → helpers/MultichainTrackingHelper.d.cts} +8 -8
  101. package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -0
  102. package/dist/helpers/MultichainTrackingHelper.d.mts +76 -0
  103. package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -0
  104. package/dist/helpers/MultichainTrackingHelper.mjs +282 -11
  105. package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
  106. package/dist/helpers/PendingTransactionTracker.cjs +327 -0
  107. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -0
  108. package/dist/{types/helpers/PendingTransactionTracker.d.ts → helpers/PendingTransactionTracker.d.cts} +7 -8
  109. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -0
  110. package/dist/helpers/PendingTransactionTracker.d.mts +42 -0
  111. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -0
  112. package/dist/helpers/PendingTransactionTracker.mjs +319 -8
  113. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  114. package/dist/index.cjs +32 -0
  115. package/dist/index.cjs.map +1 -0
  116. package/dist/{types/index.d.ts → index.d.cts} +11 -10
  117. package/dist/index.d.cts.map +1 -0
  118. package/dist/index.d.mts +11 -0
  119. package/dist/index.d.mts.map +1 -0
  120. package/dist/index.mjs +7 -76
  121. package/dist/index.mjs.map +1 -1
  122. package/dist/logger.cjs +9 -0
  123. package/dist/logger.cjs.map +1 -0
  124. package/dist/{types/logger.d.ts → logger.d.cts} +2 -2
  125. package/dist/logger.d.cts.map +1 -0
  126. package/dist/logger.d.mts +6 -0
  127. package/dist/logger.d.mts.map +1 -0
  128. package/dist/logger.mjs +5 -11
  129. package/dist/logger.mjs.map +1 -1
  130. package/dist/types.cjs +308 -0
  131. package/dist/types.cjs.map +1 -0
  132. package/dist/{types/types.d.ts → types.d.cts} +35 -35
  133. package/dist/types.d.cts.map +1 -0
  134. package/dist/types.d.mts +1027 -0
  135. package/dist/types.d.mts.map +1 -0
  136. package/dist/types.mjs +304 -23
  137. package/dist/types.mjs.map +1 -1
  138. package/dist/utils/etherscan.cjs +111 -0
  139. package/dist/utils/etherscan.cjs.map +1 -0
  140. package/dist/{types/utils/etherscan.d.ts → utils/etherscan.d.cts} +2 -2
  141. package/dist/utils/etherscan.d.cts.map +1 -0
  142. package/dist/utils/etherscan.d.mts +71 -0
  143. package/dist/utils/etherscan.d.mts.map +1 -0
  144. package/dist/utils/etherscan.mjs +104 -13
  145. package/dist/utils/etherscan.mjs.map +1 -1
  146. package/dist/utils/external-transactions.cjs +36 -0
  147. package/dist/utils/external-transactions.cjs.map +1 -0
  148. package/dist/{types/utils/external-transactions.d.ts → utils/external-transactions.d.cts} +2 -2
  149. package/dist/utils/external-transactions.d.cts.map +1 -0
  150. package/dist/utils/external-transactions.d.mts +10 -0
  151. package/dist/utils/external-transactions.d.mts.map +1 -0
  152. package/dist/utils/external-transactions.mjs +31 -8
  153. package/dist/utils/external-transactions.mjs.map +1 -1
  154. package/dist/utils/gas-fees.cjs +208 -0
  155. package/dist/utils/gas-fees.cjs.map +1 -0
  156. package/dist/{types/utils/gas-fees.d.ts → utils/gas-fees.d.cts} +5 -5
  157. package/dist/utils/gas-fees.d.cts.map +1 -0
  158. package/dist/utils/gas-fees.d.mts +26 -0
  159. package/dist/utils/gas-fees.d.mts.map +1 -0
  160. package/dist/utils/gas-fees.mjs +202 -15
  161. package/dist/utils/gas-fees.mjs.map +1 -1
  162. package/dist/utils/gas-flow.cjs +76 -0
  163. package/dist/utils/gas-flow.cjs.map +1 -0
  164. package/dist/{types/utils/gas-flow.d.ts → utils/gas-flow.d.cts} +5 -5
  165. package/dist/utils/gas-flow.d.cts.map +1 -0
  166. package/dist/utils/gas-flow.d.mts +26 -0
  167. package/dist/utils/gas-flow.d.mts.map +1 -0
  168. package/dist/utils/gas-flow.mjs +70 -10
  169. package/dist/utils/gas-flow.mjs.map +1 -1
  170. package/dist/utils/gas.cjs +112 -0
  171. package/dist/utils/gas.cjs.map +1 -0
  172. package/dist/{types/utils/gas.d.ts → utils/gas.d.cts} +4 -4
  173. package/dist/utils/gas.d.cts.map +1 -0
  174. package/dist/utils/gas.d.mts +28 -0
  175. package/dist/utils/gas.d.mts.map +1 -0
  176. package/dist/utils/gas.mjs +105 -19
  177. package/dist/utils/gas.mjs.map +1 -1
  178. package/dist/utils/history.cjs +164 -0
  179. package/dist/utils/history.cjs.map +1 -0
  180. package/dist/{types/utils/history.d.ts → utils/history.d.cts} +2 -2
  181. package/dist/utils/history.d.cts.map +1 -0
  182. package/dist/utils/history.d.mts +29 -0
  183. package/dist/utils/history.d.mts.map +1 -0
  184. package/dist/utils/history.mjs +163 -13
  185. package/dist/utils/history.mjs.map +1 -1
  186. package/dist/utils/layer1-gas-fee-flow.cjs +59 -0
  187. package/dist/utils/layer1-gas-fee-flow.cjs.map +1 -0
  188. package/dist/{types/utils/layer1-gas-fee-flow.d.ts → utils/layer1-gas-fee-flow.d.cts} +4 -4
  189. package/dist/utils/layer1-gas-fee-flow.d.cts.map +1 -0
  190. package/dist/utils/layer1-gas-fee-flow.d.mts +25 -0
  191. package/dist/utils/layer1-gas-fee-flow.d.mts.map +1 -0
  192. package/dist/utils/layer1-gas-fee-flow.mjs +53 -10
  193. package/dist/utils/layer1-gas-fee-flow.mjs.map +1 -1
  194. package/dist/utils/nonce.cjs +66 -0
  195. package/dist/utils/nonce.cjs.map +1 -0
  196. package/dist/{types/utils/nonce.d.ts → utils/nonce.d.cts} +3 -3
  197. package/dist/utils/nonce.d.cts.map +1 -0
  198. package/dist/utils/nonce.d.mts +21 -0
  199. package/dist/utils/nonce.d.mts.map +1 -0
  200. package/dist/utils/nonce.mjs +60 -10
  201. package/dist/utils/nonce.mjs.map +1 -1
  202. package/dist/utils/retry.cjs +89 -0
  203. package/dist/utils/retry.cjs.map +1 -0
  204. package/dist/{types/utils/retry.d.ts → utils/retry.d.cts} +3 -3
  205. package/dist/utils/retry.d.cts.map +1 -0
  206. package/dist/utils/retry.d.mts +11 -0
  207. package/dist/utils/retry.d.mts.map +1 -0
  208. package/dist/utils/retry.mjs +84 -7
  209. package/dist/utils/retry.mjs.map +1 -1
  210. package/dist/utils/simulation-api.cjs +72 -0
  211. package/dist/utils/simulation-api.cjs.map +1 -0
  212. package/dist/{types/utils/simulation-api.d.ts → utils/simulation-api.d.cts} +2 -2
  213. package/dist/utils/simulation-api.d.cts.map +1 -0
  214. package/dist/utils/simulation-api.d.mts +107 -0
  215. package/dist/utils/simulation-api.d.mts.map +1 -0
  216. package/dist/utils/simulation-api.mjs +67 -10
  217. package/dist/utils/simulation-api.mjs.map +1 -1
  218. package/dist/utils/simulation.cjs +443 -0
  219. package/dist/utils/simulation.cjs.map +1 -0
  220. package/dist/{types/utils/simulation.d.ts → utils/simulation.d.cts} +6 -6
  221. package/dist/utils/simulation.d.cts.map +1 -0
  222. package/dist/utils/simulation.d.mts +46 -0
  223. package/dist/utils/simulation.d.mts.map +1 -0
  224. package/dist/utils/simulation.mjs +436 -15
  225. package/dist/utils/simulation.mjs.map +1 -1
  226. package/dist/utils/swaps.cjs +309 -0
  227. package/dist/utils/swaps.cjs.map +1 -0
  228. package/dist/{types/utils/swaps.d.ts → utils/swaps.d.cts} +5 -5
  229. package/dist/utils/swaps.d.cts.map +1 -0
  230. package/dist/utils/swaps.d.mts +84 -0
  231. package/dist/utils/swaps.d.mts.map +1 -0
  232. package/dist/utils/swaps.mjs +303 -22
  233. package/dist/utils/swaps.mjs.map +1 -1
  234. package/dist/utils/transaction-type.cjs +115 -0
  235. package/dist/utils/transaction-type.cjs.map +1 -0
  236. package/dist/{types/utils/transaction-type.d.ts → utils/transaction-type.d.cts} +3 -3
  237. package/dist/utils/transaction-type.d.cts.map +1 -0
  238. package/dist/utils/transaction-type.d.mts +14 -0
  239. package/dist/utils/transaction-type.d.mts.map +1 -0
  240. package/dist/utils/transaction-type.mjs +110 -10
  241. package/dist/utils/transaction-type.mjs.map +1 -1
  242. package/dist/utils/utils.cjs +151 -0
  243. package/dist/utils/utils.cjs.map +1 -0
  244. package/dist/{types/utils/utils.d.ts → utils/utils.d.cts} +2 -2
  245. package/dist/utils/utils.d.cts.map +1 -0
  246. package/dist/utils/utils.d.mts +52 -0
  247. package/dist/utils/utils.d.mts.map +1 -0
  248. package/dist/utils/utils.mjs +139 -21
  249. package/dist/utils/utils.mjs.map +1 -1
  250. package/dist/utils/validation.cjs +267 -0
  251. package/dist/{chunk-4OYPDGHO.js.map → utils/validation.cjs.map} +1 -1
  252. package/dist/{types/utils/validation.d.ts → utils/validation.d.cts} +2 -2
  253. package/dist/utils/validation.d.cts.map +1 -0
  254. package/dist/utils/validation.d.mts +20 -0
  255. package/dist/utils/validation.d.mts.map +1 -0
  256. package/dist/utils/validation.mjs +261 -11
  257. package/dist/utils/validation.mjs.map +1 -1
  258. package/package.json +20 -15
  259. package/dist/TransactionController.js +0 -46
  260. package/dist/TransactionController.js.map +0 -1
  261. package/dist/chunk-2XKEAKQG.js +0 -55
  262. package/dist/chunk-2XKEAKQG.js.map +0 -1
  263. package/dist/chunk-3AVRGHUO.mjs +0 -360
  264. package/dist/chunk-3AVRGHUO.mjs.map +0 -1
  265. package/dist/chunk-3ZV5YEUV.mjs +0 -239
  266. package/dist/chunk-3ZV5YEUV.mjs.map +0 -1
  267. package/dist/chunk-4OYPDGHO.js +0 -201
  268. package/dist/chunk-4V4XIPCI.mjs +0 -338
  269. package/dist/chunk-4V4XIPCI.mjs.map +0 -1
  270. package/dist/chunk-5G6OHAXI.mjs +0 -137
  271. package/dist/chunk-5G6OHAXI.mjs.map +0 -1
  272. package/dist/chunk-5HYWLTVQ.js +0 -228
  273. package/dist/chunk-5HYWLTVQ.js.map +0 -1
  274. package/dist/chunk-5QVDIVJH.js +0 -68
  275. package/dist/chunk-5QVDIVJH.js.map +0 -1
  276. package/dist/chunk-6B5BEO3R.mjs +0 -399
  277. package/dist/chunk-6B5BEO3R.mjs.map +0 -1
  278. package/dist/chunk-6DDVVUJC.mjs +0 -50
  279. package/dist/chunk-6DDVVUJC.mjs.map +0 -1
  280. package/dist/chunk-6OLJWLKK.js +0 -338
  281. package/dist/chunk-6OLJWLKK.js.map +0 -1
  282. package/dist/chunk-7LXE4KHV.js +0 -40
  283. package/dist/chunk-7LXE4KHV.js.map +0 -1
  284. package/dist/chunk-7NMV2NPM.js +0 -172
  285. package/dist/chunk-7NMV2NPM.js.map +0 -1
  286. package/dist/chunk-AWIJZAW3.mjs +0 -112
  287. package/dist/chunk-AWIJZAW3.mjs.map +0 -1
  288. package/dist/chunk-BZV72SCF.js +0 -226
  289. package/dist/chunk-BZV72SCF.js.map +0 -1
  290. package/dist/chunk-EGQCE3FK.mjs +0 -85
  291. package/dist/chunk-EGQCE3FK.mjs.map +0 -1
  292. package/dist/chunk-EHWAY6XU.js +0 -112
  293. package/dist/chunk-EHWAY6XU.js.map +0 -1
  294. package/dist/chunk-EKJXGERC.mjs +0 -172
  295. package/dist/chunk-EKJXGERC.mjs.map +0 -1
  296. package/dist/chunk-FG74Z3F5.mjs +0 -102
  297. package/dist/chunk-FG74Z3F5.mjs.map +0 -1
  298. package/dist/chunk-FMRLPVFZ.mjs +0 -66
  299. package/dist/chunk-FRKQ3Z2L.mjs +0 -40
  300. package/dist/chunk-FRKQ3Z2L.mjs.map +0 -1
  301. package/dist/chunk-HMOSP33F.js +0 -36
  302. package/dist/chunk-HQSNKCXI.mjs +0 -36
  303. package/dist/chunk-HQSNKCXI.mjs.map +0 -1
  304. package/dist/chunk-JIFPK37W.mjs +0 -257
  305. package/dist/chunk-JIFPK37W.mjs.map +0 -1
  306. package/dist/chunk-JOQK7A5G.mjs +0 -68
  307. package/dist/chunk-JOQK7A5G.mjs.map +0 -1
  308. package/dist/chunk-K4KOSAGM.mjs +0 -61
  309. package/dist/chunk-K4KOSAGM.mjs.map +0 -1
  310. package/dist/chunk-KG4UW4K4.mjs +0 -88
  311. package/dist/chunk-KG4UW4K4.mjs.map +0 -1
  312. package/dist/chunk-KT6UAKBB.js +0 -61
  313. package/dist/chunk-KT6UAKBB.js.map +0 -1
  314. package/dist/chunk-KTGMNUTQ.js +0 -106
  315. package/dist/chunk-KTGMNUTQ.js.map +0 -1
  316. package/dist/chunk-KYRW4BLA.mjs +0 -121
  317. package/dist/chunk-KYRW4BLA.mjs.map +0 -1
  318. package/dist/chunk-LFFYCDHB.mjs +0 -92
  319. package/dist/chunk-LFFYCDHB.mjs.map +0 -1
  320. package/dist/chunk-NNCUD3QF.js +0 -360
  321. package/dist/chunk-NNCUD3QF.js.map +0 -1
  322. package/dist/chunk-NNHSNPT2.mjs +0 -67
  323. package/dist/chunk-NNHSNPT2.mjs.map +0 -1
  324. package/dist/chunk-NOHEXQ7Y.mjs +0 -55
  325. package/dist/chunk-NOHEXQ7Y.mjs.map +0 -1
  326. package/dist/chunk-NYKRCWBG.js +0 -31
  327. package/dist/chunk-NYKRCWBG.js.map +0 -1
  328. package/dist/chunk-O6ZZVIFH.mjs +0 -176
  329. package/dist/chunk-O6ZZVIFH.mjs.map +0 -1
  330. package/dist/chunk-PRUNMTRD.js +0 -50
  331. package/dist/chunk-PRUNMTRD.js.map +0 -1
  332. package/dist/chunk-PSZ34BI5.js +0 -92
  333. package/dist/chunk-PSZ34BI5.js.map +0 -1
  334. package/dist/chunk-QKV7E5BO.js +0 -257
  335. package/dist/chunk-QKV7E5BO.js.map +0 -1
  336. package/dist/chunk-RHDPOIS4.js +0 -239
  337. package/dist/chunk-RHDPOIS4.js.map +0 -1
  338. package/dist/chunk-S6VGOPUY.js +0 -14
  339. package/dist/chunk-S6VGOPUY.js.map +0 -1
  340. package/dist/chunk-SD6CWFDF.js +0 -88
  341. package/dist/chunk-SD6CWFDF.js.map +0 -1
  342. package/dist/chunk-SFFOC25Q.mjs +0 -226
  343. package/dist/chunk-SFFOC25Q.mjs.map +0 -1
  344. package/dist/chunk-SMC5Q6ZH.mjs +0 -120
  345. package/dist/chunk-SMC5Q6ZH.mjs.map +0 -1
  346. package/dist/chunk-TIE3CPF7.js +0 -120
  347. package/dist/chunk-TIE3CPF7.js.map +0 -1
  348. package/dist/chunk-TJMQEH57.js +0 -66
  349. package/dist/chunk-TJMQEH57.js.map +0 -1
  350. package/dist/chunk-UGN7PBON.js +0 -176
  351. package/dist/chunk-UGN7PBON.js.map +0 -1
  352. package/dist/chunk-UHAFIPSL.js +0 -121
  353. package/dist/chunk-UHAFIPSL.js.map +0 -1
  354. package/dist/chunk-UHSRHP55.mjs +0 -106
  355. package/dist/chunk-UHSRHP55.mjs.map +0 -1
  356. package/dist/chunk-ULD4JC3Q.js +0 -399
  357. package/dist/chunk-ULD4JC3Q.js.map +0 -1
  358. package/dist/chunk-UQQWZT6C.mjs +0 -14
  359. package/dist/chunk-UQQWZT6C.mjs.map +0 -1
  360. package/dist/chunk-V72C4MCR.js +0 -137
  361. package/dist/chunk-V72C4MCR.js.map +0 -1
  362. package/dist/chunk-VEVVBHP3.mjs +0 -31
  363. package/dist/chunk-VEVVBHP3.mjs.map +0 -1
  364. package/dist/chunk-VGFPVAKX.mjs +0 -228
  365. package/dist/chunk-VGFPVAKX.mjs.map +0 -1
  366. package/dist/chunk-VKWOHNDO.js +0 -2509
  367. package/dist/chunk-VKWOHNDO.js.map +0 -1
  368. package/dist/chunk-WR5F34OW.js +0 -23
  369. package/dist/chunk-WR5F34OW.js.map +0 -1
  370. package/dist/chunk-X4XSEYPL.mjs +0 -201
  371. package/dist/chunk-X4XSEYPL.mjs.map +0 -1
  372. package/dist/chunk-XTMJ25EF.mjs +0 -2509
  373. package/dist/chunk-XTMJ25EF.mjs.map +0 -1
  374. package/dist/chunk-XUI43LEZ.mjs +0 -30
  375. package/dist/chunk-XUI43LEZ.mjs.map +0 -1
  376. package/dist/chunk-XVYXRCRL.js +0 -85
  377. package/dist/chunk-XVYXRCRL.js.map +0 -1
  378. package/dist/chunk-YVCX6Z75.js +0 -102
  379. package/dist/chunk-YVCX6Z75.js.map +0 -1
  380. package/dist/chunk-YWLMT7XH.js +0 -67
  381. package/dist/chunk-YWLMT7XH.js.map +0 -1
  382. package/dist/chunk-Z4BLTVTB.js +0 -30
  383. package/dist/chunk-Z4BLTVTB.js.map +0 -1
  384. package/dist/chunk-Z4GV3YQQ.mjs +0 -23
  385. package/dist/chunk-Z4GV3YQQ.mjs.map +0 -1
  386. package/dist/constants.js +0 -20
  387. package/dist/constants.js.map +0 -1
  388. package/dist/errors.js +0 -15
  389. package/dist/errors.js.map +0 -1
  390. package/dist/gas-flows/DefaultGasFeeFlow.js +0 -15
  391. package/dist/gas-flows/DefaultGasFeeFlow.js.map +0 -1
  392. package/dist/gas-flows/LineaGasFeeFlow.js +0 -16
  393. package/dist/gas-flows/LineaGasFeeFlow.js.map +0 -1
  394. package/dist/gas-flows/OptimismLayer1GasFeeFlow.js +0 -11
  395. package/dist/gas-flows/OptimismLayer1GasFeeFlow.js.map +0 -1
  396. package/dist/gas-flows/OracleLayer1GasFeeFlow.js +0 -9
  397. package/dist/gas-flows/OracleLayer1GasFeeFlow.js.map +0 -1
  398. package/dist/gas-flows/ScrollLayer1GasFeeFlow.js +0 -11
  399. package/dist/gas-flows/ScrollLayer1GasFeeFlow.js.map +0 -1
  400. package/dist/gas-flows/TestGasFeeFlow.js +0 -9
  401. package/dist/gas-flows/TestGasFeeFlow.js.map +0 -1
  402. package/dist/helpers/EtherscanRemoteTransactionSource.js +0 -12
  403. package/dist/helpers/EtherscanRemoteTransactionSource.js.map +0 -1
  404. package/dist/helpers/GasFeePoller.js +0 -12
  405. package/dist/helpers/GasFeePoller.js.map +0 -1
  406. package/dist/helpers/IncomingTransactionHelper.js +0 -9
  407. package/dist/helpers/IncomingTransactionHelper.js.map +0 -1
  408. package/dist/helpers/MultichainTrackingHelper.js +0 -13
  409. package/dist/helpers/MultichainTrackingHelper.js.map +0 -1
  410. package/dist/helpers/PendingTransactionTracker.js +0 -10
  411. package/dist/helpers/PendingTransactionTracker.js.map +0 -1
  412. package/dist/index.js +0 -77
  413. package/dist/index.js.map +0 -1
  414. package/dist/logger.js +0 -12
  415. package/dist/logger.js.map +0 -1
  416. package/dist/tsconfig.build.tsbuildinfo +0 -1
  417. package/dist/types/TransactionController.d.ts.map +0 -1
  418. package/dist/types/constants.d.ts.map +0 -1
  419. package/dist/types/errors.d.ts.map +0 -1
  420. package/dist/types/gas-flows/DefaultGasFeeFlow.d.ts.map +0 -1
  421. package/dist/types/gas-flows/LineaGasFeeFlow.d.ts.map +0 -1
  422. package/dist/types/gas-flows/OptimismLayer1GasFeeFlow.d.ts.map +0 -1
  423. package/dist/types/gas-flows/OracleLayer1GasFeeFlow.d.ts.map +0 -1
  424. package/dist/types/gas-flows/ScrollLayer1GasFeeFlow.d.ts.map +0 -1
  425. package/dist/types/gas-flows/TestGasFeeFlow.d.ts.map +0 -1
  426. package/dist/types/helpers/EtherscanRemoteTransactionSource.d.ts.map +0 -1
  427. package/dist/types/helpers/GasFeePoller.d.ts.map +0 -1
  428. package/dist/types/helpers/IncomingTransactionHelper.d.ts.map +0 -1
  429. package/dist/types/helpers/MultichainTrackingHelper.d.ts.map +0 -1
  430. package/dist/types/helpers/PendingTransactionTracker.d.ts.map +0 -1
  431. package/dist/types/index.d.ts.map +0 -1
  432. package/dist/types/logger.d.ts.map +0 -1
  433. package/dist/types/types.d.ts.map +0 -1
  434. package/dist/types/utils/etherscan.d.ts.map +0 -1
  435. package/dist/types/utils/external-transactions.d.ts.map +0 -1
  436. package/dist/types/utils/gas-fees.d.ts.map +0 -1
  437. package/dist/types/utils/gas-flow.d.ts.map +0 -1
  438. package/dist/types/utils/gas.d.ts.map +0 -1
  439. package/dist/types/utils/history.d.ts.map +0 -1
  440. package/dist/types/utils/layer1-gas-fee-flow.d.ts.map +0 -1
  441. package/dist/types/utils/nonce.d.ts.map +0 -1
  442. package/dist/types/utils/retry.d.ts.map +0 -1
  443. package/dist/types/utils/simulation-api.d.ts.map +0 -1
  444. package/dist/types/utils/simulation.d.ts.map +0 -1
  445. package/dist/types/utils/swaps.d.ts.map +0 -1
  446. package/dist/types/utils/transaction-type.d.ts.map +0 -1
  447. package/dist/types/utils/utils.d.ts.map +0 -1
  448. package/dist/types/utils/validation.d.ts.map +0 -1
  449. package/dist/types.js +0 -24
  450. package/dist/types.js.map +0 -1
  451. package/dist/utils/etherscan.js +0 -14
  452. package/dist/utils/etherscan.js.map +0 -1
  453. package/dist/utils/external-transactions.js +0 -9
  454. package/dist/utils/external-transactions.js.map +0 -1
  455. package/dist/utils/gas-fees.js +0 -16
  456. package/dist/utils/gas-fees.js.map +0 -1
  457. package/dist/utils/gas-flow.js +0 -11
  458. package/dist/utils/gas-flow.js.map +0 -1
  459. package/dist/utils/gas.js +0 -20
  460. package/dist/utils/gas.js.map +0 -1
  461. package/dist/utils/history.js +0 -14
  462. package/dist/utils/history.js.map +0 -1
  463. package/dist/utils/layer1-gas-fee-flow.js +0 -11
  464. package/dist/utils/layer1-gas-fee-flow.js.map +0 -1
  465. package/dist/utils/nonce.js +0 -11
  466. package/dist/utils/nonce.js.map +0 -1
  467. package/dist/utils/retry.js +0 -8
  468. package/dist/utils/retry.js.map +0 -1
  469. package/dist/utils/simulation-api.js +0 -11
  470. package/dist/utils/simulation-api.js.map +0 -1
  471. package/dist/utils/simulation.js +0 -17
  472. package/dist/utils/simulation.js.map +0 -1
  473. package/dist/utils/swaps.js +0 -24
  474. package/dist/utils/swaps.js.map +0 -1
  475. package/dist/utils/transaction-type.js +0 -11
  476. package/dist/utils/transaction-type.js.map +0 -1
  477. package/dist/utils/utils.js +0 -23
  478. package/dist/utils/utils.js.map +0 -1
  479. package/dist/utils/validation.js +0 -12
  480. package/dist/utils/validation.js.map +0 -1
@@ -1,46 +1,2074 @@
1
- import {
2
- ApprovalState,
3
- CANCEL_RATE,
4
- HARDFORK,
5
- SPEED_UP_RATE,
6
- TransactionController
7
- } from "./chunk-XTMJ25EF.mjs";
8
- import "./chunk-6DDVVUJC.mjs";
9
- import "./chunk-JOQK7A5G.mjs";
10
- import "./chunk-3AVRGHUO.mjs";
11
- import "./chunk-K4KOSAGM.mjs";
12
- import "./chunk-KG4UW4K4.mjs";
13
- import "./chunk-X4XSEYPL.mjs";
14
- import "./chunk-6B5BEO3R.mjs";
15
- import "./chunk-FRKQ3Z2L.mjs";
16
- import "./chunk-5G6OHAXI.mjs";
17
- import "./chunk-SMC5Q6ZH.mjs";
18
- import "./chunk-VEVVBHP3.mjs";
19
- import "./chunk-Z4GV3YQQ.mjs";
20
- import "./chunk-FG74Z3F5.mjs";
21
- import "./chunk-FMRLPVFZ.mjs";
22
- import "./chunk-VGFPVAKX.mjs";
23
- import "./chunk-NOHEXQ7Y.mjs";
24
- import "./chunk-3ZV5YEUV.mjs";
25
- import "./chunk-4V4XIPCI.mjs";
26
- import "./chunk-EKJXGERC.mjs";
27
- import "./chunk-EGQCE3FK.mjs";
28
- import "./chunk-HQSNKCXI.mjs";
29
- import "./chunk-KYRW4BLA.mjs";
30
- import "./chunk-AWIJZAW3.mjs";
31
- import "./chunk-SFFOC25Q.mjs";
32
- import "./chunk-JIFPK37W.mjs";
33
- import "./chunk-UHSRHP55.mjs";
34
- import "./chunk-NNHSNPT2.mjs";
35
- import "./chunk-O6ZZVIFH.mjs";
36
- import "./chunk-UQQWZT6C.mjs";
37
- import "./chunk-LFFYCDHB.mjs";
38
- import "./chunk-XUI43LEZ.mjs";
39
- export {
40
- ApprovalState,
41
- CANCEL_RATE,
42
- HARDFORK,
43
- SPEED_UP_RATE,
44
- TransactionController
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
+ if (kind === "m") throw new TypeError("Private method is not writable");
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
+ };
12
+ var _TransactionController_instances, _TransactionController_internalEvents, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_trace, _TransactionController_transactionHistoryLimit, _TransactionController_isSimulationEnabled, _TransactionController_testGasFeeFlows, _TransactionController_multichainTrackingHelper, _TransactionController_retryTransaction, _TransactionController_createNonceTracker, _TransactionController_createIncomingTransactionHelper, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_removeIncomingTransactionHelperListeners, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_getLayer1GasFeeFlows, _TransactionController_updateTransactionInternal, _TransactionController_checkIfTransactionParamsUpdated, _TransactionController_onTransactionParamsUpdated, _TransactionController_updateSimulationData, _TransactionController_onGasFeePollerTransactionUpdate, _TransactionController_getNetworkClientId, _TransactionController_getGlobalNetworkClientId, _TransactionController_getGlobalChainId, _TransactionController_isCustomNetwork, _TransactionController_getSelectedAccount, _TransactionController_updateSubmitHistory;
13
+ function $importDefault(module) {
14
+ if (module?.__esModule) {
15
+ return module.default;
16
+ }
17
+ return module;
18
+ }
19
+ import $ethereumjscommon from "@ethereumjs/common";
20
+ const { Hardfork, Common } = $ethereumjscommon;
21
+ import { TransactionFactory } from "@ethereumjs/tx";
22
+ import $ethereumjsutil from "@ethereumjs/util";
23
+ const { bufferToHex } = $ethereumjsutil;
24
+ import { BaseController } from "@metamask/base-controller";
25
+ import { query, ApprovalType, ORIGIN_METAMASK, convertHexToDecimal, isInfuraNetworkType } from "@metamask/controller-utils";
26
+ import $EthQuery from "@metamask/eth-query";
27
+ const EthQuery = $importDefault($EthQuery);
28
+ import { NetworkClientType } from "@metamask/network-controller";
29
+ import { NonceTracker } from "@metamask/nonce-tracker";
30
+ import { errorCodes, rpcErrors, providerErrors } from "@metamask/rpc-errors";
31
+ import { add0x } from "@metamask/utils";
32
+ import { Mutex } from "async-mutex";
33
+ import { MethodRegistry } from "eth-method-registry";
34
+ import { EventEmitter } from "events";
35
+ import $lodash from "lodash";
36
+ const { cloneDeep, mapValues, merge, pickBy, sortBy, isEqual } = $lodash;
37
+ import { v1 as random } from "uuid";
38
+ import { DefaultGasFeeFlow } from "./gas-flows/DefaultGasFeeFlow.mjs";
39
+ import { LineaGasFeeFlow } from "./gas-flows/LineaGasFeeFlow.mjs";
40
+ import { OptimismLayer1GasFeeFlow } from "./gas-flows/OptimismLayer1GasFeeFlow.mjs";
41
+ import { ScrollLayer1GasFeeFlow } from "./gas-flows/ScrollLayer1GasFeeFlow.mjs";
42
+ import { TestGasFeeFlow } from "./gas-flows/TestGasFeeFlow.mjs";
43
+ import { EtherscanRemoteTransactionSource } from "./helpers/EtherscanRemoteTransactionSource.mjs";
44
+ import { GasFeePoller } from "./helpers/GasFeePoller.mjs";
45
+ import { IncomingTransactionHelper } from "./helpers/IncomingTransactionHelper.mjs";
46
+ import { MultichainTrackingHelper } from "./helpers/MultichainTrackingHelper.mjs";
47
+ import { PendingTransactionTracker } from "./helpers/PendingTransactionTracker.mjs";
48
+ import { projectLogger as log } from "./logger.mjs";
49
+ import { TransactionEnvelopeType, TransactionType, TransactionStatus, SimulationErrorCode } from "./types.mjs";
50
+ import { validateConfirmedExternalTransaction } from "./utils/external-transactions.mjs";
51
+ import { addGasBuffer, estimateGas, updateGas } from "./utils/gas.mjs";
52
+ import { updateGasFees } from "./utils/gas-fees.mjs";
53
+ import { getGasFeeFlow } from "./utils/gas-flow.mjs";
54
+ import { addInitialHistorySnapshot, updateTransactionHistory } from "./utils/history.mjs";
55
+ import { getTransactionLayer1GasFee, updateTransactionLayer1GasFee } from "./utils/layer1-gas-fee-flow.mjs";
56
+ import { getAndFormatTransactionsForNonceTracker, getNextNonce } from "./utils/nonce.mjs";
57
+ import { getTransactionParamsWithIncreasedGasFee } from "./utils/retry.mjs";
58
+ import { getSimulationData } from "./utils/simulation.mjs";
59
+ import { updatePostTransactionBalance, updateSwapsTransaction } from "./utils/swaps.mjs";
60
+ import { determineTransactionType } from "./utils/transaction-type.mjs";
61
+ import { normalizeTransactionParams, isEIP1559Transaction, validateGasValues, validateIfTransactionUnapproved, normalizeTxError, normalizeGasFeeValues } from "./utils/utils.mjs";
62
+ import { validateTransactionOrigin, validateTxParams } from "./utils/validation.mjs";
63
+ /**
64
+ * Metadata for the TransactionController state, describing how to "anonymize"
65
+ * the state and which parts should be persisted.
66
+ */
67
+ const metadata = {
68
+ transactions: {
69
+ persist: true,
70
+ anonymous: false,
71
+ },
72
+ methodData: {
73
+ persist: true,
74
+ anonymous: false,
75
+ },
76
+ lastFetchedBlockNumbers: {
77
+ persist: true,
78
+ anonymous: false,
79
+ },
80
+ submitHistory: {
81
+ persist: true,
82
+ anonymous: false,
83
+ },
84
+ };
85
+ export const HARDFORK = Hardfork.London;
86
+ const SUBMIT_HISTORY_LIMIT = 100;
87
+ /**
88
+ * Multiplier used to determine a transaction's increased gas fee during cancellation
89
+ */
90
+ export const CANCEL_RATE = 1.1;
91
+ /**
92
+ * Multiplier used to determine a transaction's increased gas fee during speed up
93
+ */
94
+ export const SPEED_UP_RATE = 1.1;
95
+ /**
96
+ * The name of the {@link TransactionController}.
97
+ */
98
+ const controllerName = 'TransactionController';
99
+ /**
100
+ * Possible states of the approve transaction step.
101
+ */
102
+ export var ApprovalState;
103
+ (function (ApprovalState) {
104
+ ApprovalState["Approved"] = "approved";
105
+ ApprovalState["NotApproved"] = "not-approved";
106
+ ApprovalState["SkippedViaBeforePublishHook"] = "skipped-via-before-publish-hook";
107
+ })(ApprovalState || (ApprovalState = {}));
108
+ /**
109
+ * Get the default TransactionsController state.
110
+ *
111
+ * @returns The default TransactionsController state.
112
+ */
113
+ function getDefaultTransactionControllerState() {
114
+ return {
115
+ methodData: {},
116
+ transactions: [],
117
+ lastFetchedBlockNumbers: {},
118
+ submitHistory: [],
119
+ };
120
+ }
121
+ /**
122
+ * Controller responsible for submitting and managing transactions.
123
+ */
124
+ export class TransactionController extends BaseController {
125
+ failTransaction(transactionMeta, error, actionId) {
126
+ let newTransactionMeta;
127
+ try {
128
+ newTransactionMeta = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, {
129
+ transactionId: transactionMeta.id,
130
+ note: 'TransactionController#failTransaction - Add error message and set status to failed',
131
+ skipValidation: true,
132
+ }, (draftTransactionMeta) => {
133
+ draftTransactionMeta.status = TransactionStatus.failed;
134
+ draftTransactionMeta.error = normalizeTxError(error);
135
+ });
136
+ }
137
+ catch (err) {
138
+ log('Failed to mark transaction as failed', err);
139
+ newTransactionMeta = {
140
+ ...transactionMeta,
141
+ status: TransactionStatus.failed,
142
+ error: normalizeTxError(error),
143
+ };
144
+ }
145
+ this.messagingSystem.publish(`${controllerName}:transactionFailed`, {
146
+ actionId,
147
+ error: error.message,
148
+ transactionMeta: newTransactionMeta,
149
+ });
150
+ this.onTransactionStatusChange(newTransactionMeta);
151
+ this.messagingSystem.publish(`${controllerName}:transactionFinished`, newTransactionMeta);
152
+ __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, newTransactionMeta);
153
+ }
154
+ async registryLookup(fourBytePrefix) {
155
+ const registryMethod = await this.registry.lookup(fourBytePrefix);
156
+ if (!registryMethod) {
157
+ return {
158
+ registryMethod: '',
159
+ parsedRegistryMethod: { name: undefined, args: undefined },
160
+ };
161
+ }
162
+ const parsedRegistryMethod = this.registry.parse(registryMethod);
163
+ return { registryMethod, parsedRegistryMethod };
164
+ }
165
+ /**
166
+ * Constructs a TransactionController.
167
+ *
168
+ * @param options - The controller options.
169
+ * @param options.blockTracker - The block tracker used to poll for new blocks data.
170
+ * @param options.disableHistory - Whether to disable storing history in transaction metadata.
171
+ * @param options.disableSendFlowHistory - Explicitly disable transaction metadata history.
172
+ * @param options.disableSwaps - Whether to disable additional processing on swaps transactions.
173
+ * @param options.getCurrentAccountEIP1559Compatibility - Whether or not the account supports EIP-1559.
174
+ * @param options.getCurrentNetworkEIP1559Compatibility - Whether or not the network supports EIP-1559.
175
+ * @param options.getExternalPendingTransactions - Callback to retrieve pending transactions from external sources.
176
+ * @param options.getGasFeeEstimates - Callback to retrieve gas fee estimates.
177
+ * @param options.getNetworkClientRegistry - Gets the network client registry.
178
+ * @param options.getNetworkState - Gets the state of the network controller.
179
+ * @param options.getPermittedAccounts - Get accounts that a given origin has permissions for.
180
+ * @param options.getSavedGasFees - Gets the saved gas fee config.
181
+ * @param options.incomingTransactions - Configuration options for incoming transaction support.
182
+ * @param options.isMultichainEnabled - Enable multichain support.
183
+ * @param options.isSimulationEnabled - Whether new transactions will be automatically simulated.
184
+ * @param options.messenger - The controller messenger.
185
+ * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
186
+ * @param options.pendingTransactions - Configuration options for pending transaction support.
187
+ * @param options.provider - The provider used to create the underlying EthQuery instance.
188
+ * @param options.securityProviderRequest - A function for verifying a transaction, whether it is malicious or not.
189
+ * @param options.sign - Function used to sign transactions.
190
+ * @param options.state - Initial state to set on this controller.
191
+ * @param options.testGasFeeFlows - Whether to use the test gas fee flow.
192
+ * @param options.trace - Callback to generate trace information.
193
+ * @param options.transactionHistoryLimit - Transaction history limit.
194
+ * @param options.hooks - The controller hooks.
195
+ */
196
+ constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkClientRegistry, getNetworkState, getPermittedAccounts, getSavedGasFees, incomingTransactions = {}, isMultichainEnabled = false, isSimulationEnabled, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, sign, state, testGasFeeFlows, trace, transactionHistoryLimit = 40, hooks, }) {
197
+ super({
198
+ name: controllerName,
199
+ metadata,
200
+ messenger,
201
+ state: {
202
+ ...getDefaultTransactionControllerState(),
203
+ ...state,
204
+ },
205
+ });
206
+ _TransactionController_instances.add(this);
207
+ _TransactionController_internalEvents.set(this, new EventEmitter());
208
+ this.approvingTransactionIds = new Set();
209
+ this.mutex = new Mutex();
210
+ _TransactionController_incomingTransactionOptions.set(this, void 0);
211
+ _TransactionController_pendingTransactionOptions.set(this, void 0);
212
+ this.signAbortCallbacks = new Map();
213
+ _TransactionController_trace.set(this, void 0);
214
+ _TransactionController_transactionHistoryLimit.set(this, void 0);
215
+ _TransactionController_isSimulationEnabled.set(this, void 0);
216
+ _TransactionController_testGasFeeFlows.set(this, void 0);
217
+ _TransactionController_multichainTrackingHelper.set(this, void 0);
218
+ _TransactionController_checkForPendingTransactionAndStartPolling.set(this, () => {
219
+ // PendingTransactionTracker reads state through its getTransactions hook
220
+ this.pendingTransactionTracker.startIfPendingTransactions();
221
+ __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").checkForPendingTransactionAndStartPolling();
222
+ });
223
+ this.messagingSystem = messenger;
224
+ this.getNetworkState = getNetworkState;
225
+ this.isSendFlowHistoryDisabled = disableSendFlowHistory ?? false;
226
+ this.isHistoryDisabled = disableHistory ?? false;
227
+ this.isSwapsDisabled = disableSwaps ?? false;
228
+ __classPrivateFieldSet(this, _TransactionController_isSimulationEnabled, isSimulationEnabled ?? (() => true), "f");
229
+ // @ts-expect-error the type in eth-method-registry is inappropriate and should be changed
230
+ this.registry = new MethodRegistry({ provider });
231
+ this.getSavedGasFees = getSavedGasFees ?? ((_chainId) => undefined);
232
+ this.getCurrentAccountEIP1559Compatibility =
233
+ getCurrentAccountEIP1559Compatibility ?? (() => Promise.resolve(true));
234
+ this.getCurrentNetworkEIP1559Compatibility =
235
+ getCurrentNetworkEIP1559Compatibility;
236
+ this.getGasFeeEstimates =
237
+ getGasFeeEstimates || (() => Promise.resolve({}));
238
+ this.getPermittedAccounts = getPermittedAccounts;
239
+ this.getExternalPendingTransactions =
240
+ getExternalPendingTransactions ?? (() => []);
241
+ this.securityProviderRequest = securityProviderRequest;
242
+ __classPrivateFieldSet(this, _TransactionController_incomingTransactionOptions, incomingTransactions, "f");
243
+ __classPrivateFieldSet(this, _TransactionController_pendingTransactionOptions, pendingTransactions, "f");
244
+ __classPrivateFieldSet(this, _TransactionController_transactionHistoryLimit, transactionHistoryLimit, "f");
245
+ this.sign = sign;
246
+ __classPrivateFieldSet(this, _TransactionController_testGasFeeFlows, testGasFeeFlows === true, "f");
247
+ __classPrivateFieldSet(this, _TransactionController_trace, trace ?? ((_request, fn) => fn?.()), "f");
248
+ this.afterSign = hooks?.afterSign ?? (() => true);
249
+ this.beforeCheckPendingTransaction =
250
+ hooks?.beforeCheckPendingTransaction ??
251
+ /* istanbul ignore next */
252
+ (() => true);
253
+ this.beforePublish = hooks?.beforePublish ?? (() => true);
254
+ this.getAdditionalSignArguments =
255
+ hooks?.getAdditionalSignArguments ?? (() => []);
256
+ this.publish =
257
+ hooks?.publish ?? (() => Promise.resolve({ transactionHash: undefined }));
258
+ this.nonceTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).call(this, {
259
+ provider,
260
+ blockTracker,
261
+ });
262
+ const findNetworkClientIdByChainId = (chainId) => {
263
+ return this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, chainId);
264
+ };
265
+ __classPrivateFieldSet(this, _TransactionController_multichainTrackingHelper, new MultichainTrackingHelper({
266
+ isMultichainEnabled,
267
+ provider,
268
+ nonceTracker: this.nonceTracker,
269
+ incomingTransactionOptions: incomingTransactions,
270
+ findNetworkClientIdByChainId,
271
+ getNetworkClientById: ((networkClientId) => {
272
+ return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
273
+ }),
274
+ getNetworkClientRegistry,
275
+ removeIncomingTransactionHelperListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).bind(this),
276
+ removePendingTransactionTrackerListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).bind(this),
277
+ createNonceTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).bind(this),
278
+ createIncomingTransactionHelper: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).bind(this),
279
+ createPendingTransactionTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).bind(this),
280
+ onNetworkStateChange: (listener) => {
281
+ this.messagingSystem.subscribe('NetworkController:stateChange', listener);
282
+ },
283
+ }), "f");
284
+ __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").initialize();
285
+ const etherscanRemoteTransactionSource = new EtherscanRemoteTransactionSource({
286
+ includeTokenTransfers: incomingTransactions.includeTokenTransfers,
287
+ });
288
+ this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this, {
289
+ blockTracker,
290
+ etherscanRemoteTransactionSource,
291
+ });
292
+ this.pendingTransactionTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).call(this, {
293
+ provider,
294
+ blockTracker,
295
+ });
296
+ this.gasFeeFlows = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGasFeeFlows).call(this);
297
+ this.layer1GasFeeFlows = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getLayer1GasFeeFlows).call(this);
298
+ const gasFeePoller = new GasFeePoller({
299
+ findNetworkClientIdByChainId,
300
+ gasFeeFlows: this.gasFeeFlows,
301
+ getGasFeeControllerEstimates: this.getGasFeeEstimates,
302
+ getProvider: (chainId, networkClientId) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
303
+ networkClientId,
304
+ chainId,
305
+ }),
306
+ getTransactions: () => this.state.transactions,
307
+ layer1GasFeeFlows: this.layer1GasFeeFlows,
308
+ onStateChange: (listener) => {
309
+ this.messagingSystem.subscribe('TransactionController:stateChange', listener);
310
+ },
311
+ });
312
+ gasFeePoller.hub.on('transaction-updated', __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_onGasFeePollerTransactionUpdate).bind(this));
313
+ // when transactionsController state changes
314
+ // check for pending transactions and start polling if there are any
315
+ this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f"));
316
+ // TODO once v2 is merged make sure this only runs when
317
+ // selectedNetworkClientId changes
318
+ onNetworkStateChange(() => {
319
+ log('Detected network change', this.getChainId());
320
+ this.pendingTransactionTracker.startIfPendingTransactions();
321
+ this.onBootCleanup();
322
+ });
323
+ this.onBootCleanup();
324
+ __classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f").call(this);
325
+ }
326
+ /**
327
+ * Stops polling and removes listeners to prepare the controller for garbage collection.
328
+ */
329
+ destroy() {
330
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_stopAllTracking).call(this);
331
+ }
332
+ /**
333
+ * Handle new method data request.
334
+ *
335
+ * @param fourBytePrefix - The method prefix.
336
+ * @returns The method data object corresponding to the given signature prefix.
337
+ */
338
+ async handleMethodData(fourBytePrefix) {
339
+ const releaseLock = await this.mutex.acquire();
340
+ try {
341
+ const { methodData } = this.state;
342
+ const knownMethod = Object.keys(methodData).find((knownFourBytePrefix) => fourBytePrefix === knownFourBytePrefix);
343
+ if (knownMethod) {
344
+ return methodData[fourBytePrefix];
345
+ }
346
+ const registry = await this.registryLookup(fourBytePrefix);
347
+ this.update((state) => {
348
+ state.methodData[fourBytePrefix] = registry;
349
+ });
350
+ return registry;
351
+ }
352
+ finally {
353
+ releaseLock();
354
+ }
355
+ }
356
+ /**
357
+ * Add a new unapproved transaction to state. Parameters will be validated, a
358
+ * unique transaction id will be generated, and gas and gasPrice will be calculated
359
+ * if not provided. If A `<tx.id>:unapproved` hub event will be emitted once added.
360
+ *
361
+ * @param txParams - Standard parameters for an Ethereum transaction.
362
+ * @param opts - Additional options to control how the transaction is added.
363
+ * @param opts.actionId - Unique ID to prevent duplicate requests.
364
+ * @param opts.deviceConfirmedOn - An enum to indicate what device confirmed the transaction.
365
+ * @param opts.method - RPC method that requested the transaction.
366
+ * @param opts.origin - The origin of the transaction request, such as a dApp hostname.
367
+ * @param opts.requireApproval - Whether the transaction requires approval by the user, defaults to true unless explicitly disabled.
368
+ * @param opts.securityAlertResponse - Response from security validator.
369
+ * @param opts.sendFlowHistory - The sendFlowHistory entries to add.
370
+ * @param opts.type - Type of transaction to add, such as 'cancel' or 'swap'.
371
+ * @param opts.swaps - Options for swaps transactions.
372
+ * @param opts.swaps.hasApproveTx - Whether the transaction has an approval transaction.
373
+ * @param opts.swaps.meta - Metadata for swap transaction.
374
+ * @param opts.networkClientId - The id of the network client for this transaction.
375
+ * @param opts.traceContext - The parent context for any new traces.
376
+ * @returns Object containing a promise resolving to the transaction hash if approved.
377
+ */
378
+ async addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, traceContext, type, networkClientId: requestNetworkClientId, } = {}) {
379
+ log('Adding transaction', txParams);
380
+ txParams = normalizeTransactionParams(txParams);
381
+ if (requestNetworkClientId &&
382
+ !__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").has(requestNetworkClientId)) {
383
+ throw new Error('The networkClientId for this transaction could not be found');
384
+ }
385
+ const networkClientId = requestNetworkClientId ?? __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
386
+ const isEIP1559Compatible = await this.getEIP1559Compatibility(networkClientId);
387
+ validateTxParams(txParams, isEIP1559Compatible);
388
+ if (origin && this.getPermittedAccounts) {
389
+ await validateTransactionOrigin(await this.getPermittedAccounts(origin), __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getSelectedAccount).call(this).address, txParams.from, origin);
390
+ }
391
+ const dappSuggestedGasFees = this.generateDappSuggestedGasFees(txParams, origin);
392
+ const chainId = this.getChainId(networkClientId);
393
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
394
+ networkClientId,
395
+ chainId,
396
+ });
397
+ const transactionType = type ?? (await determineTransactionType(txParams, ethQuery)).type;
398
+ const existingTransactionMeta = this.getTransactionWithActionId(actionId);
399
+ // If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
400
+ let addedTransactionMeta = existingTransactionMeta
401
+ ? cloneDeep(existingTransactionMeta)
402
+ : {
403
+ // Add actionId to txMeta to check if same actionId is seen again
404
+ actionId,
405
+ chainId,
406
+ dappSuggestedGasFees,
407
+ deviceConfirmedOn,
408
+ id: random(),
409
+ origin,
410
+ securityAlertResponse,
411
+ status: TransactionStatus.unapproved,
412
+ time: Date.now(),
413
+ txParams,
414
+ userEditedGasLimit: false,
415
+ verifiedOnBlockchain: false,
416
+ type: transactionType,
417
+ networkClientId,
418
+ };
419
+ await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Estimate Gas Properties', parentContext: traceContext }, (context) => this.updateGasProperties(addedTransactionMeta, {
420
+ traceContext: context,
421
+ }));
422
+ // Checks if a transaction already exists with a given actionId
423
+ if (!existingTransactionMeta) {
424
+ // Set security provider response
425
+ if (method && this.securityProviderRequest) {
426
+ const securityProviderResponse = await this.securityProviderRequest(addedTransactionMeta, method);
427
+ addedTransactionMeta.securityProviderResponse =
428
+ securityProviderResponse;
429
+ }
430
+ if (!this.isSendFlowHistoryDisabled) {
431
+ addedTransactionMeta.sendFlowHistory = sendFlowHistory ?? [];
432
+ }
433
+ // Initial history push
434
+ if (!this.isHistoryDisabled) {
435
+ addedTransactionMeta = addInitialHistorySnapshot(addedTransactionMeta);
436
+ }
437
+ addedTransactionMeta = updateSwapsTransaction(addedTransactionMeta, transactionType, swaps, {
438
+ isSwapsDisabled: this.isSwapsDisabled,
439
+ cancelTransaction: this.cancelTransaction.bind(this),
440
+ messenger: this.messagingSystem,
441
+ });
442
+ this.addMetadata(addedTransactionMeta);
443
+ if (requireApproval !== false) {
444
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateSimulationData).call(this, addedTransactionMeta, {
445
+ traceContext,
446
+ }).catch((error) => {
447
+ log('Error while updating simulation data', error);
448
+ throw error;
449
+ });
450
+ }
451
+ else {
452
+ log('Skipping simulation as approval not required');
453
+ }
454
+ this.messagingSystem.publish(`${controllerName}:unapprovedTransactionAdded`, addedTransactionMeta);
455
+ }
456
+ return {
457
+ result: this.processApproval(addedTransactionMeta, {
458
+ isExisting: Boolean(existingTransactionMeta),
459
+ requireApproval,
460
+ actionId,
461
+ traceContext,
462
+ }),
463
+ transactionMeta: addedTransactionMeta,
464
+ };
465
+ }
466
+ startIncomingTransactionPolling(networkClientIds = []) {
467
+ if (networkClientIds.length === 0) {
468
+ this.incomingTransactionHelper.start();
469
+ return;
470
+ }
471
+ __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").startIncomingTransactionPolling(networkClientIds);
472
+ }
473
+ stopIncomingTransactionPolling(networkClientIds = []) {
474
+ if (networkClientIds.length === 0) {
475
+ this.incomingTransactionHelper.stop();
476
+ return;
477
+ }
478
+ __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopIncomingTransactionPolling(networkClientIds);
479
+ }
480
+ stopAllIncomingTransactionPolling() {
481
+ this.incomingTransactionHelper.stop();
482
+ __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllIncomingTransactionPolling();
483
+ }
484
+ async updateIncomingTransactions(networkClientIds = []) {
485
+ if (networkClientIds.length === 0) {
486
+ await this.incomingTransactionHelper.update();
487
+ return;
488
+ }
489
+ await __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").updateIncomingTransactions(networkClientIds);
490
+ }
491
+ /**
492
+ * Attempts to cancel a transaction based on its ID by setting its status to "rejected"
493
+ * and emitting a `<tx.id>:finished` hub event.
494
+ *
495
+ * @param transactionId - The ID of the transaction to cancel.
496
+ * @param gasValues - The gas values to use for the cancellation transaction.
497
+ * @param options - The options for the cancellation transaction.
498
+ * @param options.actionId - Unique ID to prevent duplicate requests.
499
+ * @param options.estimatedBaseFee - The estimated base fee of the transaction.
500
+ */
501
+ async stopTransaction(transactionId, gasValues, { estimatedBaseFee, actionId, } = {}) {
502
+ return await __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_retryTransaction).call(this, {
503
+ actionId,
504
+ estimatedBaseFee,
505
+ gasValues,
506
+ label: 'cancel',
507
+ rate: CANCEL_RATE,
508
+ transactionId,
509
+ transactionType: TransactionType.cancel,
510
+ prepareTransactionParams: (txParams) => {
511
+ delete txParams.data;
512
+ txParams.to = txParams.from;
513
+ txParams.value = '0x0';
514
+ },
515
+ afterSubmit: (newTransactionMeta) => {
516
+ this.messagingSystem.publish(`${controllerName}:transactionFinished`, newTransactionMeta);
517
+ __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${newTransactionMeta.id}:finished`, newTransactionMeta);
518
+ },
519
+ });
520
+ }
521
+ /**
522
+ * Attempts to speed up a transaction increasing transaction gasPrice by ten percent.
523
+ *
524
+ * @param transactionId - The ID of the transaction to speed up.
525
+ * @param gasValues - The gas values to use for the speed up transaction.
526
+ * @param options - The options for the speed up transaction.
527
+ * @param options.actionId - Unique ID to prevent duplicate requests
528
+ * @param options.estimatedBaseFee - The estimated base fee of the transaction.
529
+ */
530
+ async speedUpTransaction(transactionId, gasValues, { actionId, estimatedBaseFee, } = {}) {
531
+ return await __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_retryTransaction).call(this, {
532
+ actionId,
533
+ estimatedBaseFee,
534
+ gasValues,
535
+ label: 'speed up',
536
+ rate: SPEED_UP_RATE,
537
+ transactionId,
538
+ transactionType: TransactionType.retry,
539
+ afterSubmit: (newTransactionMeta) => {
540
+ this.messagingSystem.publish(`${controllerName}:speedupTransactionAdded`, newTransactionMeta);
541
+ },
542
+ });
543
+ }
544
+ /**
545
+ * Estimates required gas for a given transaction.
546
+ *
547
+ * @param transaction - The transaction to estimate gas for.
548
+ * @param networkClientId - The network client id to use for the estimate.
549
+ * @returns The gas and gas price.
550
+ */
551
+ async estimateGas(transaction, networkClientId) {
552
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
553
+ networkClientId,
554
+ });
555
+ const { estimatedGas, simulationFails } = await estimateGas(transaction, ethQuery);
556
+ return { gas: estimatedGas, simulationFails };
557
+ }
558
+ /**
559
+ * Estimates required gas for a given transaction and add additional gas buffer with the given multiplier.
560
+ *
561
+ * @param transaction - The transaction params to estimate gas for.
562
+ * @param multiplier - The multiplier to use for the gas buffer.
563
+ * @param networkClientId - The network client id to use for the estimate.
564
+ */
565
+ async estimateGasBuffered(transaction, multiplier, networkClientId) {
566
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
567
+ networkClientId,
568
+ });
569
+ const { blockGasLimit, estimatedGas, simulationFails } = await estimateGas(transaction, ethQuery);
570
+ const gas = addGasBuffer(estimatedGas, blockGasLimit, multiplier);
571
+ return {
572
+ gas,
573
+ simulationFails,
574
+ };
575
+ }
576
+ /**
577
+ * Updates an existing transaction in state.
578
+ *
579
+ * @param transactionMeta - The new transaction to store in state.
580
+ * @param note - A note or update reason to include in the transaction history.
581
+ */
582
+ updateTransaction(transactionMeta, note) {
583
+ const { id: transactionId } = transactionMeta;
584
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, { transactionId, note }, () => ({
585
+ ...transactionMeta,
586
+ }));
587
+ }
588
+ /**
589
+ * Update the security alert response for a transaction.
590
+ *
591
+ * @param transactionId - ID of the transaction.
592
+ * @param securityAlertResponse - The new security alert response for the transaction.
593
+ */
594
+ updateSecurityAlertResponse(transactionId, securityAlertResponse) {
595
+ if (!securityAlertResponse) {
596
+ throw new Error('updateSecurityAlertResponse: securityAlertResponse should not be null');
597
+ }
598
+ const transactionMeta = this.getTransaction(transactionId);
599
+ if (!transactionMeta) {
600
+ throw new Error(`Cannot update security alert response as no transaction metadata found`);
601
+ }
602
+ const updatedTransactionMeta = {
603
+ ...transactionMeta,
604
+ securityAlertResponse,
605
+ };
606
+ this.updateTransaction(updatedTransactionMeta, `${controllerName}:updatesecurityAlertResponse - securityAlertResponse updated`);
607
+ }
608
+ /**
609
+ * Removes all transactions from state, optionally based on the current network.
610
+ *
611
+ * @param ignoreNetwork - Determines whether to wipe all transactions, or just those on the
612
+ * current network. If `true`, all transactions are wiped.
613
+ * @param address - If specified, only transactions originating from this address will be
614
+ * wiped on current network.
615
+ */
616
+ wipeTransactions(ignoreNetwork, address) {
617
+ /* istanbul ignore next */
618
+ if (ignoreNetwork && !address) {
619
+ this.update((state) => {
620
+ state.transactions = [];
621
+ });
622
+ return;
623
+ }
624
+ const currentChainId = this.getChainId();
625
+ const newTransactions = this.state.transactions.filter(({ chainId, txParams }) => {
626
+ const isMatchingNetwork = ignoreNetwork || chainId === currentChainId;
627
+ if (!isMatchingNetwork) {
628
+ return true;
629
+ }
630
+ const isMatchingAddress = !address || txParams.from?.toLowerCase() === address.toLowerCase();
631
+ return !isMatchingAddress;
632
+ });
633
+ this.update((state) => {
634
+ state.transactions = this.trimTransactionsForState(newTransactions);
635
+ });
636
+ }
637
+ /**
638
+ * Adds external provided transaction to state as confirmed transaction.
639
+ *
640
+ * @param transactionMeta - TransactionMeta to add transactions.
641
+ * @param transactionReceipt - TransactionReceipt of the external transaction.
642
+ * @param baseFeePerGas - Base fee per gas of the external transaction.
643
+ */
644
+ async confirmExternalTransaction(transactionMeta, transactionReceipt, baseFeePerGas) {
645
+ // Run validation and add external transaction to state.
646
+ const newTransactionMeta = this.addExternalTransaction(transactionMeta);
647
+ try {
648
+ const transactionId = newTransactionMeta.id;
649
+ // Make sure status is confirmed and define gasUsed as in receipt.
650
+ const updatedTransactionMeta = {
651
+ ...newTransactionMeta,
652
+ status: TransactionStatus.confirmed,
653
+ txReceipt: transactionReceipt,
654
+ };
655
+ if (baseFeePerGas) {
656
+ updatedTransactionMeta.baseFeePerGas = baseFeePerGas;
657
+ }
658
+ // Update same nonce local transactions as dropped and define replacedBy properties.
659
+ this.markNonceDuplicatesDropped(transactionId);
660
+ // Update external provided transaction with updated gas values and confirmed status.
661
+ this.updateTransaction(updatedTransactionMeta, `${controllerName}:confirmExternalTransaction - Add external transaction`);
662
+ this.onTransactionStatusChange(updatedTransactionMeta);
663
+ // Intentional given potential duration of process.
664
+ this.updatePostBalance(updatedTransactionMeta).catch((error) => {
665
+ log('Error while updating post balance', error);
666
+ throw error;
667
+ });
668
+ this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, updatedTransactionMeta);
669
+ }
670
+ catch (error) {
671
+ console.error('Failed to confirm external transaction', error);
672
+ }
673
+ }
674
+ /**
675
+ * Append new send flow history to a transaction.
676
+ *
677
+ * @param transactionID - The ID of the transaction to update.
678
+ * @param currentSendFlowHistoryLength - The length of the current sendFlowHistory array.
679
+ * @param sendFlowHistoryToAdd - The sendFlowHistory entries to add.
680
+ * @returns The updated transactionMeta.
681
+ */
682
+ updateTransactionSendFlowHistory(transactionID, currentSendFlowHistoryLength, sendFlowHistoryToAdd) {
683
+ if (this.isSendFlowHistoryDisabled) {
684
+ throw new Error('Send flow history is disabled for the current transaction controller');
685
+ }
686
+ const transactionMeta = this.getTransaction(transactionID);
687
+ if (!transactionMeta) {
688
+ throw new Error(`Cannot update send flow history as no transaction metadata found`);
689
+ }
690
+ validateIfTransactionUnapproved(transactionMeta, 'updateTransactionSendFlowHistory');
691
+ const sendFlowHistory = transactionMeta.sendFlowHistory ?? [];
692
+ if (currentSendFlowHistoryLength === sendFlowHistory.length) {
693
+ const updatedTransactionMeta = {
694
+ ...transactionMeta,
695
+ sendFlowHistory: [...sendFlowHistory, ...sendFlowHistoryToAdd],
696
+ };
697
+ this.updateTransaction(updatedTransactionMeta, `${controllerName}:updateTransactionSendFlowHistory - sendFlowHistory updated`);
698
+ }
699
+ return this.getTransaction(transactionID);
700
+ }
701
+ /**
702
+ * Update the gas values of a transaction.
703
+ *
704
+ * @param transactionId - The ID of the transaction to update.
705
+ * @param gasValues - Gas values to update.
706
+ * @param gasValues.gas - Same as transaction.gasLimit.
707
+ * @param gasValues.gasLimit - Maxmimum number of units of gas to use for this transaction.
708
+ * @param gasValues.gasPrice - Price per gas for legacy transactions.
709
+ * @param gasValues.maxPriorityFeePerGas - Maximum amount per gas to give to validator as incentive.
710
+ * @param gasValues.maxFeePerGas - Maximum amount per gas to pay for the transaction, including the priority fee.
711
+ * @param gasValues.estimateUsed - Which estimate level was used.
712
+ * @param gasValues.estimateSuggested - Which estimate level that the API suggested.
713
+ * @param gasValues.defaultGasEstimates - The default estimate for gas.
714
+ * @param gasValues.originalGasEstimate - Original estimate for gas.
715
+ * @param gasValues.userEditedGasLimit - The gas limit supplied by user.
716
+ * @param gasValues.userFeeLevel - Estimate level user selected.
717
+ * @returns The updated transactionMeta.
718
+ */
719
+ updateTransactionGasFees(transactionId, { defaultGasEstimates, estimateUsed, estimateSuggested, gas, gasLimit, gasPrice, maxPriorityFeePerGas, maxFeePerGas, originalGasEstimate, userEditedGasLimit, userFeeLevel, }) {
720
+ const transactionMeta = this.getTransaction(transactionId);
721
+ if (!transactionMeta) {
722
+ throw new Error(`Cannot update transaction as no transaction metadata found`);
723
+ }
724
+ validateIfTransactionUnapproved(transactionMeta, 'updateTransactionGasFees');
725
+ let transactionGasFees = {
726
+ txParams: {
727
+ gas,
728
+ gasLimit,
729
+ gasPrice,
730
+ maxPriorityFeePerGas,
731
+ maxFeePerGas,
732
+ },
733
+ defaultGasEstimates,
734
+ estimateUsed,
735
+ estimateSuggested,
736
+ originalGasEstimate,
737
+ userEditedGasLimit,
738
+ userFeeLevel,
739
+ // TODO: Replace `any` with type
740
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
741
+ };
742
+ // only update what is defined
743
+ transactionGasFees.txParams = pickBy(transactionGasFees.txParams);
744
+ transactionGasFees = pickBy(transactionGasFees);
745
+ // merge updated gas values with existing transaction meta
746
+ const updatedMeta = merge({}, transactionMeta, transactionGasFees);
747
+ this.updateTransaction(updatedMeta, `${controllerName}:updateTransactionGasFees - gas values updated`);
748
+ return this.getTransaction(transactionId);
749
+ }
750
+ /**
751
+ * Update the previous gas values of a transaction.
752
+ *
753
+ * @param transactionId - The ID of the transaction to update.
754
+ * @param previousGas - Previous gas values to update.
755
+ * @param previousGas.gasLimit - Maxmimum number of units of gas to use for this transaction.
756
+ * @param previousGas.maxFeePerGas - Maximum amount per gas to pay for the transaction, including the priority fee.
757
+ * @param previousGas.maxPriorityFeePerGas - Maximum amount per gas to give to validator as incentive.
758
+ * @returns The updated transactionMeta.
759
+ */
760
+ updatePreviousGasParams(transactionId, { gasLimit, maxFeePerGas, maxPriorityFeePerGas, }) {
761
+ const transactionMeta = this.getTransaction(transactionId);
762
+ if (!transactionMeta) {
763
+ throw new Error(`Cannot update transaction as no transaction metadata found`);
764
+ }
765
+ validateIfTransactionUnapproved(transactionMeta, 'updatePreviousGasParams');
766
+ const transactionPreviousGas = {
767
+ previousGas: {
768
+ gasLimit,
769
+ maxFeePerGas,
770
+ maxPriorityFeePerGas,
771
+ },
772
+ // TODO: Replace `any` with type
773
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
774
+ };
775
+ // only update what is defined
776
+ transactionPreviousGas.previousGas = pickBy(transactionPreviousGas.previousGas);
777
+ // merge updated previous gas values with existing transaction meta
778
+ const updatedMeta = merge({}, transactionMeta, transactionPreviousGas);
779
+ this.updateTransaction(updatedMeta, `${controllerName}:updatePreviousGasParams - Previous gas values updated`);
780
+ return this.getTransaction(transactionId);
781
+ }
782
+ async getNonceLock(address, networkClientId) {
783
+ return __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId);
784
+ }
785
+ /**
786
+ * Updates the editable parameters of a transaction.
787
+ *
788
+ * @param txId - The ID of the transaction to update.
789
+ * @param params - The editable parameters to update.
790
+ * @param params.data - Data to pass with the transaction.
791
+ * @param params.gas - Maximum number of units of gas to use for the transaction.
792
+ * @param params.gasPrice - Price per gas for legacy transactions.
793
+ * @param params.from - Address to send the transaction from.
794
+ * @param params.to - Address to send the transaction to.
795
+ * @param params.value - Value associated with the transaction.
796
+ * @returns The updated transaction metadata.
797
+ */
798
+ async updateEditableParams(txId, { data, gas, gasPrice, from, to, value, }) {
799
+ const transactionMeta = this.getTransaction(txId);
800
+ if (!transactionMeta) {
801
+ throw new Error(`Cannot update editable params as no transaction metadata found`);
802
+ }
803
+ validateIfTransactionUnapproved(transactionMeta, 'updateEditableParams');
804
+ const editableParams = {
805
+ txParams: {
806
+ data,
807
+ from,
808
+ to,
809
+ value,
810
+ gas,
811
+ gasPrice,
812
+ },
813
+ };
814
+ editableParams.txParams = pickBy(editableParams.txParams);
815
+ const updatedTransaction = merge({}, transactionMeta, editableParams);
816
+ const provider = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
817
+ chainId: transactionMeta.chainId,
818
+ networkClientId: transactionMeta.networkClientId,
819
+ });
820
+ const ethQuery = new EthQuery(provider);
821
+ const { type } = await determineTransactionType(updatedTransaction.txParams, ethQuery);
822
+ updatedTransaction.type = type;
823
+ await updateTransactionLayer1GasFee({
824
+ layer1GasFeeFlows: this.layer1GasFeeFlows,
825
+ provider,
826
+ transactionMeta: updatedTransaction,
827
+ });
828
+ this.updateTransaction(updatedTransaction, `Update Editable Params for ${txId}`);
829
+ return this.getTransaction(txId);
830
+ }
831
+ /**
832
+ * Signs and returns the raw transaction data for provided transaction params list.
833
+ *
834
+ * @param listOfTxParams - The list of transaction params to approve.
835
+ * @param opts - Options bag.
836
+ * @param opts.hasNonce - Whether the transactions already have a nonce.
837
+ * @returns The raw transactions.
838
+ */
839
+ async approveTransactionsWithSameNonce(listOfTxParams = [], { hasNonce } = {}) {
840
+ log('Approving transactions with same nonce', {
841
+ transactions: listOfTxParams,
842
+ });
843
+ if (listOfTxParams.length === 0) {
844
+ return '';
845
+ }
846
+ const initialTx = listOfTxParams[0];
847
+ const common = this.getCommonConfiguration(initialTx.chainId);
848
+ // We need to ensure we get the nonce using the the NonceTracker on the chain matching
849
+ // the txParams. In this context we only have chainId available to us, but the
850
+ // NonceTrackers are keyed by networkClientId. To workaround this, we attempt to find
851
+ // a networkClientId that matches the chainId. As a fallback, the globally selected
852
+ // network's NonceTracker will be used instead.
853
+ let networkClientId;
854
+ try {
855
+ networkClientId = this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, initialTx.chainId);
856
+ }
857
+ catch (err) {
858
+ log('failed to find networkClientId from chainId', err);
859
+ }
860
+ const initialTxAsEthTx = TransactionFactory.fromTxData(initialTx, {
861
+ common,
862
+ });
863
+ const initialTxAsSerializedHex = bufferToHex(initialTxAsEthTx.serialize());
864
+ if (this.approvingTransactionIds.has(initialTxAsSerializedHex)) {
865
+ return '';
866
+ }
867
+ this.approvingTransactionIds.add(initialTxAsSerializedHex);
868
+ let rawTransactions, nonceLock;
869
+ try {
870
+ // TODO: we should add a check to verify that all transactions have the same from address
871
+ const fromAddress = initialTx.from;
872
+ const requiresNonce = hasNonce !== true;
873
+ nonceLock = requiresNonce
874
+ ? await this.getNonceLock(fromAddress, networkClientId)
875
+ : undefined;
876
+ const nonce = nonceLock
877
+ ? add0x(nonceLock.nextNonce.toString(16))
878
+ : initialTx.nonce;
879
+ if (nonceLock) {
880
+ log('Using nonce from nonce tracker', nonce, nonceLock.nonceDetails);
881
+ }
882
+ rawTransactions = await Promise.all(listOfTxParams.map((txParams) => {
883
+ txParams.nonce = nonce;
884
+ return this.signExternalTransaction(txParams.chainId, txParams);
885
+ }));
886
+ }
887
+ catch (err) {
888
+ log('Error while signing transactions with same nonce', err);
889
+ // Must set transaction to submitted/failed before releasing lock
890
+ // continue with error chain
891
+ throw err;
892
+ }
893
+ finally {
894
+ nonceLock?.releaseLock();
895
+ this.approvingTransactionIds.delete(initialTxAsSerializedHex);
896
+ }
897
+ return rawTransactions;
898
+ }
899
+ /**
900
+ * Update a custodial transaction.
901
+ *
902
+ * @param transactionId - The ID of the transaction to update.
903
+ * @param options - The custodial transaction options to update.
904
+ * @param options.errorMessage - The error message to be assigned in case transaction status update to failed.
905
+ * @param options.hash - The new hash value to be assigned.
906
+ * @param options.status - The new status value to be assigned.
907
+ */
908
+ updateCustodialTransaction(transactionId, { errorMessage, hash, status, }) {
909
+ const transactionMeta = this.getTransaction(transactionId);
910
+ if (!transactionMeta) {
911
+ throw new Error(`Cannot update custodial transaction as no transaction metadata found`);
912
+ }
913
+ if (!transactionMeta.custodyId) {
914
+ throw new Error('Transaction must be a custodian transaction');
915
+ }
916
+ if (status &&
917
+ ![
918
+ TransactionStatus.submitted,
919
+ TransactionStatus.signed,
920
+ TransactionStatus.failed,
921
+ ].includes(status)) {
922
+ throw new Error(`Cannot update custodial transaction with status: ${status}`);
923
+ }
924
+ const updatedTransactionMeta = merge({}, transactionMeta, pickBy({ hash, status }));
925
+ if (updatedTransactionMeta.status === TransactionStatus.submitted) {
926
+ updatedTransactionMeta.submittedTime = new Date().getTime();
927
+ }
928
+ if (updatedTransactionMeta.status === TransactionStatus.failed) {
929
+ updatedTransactionMeta.error = normalizeTxError(new Error(errorMessage));
930
+ }
931
+ this.updateTransaction(updatedTransactionMeta, `${controllerName}:updateCustodialTransaction - Custodial transaction updated`);
932
+ if ([TransactionStatus.submitted, TransactionStatus.failed].includes(status)) {
933
+ this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
934
+ __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${updatedTransactionMeta.id}:finished`, updatedTransactionMeta);
935
+ }
936
+ }
937
+ /**
938
+ * Search transaction metadata for matching entries.
939
+ *
940
+ * @param opts - Options bag.
941
+ * @param opts.searchCriteria - An object containing values or functions for transaction properties to filter transactions with.
942
+ * @param opts.initialList - The transactions to search. Defaults to the current state.
943
+ * @param opts.filterToCurrentNetwork - Whether to filter the results to the current network. Defaults to true.
944
+ * @param opts.limit - The maximum number of transactions to return. No limit by default.
945
+ * @returns An array of transactions matching the provided options.
946
+ */
947
+ getTransactions({ searchCriteria = {}, initialList, filterToCurrentNetwork = true, limit, } = {}) {
948
+ const chainId = this.getChainId();
949
+ // searchCriteria is an object that might have values that aren't predicate
950
+ // methods. When providing any other value type (string, number, etc), we
951
+ // consider this shorthand for "check the value at key for strict equality
952
+ // with the provided value". To conform this object to be only methods, we
953
+ // mapValues (lodash) such that every value on the object is a method that
954
+ // returns a boolean.
955
+ const predicateMethods = mapValues(searchCriteria, (predicate) => {
956
+ return typeof predicate === 'function'
957
+ ? predicate
958
+ : // TODO: Replace `any` with type
959
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
960
+ (v) => v === predicate;
961
+ });
962
+ const transactionsToFilter = initialList ?? this.state.transactions;
963
+ // Combine sortBy and pickBy to transform our state object into an array of
964
+ // matching transactions that are sorted by time.
965
+ const filteredTransactions = sortBy(pickBy(transactionsToFilter, (transaction) => {
966
+ if (filterToCurrentNetwork && transaction.chainId !== chainId) {
967
+ return false;
968
+ }
969
+ // iterate over the predicateMethods keys to check if the transaction
970
+ // matches the searchCriteria
971
+ for (const [key, predicate] of Object.entries(predicateMethods)) {
972
+ // We return false early as soon as we know that one of the specified
973
+ // search criteria do not match the transaction. This prevents
974
+ // needlessly checking all criteria when we already know the criteria
975
+ // are not fully satisfied. We check both txParams and the base
976
+ // object as predicate keys can be either.
977
+ if (key in transaction.txParams) {
978
+ // TODO: Replace `any` with type
979
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
980
+ if (predicate(transaction.txParams[key]) === false) {
981
+ return false;
982
+ }
983
+ // TODO: Replace `any` with type
984
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
985
+ }
986
+ else if (predicate(transaction[key]) === false) {
987
+ return false;
988
+ }
989
+ }
990
+ return true;
991
+ }), 'time');
992
+ if (limit !== undefined) {
993
+ // We need to have all transactions of a given nonce in order to display
994
+ // necessary details in the UI. We use the size of this set to determine
995
+ // whether we have reached the limit provided, thus ensuring that all
996
+ // transactions of nonces we include will be sent to the UI.
997
+ const nonces = new Set();
998
+ const txs = [];
999
+ // By default, the transaction list we filter from is sorted by time ASC.
1000
+ // To ensure that filtered results prefers the newest transactions we
1001
+ // iterate from right to left, inserting transactions into front of a new
1002
+ // array. The original order is preserved, but we ensure that newest txs
1003
+ // are preferred.
1004
+ for (let i = filteredTransactions.length - 1; i > -1; i--) {
1005
+ const txMeta = filteredTransactions[i];
1006
+ const { nonce } = txMeta.txParams;
1007
+ if (!nonces.has(nonce)) {
1008
+ if (nonces.size < limit) {
1009
+ nonces.add(nonce);
1010
+ }
1011
+ else {
1012
+ continue;
1013
+ }
1014
+ }
1015
+ // Push transaction into the beginning of our array to ensure the
1016
+ // original order is preserved.
1017
+ txs.unshift(txMeta);
1018
+ }
1019
+ return txs;
1020
+ }
1021
+ return filteredTransactions;
1022
+ }
1023
+ async estimateGasFee({ transactionParams, chainId, networkClientId: requestNetworkClientId, }) {
1024
+ const networkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNetworkClientId).call(this, {
1025
+ networkClientId: requestNetworkClientId,
1026
+ chainId,
1027
+ });
1028
+ const transactionMeta = {
1029
+ txParams: transactionParams,
1030
+ chainId,
1031
+ networkClientId,
1032
+ };
1033
+ // Guaranteed as the default gas fee flow matches all transactions.
1034
+ const gasFeeFlow = getGasFeeFlow(transactionMeta, this.gasFeeFlows);
1035
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1036
+ networkClientId,
1037
+ chainId,
1038
+ });
1039
+ const gasFeeControllerData = await this.getGasFeeEstimates({
1040
+ networkClientId,
1041
+ });
1042
+ return gasFeeFlow.getGasFees({
1043
+ ethQuery,
1044
+ gasFeeControllerData,
1045
+ transactionMeta,
1046
+ });
1047
+ }
1048
+ /**
1049
+ * Determine the layer 1 gas fee for the given transaction parameters.
1050
+ *
1051
+ * @param request - The request object.
1052
+ * @param request.transactionParams - The transaction parameters to estimate the layer 1 gas fee for.
1053
+ * @param request.chainId - The ID of the chain where the transaction will be executed.
1054
+ * @param request.networkClientId - The ID of a specific network client to process the transaction.
1055
+ */
1056
+ async getLayer1GasFee({ transactionParams, chainId, networkClientId, }) {
1057
+ const provider = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
1058
+ networkClientId,
1059
+ chainId,
1060
+ });
1061
+ return await getTransactionLayer1GasFee({
1062
+ layer1GasFeeFlows: this.layer1GasFeeFlows,
1063
+ provider,
1064
+ transactionMeta: {
1065
+ txParams: transactionParams,
1066
+ chainId,
1067
+ },
1068
+ });
1069
+ }
1070
+ async signExternalTransaction(chainId, transactionParams) {
1071
+ if (!this.sign) {
1072
+ throw new Error('No sign method defined.');
1073
+ }
1074
+ const normalizedTransactionParams = normalizeTransactionParams(transactionParams);
1075
+ const type = isEIP1559Transaction(normalizedTransactionParams)
1076
+ ? TransactionEnvelopeType.feeMarket
1077
+ : TransactionEnvelopeType.legacy;
1078
+ const updatedTransactionParams = {
1079
+ ...normalizedTransactionParams,
1080
+ type,
1081
+ gasLimit: normalizedTransactionParams.gas,
1082
+ chainId,
1083
+ };
1084
+ const { from } = updatedTransactionParams;
1085
+ const common = this.getCommonConfiguration(chainId);
1086
+ const unsignedTransaction = TransactionFactory.fromTxData(updatedTransactionParams, { common });
1087
+ const signedTransaction = await this.sign(unsignedTransaction, from);
1088
+ const rawTransaction = bufferToHex(signedTransaction.serialize());
1089
+ return rawTransaction;
1090
+ }
1091
+ /**
1092
+ * Removes unapproved transactions from state.
1093
+ */
1094
+ clearUnapprovedTransactions() {
1095
+ const transactions = this.state.transactions.filter(({ status }) => status !== TransactionStatus.unapproved);
1096
+ this.update((state) => {
1097
+ state.transactions = this.trimTransactionsForState(transactions);
1098
+ });
1099
+ }
1100
+ /**
1101
+ * Stop the signing process for a specific transaction.
1102
+ * Throws an error causing the transaction status to be set to failed.
1103
+ * @param transactionId - The ID of the transaction to stop signing.
1104
+ */
1105
+ abortTransactionSigning(transactionId) {
1106
+ const transactionMeta = this.getTransaction(transactionId);
1107
+ if (!transactionMeta) {
1108
+ throw new Error(`Cannot abort signing as no transaction metadata found`);
1109
+ }
1110
+ const abortCallback = this.signAbortCallbacks.get(transactionId);
1111
+ if (!abortCallback) {
1112
+ throw new Error(`Cannot abort signing as transaction is not waiting for signing`);
1113
+ }
1114
+ abortCallback();
1115
+ this.signAbortCallbacks.delete(transactionId);
1116
+ }
1117
+ addMetadata(transactionMeta) {
1118
+ validateTxParams(transactionMeta.txParams);
1119
+ this.update((state) => {
1120
+ state.transactions = this.trimTransactionsForState([
1121
+ ...state.transactions,
1122
+ transactionMeta,
1123
+ ]);
1124
+ });
1125
+ }
1126
+ async updateGasProperties(transactionMeta, { traceContext } = {}) {
1127
+ const isEIP1559Compatible = transactionMeta.txParams.type !== TransactionEnvelopeType.legacy &&
1128
+ (await this.getEIP1559Compatibility(transactionMeta.networkClientId));
1129
+ const { networkClientId, chainId } = transactionMeta;
1130
+ const isCustomNetwork = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_isCustomNetwork).call(this, networkClientId);
1131
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1132
+ networkClientId,
1133
+ chainId,
1134
+ });
1135
+ const provider = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
1136
+ networkClientId,
1137
+ chainId,
1138
+ });
1139
+ await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Update Gas', parentContext: traceContext }, async () => {
1140
+ await updateGas({
1141
+ ethQuery,
1142
+ chainId,
1143
+ isCustomNetwork,
1144
+ txMeta: transactionMeta,
1145
+ });
1146
+ });
1147
+ await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Update Gas Fees', parentContext: traceContext }, async () => await updateGasFees({
1148
+ eip1559: isEIP1559Compatible,
1149
+ ethQuery,
1150
+ gasFeeFlows: this.gasFeeFlows,
1151
+ getGasFeeEstimates: this.getGasFeeEstimates,
1152
+ getSavedGasFees: this.getSavedGasFees.bind(this),
1153
+ txMeta: transactionMeta,
1154
+ }));
1155
+ await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Update Layer 1 Gas Fees', parentContext: traceContext }, async () => await updateTransactionLayer1GasFee({
1156
+ layer1GasFeeFlows: this.layer1GasFeeFlows,
1157
+ provider,
1158
+ transactionMeta,
1159
+ }));
1160
+ }
1161
+ onBootCleanup() {
1162
+ this.clearUnapprovedTransactions();
1163
+ this.failIncompleteTransactions();
1164
+ }
1165
+ failIncompleteTransactions() {
1166
+ const incompleteTransactions = this.state.transactions.filter((transaction) => [TransactionStatus.approved, TransactionStatus.signed].includes(transaction.status));
1167
+ for (const transactionMeta of incompleteTransactions) {
1168
+ this.failTransaction(transactionMeta, new Error('Transaction incomplete at startup'));
1169
+ }
1170
+ }
1171
+ async processApproval(transactionMeta, { isExisting = false, requireApproval, shouldShowRequest = true, actionId, traceContext, }) {
1172
+ const transactionId = transactionMeta.id;
1173
+ let resultCallbacks;
1174
+ const { meta, isCompleted } = this.isTransactionCompleted(transactionId);
1175
+ const finishedPromise = isCompleted
1176
+ ? Promise.resolve(meta)
1177
+ : this.waitForTransactionFinished(transactionId);
1178
+ if (meta && !isExisting && !isCompleted) {
1179
+ try {
1180
+ if (requireApproval !== false) {
1181
+ const acceptResult = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Await Approval', parentContext: traceContext }, (context) => this.requestApproval(transactionMeta, {
1182
+ shouldShowRequest,
1183
+ traceContext: context,
1184
+ }));
1185
+ resultCallbacks = acceptResult.resultCallbacks;
1186
+ const approvalValue = acceptResult.value;
1187
+ const updatedTransaction = approvalValue?.txMeta;
1188
+ if (updatedTransaction) {
1189
+ log('Updating transaction with approval data', {
1190
+ customNonce: updatedTransaction.customNonceValue,
1191
+ params: updatedTransaction.txParams,
1192
+ });
1193
+ this.updateTransaction(updatedTransaction, 'TransactionController#processApproval - Updated with approval data');
1194
+ }
1195
+ }
1196
+ const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
1197
+ if (!isTxCompleted) {
1198
+ const approvalResult = await this.approveTransaction(transactionId, traceContext);
1199
+ if (approvalResult === ApprovalState.SkippedViaBeforePublishHook &&
1200
+ resultCallbacks) {
1201
+ resultCallbacks.success();
1202
+ }
1203
+ const updatedTransactionMeta = this.getTransaction(transactionId);
1204
+ this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
1205
+ transactionMeta: updatedTransactionMeta,
1206
+ actionId,
1207
+ });
1208
+ }
1209
+ // TODO: Replace `any` with type
1210
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1211
+ }
1212
+ catch (error) {
1213
+ const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
1214
+ if (!isTxCompleted) {
1215
+ if (error?.code === errorCodes.provider.userRejectedRequest) {
1216
+ this.cancelTransaction(transactionId, actionId);
1217
+ throw providerErrors.userRejectedRequest('MetaMask Tx Signature: User denied transaction signature.');
1218
+ }
1219
+ else {
1220
+ this.failTransaction(meta, error, actionId);
1221
+ }
1222
+ }
1223
+ }
1224
+ }
1225
+ const finalMeta = await finishedPromise;
1226
+ switch (finalMeta?.status) {
1227
+ case TransactionStatus.failed:
1228
+ resultCallbacks?.error(finalMeta.error);
1229
+ throw rpcErrors.internal(finalMeta.error.message);
1230
+ case TransactionStatus.submitted:
1231
+ resultCallbacks?.success();
1232
+ return finalMeta.hash;
1233
+ default:
1234
+ const internalError = rpcErrors.internal(`MetaMask Tx Signature: Unknown problem: ${JSON.stringify(finalMeta || transactionId)}`);
1235
+ resultCallbacks?.error(internalError);
1236
+ throw internalError;
1237
+ }
1238
+ }
1239
+ /**
1240
+ * Approves a transaction and updates it's status in state. If this is not a
1241
+ * retry transaction, a nonce will be generated. The transaction is signed
1242
+ * using the sign configuration property, then published to the blockchain.
1243
+ * A `<tx.id>:finished` hub event is fired after success or failure.
1244
+ *
1245
+ * @param transactionId - The ID of the transaction to approve.
1246
+ * @param traceContext - The parent context for any new traces.
1247
+ */
1248
+ async approveTransaction(transactionId, traceContext) {
1249
+ const cleanupTasks = new Array();
1250
+ cleanupTasks.push(await this.mutex.acquire());
1251
+ let transactionMeta = this.getTransactionOrThrow(transactionId);
1252
+ try {
1253
+ if (!this.sign) {
1254
+ this.failTransaction(transactionMeta, new Error('No sign method defined.'));
1255
+ return ApprovalState.NotApproved;
1256
+ }
1257
+ else if (!transactionMeta.chainId) {
1258
+ this.failTransaction(transactionMeta, new Error('No chainId defined.'));
1259
+ return ApprovalState.NotApproved;
1260
+ }
1261
+ if (this.approvingTransactionIds.has(transactionId)) {
1262
+ log('Skipping approval as signing in progress', transactionId);
1263
+ return ApprovalState.NotApproved;
1264
+ }
1265
+ this.approvingTransactionIds.add(transactionId);
1266
+ cleanupTasks.push(() => this.approvingTransactionIds.delete(transactionId));
1267
+ const [nonce, releaseNonce] = await getNextNonce(transactionMeta, (address) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, transactionMeta.networkClientId));
1268
+ // must set transaction to submitted/failed before releasing lock
1269
+ releaseNonce && cleanupTasks.push(releaseNonce);
1270
+ transactionMeta = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, {
1271
+ transactionId,
1272
+ note: 'TransactionController#approveTransaction - Transaction approved',
1273
+ }, (draftTxMeta) => {
1274
+ const { txParams, chainId } = draftTxMeta;
1275
+ draftTxMeta.status = TransactionStatus.approved;
1276
+ draftTxMeta.txParams = {
1277
+ ...txParams,
1278
+ nonce,
1279
+ chainId,
1280
+ gasLimit: txParams.gas,
1281
+ ...(isEIP1559Transaction(txParams) && {
1282
+ type: TransactionEnvelopeType.feeMarket,
1283
+ }),
1284
+ };
1285
+ });
1286
+ this.onTransactionStatusChange(transactionMeta);
1287
+ const rawTx = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Sign', parentContext: traceContext }, () => this.signTransaction(transactionMeta, transactionMeta.txParams));
1288
+ if (!this.beforePublish(transactionMeta)) {
1289
+ log('Skipping publishing transaction based on hook');
1290
+ this.messagingSystem.publish(`${controllerName}:transactionPublishingSkipped`, transactionMeta);
1291
+ return ApprovalState.SkippedViaBeforePublishHook;
1292
+ }
1293
+ if (!rawTx) {
1294
+ return ApprovalState.NotApproved;
1295
+ }
1296
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1297
+ networkClientId: transactionMeta.networkClientId,
1298
+ chainId: transactionMeta.chainId,
1299
+ });
1300
+ let preTxBalance;
1301
+ const shouldUpdatePreTxBalance = transactionMeta.type === TransactionType.swap;
1302
+ if (shouldUpdatePreTxBalance) {
1303
+ log('Determining pre-transaction balance');
1304
+ preTxBalance = await query(ethQuery, 'getBalance', [
1305
+ transactionMeta.txParams.from,
1306
+ ]);
1307
+ }
1308
+ log('Publishing transaction', transactionMeta.txParams);
1309
+ let hash;
1310
+ await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Publish', parentContext: traceContext }, async () => {
1311
+ ({ transactionHash: hash } = await this.publish(transactionMeta, rawTx));
1312
+ if (hash === undefined) {
1313
+ hash = await this.publishTransaction(ethQuery, {
1314
+ ...transactionMeta,
1315
+ rawTx,
1316
+ });
1317
+ }
1318
+ });
1319
+ log('Publish successful', hash);
1320
+ transactionMeta = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, {
1321
+ transactionId,
1322
+ note: 'TransactionController#approveTransaction - Transaction submitted',
1323
+ }, (draftTxMeta) => {
1324
+ draftTxMeta.hash = hash;
1325
+ draftTxMeta.status = TransactionStatus.submitted;
1326
+ draftTxMeta.submittedTime = new Date().getTime();
1327
+ if (shouldUpdatePreTxBalance) {
1328
+ draftTxMeta.preTxBalance = preTxBalance;
1329
+ log('Updated pre-transaction balance', preTxBalance);
1330
+ }
1331
+ });
1332
+ this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
1333
+ transactionMeta,
1334
+ });
1335
+ this.messagingSystem.publish(`${controllerName}:transactionFinished`, transactionMeta);
1336
+ __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionId}:finished`, transactionMeta);
1337
+ this.onTransactionStatusChange(transactionMeta);
1338
+ return ApprovalState.Approved;
1339
+ // TODO: Replace `any` with type
1340
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1341
+ }
1342
+ catch (error) {
1343
+ this.failTransaction(transactionMeta, error);
1344
+ return ApprovalState.NotApproved;
1345
+ }
1346
+ finally {
1347
+ cleanupTasks.forEach((task) => task());
1348
+ }
1349
+ }
1350
+ async publishTransaction(ethQuery, transactionMeta, { skipSubmitHistory } = {}) {
1351
+ const transactionHash = await query(ethQuery, 'sendRawTransaction', [
1352
+ transactionMeta.rawTx,
1353
+ ]);
1354
+ if (skipSubmitHistory !== true) {
1355
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateSubmitHistory).call(this, transactionMeta, transactionHash);
1356
+ }
1357
+ return transactionHash;
1358
+ }
1359
+ /**
1360
+ * Cancels a transaction based on its ID by setting its status to "rejected"
1361
+ * and emitting a `<tx.id>:finished` hub event.
1362
+ *
1363
+ * @param transactionId - The ID of the transaction to cancel.
1364
+ * @param actionId - The actionId passed from UI
1365
+ */
1366
+ cancelTransaction(transactionId, actionId) {
1367
+ const transactionMeta = this.state.transactions.find(({ id }) => id === transactionId);
1368
+ if (!transactionMeta) {
1369
+ return;
1370
+ }
1371
+ this.update((state) => {
1372
+ const transactions = state.transactions.filter(({ id }) => id !== transactionId);
1373
+ state.transactions = this.trimTransactionsForState(transactions);
1374
+ });
1375
+ const updatedTransactionMeta = {
1376
+ ...transactionMeta,
1377
+ status: TransactionStatus.rejected,
1378
+ };
1379
+ this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
1380
+ __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(
1381
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
1382
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
1383
+ `${transactionMeta.id}:finished`, updatedTransactionMeta);
1384
+ this.messagingSystem.publish(`${controllerName}:transactionRejected`, {
1385
+ transactionMeta: updatedTransactionMeta,
1386
+ actionId,
1387
+ });
1388
+ this.onTransactionStatusChange(updatedTransactionMeta);
1389
+ }
1390
+ /**
1391
+ * Trim the amount of transactions that are set on the state. Checks
1392
+ * if the length of the tx history is longer then desired persistence
1393
+ * limit and then if it is removes the oldest confirmed or rejected tx.
1394
+ * Pending or unapproved transactions will not be removed by this
1395
+ * operation. For safety of presenting a fully functional transaction UI
1396
+ * representation, this function will not break apart transactions with the
1397
+ * same nonce, created on the same day, per network. Not accounting for
1398
+ * transactions of the same nonce, same day and network combo can result in
1399
+ * confusing or broken experiences in the UI.
1400
+ *
1401
+ * @param transactions - The transactions to be applied to the state.
1402
+ * @returns The trimmed list of transactions.
1403
+ */
1404
+ trimTransactionsForState(transactions) {
1405
+ const nonceNetworkSet = new Set();
1406
+ const txsToKeep = [...transactions]
1407
+ .sort((a, b) => (a.time > b.time ? -1 : 1)) // Descending time order
1408
+ .filter((tx) => {
1409
+ const { chainId, status, txParams, time } = tx;
1410
+ if (txParams) {
1411
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
1412
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
1413
+ const key = `${String(txParams.nonce)}-${convertHexToDecimal(chainId)}-${new Date(time).toDateString()}`;
1414
+ if (nonceNetworkSet.has(key)) {
1415
+ return true;
1416
+ }
1417
+ else if (nonceNetworkSet.size < __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f") ||
1418
+ !this.isFinalState(status)) {
1419
+ nonceNetworkSet.add(key);
1420
+ return true;
1421
+ }
1422
+ }
1423
+ return false;
1424
+ });
1425
+ txsToKeep.reverse(); // Ascending time order
1426
+ return txsToKeep;
1427
+ }
1428
+ /**
1429
+ * Determines if the transaction is in a final state.
1430
+ *
1431
+ * @param status - The transaction status.
1432
+ * @returns Whether the transaction is in a final state.
1433
+ */
1434
+ isFinalState(status) {
1435
+ return (status === TransactionStatus.rejected ||
1436
+ status === TransactionStatus.confirmed ||
1437
+ status === TransactionStatus.failed);
1438
+ }
1439
+ /**
1440
+ * Whether the transaction has at least completed all local processing.
1441
+ *
1442
+ * @param status - The transaction status.
1443
+ * @returns Whether the transaction is in a final state.
1444
+ */
1445
+ isLocalFinalState(status) {
1446
+ return [
1447
+ TransactionStatus.confirmed,
1448
+ TransactionStatus.failed,
1449
+ TransactionStatus.rejected,
1450
+ TransactionStatus.submitted,
1451
+ ].includes(status);
1452
+ }
1453
+ async requestApproval(txMeta, { shouldShowRequest, traceContext, }) {
1454
+ const id = this.getApprovalId(txMeta);
1455
+ const { origin } = txMeta;
1456
+ const type = ApprovalType.Transaction;
1457
+ const requestData = { txId: txMeta.id };
1458
+ await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, {
1459
+ name: 'Notification Display',
1460
+ id,
1461
+ parentContext: traceContext,
1462
+ });
1463
+ return (await this.messagingSystem.call('ApprovalController:addRequest', {
1464
+ id,
1465
+ origin: origin || ORIGIN_METAMASK,
1466
+ type,
1467
+ requestData,
1468
+ expectsResult: true,
1469
+ }, shouldShowRequest));
1470
+ }
1471
+ getTransaction(transactionId) {
1472
+ const { transactions } = this.state;
1473
+ return transactions.find(({ id }) => id === transactionId);
1474
+ }
1475
+ getTransactionOrThrow(transactionId, errorMessagePrefix = 'TransactionController') {
1476
+ const txMeta = this.getTransaction(transactionId);
1477
+ if (!txMeta) {
1478
+ throw new Error(`${errorMessagePrefix}: No transaction found with id ${transactionId}`);
1479
+ }
1480
+ return txMeta;
1481
+ }
1482
+ getApprovalId(txMeta) {
1483
+ return String(txMeta.id);
1484
+ }
1485
+ isTransactionCompleted(transactionId) {
1486
+ const transaction = this.getTransaction(transactionId);
1487
+ if (!transaction) {
1488
+ return { meta: undefined, isCompleted: false };
1489
+ }
1490
+ const isCompleted = this.isLocalFinalState(transaction.status);
1491
+ return { meta: transaction, isCompleted };
1492
+ }
1493
+ getChainId(networkClientId) {
1494
+ const globalChainId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalChainId).call(this);
1495
+ const globalNetworkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
1496
+ if (!networkClientId || networkClientId === globalNetworkClientId) {
1497
+ return globalChainId;
1498
+ }
1499
+ return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.chainId;
1500
+ }
1501
+ prepareUnsignedEthTx(chainId, txParams) {
1502
+ return TransactionFactory.fromTxData(txParams, {
1503
+ freeze: false,
1504
+ common: this.getCommonConfiguration(chainId),
1505
+ });
1506
+ }
1507
+ /**
1508
+ * `@ethereumjs/tx` uses `@ethereumjs/common` as a configuration tool for
1509
+ * specifying which chain, network, hardfork and EIPs to support for
1510
+ * a transaction. By referencing this configuration, and analyzing the fields
1511
+ * specified in txParams, @ethereumjs/tx is able to determine which EIP-2718
1512
+ * transaction type to use.
1513
+ *
1514
+ * @param chainId - The chainId to use for the configuration.
1515
+ * @returns common configuration object
1516
+ */
1517
+ getCommonConfiguration(chainId) {
1518
+ const customChainParams = {
1519
+ chainId: parseInt(chainId, 16),
1520
+ defaultHardfork: HARDFORK,
1521
+ };
1522
+ return Common.custom(customChainParams);
1523
+ }
1524
+ onIncomingTransactions({ added, updated, }) {
1525
+ this.update((state) => {
1526
+ const { transactions: currentTransactions } = state;
1527
+ const updatedTransactions = [
1528
+ ...added,
1529
+ ...currentTransactions.map((originalTransaction) => {
1530
+ const updatedTransaction = updated.find(({ hash }) => hash === originalTransaction.hash);
1531
+ return updatedTransaction ?? originalTransaction;
1532
+ }),
1533
+ ];
1534
+ state.transactions = this.trimTransactionsForState(updatedTransactions);
1535
+ });
1536
+ }
1537
+ onUpdatedLastFetchedBlockNumbers({ lastFetchedBlockNumbers, blockNumber, }) {
1538
+ this.update((state) => {
1539
+ state.lastFetchedBlockNumbers = lastFetchedBlockNumbers;
1540
+ });
1541
+ this.messagingSystem.publish(`${controllerName}:incomingTransactionBlockReceived`, blockNumber);
1542
+ }
1543
+ generateDappSuggestedGasFees(txParams, origin) {
1544
+ if (!origin || origin === ORIGIN_METAMASK) {
1545
+ return undefined;
1546
+ }
1547
+ const { gasPrice, maxFeePerGas, maxPriorityFeePerGas, gas } = txParams;
1548
+ if (gasPrice === undefined &&
1549
+ maxFeePerGas === undefined &&
1550
+ maxPriorityFeePerGas === undefined &&
1551
+ gas === undefined) {
1552
+ return undefined;
1553
+ }
1554
+ const dappSuggestedGasFees = {};
1555
+ if (gasPrice !== undefined) {
1556
+ dappSuggestedGasFees.gasPrice = gasPrice;
1557
+ }
1558
+ else if (maxFeePerGas !== undefined ||
1559
+ maxPriorityFeePerGas !== undefined) {
1560
+ dappSuggestedGasFees.maxFeePerGas = maxFeePerGas;
1561
+ dappSuggestedGasFees.maxPriorityFeePerGas = maxPriorityFeePerGas;
1562
+ }
1563
+ if (gas !== undefined) {
1564
+ dappSuggestedGasFees.gas = gas;
1565
+ }
1566
+ return dappSuggestedGasFees;
1567
+ }
1568
+ /**
1569
+ * Validates and adds external provided transaction to state.
1570
+ *
1571
+ * @param transactionMeta - Nominated external transaction to be added to state.
1572
+ * @returns The new transaction.
1573
+ */
1574
+ addExternalTransaction(transactionMeta) {
1575
+ const { chainId } = transactionMeta;
1576
+ const { transactions } = this.state;
1577
+ const fromAddress = transactionMeta?.txParams?.from;
1578
+ const sameFromAndNetworkTransactions = transactions.filter((transaction) => transaction.txParams.from === fromAddress &&
1579
+ transaction.chainId === chainId);
1580
+ const confirmedTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === TransactionStatus.confirmed);
1581
+ const pendingTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === TransactionStatus.submitted);
1582
+ validateConfirmedExternalTransaction(transactionMeta, confirmedTxs, pendingTxs);
1583
+ // Make sure provided external transaction has non empty history array
1584
+ const newTransactionMeta = (transactionMeta.history ?? []).length === 0 && !this.isHistoryDisabled
1585
+ ? addInitialHistorySnapshot(transactionMeta)
1586
+ : transactionMeta;
1587
+ this.update((state) => {
1588
+ state.transactions = this.trimTransactionsForState([
1589
+ ...state.transactions,
1590
+ newTransactionMeta,
1591
+ ]);
1592
+ });
1593
+ return newTransactionMeta;
1594
+ }
1595
+ /**
1596
+ * Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
1597
+ * in the transactions have the same nonce.
1598
+ *
1599
+ * @param transactionId - Used to identify original transaction.
1600
+ */
1601
+ markNonceDuplicatesDropped(transactionId) {
1602
+ const transactionMeta = this.getTransaction(transactionId);
1603
+ if (!transactionMeta) {
1604
+ return;
1605
+ }
1606
+ const nonce = transactionMeta.txParams?.nonce;
1607
+ const from = transactionMeta.txParams?.from;
1608
+ const { chainId } = transactionMeta;
1609
+ const sameNonceTransactions = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
1610
+ transaction.txParams.from === from &&
1611
+ transaction.txParams.nonce === nonce &&
1612
+ transaction.chainId === chainId &&
1613
+ transaction.type !== TransactionType.incoming);
1614
+ const sameNonceTransactionIds = sameNonceTransactions.map((transaction) => transaction.id);
1615
+ if (sameNonceTransactions.length === 0) {
1616
+ return;
1617
+ }
1618
+ this.update((state) => {
1619
+ for (const transaction of state.transactions) {
1620
+ if (sameNonceTransactionIds.includes(transaction.id)) {
1621
+ transaction.replacedBy = transactionMeta?.hash;
1622
+ transaction.replacedById = transactionMeta?.id;
1623
+ }
1624
+ }
1625
+ });
1626
+ for (const transaction of this.state.transactions) {
1627
+ if (sameNonceTransactionIds.includes(transaction.id) &&
1628
+ transaction.status !== TransactionStatus.failed) {
1629
+ this.setTransactionStatusDropped(transaction);
1630
+ }
1631
+ }
1632
+ }
1633
+ /**
1634
+ * Method to set transaction status to dropped.
1635
+ *
1636
+ * @param transactionMeta - TransactionMeta of transaction to be marked as dropped.
1637
+ */
1638
+ setTransactionStatusDropped(transactionMeta) {
1639
+ const updatedTransactionMeta = {
1640
+ ...transactionMeta,
1641
+ status: TransactionStatus.dropped,
1642
+ };
1643
+ this.messagingSystem.publish(`${controllerName}:transactionDropped`, {
1644
+ transactionMeta: updatedTransactionMeta,
1645
+ });
1646
+ this.updateTransaction(updatedTransactionMeta, 'TransactionController#setTransactionStatusDropped - Transaction dropped');
1647
+ this.onTransactionStatusChange(updatedTransactionMeta);
1648
+ }
1649
+ /**
1650
+ * Get transaction with provided actionId.
1651
+ *
1652
+ * @param actionId - Unique ID to prevent duplicate requests
1653
+ * @returns the filtered transaction
1654
+ */
1655
+ getTransactionWithActionId(actionId) {
1656
+ return this.state.transactions.find((transaction) => actionId && transaction.actionId === actionId);
1657
+ }
1658
+ async waitForTransactionFinished(transactionId) {
1659
+ return new Promise((resolve) => {
1660
+ __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").once(`${transactionId}:finished`, (txMeta) => {
1661
+ resolve(txMeta);
1662
+ });
1663
+ });
1664
+ }
1665
+ /**
1666
+ * Updates the r, s, and v properties of a TransactionMeta object
1667
+ * with values from a signed transaction.
1668
+ *
1669
+ * @param transactionMeta - The TransactionMeta object to update.
1670
+ * @param signedTx - The encompassing type for all transaction types containing r, s, and v values.
1671
+ * @returns The updated TransactionMeta object.
1672
+ */
1673
+ updateTransactionMetaRSV(transactionMeta, signedTx) {
1674
+ const transactionMetaWithRsv = cloneDeep(transactionMeta);
1675
+ for (const key of ['r', 's', 'v']) {
1676
+ const value = signedTx[key];
1677
+ if (value === undefined || value === null) {
1678
+ continue;
1679
+ }
1680
+ transactionMetaWithRsv[key] = add0x(value.toString(16));
1681
+ }
1682
+ return transactionMetaWithRsv;
1683
+ }
1684
+ async getEIP1559Compatibility(networkClientId) {
1685
+ const currentNetworkIsEIP1559Compatible = await this.getCurrentNetworkEIP1559Compatibility(networkClientId);
1686
+ const currentAccountIsEIP1559Compatible = await this.getCurrentAccountEIP1559Compatibility();
1687
+ return (currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible);
1688
+ }
1689
+ async signTransaction(transactionMeta, txParams) {
1690
+ log('Signing transaction', txParams);
1691
+ const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
1692
+ this.approvingTransactionIds.add(transactionMeta.id);
1693
+ const signedTx = await new Promise((resolve, reject) => {
1694
+ this.sign?.(unsignedEthTx, txParams.from, ...this.getAdditionalSignArguments(transactionMeta)).then(resolve, reject);
1695
+ this.signAbortCallbacks.set(transactionMeta.id, () => reject(new Error('Signing aborted by user')));
1696
+ });
1697
+ this.signAbortCallbacks.delete(transactionMeta.id);
1698
+ if (!signedTx) {
1699
+ log('Skipping signed status as no signed transaction');
1700
+ return undefined;
1701
+ }
1702
+ const transactionMetaFromHook = cloneDeep(transactionMeta);
1703
+ if (!this.afterSign(transactionMetaFromHook, signedTx)) {
1704
+ this.updateTransaction(transactionMetaFromHook, 'TransactionController#signTransaction - Update after sign');
1705
+ log('Skipping signed status based on hook');
1706
+ return undefined;
1707
+ }
1708
+ const transactionMetaWithRsv = {
1709
+ ...this.updateTransactionMetaRSV(transactionMetaFromHook, signedTx),
1710
+ status: TransactionStatus.signed,
1711
+ };
1712
+ this.updateTransaction(transactionMetaWithRsv, 'TransactionController#approveTransaction - Transaction signed');
1713
+ this.onTransactionStatusChange(transactionMetaWithRsv);
1714
+ const rawTx = bufferToHex(signedTx.serialize());
1715
+ const transactionMetaWithRawTx = merge({}, transactionMetaWithRsv, {
1716
+ rawTx,
1717
+ });
1718
+ this.updateTransaction(transactionMetaWithRawTx, 'TransactionController#approveTransaction - RawTransaction added');
1719
+ return rawTx;
1720
+ }
1721
+ onTransactionStatusChange(transactionMeta) {
1722
+ this.messagingSystem.publish(`${controllerName}:transactionStatusUpdated`, {
1723
+ transactionMeta,
1724
+ });
1725
+ }
1726
+ getNonceTrackerTransactions(status, address, chainId = this.getChainId()) {
1727
+ return getAndFormatTransactionsForNonceTracker(chainId, address, status, this.state.transactions);
1728
+ }
1729
+ onConfirmedTransaction(transactionMeta) {
1730
+ log('Processing confirmed transaction', transactionMeta.id);
1731
+ this.markNonceDuplicatesDropped(transactionMeta.id);
1732
+ this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, transactionMeta);
1733
+ this.onTransactionStatusChange(transactionMeta);
1734
+ // Intentional given potential duration of process.
1735
+ this.updatePostBalance(transactionMeta).catch((error) => {
1736
+ log('Error while updating post balance', error);
1737
+ throw error;
1738
+ });
1739
+ }
1740
+ async updatePostBalance(transactionMeta) {
1741
+ try {
1742
+ if (transactionMeta.type !== TransactionType.swap) {
1743
+ return;
1744
+ }
1745
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1746
+ networkClientId: transactionMeta.networkClientId,
1747
+ chainId: transactionMeta.chainId,
1748
+ });
1749
+ const { updatedTransactionMeta, approvalTransactionMeta } = await updatePostTransactionBalance(transactionMeta, {
1750
+ ethQuery,
1751
+ getTransaction: this.getTransaction.bind(this),
1752
+ updateTransaction: this.updateTransaction.bind(this),
1753
+ });
1754
+ this.messagingSystem.publish(`${controllerName}:postTransactionBalanceUpdated`, {
1755
+ transactionMeta: updatedTransactionMeta,
1756
+ approvalTransactionMeta,
1757
+ });
1758
+ }
1759
+ catch (error) {
1760
+ /* istanbul ignore next */
1761
+ log('Error while updating post transaction balance', error);
1762
+ }
1763
+ }
1764
+ async publishTransactionForRetry(ethQuery, transactionMeta) {
1765
+ try {
1766
+ return await this.publishTransaction(ethQuery, transactionMeta);
1767
+ }
1768
+ catch (error) {
1769
+ if (this.isTransactionAlreadyConfirmedError(error)) {
1770
+ await this.pendingTransactionTracker.forceCheckTransaction(transactionMeta);
1771
+ throw new Error('Previous transaction is already confirmed');
1772
+ }
1773
+ throw error;
1774
+ }
1775
+ }
1776
+ /**
1777
+ * Ensures that error is a nonce issue
1778
+ *
1779
+ * @param error - The error to check
1780
+ * @returns Whether or not the error is a nonce issue
1781
+ */
1782
+ // TODO: Replace `any` with type
1783
+ // Some networks are returning original error in the data field
1784
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1785
+ isTransactionAlreadyConfirmedError(error) {
1786
+ return (error?.message?.includes('nonce too low') ||
1787
+ error?.data?.message?.includes('nonce too low'));
1788
+ }
1789
+ }
1790
+ _TransactionController_internalEvents = new WeakMap(), _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionController_pendingTransactionOptions = new WeakMap(), _TransactionController_trace = new WeakMap(), _TransactionController_transactionHistoryLimit = new WeakMap(), _TransactionController_isSimulationEnabled = new WeakMap(), _TransactionController_testGasFeeFlows = new WeakMap(), _TransactionController_multichainTrackingHelper = new WeakMap(), _TransactionController_checkForPendingTransactionAndStartPolling = new WeakMap(), _TransactionController_instances = new WeakSet(), _TransactionController_retryTransaction = async function _TransactionController_retryTransaction({ actionId, afterSubmit, estimatedBaseFee, gasValues, label, prepareTransactionParams, rate, transactionId, transactionType, }) {
1791
+ // If transaction is found for same action id, do not create a new transaction.
1792
+ if (this.getTransactionWithActionId(actionId)) {
1793
+ return;
1794
+ }
1795
+ if (gasValues) {
1796
+ // Not good practice to reassign a parameter but temporarily avoiding a larger refactor.
1797
+ gasValues = normalizeGasFeeValues(gasValues);
1798
+ validateGasValues(gasValues);
1799
+ }
1800
+ log(`Creating ${label} transaction`, transactionId, gasValues);
1801
+ const transactionMeta = this.getTransaction(transactionId);
1802
+ /* istanbul ignore next */
1803
+ if (!transactionMeta) {
1804
+ return;
1805
+ }
1806
+ /* istanbul ignore next */
1807
+ if (!this.sign) {
1808
+ throw new Error('No sign method defined.');
1809
+ }
1810
+ const newTxParams = getTransactionParamsWithIncreasedGasFee(transactionMeta.txParams, rate, gasValues);
1811
+ prepareTransactionParams?.(newTxParams);
1812
+ const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, newTxParams);
1813
+ const signedTx = await this.sign(unsignedEthTx, transactionMeta.txParams.from);
1814
+ const transactionMetaWithRsv = this.updateTransactionMetaRSV(transactionMeta, signedTx);
1815
+ const rawTx = bufferToHex(signedTx.serialize());
1816
+ const newFee = newTxParams.maxFeePerGas ?? newTxParams.gasPrice;
1817
+ const oldFee = newTxParams.maxFeePerGas
1818
+ ? transactionMetaWithRsv.txParams.maxFeePerGas
1819
+ : transactionMetaWithRsv.txParams.gasPrice;
1820
+ log(`Submitting ${label} transaction`, {
1821
+ oldFee,
1822
+ newFee,
1823
+ txParams: newTxParams,
1824
+ });
1825
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1826
+ networkClientId: transactionMeta.networkClientId,
1827
+ chainId: transactionMeta.chainId,
1828
+ });
1829
+ const newTransactionMeta = {
1830
+ ...transactionMetaWithRsv,
1831
+ actionId,
1832
+ estimatedBaseFee,
1833
+ id: random(),
1834
+ originalGasEstimate: transactionMeta.txParams.gas,
1835
+ originalType: transactionMeta.type,
1836
+ rawTx,
1837
+ time: Date.now(),
1838
+ txParams: newTxParams,
1839
+ type: transactionType,
1840
+ };
1841
+ const hash = await this.publishTransactionForRetry(ethQuery, {
1842
+ ...newTransactionMeta,
1843
+ origin: label,
1844
+ });
1845
+ newTransactionMeta.hash = hash;
1846
+ this.addMetadata(newTransactionMeta);
1847
+ // speedUpTransaction has no approval request, so we assume the user has already approved the transaction
1848
+ this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
1849
+ transactionMeta: newTransactionMeta,
1850
+ actionId,
1851
+ });
1852
+ this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
1853
+ transactionMeta: newTransactionMeta,
1854
+ actionId,
1855
+ });
1856
+ afterSubmit?.(newTransactionMeta);
1857
+ }, _TransactionController_createNonceTracker = function _TransactionController_createNonceTracker({ provider, blockTracker, chainId, }) {
1858
+ return new NonceTracker({
1859
+ // TODO: Fix types
1860
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1861
+ provider: provider,
1862
+ // TODO: Fix types
1863
+ blockTracker,
1864
+ getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
1865
+ getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, TransactionStatus.confirmed),
1866
+ });
1867
+ }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, etherscanRemoteTransactionSource, chainId, }) {
1868
+ const incomingTransactionHelper = new IncomingTransactionHelper({
1869
+ blockTracker,
1870
+ getCurrentAccount: () => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getSelectedAccount).call(this),
1871
+ getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
1872
+ getLocalTransactions: () => this.state.transactions,
1873
+ getChainId: chainId ? () => chainId : this.getChainId.bind(this),
1874
+ isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
1875
+ queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
1876
+ remoteTransactionSource: etherscanRemoteTransactionSource,
1877
+ transactionLimit: __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f"),
1878
+ updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
1879
+ });
1880
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
1881
+ return incomingTransactionHelper;
1882
+ }, _TransactionController_createPendingTransactionTracker = function _TransactionController_createPendingTransactionTracker({ provider, blockTracker, chainId, }) {
1883
+ const ethQuery = new EthQuery(provider);
1884
+ const getChainId = chainId ? () => chainId : this.getChainId.bind(this);
1885
+ const pendingTransactionTracker = new PendingTransactionTracker({
1886
+ blockTracker,
1887
+ getChainId,
1888
+ getEthQuery: () => ethQuery,
1889
+ getTransactions: () => this.state.transactions,
1890
+ isResubmitEnabled: __classPrivateFieldGet(this, _TransactionController_pendingTransactionOptions, "f").isResubmitEnabled,
1891
+ getGlobalLock: () => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").acquireNonceLockForChainIdKey({
1892
+ chainId: getChainId(),
1893
+ }),
1894
+ publishTransaction: (_ethQuery, transactionMeta) => this.publishTransaction(_ethQuery, transactionMeta, {
1895
+ skipSubmitHistory: true,
1896
+ }),
1897
+ hooks: {
1898
+ beforeCheckPendingTransaction: this.beforeCheckPendingTransaction.bind(this),
1899
+ beforePublish: this.beforePublish.bind(this),
1900
+ },
1901
+ });
1902
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addPendingTransactionTrackerListeners).call(this, pendingTransactionTracker);
1903
+ return pendingTransactionTracker;
1904
+ }, _TransactionController_stopAllTracking = function _TransactionController_stopAllTracking() {
1905
+ this.pendingTransactionTracker.stop();
1906
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).call(this, this.pendingTransactionTracker);
1907
+ this.incomingTransactionHelper.stop();
1908
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).call(this, this.incomingTransactionHelper);
1909
+ __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllTracking();
1910
+ }, _TransactionController_removeIncomingTransactionHelperListeners = function _TransactionController_removeIncomingTransactionHelperListeners(incomingTransactionHelper) {
1911
+ incomingTransactionHelper.hub.removeAllListeners('transactions');
1912
+ incomingTransactionHelper.hub.removeAllListeners('updatedLastFetchedBlockNumbers');
1913
+ }, _TransactionController_addIncomingTransactionHelperListeners = function _TransactionController_addIncomingTransactionHelperListeners(incomingTransactionHelper) {
1914
+ incomingTransactionHelper.hub.on('transactions', this.onIncomingTransactions.bind(this));
1915
+ incomingTransactionHelper.hub.on('updatedLastFetchedBlockNumbers', this.onUpdatedLastFetchedBlockNumbers.bind(this));
1916
+ }, _TransactionController_removePendingTransactionTrackerListeners = function _TransactionController_removePendingTransactionTrackerListeners(pendingTransactionTracker) {
1917
+ pendingTransactionTracker.hub.removeAllListeners('transaction-confirmed');
1918
+ pendingTransactionTracker.hub.removeAllListeners('transaction-dropped');
1919
+ pendingTransactionTracker.hub.removeAllListeners('transaction-failed');
1920
+ pendingTransactionTracker.hub.removeAllListeners('transaction-updated');
1921
+ }, _TransactionController_addPendingTransactionTrackerListeners = function _TransactionController_addPendingTransactionTrackerListeners(pendingTransactionTracker) {
1922
+ pendingTransactionTracker.hub.on('transaction-confirmed', this.onConfirmedTransaction.bind(this));
1923
+ pendingTransactionTracker.hub.on('transaction-dropped', this.setTransactionStatusDropped.bind(this));
1924
+ pendingTransactionTracker.hub.on('transaction-failed', this.failTransaction.bind(this));
1925
+ pendingTransactionTracker.hub.on('transaction-updated', this.updateTransaction.bind(this));
1926
+ }, _TransactionController_getNonceTrackerPendingTransactions = function _TransactionController_getNonceTrackerPendingTransactions(chainId, address) {
1927
+ const standardPendingTransactions = this.getNonceTrackerTransactions(TransactionStatus.submitted, address, chainId);
1928
+ const externalPendingTransactions = this.getExternalPendingTransactions(address, chainId);
1929
+ return [...standardPendingTransactions, ...externalPendingTransactions];
1930
+ }, _TransactionController_getGasFeeFlows = function _TransactionController_getGasFeeFlows() {
1931
+ if (__classPrivateFieldGet(this, _TransactionController_testGasFeeFlows, "f")) {
1932
+ return [new TestGasFeeFlow()];
1933
+ }
1934
+ return [new LineaGasFeeFlow(), new DefaultGasFeeFlow()];
1935
+ }, _TransactionController_getLayer1GasFeeFlows = function _TransactionController_getLayer1GasFeeFlows() {
1936
+ return [new OptimismLayer1GasFeeFlow(), new ScrollLayer1GasFeeFlow()];
1937
+ }, _TransactionController_updateTransactionInternal = function _TransactionController_updateTransactionInternal({ transactionId, note, skipHistory, skipValidation, }, callback) {
1938
+ let updatedTransactionParams = [];
1939
+ this.update((state) => {
1940
+ const index = state.transactions.findIndex(({ id }) => id === transactionId);
1941
+ let transactionMeta = state.transactions[index];
1942
+ // eslint-disable-next-line n/callback-return
1943
+ transactionMeta = callback(transactionMeta) ?? transactionMeta;
1944
+ if (skipValidation !== true) {
1945
+ transactionMeta.txParams = normalizeTransactionParams(transactionMeta.txParams);
1946
+ validateTxParams(transactionMeta.txParams);
1947
+ }
1948
+ updatedTransactionParams =
1949
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_checkIfTransactionParamsUpdated).call(this, transactionMeta);
1950
+ const shouldSkipHistory = this.isHistoryDisabled || skipHistory;
1951
+ if (!shouldSkipHistory) {
1952
+ transactionMeta = updateTransactionHistory(transactionMeta, note ?? 'Transaction updated');
1953
+ }
1954
+ state.transactions[index] = transactionMeta;
1955
+ });
1956
+ const transactionMeta = this.getTransaction(transactionId);
1957
+ if (updatedTransactionParams.length > 0) {
1958
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_onTransactionParamsUpdated).call(this, transactionMeta, updatedTransactionParams);
1959
+ }
1960
+ return transactionMeta;
1961
+ }, _TransactionController_checkIfTransactionParamsUpdated = function _TransactionController_checkIfTransactionParamsUpdated(newTransactionMeta) {
1962
+ const { id: transactionId, txParams: newParams } = newTransactionMeta;
1963
+ const originalParams = this.getTransaction(transactionId)?.txParams;
1964
+ if (!originalParams || isEqual(originalParams, newParams)) {
1965
+ return [];
1966
+ }
1967
+ const params = Object.keys(newParams);
1968
+ const updatedProperties = params.filter((param) => newParams[param] !== originalParams[param]);
1969
+ log('Transaction parameters have been updated', transactionId, updatedProperties, originalParams, newParams);
1970
+ return updatedProperties;
1971
+ }, _TransactionController_onTransactionParamsUpdated = function _TransactionController_onTransactionParamsUpdated(transactionMeta, updatedParams) {
1972
+ if (['to', 'value', 'data'].some((param) => updatedParams.includes(param))) {
1973
+ log('Updating simulation data due to transaction parameter update');
1974
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateSimulationData).call(this, transactionMeta).catch((error) => {
1975
+ log('Error updating simulation data', error);
1976
+ throw error;
1977
+ });
1978
+ }
1979
+ }, _TransactionController_updateSimulationData = async function _TransactionController_updateSimulationData(transactionMeta, { traceContext } = {}) {
1980
+ const { id: transactionId, chainId, txParams } = transactionMeta;
1981
+ const { from, to, value, data } = txParams;
1982
+ let simulationData = {
1983
+ error: {
1984
+ code: SimulationErrorCode.Disabled,
1985
+ message: 'Simulation disabled',
1986
+ },
1987
+ tokenBalanceChanges: [],
1988
+ };
1989
+ if (__classPrivateFieldGet(this, _TransactionController_isSimulationEnabled, "f").call(this)) {
1990
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, { transactionId, skipHistory: true }, (txMeta) => {
1991
+ txMeta.simulationData = undefined;
1992
+ });
1993
+ simulationData = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Simulate', parentContext: traceContext }, () => getSimulationData({
1994
+ chainId,
1995
+ from: from,
1996
+ to: to,
1997
+ value: value,
1998
+ data: data,
1999
+ }));
2000
+ }
2001
+ const finalTransactionMeta = this.getTransaction(transactionId);
2002
+ /* istanbul ignore if */
2003
+ if (!finalTransactionMeta) {
2004
+ log('Cannot update simulation data as transaction not found', transactionId, simulationData);
2005
+ return;
2006
+ }
2007
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, {
2008
+ transactionId,
2009
+ note: 'TransactionController#updateSimulationData - Update simulation data',
2010
+ }, (txMeta) => {
2011
+ txMeta.simulationData = simulationData;
2012
+ });
2013
+ log('Updated simulation data', transactionId, simulationData);
2014
+ }, _TransactionController_onGasFeePollerTransactionUpdate = function _TransactionController_onGasFeePollerTransactionUpdate({ transactionId, gasFeeEstimates, gasFeeEstimatesLoaded, layer1GasFee, }) {
2015
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, { transactionId, skipHistory: true }, (txMeta) => {
2016
+ if (gasFeeEstimates) {
2017
+ txMeta.gasFeeEstimates = gasFeeEstimates;
2018
+ }
2019
+ if (gasFeeEstimatesLoaded !== undefined) {
2020
+ txMeta.gasFeeEstimatesLoaded = gasFeeEstimatesLoaded;
2021
+ }
2022
+ if (layer1GasFee) {
2023
+ txMeta.layer1GasFee = layer1GasFee;
2024
+ }
2025
+ });
2026
+ }, _TransactionController_getNetworkClientId = function _TransactionController_getNetworkClientId({ networkClientId: requestNetworkClientId, chainId, }) {
2027
+ const globalChainId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalChainId).call(this);
2028
+ const globalNetworkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
2029
+ if (requestNetworkClientId) {
2030
+ return requestNetworkClientId;
2031
+ }
2032
+ if (!chainId || chainId === globalChainId) {
2033
+ return globalNetworkClientId;
2034
+ }
2035
+ return this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, chainId);
2036
+ }, _TransactionController_getGlobalNetworkClientId = function _TransactionController_getGlobalNetworkClientId() {
2037
+ return this.getNetworkState().selectedNetworkClientId;
2038
+ }, _TransactionController_getGlobalChainId = function _TransactionController_getGlobalChainId() {
2039
+ return this.messagingSystem.call(`NetworkController:getNetworkClientById`, this.getNetworkState().selectedNetworkClientId).configuration.chainId;
2040
+ }, _TransactionController_isCustomNetwork = function _TransactionController_isCustomNetwork(networkClientId) {
2041
+ const globalNetworkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
2042
+ if (!networkClientId || networkClientId === globalNetworkClientId) {
2043
+ return !isInfuraNetworkType(this.getNetworkState().selectedNetworkClientId);
2044
+ }
2045
+ return (this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.type === NetworkClientType.Custom);
2046
+ }, _TransactionController_getSelectedAccount = function _TransactionController_getSelectedAccount() {
2047
+ return this.messagingSystem.call('AccountsController:getSelectedAccount');
2048
+ }, _TransactionController_updateSubmitHistory = function _TransactionController_updateSubmitHistory(transactionMeta, hash) {
2049
+ const { chainId, networkClientId, origin, rawTx, txParams } = transactionMeta;
2050
+ const { networkConfigurationsByChainId } = this.getNetworkState();
2051
+ const networkConfiguration = networkConfigurationsByChainId[chainId];
2052
+ const endpoint = networkConfiguration?.rpcEndpoints.find((currentEndpoint) => currentEndpoint.networkClientId === networkClientId);
2053
+ const networkUrl = endpoint?.url;
2054
+ const networkType = endpoint?.name ?? networkClientId;
2055
+ const submitHistoryEntry = {
2056
+ chainId,
2057
+ hash,
2058
+ networkType,
2059
+ networkUrl,
2060
+ origin,
2061
+ rawTransaction: rawTx,
2062
+ time: Date.now(),
2063
+ transaction: txParams,
2064
+ };
2065
+ log('Updating submit history', submitHistoryEntry);
2066
+ this.update((state) => {
2067
+ const { submitHistory } = state;
2068
+ if (submitHistory.length === SUBMIT_HISTORY_LIMIT) {
2069
+ submitHistory.pop();
2070
+ }
2071
+ submitHistory.unshift(submitHistoryEntry);
2072
+ });
45
2073
  };
46
2074
  //# sourceMappingURL=TransactionController.mjs.map