@metamask/transaction-controller 23.1.0 → 25.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/CHANGELOG.md +134 -1
  2. package/dist/TransactionController.js +38 -1816
  3. package/dist/TransactionController.js.map +1 -1
  4. package/dist/TransactionController.mjs +39 -0
  5. package/dist/TransactionController.mjs.map +1 -0
  6. package/dist/chunk-2K7J3EY3.mjs +170 -0
  7. package/dist/chunk-2K7J3EY3.mjs.map +1 -0
  8. package/dist/chunk-5XBULBP2.js +399 -0
  9. package/dist/chunk-5XBULBP2.js.map +1 -0
  10. package/dist/chunk-6MYNWYJK.mjs +158 -0
  11. package/dist/chunk-6MYNWYJK.mjs.map +1 -0
  12. package/dist/chunk-7APMBUKB.js +158 -0
  13. package/dist/chunk-7APMBUKB.js.map +1 -0
  14. package/dist/chunk-7LXE4KHV.js +40 -0
  15. package/dist/chunk-7LXE4KHV.js.map +1 -0
  16. package/dist/chunk-7MZ57ILQ.mjs +62 -0
  17. package/dist/chunk-7MZ57ILQ.mjs.map +1 -0
  18. package/dist/chunk-BJEESIBE.js +2313 -0
  19. package/dist/chunk-BJEESIBE.js.map +1 -0
  20. package/dist/chunk-C67QD5PV.mjs +320 -0
  21. package/dist/chunk-C67QD5PV.mjs.map +1 -0
  22. package/dist/chunk-DE3MZYVY.mjs +2313 -0
  23. package/dist/chunk-DE3MZYVY.mjs.map +1 -0
  24. package/dist/chunk-DEKM6PVG.mjs +46 -0
  25. package/dist/chunk-DEKM6PVG.mjs.map +1 -0
  26. package/dist/chunk-DQP6X25N.mjs +208 -0
  27. package/dist/chunk-DQP6X25N.mjs.map +1 -0
  28. package/dist/chunk-DTDTOMTB.js +238 -0
  29. package/dist/chunk-DTDTOMTB.js.map +1 -0
  30. package/dist/chunk-DTEDYRTL.js +242 -0
  31. package/dist/chunk-DTEDYRTL.js.map +1 -0
  32. package/dist/chunk-EQ3RRHB7.mjs +211 -0
  33. package/dist/chunk-EQ3RRHB7.mjs.map +1 -0
  34. package/dist/chunk-FDJPXQTF.js +46 -0
  35. package/dist/chunk-FDJPXQTF.js.map +1 -0
  36. package/dist/chunk-FRKQ3Z2L.mjs +40 -0
  37. package/dist/chunk-FRKQ3Z2L.mjs.map +1 -0
  38. package/dist/chunk-FS7FRO7B.mjs +90 -0
  39. package/dist/chunk-FS7FRO7B.mjs.map +1 -0
  40. package/dist/chunk-GKTIFXPN.js +170 -0
  41. package/dist/chunk-GKTIFXPN.js.map +1 -0
  42. package/dist/chunk-H4M66BA3.js +62 -0
  43. package/dist/chunk-H4M66BA3.js.map +1 -0
  44. package/dist/chunk-HPNXIKFY.js +76 -0
  45. package/dist/chunk-HPNXIKFY.js.map +1 -0
  46. package/dist/chunk-HS277C77.js +75 -0
  47. package/dist/chunk-HS277C77.js.map +1 -0
  48. package/dist/chunk-I5YZ7QUK.js +121 -0
  49. package/dist/chunk-I5YZ7QUK.js.map +1 -0
  50. package/dist/chunk-IC233ZQS.js +211 -0
  51. package/dist/chunk-IC233ZQS.js.map +1 -0
  52. package/dist/chunk-IUBAETUH.js +137 -0
  53. package/dist/chunk-IUBAETUH.js.map +1 -0
  54. package/dist/chunk-J56A7UCK.mjs +123 -0
  55. package/dist/chunk-J56A7UCK.mjs.map +1 -0
  56. package/dist/chunk-JR6HDRNV.mjs +242 -0
  57. package/dist/chunk-JR6HDRNV.mjs.map +1 -0
  58. package/dist/chunk-JRBREX22.mjs +75 -0
  59. package/dist/chunk-JRBREX22.mjs.map +1 -0
  60. package/dist/chunk-JRQHIBG5.mjs +399 -0
  61. package/dist/chunk-JRQHIBG5.mjs.map +1 -0
  62. package/dist/chunk-LM4NUNMT.mjs +76 -0
  63. package/dist/chunk-LM4NUNMT.mjs.map +1 -0
  64. package/dist/chunk-M7455RU7.js +320 -0
  65. package/dist/chunk-M7455RU7.js.map +1 -0
  66. package/dist/chunk-MHM5LRRF.mjs +122 -0
  67. package/dist/chunk-MHM5LRRF.mjs.map +1 -0
  68. package/dist/chunk-NHRBO3LU.mjs +50 -0
  69. package/dist/chunk-NHRBO3LU.mjs.map +1 -0
  70. package/dist/chunk-NM6OYEPP.mjs +182 -0
  71. package/dist/chunk-NM6OYEPP.mjs.map +1 -0
  72. package/dist/chunk-NUOBUW7C.js +85 -0
  73. package/dist/chunk-NUOBUW7C.js.map +1 -0
  74. package/dist/chunk-QP75SWIQ.js +53 -0
  75. package/dist/chunk-QP75SWIQ.js.map +1 -0
  76. package/dist/chunk-RI6MVJJN.js +122 -0
  77. package/dist/chunk-RI6MVJJN.js.map +1 -0
  78. package/dist/chunk-S6VGOPUY.js +14 -0
  79. package/dist/chunk-S6VGOPUY.js.map +1 -0
  80. package/dist/chunk-UGFBA4GV.js +123 -0
  81. package/dist/chunk-UGFBA4GV.js.map +1 -0
  82. package/dist/chunk-UKYY2RVS.mjs +137 -0
  83. package/dist/chunk-UKYY2RVS.mjs.map +1 -0
  84. package/dist/chunk-UM4ORJ5B.mjs +121 -0
  85. package/dist/chunk-UM4ORJ5B.mjs.map +1 -0
  86. package/dist/chunk-UQQWZT6C.mjs +14 -0
  87. package/dist/chunk-UQQWZT6C.mjs.map +1 -0
  88. package/dist/chunk-VH47Q6TS.js +182 -0
  89. package/dist/chunk-VH47Q6TS.js.map +1 -0
  90. package/dist/chunk-XGRAHX6T.mjs +53 -0
  91. package/dist/chunk-XGRAHX6T.mjs.map +1 -0
  92. package/dist/chunk-XUI43LEZ.mjs +30 -0
  93. package/dist/chunk-XUI43LEZ.mjs.map +1 -0
  94. package/dist/chunk-Y734U4V6.mjs +85 -0
  95. package/dist/chunk-Y734U4V6.mjs.map +1 -0
  96. package/dist/chunk-Y7ENNK7L.mjs +238 -0
  97. package/dist/chunk-Y7ENNK7L.mjs.map +1 -0
  98. package/dist/chunk-Z4BLTVTB.js +30 -0
  99. package/dist/chunk-Z4BLTVTB.js.map +1 -0
  100. package/dist/chunk-ZCQRDZ36.js +208 -0
  101. package/dist/chunk-ZCQRDZ36.js.map +1 -0
  102. package/dist/chunk-ZJLZSFOZ.js +90 -0
  103. package/dist/chunk-ZJLZSFOZ.js.map +1 -0
  104. package/dist/chunk-ZNZEJDOE.js +50 -0
  105. package/dist/chunk-ZNZEJDOE.js.map +1 -0
  106. package/dist/constants.js +15 -110
  107. package/dist/constants.js.map +1 -1
  108. package/dist/constants.mjs +16 -0
  109. package/dist/constants.mjs.map +1 -0
  110. package/dist/gas-flows/DefaultGasFeeFlow.js +14 -77
  111. package/dist/gas-flows/DefaultGasFeeFlow.js.map +1 -1
  112. package/dist/gas-flows/DefaultGasFeeFlow.mjs +15 -0
  113. package/dist/gas-flows/DefaultGasFeeFlow.mjs.map +1 -0
  114. package/dist/gas-flows/LineaGasFeeFlow.js +15 -110
  115. package/dist/gas-flows/LineaGasFeeFlow.js.map +1 -1
  116. package/dist/gas-flows/LineaGasFeeFlow.mjs +16 -0
  117. package/dist/gas-flows/LineaGasFeeFlow.mjs.map +1 -0
  118. package/dist/helpers/EtherscanRemoteTransactionSource.js +11 -145
  119. package/dist/helpers/EtherscanRemoteTransactionSource.js.map +1 -1
  120. package/dist/helpers/EtherscanRemoteTransactionSource.mjs +12 -0
  121. package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +1 -0
  122. package/dist/helpers/GasFeePoller.js +10 -143
  123. package/dist/helpers/GasFeePoller.js.map +1 -1
  124. package/dist/helpers/GasFeePoller.mjs +11 -0
  125. package/dist/helpers/GasFeePoller.mjs.map +1 -0
  126. package/dist/helpers/IncomingTransactionHelper.js +8 -205
  127. package/dist/helpers/IncomingTransactionHelper.js.map +1 -1
  128. package/dist/helpers/IncomingTransactionHelper.mjs +9 -0
  129. package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -0
  130. package/dist/helpers/MultichainTrackingHelper.js +12 -291
  131. package/dist/helpers/MultichainTrackingHelper.js.map +1 -1
  132. package/dist/helpers/MultichainTrackingHelper.mjs +13 -0
  133. package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -0
  134. package/dist/helpers/PendingTransactionTracker.js +9 -360
  135. package/dist/helpers/PendingTransactionTracker.js.map +1 -1
  136. package/dist/helpers/PendingTransactionTracker.mjs +10 -0
  137. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -0
  138. package/dist/index.js +56 -25
  139. package/dist/index.js.map +1 -1
  140. package/dist/index.mjs +57 -0
  141. package/dist/index.mjs.map +1 -0
  142. package/dist/logger.js +11 -8
  143. package/dist/logger.js.map +1 -1
  144. package/dist/logger.mjs +12 -0
  145. package/dist/logger.mjs.map +1 -0
  146. package/dist/tsconfig.build.tsbuildinfo +1 -0
  147. package/dist/{TransactionController.d.ts → types/TransactionController.d.ts} +235 -46
  148. package/dist/types/TransactionController.d.ts.map +1 -0
  149. package/dist/{constants.d.ts → types/constants.d.ts} +8 -3
  150. package/dist/types/constants.d.ts.map +1 -0
  151. package/dist/types/gas-flows/DefaultGasFeeFlow.d.ts.map +1 -0
  152. package/dist/types/gas-flows/LineaGasFeeFlow.d.ts.map +1 -0
  153. package/dist/types/helpers/EtherscanRemoteTransactionSource.d.ts.map +1 -0
  154. package/dist/types/helpers/GasFeePoller.d.ts.map +1 -0
  155. package/dist/types/helpers/IncomingTransactionHelper.d.ts.map +1 -0
  156. package/dist/types/helpers/MultichainTrackingHelper.d.ts.map +1 -0
  157. package/dist/types/helpers/PendingTransactionTracker.d.ts.map +1 -0
  158. package/dist/types/index.d.ts +9 -0
  159. package/dist/types/index.d.ts.map +1 -0
  160. package/dist/types/logger.d.ts.map +1 -0
  161. package/dist/{types.d.ts → types/types.d.ts} +63 -65
  162. package/dist/types/types.d.ts.map +1 -0
  163. package/dist/types/utils/etherscan.d.ts.map +1 -0
  164. package/dist/types/utils/external-transactions.d.ts.map +1 -0
  165. package/dist/types/utils/gas-fees.d.ts.map +1 -0
  166. package/dist/types/utils/gas-flow.d.ts.map +1 -0
  167. package/dist/types/utils/gas.d.ts.map +1 -0
  168. package/dist/types/utils/history.d.ts +20 -0
  169. package/dist/types/utils/history.d.ts.map +1 -0
  170. package/dist/types/utils/nonce.d.ts.map +1 -0
  171. package/dist/types/utils/simulation-api.d.ts +99 -0
  172. package/dist/types/utils/simulation-api.d.ts.map +1 -0
  173. package/dist/types/utils/simulation.d.ts +21 -0
  174. package/dist/types/utils/simulation.d.ts.map +1 -0
  175. package/dist/{utils → types/utils}/swaps.d.ts +8 -5
  176. package/dist/types/utils/swaps.d.ts.map +1 -0
  177. package/dist/types/utils/transaction-type.d.ts.map +1 -0
  178. package/dist/{utils → types/utils}/utils.d.ts +9 -1
  179. package/dist/types/utils/utils.d.ts.map +1 -0
  180. package/dist/types/utils/validation.d.ts.map +1 -0
  181. package/dist/types.js +19 -170
  182. package/dist/types.js.map +1 -1
  183. package/dist/types.mjs +20 -0
  184. package/dist/types.mjs.map +1 -0
  185. package/dist/utils/etherscan.js +13 -118
  186. package/dist/utils/etherscan.js.map +1 -1
  187. package/dist/utils/etherscan.mjs +14 -0
  188. package/dist/utils/etherscan.mjs.map +1 -0
  189. package/dist/utils/external-transactions.js +8 -35
  190. package/dist/utils/external-transactions.js.map +1 -1
  191. package/dist/utils/external-transactions.mjs +9 -0
  192. package/dist/utils/external-transactions.mjs.map +1 -0
  193. package/dist/utils/gas-fees.js +15 -200
  194. package/dist/utils/gas-fees.js.map +1 -1
  195. package/dist/utils/gas-fees.mjs +16 -0
  196. package/dist/utils/gas-fees.mjs.map +1 -0
  197. package/dist/utils/gas-flow.js +10 -52
  198. package/dist/utils/gas-flow.js.map +1 -1
  199. package/dist/utils/gas-flow.mjs +11 -0
  200. package/dist/utils/gas-flow.mjs.map +1 -0
  201. package/dist/utils/gas.js +19 -133
  202. package/dist/utils/gas.js.map +1 -1
  203. package/dist/utils/gas.mjs +20 -0
  204. package/dist/utils/gas.mjs.map +1 -0
  205. package/dist/utils/history.js +9 -83
  206. package/dist/utils/history.js.map +1 -1
  207. package/dist/utils/history.mjs +10 -0
  208. package/dist/utils/history.mjs.map +1 -0
  209. package/dist/utils/nonce.js +10 -76
  210. package/dist/utils/nonce.js.map +1 -1
  211. package/dist/utils/nonce.mjs +11 -0
  212. package/dist/utils/nonce.mjs.map +1 -0
  213. package/dist/utils/simulation-api.js +10 -0
  214. package/dist/utils/simulation-api.js.map +1 -0
  215. package/dist/utils/simulation-api.mjs +10 -0
  216. package/dist/utils/simulation-api.mjs.map +1 -0
  217. package/dist/utils/simulation.js +12 -0
  218. package/dist/utils/simulation.js.map +1 -0
  219. package/dist/utils/simulation.mjs +12 -0
  220. package/dist/utils/simulation.mjs.map +1 -0
  221. package/dist/utils/swaps.js +23 -256
  222. package/dist/utils/swaps.js.map +1 -1
  223. package/dist/utils/swaps.mjs +24 -0
  224. package/dist/utils/swaps.mjs.map +1 -0
  225. package/dist/utils/transaction-type.js +10 -120
  226. package/dist/utils/transaction-type.js.map +1 -1
  227. package/dist/utils/transaction-type.mjs +11 -0
  228. package/dist/utils/transaction-type.mjs.map +1 -0
  229. package/dist/utils/utils.js +32 -146
  230. package/dist/utils/utils.js.map +1 -1
  231. package/dist/utils/utils.mjs +33 -0
  232. package/dist/utils/utils.mjs.map +1 -0
  233. package/dist/utils/validation.js +11 -258
  234. package/dist/utils/validation.js.map +1 -1
  235. package/dist/utils/validation.mjs +12 -0
  236. package/dist/utils/validation.mjs.map +1 -0
  237. package/package.json +21 -9
  238. package/dist/TransactionController.d.ts.map +0 -1
  239. package/dist/constants.d.ts.map +0 -1
  240. package/dist/gas-flows/DefaultGasFeeFlow.d.ts.map +0 -1
  241. package/dist/gas-flows/LineaGasFeeFlow.d.ts.map +0 -1
  242. package/dist/helpers/EtherscanRemoteTransactionSource.d.ts.map +0 -1
  243. package/dist/helpers/GasFeePoller.d.ts.map +0 -1
  244. package/dist/helpers/IncomingTransactionHelper.d.ts.map +0 -1
  245. package/dist/helpers/MultichainTrackingHelper.d.ts.map +0 -1
  246. package/dist/helpers/PendingTransactionTracker.d.ts.map +0 -1
  247. package/dist/index.d.ts +0 -7
  248. package/dist/index.d.ts.map +0 -1
  249. package/dist/logger.d.ts.map +0 -1
  250. package/dist/types.d.ts.map +0 -1
  251. package/dist/utils/etherscan.d.ts.map +0 -1
  252. package/dist/utils/external-transactions.d.ts.map +0 -1
  253. package/dist/utils/gas-fees.d.ts.map +0 -1
  254. package/dist/utils/gas-flow.d.ts.map +0 -1
  255. package/dist/utils/gas.d.ts.map +0 -1
  256. package/dist/utils/history.d.ts +0 -15
  257. package/dist/utils/history.d.ts.map +0 -1
  258. package/dist/utils/nonce.d.ts.map +0 -1
  259. package/dist/utils/swaps.d.ts.map +0 -1
  260. package/dist/utils/transaction-type.d.ts.map +0 -1
  261. package/dist/utils/utils.d.ts.map +0 -1
  262. package/dist/utils/validation.d.ts.map +0 -1
  263. /package/dist/{gas-flows → types/gas-flows}/DefaultGasFeeFlow.d.ts +0 -0
  264. /package/dist/{gas-flows → types/gas-flows}/LineaGasFeeFlow.d.ts +0 -0
  265. /package/dist/{helpers → types/helpers}/EtherscanRemoteTransactionSource.d.ts +0 -0
  266. /package/dist/{helpers → types/helpers}/GasFeePoller.d.ts +0 -0
  267. /package/dist/{helpers → types/helpers}/IncomingTransactionHelper.d.ts +0 -0
  268. /package/dist/{helpers → types/helpers}/MultichainTrackingHelper.d.ts +0 -0
  269. /package/dist/{helpers → types/helpers}/PendingTransactionTracker.d.ts +0 -0
  270. /package/dist/{logger.d.ts → types/logger.d.ts} +0 -0
  271. /package/dist/{utils → types/utils}/etherscan.d.ts +0 -0
  272. /package/dist/{utils → types/utils}/external-transactions.d.ts +0 -0
  273. /package/dist/{utils → types/utils}/gas-fees.d.ts +0 -0
  274. /package/dist/{utils → types/utils}/gas-flow.d.ts +0 -0
  275. /package/dist/{utils → types/utils}/gas.d.ts +0 -0
  276. /package/dist/{utils → types/utils}/nonce.d.ts +0 -0
  277. /package/dist/{utils → types/utils}/transaction-type.d.ts +0 -0
  278. /package/dist/{utils → types/utils}/validation.d.ts +0 -0
@@ -1,1817 +1,39 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
- if (kind === "m") throw new TypeError("Private method is not writable");
13
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
- 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");
15
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
- };
17
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
- 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");
20
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
- };
22
- var __importDefault = (this && this.__importDefault) || function (mod) {
23
- return (mod && mod.__esModule) ? mod : { "default": mod };
24
- };
25
- var _TransactionController_instances, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_multichainTrackingHelper, _TransactionController_createNonceTracker, _TransactionController_createIncomingTransactionHelper, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_removeIncomingTransactionHelperListeners, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_updateTransactionInternal;
26
- Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.TransactionController = exports.SPEED_UP_RATE = exports.CANCEL_RATE = exports.HARDFORK = void 0;
28
- const common_1 = require("@ethereumjs/common");
29
- const tx_1 = require("@ethereumjs/tx");
30
- const util_1 = require("@ethereumjs/util");
31
- const base_controller_1 = require("@metamask/base-controller");
32
- const controller_utils_1 = require("@metamask/controller-utils");
33
- const eth_query_1 = __importDefault(require("@metamask/eth-query"));
34
- const network_controller_1 = require("@metamask/network-controller");
35
- const rpc_errors_1 = require("@metamask/rpc-errors");
36
- const utils_1 = require("@metamask/utils");
37
- const async_mutex_1 = require("async-mutex");
38
- const eth_method_registry_1 = require("eth-method-registry");
39
- const events_1 = require("events");
40
- const lodash_1 = require("lodash");
41
- const nonce_tracker_1 = require("nonce-tracker");
42
- const uuid_1 = require("uuid");
43
- const DefaultGasFeeFlow_1 = require("./gas-flows/DefaultGasFeeFlow");
44
- const LineaGasFeeFlow_1 = require("./gas-flows/LineaGasFeeFlow");
45
- const EtherscanRemoteTransactionSource_1 = require("./helpers/EtherscanRemoteTransactionSource");
46
- const GasFeePoller_1 = require("./helpers/GasFeePoller");
47
- const IncomingTransactionHelper_1 = require("./helpers/IncomingTransactionHelper");
48
- const MultichainTrackingHelper_1 = require("./helpers/MultichainTrackingHelper");
49
- const PendingTransactionTracker_1 = require("./helpers/PendingTransactionTracker");
50
- const logger_1 = require("./logger");
51
- const types_1 = require("./types");
52
- const external_transactions_1 = require("./utils/external-transactions");
53
- const gas_1 = require("./utils/gas");
54
- const gas_fees_1 = require("./utils/gas-fees");
55
- const history_1 = require("./utils/history");
56
- const nonce_1 = require("./utils/nonce");
57
- const swaps_1 = require("./utils/swaps");
58
- const transaction_type_1 = require("./utils/transaction-type");
59
- const utils_2 = require("./utils/utils");
60
- const validation_1 = require("./utils/validation");
61
- exports.HARDFORK = common_1.Hardfork.London;
62
- /**
63
- * Multiplier used to determine a transaction's increased gas fee during cancellation
64
- */
65
- exports.CANCEL_RATE = 1.1;
66
- /**
67
- * Multiplier used to determine a transaction's increased gas fee during speed up
68
- */
69
- exports.SPEED_UP_RATE = 1.1;
70
- /**
71
- * The name of the {@link TransactionController}.
72
- */
73
- const controllerName = 'TransactionController';
74
- /**
75
- * Controller responsible for submitting and managing transactions.
76
- */
77
- class TransactionController extends base_controller_1.BaseControllerV1 {
78
- constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkState, getPermittedAccounts, getSavedGasFees, getSelectedAddress, incomingTransactions = {}, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, getNetworkClientRegistry, isMultichainEnabled = false, hooks, }, config, state) {
79
- var _a, _b, _c, _d, _e, _f;
80
- super(config, state);
81
- _TransactionController_instances.add(this);
82
- this.inProcessOfSigning = new Set();
83
- this.mutex = new async_mutex_1.Mutex();
84
- _TransactionController_incomingTransactionOptions.set(this, void 0);
85
- _TransactionController_pendingTransactionOptions.set(this, void 0);
86
- this.signAbortCallbacks = new Map();
87
- _TransactionController_multichainTrackingHelper.set(this, void 0);
88
- /**
89
- * EventEmitter instance used to listen to specific transactional events
90
- */
91
- this.hub = new events_1.EventEmitter();
92
- /**
93
- * Name of this controller used during composition
94
- */
95
- this.name = 'TransactionController';
96
- _TransactionController_checkForPendingTransactionAndStartPolling.set(this, () => {
97
- // PendingTransactionTracker reads state through its getTransactions hook
98
- this.pendingTransactionTracker.startIfPendingTransactions();
99
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").checkForPendingTransactionAndStartPolling();
100
- });
101
- this.defaultConfig = {
102
- txHistoryLimit: 40,
103
- };
104
- this.defaultState = {
105
- methodData: {},
106
- transactions: [],
107
- lastFetchedBlockNumbers: {},
108
- };
109
- this.initialize();
110
- this.messagingSystem = messenger;
111
- this.getNetworkState = getNetworkState;
112
- this.isSendFlowHistoryDisabled = disableSendFlowHistory !== null && disableSendFlowHistory !== void 0 ? disableSendFlowHistory : false;
113
- this.isHistoryDisabled = disableHistory !== null && disableHistory !== void 0 ? disableHistory : false;
114
- this.isSwapsDisabled = disableSwaps !== null && disableSwaps !== void 0 ? disableSwaps : false;
115
- // @ts-expect-error the type in eth-method-registry is inappropriate and should be changed
116
- this.registry = new eth_method_registry_1.MethodRegistry({ provider });
117
- this.getSavedGasFees = getSavedGasFees !== null && getSavedGasFees !== void 0 ? getSavedGasFees : ((_chainId) => undefined);
118
- this.getCurrentAccountEIP1559Compatibility =
119
- getCurrentAccountEIP1559Compatibility !== null && getCurrentAccountEIP1559Compatibility !== void 0 ? getCurrentAccountEIP1559Compatibility : (() => Promise.resolve(true));
120
- this.getCurrentNetworkEIP1559Compatibility =
121
- getCurrentNetworkEIP1559Compatibility;
122
- this.getGasFeeEstimates =
123
- getGasFeeEstimates || (() => Promise.resolve({}));
124
- this.getPermittedAccounts = getPermittedAccounts;
125
- this.getSelectedAddress = getSelectedAddress;
126
- this.getExternalPendingTransactions =
127
- getExternalPendingTransactions !== null && getExternalPendingTransactions !== void 0 ? getExternalPendingTransactions : (() => []);
128
- this.securityProviderRequest = securityProviderRequest;
129
- __classPrivateFieldSet(this, _TransactionController_incomingTransactionOptions, incomingTransactions, "f");
130
- __classPrivateFieldSet(this, _TransactionController_pendingTransactionOptions, pendingTransactions, "f");
131
- this.afterSign = (_a = hooks === null || hooks === void 0 ? void 0 : hooks.afterSign) !== null && _a !== void 0 ? _a : (() => true);
132
- this.beforeApproveOnInit = (_b = hooks === null || hooks === void 0 ? void 0 : hooks.beforeApproveOnInit) !== null && _b !== void 0 ? _b : (() => true);
133
- this.beforeCheckPendingTransaction =
134
- (_c = hooks === null || hooks === void 0 ? void 0 : hooks.beforeCheckPendingTransaction) !== null && _c !== void 0 ? _c :
135
- /* istanbul ignore next */
136
- (() => true);
137
- this.beforePublish = (_d = hooks === null || hooks === void 0 ? void 0 : hooks.beforePublish) !== null && _d !== void 0 ? _d : (() => true);
138
- this.getAdditionalSignArguments =
139
- (_e = hooks === null || hooks === void 0 ? void 0 : hooks.getAdditionalSignArguments) !== null && _e !== void 0 ? _e : (() => []);
140
- this.publish =
141
- (_f = hooks === null || hooks === void 0 ? void 0 : hooks.publish) !== null && _f !== void 0 ? _f : (() => Promise.resolve({ transactionHash: undefined }));
142
- this.nonceTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).call(this, {
143
- provider,
144
- blockTracker,
145
- });
146
- __classPrivateFieldSet(this, _TransactionController_multichainTrackingHelper, new MultichainTrackingHelper_1.MultichainTrackingHelper({
147
- isMultichainEnabled,
148
- provider,
149
- nonceTracker: this.nonceTracker,
150
- incomingTransactionOptions: incomingTransactions,
151
- findNetworkClientIdByChainId: (chainId) => {
152
- return this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, chainId);
153
- },
154
- getNetworkClientById: ((networkClientId) => {
155
- return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
156
- }),
157
- getNetworkClientRegistry,
158
- removeIncomingTransactionHelperListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).bind(this),
159
- removePendingTransactionTrackerListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).bind(this),
160
- createNonceTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).bind(this),
161
- createIncomingTransactionHelper: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).bind(this),
162
- createPendingTransactionTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).bind(this),
163
- onNetworkStateChange: (listener) => {
164
- this.messagingSystem.subscribe('NetworkController:stateChange', listener);
165
- },
166
- }), "f");
167
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").initialize();
168
- const etherscanRemoteTransactionSource = new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource({
169
- includeTokenTransfers: incomingTransactions.includeTokenTransfers,
170
- });
171
- this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this, {
172
- blockTracker,
173
- etherscanRemoteTransactionSource,
174
- });
175
- this.pendingTransactionTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).call(this, {
176
- provider,
177
- blockTracker,
178
- });
179
- this.gasFeeFlows = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGasFeeFlows).call(this);
180
- const gasFeePoller = new GasFeePoller_1.GasFeePoller({
181
- // Default gas fee polling is not yet supported by the clients
182
- gasFeeFlows: this.gasFeeFlows.slice(0, -1),
183
- getEthQuery: (chainId, networkClientId) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
184
- networkClientId,
185
- chainId,
186
- }),
187
- getGasFeeControllerEstimates: this.getGasFeeEstimates,
188
- getTransactions: () => this.state.transactions,
189
- onStateChange: (listener) => {
190
- this.subscribe(listener);
191
- },
192
- });
193
- gasFeePoller.hub.on('transaction-updated', (transactionMeta) => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, transactionMeta, { skipHistory: true }));
194
- // when transactionsController state changes
195
- // check for pending transactions and start polling if there are any
196
- this.subscribe(__classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f"));
197
- // TODO once v2 is merged make sure this only runs when
198
- // selectedNetworkClientId changes
199
- onNetworkStateChange(() => {
200
- (0, logger_1.projectLogger)('Detected network change', this.getChainId());
201
- this.pendingTransactionTracker.startIfPendingTransactions();
202
- this.onBootCleanup();
203
- });
204
- this.onBootCleanup();
205
- }
206
- failTransaction(transactionMeta, error, actionId) {
207
- const newTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { error: (0, utils_2.normalizeTxError)(error), status: types_1.TransactionStatus.failed });
208
- this.hub.emit('transaction-failed', {
209
- actionId,
210
- error: error.message,
211
- transactionMeta: newTransactionMeta,
212
- });
213
- this.updateTransaction(newTransactionMeta, 'TransactionController#failTransaction - Add error message and set status to failed');
214
- this.onTransactionStatusChange(newTransactionMeta);
215
- this.hub.emit(`${transactionMeta.id}:finished`, newTransactionMeta);
216
- }
217
- registryLookup(fourBytePrefix) {
218
- return __awaiter(this, void 0, void 0, function* () {
219
- const registryMethod = yield this.registry.lookup(fourBytePrefix);
220
- const parsedRegistryMethod = this.registry.parse(registryMethod);
221
- return { registryMethod, parsedRegistryMethod };
222
- });
223
- }
224
- /**
225
- * Stops polling and removes listeners to prepare the controller for garbage collection.
226
- */
227
- destroy() {
228
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_stopAllTracking).call(this);
229
- }
230
- /**
231
- * Handle new method data request.
232
- *
233
- * @param fourBytePrefix - The method prefix.
234
- * @returns The method data object corresponding to the given signature prefix.
235
- */
236
- handleMethodData(fourBytePrefix) {
237
- return __awaiter(this, void 0, void 0, function* () {
238
- const releaseLock = yield this.mutex.acquire();
239
- try {
240
- const { methodData } = this.state;
241
- const knownMethod = Object.keys(methodData).find((knownFourBytePrefix) => fourBytePrefix === knownFourBytePrefix);
242
- if (knownMethod) {
243
- return methodData[fourBytePrefix];
244
- }
245
- const registry = yield this.registryLookup(fourBytePrefix);
246
- this.update({
247
- methodData: Object.assign(Object.assign({}, methodData), { [fourBytePrefix]: registry }),
248
- });
249
- return registry;
250
- }
251
- finally {
252
- releaseLock();
253
- }
254
- });
255
- }
256
- /**
257
- * Add a new unapproved transaction to state. Parameters will be validated, a
258
- * unique transaction id will be generated, and gas and gasPrice will be calculated
259
- * if not provided. If A `<tx.id>:unapproved` hub event will be emitted once added.
260
- *
261
- * @param txParams - Standard parameters for an Ethereum transaction.
262
- * @param opts - Additional options to control how the transaction is added.
263
- * @param opts.actionId - Unique ID to prevent duplicate requests.
264
- * @param opts.deviceConfirmedOn - An enum to indicate what device confirmed the transaction.
265
- * @param opts.method - RPC method that requested the transaction.
266
- * @param opts.origin - The origin of the transaction request, such as a dApp hostname.
267
- * @param opts.requireApproval - Whether the transaction requires approval by the user, defaults to true unless explicitly disabled.
268
- * @param opts.securityAlertResponse - Response from security validator.
269
- * @param opts.sendFlowHistory - The sendFlowHistory entries to add.
270
- * @param opts.type - Type of transaction to add, such as 'cancel' or 'swap'.
271
- * @param opts.swaps - Options for swaps transactions.
272
- * @param opts.swaps.hasApproveTx - Whether the transaction has an approval transaction.
273
- * @param opts.swaps.meta - Metadata for swap transaction.
274
- * @param opts.networkClientId - The id of the network client for this transaction.
275
- * @returns Object containing a promise resolving to the transaction hash if approved.
276
- */
277
- addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, type, networkClientId, } = {}) {
278
- return __awaiter(this, void 0, void 0, function* () {
279
- (0, logger_1.projectLogger)('Adding transaction', txParams);
280
- txParams = (0, utils_2.normalizeTxParams)(txParams);
281
- if (networkClientId &&
282
- !__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").has(networkClientId)) {
283
- throw new Error('The networkClientId for this transaction could not be found');
284
- }
285
- const isEIP1559Compatible = yield this.getEIP1559Compatibility(networkClientId);
286
- (0, validation_1.validateTxParams)(txParams, isEIP1559Compatible);
287
- if (origin) {
288
- yield (0, validation_1.validateTransactionOrigin)(yield this.getPermittedAccounts(origin), this.getSelectedAddress(), txParams.from, origin);
289
- }
290
- const dappSuggestedGasFees = this.generateDappSuggestedGasFees(txParams, origin);
291
- const chainId = this.getChainId(networkClientId);
292
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
293
- networkClientId,
294
- chainId,
295
- });
296
- const transactionType = type !== null && type !== void 0 ? type : (yield (0, transaction_type_1.determineTransactionType)(txParams, ethQuery)).type;
297
- const existingTransactionMeta = this.getTransactionWithActionId(actionId);
298
- // If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
299
- const transactionMeta = existingTransactionMeta || {
300
- // Add actionId to txMeta to check if same actionId is seen again
301
- actionId,
302
- chainId,
303
- dappSuggestedGasFees,
304
- deviceConfirmedOn,
305
- id: (0, uuid_1.v1)(),
306
- origin,
307
- securityAlertResponse,
308
- status: types_1.TransactionStatus.unapproved,
309
- time: Date.now(),
310
- txParams,
311
- userEditedGasLimit: false,
312
- verifiedOnBlockchain: false,
313
- type: transactionType,
314
- networkClientId,
315
- };
316
- yield this.updateGasProperties(transactionMeta);
317
- // Checks if a transaction already exists with a given actionId
318
- if (!existingTransactionMeta) {
319
- // Set security provider response
320
- if (method && this.securityProviderRequest) {
321
- const securityProviderResponse = yield this.securityProviderRequest(transactionMeta, method);
322
- transactionMeta.securityProviderResponse = securityProviderResponse;
323
- }
324
- if (!this.isSendFlowHistoryDisabled) {
325
- transactionMeta.sendFlowHistory = sendFlowHistory !== null && sendFlowHistory !== void 0 ? sendFlowHistory : [];
326
- }
327
- // Initial history push
328
- if (!this.isHistoryDisabled) {
329
- (0, history_1.addInitialHistorySnapshot)(transactionMeta);
330
- }
331
- yield (0, swaps_1.updateSwapsTransaction)(transactionMeta, transactionType, swaps, {
332
- isSwapsDisabled: this.isSwapsDisabled,
333
- cancelTransaction: this.cancelTransaction.bind(this),
334
- // TODO: Replace `any` with type
335
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
336
- controllerHubEmitter: this.hub.emit.bind(this.hub),
337
- });
338
- this.addMetadata(transactionMeta);
339
- this.hub.emit(`unapprovedTransaction`, transactionMeta);
340
- }
341
- return {
342
- result: this.processApproval(transactionMeta, {
343
- isExisting: Boolean(existingTransactionMeta),
344
- requireApproval,
345
- actionId,
346
- }),
347
- transactionMeta,
348
- };
349
- });
350
- }
351
- startIncomingTransactionPolling(networkClientIds = []) {
352
- if (networkClientIds.length === 0) {
353
- this.incomingTransactionHelper.start();
354
- return;
355
- }
356
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").startIncomingTransactionPolling(networkClientIds);
357
- }
358
- stopIncomingTransactionPolling(networkClientIds = []) {
359
- if (networkClientIds.length === 0) {
360
- this.incomingTransactionHelper.stop();
361
- return;
362
- }
363
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopIncomingTransactionPolling(networkClientIds);
364
- }
365
- stopAllIncomingTransactionPolling() {
366
- this.incomingTransactionHelper.stop();
367
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllIncomingTransactionPolling();
368
- }
369
- updateIncomingTransactions(networkClientIds = []) {
370
- return __awaiter(this, void 0, void 0, function* () {
371
- if (networkClientIds.length === 0) {
372
- yield this.incomingTransactionHelper.update();
373
- return;
374
- }
375
- yield __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").updateIncomingTransactions(networkClientIds);
376
- });
377
- }
378
- /**
379
- * Attempts to cancel a transaction based on its ID by setting its status to "rejected"
380
- * and emitting a `<tx.id>:finished` hub event.
381
- *
382
- * @param transactionId - The ID of the transaction to cancel.
383
- * @param gasValues - The gas values to use for the cancellation transaction.
384
- * @param options - The options for the cancellation transaction.
385
- * @param options.actionId - Unique ID to prevent duplicate requests.
386
- * @param options.estimatedBaseFee - The estimated base fee of the transaction.
387
- */
388
- stopTransaction(transactionId, gasValues, { estimatedBaseFee, actionId, } = {}) {
389
- var _a, _b, _c;
390
- return __awaiter(this, void 0, void 0, function* () {
391
- // If transaction is found for same action id, do not create a cancel transaction.
392
- if (this.getTransactionWithActionId(actionId)) {
393
- return;
394
- }
395
- if (gasValues) {
396
- // Not good practice to reassign a parameter but temporarily avoiding a larger refactor.
397
- gasValues = (0, utils_2.normalizeGasFeeValues)(gasValues);
398
- (0, utils_2.validateGasValues)(gasValues);
399
- }
400
- (0, logger_1.projectLogger)('Creating cancel transaction', transactionId, gasValues);
401
- const transactionMeta = this.getTransaction(transactionId);
402
- if (!transactionMeta) {
403
- return;
404
- }
405
- if (!this.sign) {
406
- throw new Error('No sign method defined.');
407
- }
408
- // gasPrice (legacy non EIP1559)
409
- const minGasPrice = (0, utils_2.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, exports.CANCEL_RATE);
410
- const gasPriceFromValues = (0, utils_2.isGasPriceValue)(gasValues) && gasValues.gasPrice;
411
- const newGasPrice = (gasPriceFromValues &&
412
- (0, utils_2.validateMinimumIncrease)(gasPriceFromValues, minGasPrice)) ||
413
- minGasPrice;
414
- // maxFeePerGas (EIP1559)
415
- const existingMaxFeePerGas = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.maxFeePerGas;
416
- const minMaxFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxFeePerGas, exports.CANCEL_RATE);
417
- const maxFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxFeePerGas;
418
- const newMaxFeePerGas = (maxFeePerGasValues &&
419
- (0, utils_2.validateMinimumIncrease)(maxFeePerGasValues, minMaxFeePerGas)) ||
420
- (existingMaxFeePerGas && minMaxFeePerGas);
421
- // maxPriorityFeePerGas (EIP1559)
422
- const existingMaxPriorityFeePerGas = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.maxPriorityFeePerGas;
423
- const minMaxPriorityFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, exports.CANCEL_RATE);
424
- const maxPriorityFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxPriorityFeePerGas;
425
- const newMaxPriorityFeePerGas = (maxPriorityFeePerGasValues &&
426
- (0, utils_2.validateMinimumIncrease)(maxPriorityFeePerGasValues, minMaxPriorityFeePerGas)) ||
427
- (existingMaxPriorityFeePerGas && minMaxPriorityFeePerGas);
428
- const newTxParams = newMaxFeePerGas && newMaxPriorityFeePerGas
429
- ? {
430
- from: transactionMeta.txParams.from,
431
- gasLimit: transactionMeta.txParams.gas,
432
- maxFeePerGas: newMaxFeePerGas,
433
- maxPriorityFeePerGas: newMaxPriorityFeePerGas,
434
- type: types_1.TransactionEnvelopeType.feeMarket,
435
- nonce: transactionMeta.txParams.nonce,
436
- to: transactionMeta.txParams.from,
437
- value: '0x0',
438
- }
439
- : {
440
- from: transactionMeta.txParams.from,
441
- gasLimit: transactionMeta.txParams.gas,
442
- gasPrice: newGasPrice,
443
- nonce: transactionMeta.txParams.nonce,
444
- to: transactionMeta.txParams.from,
445
- value: '0x0',
446
- };
447
- const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, newTxParams);
448
- const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
449
- const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
450
- const newFee = (_c = newTxParams.maxFeePerGas) !== null && _c !== void 0 ? _c : newTxParams.gasPrice;
451
- const oldFee = newTxParams.maxFeePerGas
452
- ? transactionMeta.txParams.maxFeePerGas
453
- : transactionMeta.txParams.gasPrice;
454
- (0, logger_1.projectLogger)('Submitting cancel transaction', {
455
- oldFee,
456
- newFee,
457
- txParams: newTxParams,
458
- });
459
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
460
- networkClientId: transactionMeta.networkClientId,
461
- chainId: transactionMeta.chainId,
462
- });
463
- const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
464
- const cancelTransactionMeta = {
465
- actionId,
466
- chainId: transactionMeta.chainId,
467
- networkClientId: transactionMeta.networkClientId,
468
- estimatedBaseFee,
469
- hash,
470
- id: (0, uuid_1.v1)(),
471
- originalGasEstimate: transactionMeta.txParams.gas,
472
- status: types_1.TransactionStatus.submitted,
473
- time: Date.now(),
474
- type: types_1.TransactionType.cancel,
475
- txParams: newTxParams,
476
- };
477
- this.addMetadata(cancelTransactionMeta);
478
- // stopTransaction has no approval request, so we assume the user has already approved the transaction
479
- this.hub.emit('transaction-approved', {
480
- transactionMeta: cancelTransactionMeta,
481
- actionId,
482
- });
483
- this.hub.emit('transaction-submitted', {
484
- transactionMeta: cancelTransactionMeta,
485
- actionId,
486
- });
487
- this.hub.emit(`${cancelTransactionMeta.id}:finished`, cancelTransactionMeta);
488
- });
489
- }
490
- /**
491
- * Attempts to speed up a transaction increasing transaction gasPrice by ten percent.
492
- *
493
- * @param transactionId - The ID of the transaction to speed up.
494
- * @param gasValues - The gas values to use for the speed up transaction.
495
- * @param options - The options for the speed up transaction.
496
- * @param options.actionId - Unique ID to prevent duplicate requests
497
- * @param options.estimatedBaseFee - The estimated base fee of the transaction.
498
- */
499
- speedUpTransaction(transactionId, gasValues, { actionId, estimatedBaseFee, } = {}) {
500
- var _a, _b, _c;
501
- return __awaiter(this, void 0, void 0, function* () {
502
- // If transaction is found for same action id, do not create a new speed up transaction.
503
- if (this.getTransactionWithActionId(actionId)) {
504
- return;
505
- }
506
- if (gasValues) {
507
- // Not good practice to reassign a parameter but temporarily avoiding a larger refactor.
508
- gasValues = (0, utils_2.normalizeGasFeeValues)(gasValues);
509
- (0, utils_2.validateGasValues)(gasValues);
510
- }
511
- (0, logger_1.projectLogger)('Creating speed up transaction', transactionId, gasValues);
512
- const transactionMeta = this.state.transactions.find(({ id }) => id === transactionId);
513
- /* istanbul ignore next */
514
- if (!transactionMeta) {
515
- return;
516
- }
517
- /* istanbul ignore next */
518
- if (!this.sign) {
519
- throw new Error('No sign method defined.');
520
- }
521
- // gasPrice (legacy non EIP1559)
522
- const minGasPrice = (0, utils_2.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, exports.SPEED_UP_RATE);
523
- const gasPriceFromValues = (0, utils_2.isGasPriceValue)(gasValues) && gasValues.gasPrice;
524
- const newGasPrice = (gasPriceFromValues &&
525
- (0, utils_2.validateMinimumIncrease)(gasPriceFromValues, minGasPrice)) ||
526
- minGasPrice;
527
- // maxFeePerGas (EIP1559)
528
- const existingMaxFeePerGas = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.maxFeePerGas;
529
- const minMaxFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxFeePerGas, exports.SPEED_UP_RATE);
530
- const maxFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxFeePerGas;
531
- const newMaxFeePerGas = (maxFeePerGasValues &&
532
- (0, utils_2.validateMinimumIncrease)(maxFeePerGasValues, minMaxFeePerGas)) ||
533
- (existingMaxFeePerGas && minMaxFeePerGas);
534
- // maxPriorityFeePerGas (EIP1559)
535
- const existingMaxPriorityFeePerGas = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.maxPriorityFeePerGas;
536
- const minMaxPriorityFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, exports.SPEED_UP_RATE);
537
- const maxPriorityFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxPriorityFeePerGas;
538
- const newMaxPriorityFeePerGas = (maxPriorityFeePerGasValues &&
539
- (0, utils_2.validateMinimumIncrease)(maxPriorityFeePerGasValues, minMaxPriorityFeePerGas)) ||
540
- (existingMaxPriorityFeePerGas && minMaxPriorityFeePerGas);
541
- const txParams = newMaxFeePerGas && newMaxPriorityFeePerGas
542
- ? Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas, type: types_1.TransactionEnvelopeType.feeMarket }) : Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, gasPrice: newGasPrice });
543
- const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
544
- const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
545
- yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
546
- const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
547
- const newFee = (_c = txParams.maxFeePerGas) !== null && _c !== void 0 ? _c : txParams.gasPrice;
548
- const oldFee = txParams.maxFeePerGas
549
- ? transactionMeta.txParams.maxFeePerGas
550
- : transactionMeta.txParams.gasPrice;
551
- (0, logger_1.projectLogger)('Submitting speed up transaction', { oldFee, newFee, txParams });
552
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
553
- networkClientId: transactionMeta.networkClientId,
554
- chainId: transactionMeta.chainId,
555
- });
556
- const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
557
- const baseTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { estimatedBaseFee, id: (0, uuid_1.v1)(), time: Date.now(), hash,
558
- actionId, originalGasEstimate: transactionMeta.txParams.gas, type: types_1.TransactionType.retry, originalType: transactionMeta.type });
559
- const newTransactionMeta = newMaxFeePerGas && newMaxPriorityFeePerGas
560
- ? Object.assign(Object.assign({}, baseTransactionMeta), { txParams: Object.assign(Object.assign({}, transactionMeta.txParams), { maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas }) }) : Object.assign(Object.assign({}, baseTransactionMeta), { txParams: Object.assign(Object.assign({}, transactionMeta.txParams), { gasPrice: newGasPrice }) });
561
- this.addMetadata(newTransactionMeta);
562
- // speedUpTransaction has no approval request, so we assume the user has already approved the transaction
563
- this.hub.emit('transaction-approved', {
564
- transactionMeta: newTransactionMeta,
565
- actionId,
566
- });
567
- this.hub.emit('transaction-submitted', {
568
- transactionMeta: newTransactionMeta,
569
- actionId,
570
- });
571
- this.hub.emit(`${transactionMeta.id}:speedup`, newTransactionMeta);
572
- });
573
- }
574
- /**
575
- * Estimates required gas for a given transaction.
576
- *
577
- * @param transaction - The transaction to estimate gas for.
578
- * @param networkClientId - The network client id to use for the estimate.
579
- * @returns The gas and gas price.
580
- */
581
- estimateGas(transaction, networkClientId) {
582
- return __awaiter(this, void 0, void 0, function* () {
583
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
584
- networkClientId,
585
- });
586
- const { estimatedGas, simulationFails } = yield (0, gas_1.estimateGas)(transaction, ethQuery);
587
- return { gas: estimatedGas, simulationFails };
588
- });
589
- }
590
- /**
591
- * Estimates required gas for a given transaction and add additional gas buffer with the given multiplier.
592
- *
593
- * @param transaction - The transaction params to estimate gas for.
594
- * @param multiplier - The multiplier to use for the gas buffer.
595
- * @param networkClientId - The network client id to use for the estimate.
596
- */
597
- estimateGasBuffered(transaction, multiplier, networkClientId) {
598
- return __awaiter(this, void 0, void 0, function* () {
599
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
600
- networkClientId,
601
- });
602
- const { blockGasLimit, estimatedGas, simulationFails } = yield (0, gas_1.estimateGas)(transaction, ethQuery);
603
- const gas = (0, gas_1.addGasBuffer)(estimatedGas, blockGasLimit, multiplier);
604
- return {
605
- gas,
606
- simulationFails,
607
- };
608
- });
609
- }
610
- /**
611
- * Updates an existing transaction in state.
612
- *
613
- * @param transactionMeta - The new transaction to store in state.
614
- * @param note - A note or update reason to include in the transaction history.
615
- */
616
- updateTransaction(transactionMeta, note) {
617
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, transactionMeta, {
618
- note,
619
- skipHistory: this.isHistoryDisabled,
620
- });
621
- }
622
- /**
623
- * Update the security alert response for a transaction.
624
- *
625
- * @param transactionId - ID of the transaction.
626
- * @param securityAlertResponse - The new security alert response for the transaction.
627
- */
628
- updateSecurityAlertResponse(transactionId, securityAlertResponse) {
629
- if (!securityAlertResponse) {
630
- throw new Error('updateSecurityAlertResponse: securityAlertResponse should not be null');
631
- }
632
- const transactionMeta = this.getTransaction(transactionId);
633
- if (!transactionMeta) {
634
- throw new Error(`Cannot update security alert response as no transaction metadata found`);
635
- }
636
- const updatedMeta = (0, lodash_1.merge)(transactionMeta, { securityAlertResponse });
637
- this.updateTransaction(updatedMeta, 'TransactionController:updatesecurityAlertResponse - securityAlertResponse updated');
638
- }
639
- /**
640
- * Removes all transactions from state, optionally based on the current network.
641
- *
642
- * @param ignoreNetwork - Determines whether to wipe all transactions, or just those on the
643
- * current network. If `true`, all transactions are wiped.
644
- * @param address - If specified, only transactions originating from this address will be
645
- * wiped on current network.
646
- */
647
- wipeTransactions(ignoreNetwork, address) {
648
- /* istanbul ignore next */
649
- if (ignoreNetwork && !address) {
650
- this.update({ transactions: [] });
651
- return;
652
- }
653
- const currentChainId = this.getChainId();
654
- const newTransactions = this.state.transactions.filter(({ chainId, txParams }) => {
655
- var _a;
656
- const isMatchingNetwork = ignoreNetwork || chainId === currentChainId;
657
- if (!isMatchingNetwork) {
658
- return true;
659
- }
660
- const isMatchingAddress = !address || ((_a = txParams.from) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === address.toLowerCase();
661
- return !isMatchingAddress;
662
- });
663
- this.update({
664
- transactions: this.trimTransactionsForState(newTransactions),
665
- });
666
- }
667
- /**
668
- * Adds external provided transaction to state as confirmed transaction.
669
- *
670
- * @param transactionMeta - TransactionMeta to add transactions.
671
- * @param transactionReceipt - TransactionReceipt of the external transaction.
672
- * @param baseFeePerGas - Base fee per gas of the external transaction.
673
- */
674
- confirmExternalTransaction(transactionMeta, transactionReceipt, baseFeePerGas) {
675
- return __awaiter(this, void 0, void 0, function* () {
676
- // Run validation and add external transaction to state.
677
- this.addExternalTransaction(transactionMeta);
678
- try {
679
- const transactionId = transactionMeta.id;
680
- // Make sure status is confirmed and define gasUsed as in receipt.
681
- transactionMeta.status = types_1.TransactionStatus.confirmed;
682
- transactionMeta.txReceipt = transactionReceipt;
683
- if (baseFeePerGas) {
684
- transactionMeta.baseFeePerGas = baseFeePerGas;
685
- }
686
- // Update same nonce local transactions as dropped and define replacedBy properties.
687
- this.markNonceDuplicatesDropped(transactionId);
688
- // Update external provided transaction with updated gas values and confirmed status.
689
- this.updateTransaction(transactionMeta, 'TransactionController:confirmExternalTransaction - Add external transaction');
690
- this.onTransactionStatusChange(transactionMeta);
691
- // Intentional given potential duration of process.
692
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
693
- this.updatePostBalance(transactionMeta);
694
- this.hub.emit('transaction-confirmed', {
695
- transactionMeta,
696
- });
697
- }
698
- catch (error) {
699
- console.error('Failed to confirm external transaction', error);
700
- }
701
- });
702
- }
703
- /**
704
- * Append new send flow history to a transaction.
705
- *
706
- * @param transactionID - The ID of the transaction to update.
707
- * @param currentSendFlowHistoryLength - The length of the current sendFlowHistory array.
708
- * @param sendFlowHistoryToAdd - The sendFlowHistory entries to add.
709
- * @returns The updated transactionMeta.
710
- */
711
- updateTransactionSendFlowHistory(transactionID, currentSendFlowHistoryLength, sendFlowHistoryToAdd) {
712
- var _a, _b;
713
- if (this.isSendFlowHistoryDisabled) {
714
- throw new Error('Send flow history is disabled for the current transaction controller');
715
- }
716
- const transactionMeta = this.getTransaction(transactionID);
717
- if (!transactionMeta) {
718
- throw new Error(`Cannot update send flow history as no transaction metadata found`);
719
- }
720
- (0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateTransactionSendFlowHistory');
721
- if (currentSendFlowHistoryLength ===
722
- (((_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.sendFlowHistory) === null || _a === void 0 ? void 0 : _a.length) || 0)) {
723
- transactionMeta.sendFlowHistory = [
724
- ...((_b = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.sendFlowHistory) !== null && _b !== void 0 ? _b : []),
725
- ...sendFlowHistoryToAdd,
726
- ];
727
- this.updateTransaction(transactionMeta, 'TransactionController:updateTransactionSendFlowHistory - sendFlowHistory updated');
728
- }
729
- return this.getTransaction(transactionID);
730
- }
731
- /**
732
- * Update the gas values of a transaction.
733
- *
734
- * @param transactionId - The ID of the transaction to update.
735
- * @param gasValues - Gas values to update.
736
- * @param gasValues.gas - Same as transaction.gasLimit.
737
- * @param gasValues.gasLimit - Maxmimum number of units of gas to use for this transaction.
738
- * @param gasValues.gasPrice - Price per gas for legacy transactions.
739
- * @param gasValues.maxPriorityFeePerGas - Maximum amount per gas to give to validator as incentive.
740
- * @param gasValues.maxFeePerGas - Maximum amount per gas to pay for the transaction, including the priority fee.
741
- * @param gasValues.estimateUsed - Which estimate level was used.
742
- * @param gasValues.estimateSuggested - Which estimate level that the API suggested.
743
- * @param gasValues.defaultGasEstimates - The default estimate for gas.
744
- * @param gasValues.originalGasEstimate - Original estimate for gas.
745
- * @param gasValues.userEditedGasLimit - The gas limit supplied by user.
746
- * @param gasValues.userFeeLevel - Estimate level user selected.
747
- * @returns The updated transactionMeta.
748
- */
749
- updateTransactionGasFees(transactionId, { defaultGasEstimates, estimateUsed, estimateSuggested, gas, gasLimit, gasPrice, maxPriorityFeePerGas, maxFeePerGas, originalGasEstimate, userEditedGasLimit, userFeeLevel, }) {
750
- const transactionMeta = this.getTransaction(transactionId);
751
- if (!transactionMeta) {
752
- throw new Error(`Cannot update transaction as no transaction metadata found`);
753
- }
754
- (0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateTransactionGasFees');
755
- let transactionGasFees = {
756
- txParams: {
757
- gas,
758
- gasLimit,
759
- gasPrice,
760
- maxPriorityFeePerGas,
761
- maxFeePerGas,
762
- },
763
- defaultGasEstimates,
764
- estimateUsed,
765
- estimateSuggested,
766
- originalGasEstimate,
767
- userEditedGasLimit,
768
- userFeeLevel,
769
- // TODO: Replace `any` with type
770
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
771
- };
772
- // only update what is defined
773
- transactionGasFees.txParams = (0, lodash_1.pickBy)(transactionGasFees.txParams);
774
- transactionGasFees = (0, lodash_1.pickBy)(transactionGasFees);
775
- // merge updated gas values with existing transaction meta
776
- const updatedMeta = (0, lodash_1.merge)(transactionMeta, transactionGasFees);
777
- this.updateTransaction(updatedMeta, 'TransactionController:updateTransactionGasFees - gas values updated');
778
- return this.getTransaction(transactionId);
779
- }
780
- /**
781
- * Update the previous gas values of a transaction.
782
- *
783
- * @param transactionId - The ID of the transaction to update.
784
- * @param previousGas - Previous gas values to update.
785
- * @param previousGas.gasLimit - Maxmimum number of units of gas to use for this transaction.
786
- * @param previousGas.maxFeePerGas - Maximum amount per gas to pay for the transaction, including the priority fee.
787
- * @param previousGas.maxPriorityFeePerGas - Maximum amount per gas to give to validator as incentive.
788
- * @returns The updated transactionMeta.
789
- */
790
- updatePreviousGasParams(transactionId, { gasLimit, maxFeePerGas, maxPriorityFeePerGas, }) {
791
- const transactionMeta = this.getTransaction(transactionId);
792
- if (!transactionMeta) {
793
- throw new Error(`Cannot update transaction as no transaction metadata found`);
794
- }
795
- (0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updatePreviousGasParams');
796
- const transactionPreviousGas = {
797
- previousGas: {
798
- gasLimit,
799
- maxFeePerGas,
800
- maxPriorityFeePerGas,
801
- },
802
- // TODO: Replace `any` with type
803
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
804
- };
805
- // only update what is defined
806
- transactionPreviousGas.previousGas = (0, lodash_1.pickBy)(transactionPreviousGas.previousGas);
807
- // merge updated previous gas values with existing transaction meta
808
- const updatedMeta = (0, lodash_1.merge)(transactionMeta, transactionPreviousGas);
809
- this.updateTransaction(updatedMeta, 'TransactionController:updatePreviousGasParams - Previous gas values updated');
810
- return this.getTransaction(transactionId);
811
- }
812
- getNonceLock(address, networkClientId) {
813
- return __awaiter(this, void 0, void 0, function* () {
814
- return __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId);
815
- });
816
- }
817
- /**
818
- * Updates the editable parameters of a transaction.
819
- *
820
- * @param txId - The ID of the transaction to update.
821
- * @param params - The editable parameters to update.
822
- * @param params.data - Data to pass with the transaction.
823
- * @param params.gas - Maximum number of units of gas to use for the transaction.
824
- * @param params.gasPrice - Price per gas for legacy transactions.
825
- * @param params.from - Address to send the transaction from.
826
- * @param params.to - Address to send the transaction to.
827
- * @param params.value - Value associated with the transaction.
828
- * @returns The updated transaction metadata.
829
- */
830
- updateEditableParams(txId, { data, gas, gasPrice, from, to, value, }) {
831
- return __awaiter(this, void 0, void 0, function* () {
832
- const transactionMeta = this.getTransaction(txId);
833
- if (!transactionMeta) {
834
- throw new Error(`Cannot update editable params as no transaction metadata found`);
835
- }
836
- (0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateEditableParams');
837
- const editableParams = {
838
- txParams: {
839
- data,
840
- from,
841
- to,
842
- value,
843
- gas,
844
- gasPrice,
845
- },
846
- };
847
- editableParams.txParams = (0, lodash_1.pickBy)(editableParams.txParams);
848
- const updatedTransaction = (0, lodash_1.merge)(transactionMeta, editableParams);
849
- const { type } = yield (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
850
- networkClientId: transactionMeta.networkClientId,
851
- chainId: transactionMeta.chainId,
852
- }));
853
- updatedTransaction.type = type;
854
- this.updateTransaction(updatedTransaction, `Update Editable Params for ${txId}`);
855
- return this.getTransaction(txId);
856
- });
857
- }
858
- /**
859
- * Signs and returns the raw transaction data for provided transaction params list.
860
- *
861
- * @param listOfTxParams - The list of transaction params to approve.
862
- * @param opts - Options bag.
863
- * @param opts.hasNonce - Whether the transactions already have a nonce.
864
- * @returns The raw transactions.
865
- */
866
- approveTransactionsWithSameNonce(listOfTxParams = [], { hasNonce } = {}) {
867
- return __awaiter(this, void 0, void 0, function* () {
868
- (0, logger_1.projectLogger)('Approving transactions with same nonce', {
869
- transactions: listOfTxParams,
870
- });
871
- if (listOfTxParams.length === 0) {
872
- return '';
873
- }
874
- const initialTx = listOfTxParams[0];
875
- const common = this.getCommonConfiguration(initialTx.chainId);
876
- // We need to ensure we get the nonce using the the NonceTracker on the chain matching
877
- // the txParams. In this context we only have chainId available to us, but the
878
- // NonceTrackers are keyed by networkClientId. To workaround this, we attempt to find
879
- // a networkClientId that matches the chainId. As a fallback, the globally selected
880
- // network's NonceTracker will be used instead.
881
- let networkClientId;
882
- try {
883
- networkClientId = this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, initialTx.chainId);
884
- }
885
- catch (err) {
886
- (0, logger_1.projectLogger)('failed to find networkClientId from chainId', err);
887
- }
888
- const initialTxAsEthTx = tx_1.TransactionFactory.fromTxData(initialTx, {
889
- common,
890
- });
891
- const initialTxAsSerializedHex = (0, util_1.bufferToHex)(initialTxAsEthTx.serialize());
892
- if (this.inProcessOfSigning.has(initialTxAsSerializedHex)) {
893
- return '';
894
- }
895
- this.inProcessOfSigning.add(initialTxAsSerializedHex);
896
- let rawTransactions, nonceLock;
897
- try {
898
- // TODO: we should add a check to verify that all transactions have the same from address
899
- const fromAddress = initialTx.from;
900
- const requiresNonce = hasNonce !== true;
901
- nonceLock = requiresNonce
902
- ? yield this.getNonceLock(fromAddress, networkClientId)
903
- : undefined;
904
- const nonce = nonceLock
905
- ? (0, utils_1.add0x)(nonceLock.nextNonce.toString(16))
906
- : initialTx.nonce;
907
- if (nonceLock) {
908
- (0, logger_1.projectLogger)('Using nonce from nonce tracker', nonce, nonceLock.nonceDetails);
909
- }
910
- rawTransactions = yield Promise.all(listOfTxParams.map((txParams) => {
911
- txParams.nonce = nonce;
912
- return this.signExternalTransaction(txParams.chainId, txParams);
913
- }));
914
- }
915
- catch (err) {
916
- (0, logger_1.projectLogger)('Error while signing transactions with same nonce', err);
917
- // Must set transaction to submitted/failed before releasing lock
918
- // continue with error chain
919
- throw err;
920
- }
921
- finally {
922
- nonceLock === null || nonceLock === void 0 ? void 0 : nonceLock.releaseLock();
923
- this.inProcessOfSigning.delete(initialTxAsSerializedHex);
924
- }
925
- return rawTransactions;
926
- });
927
- }
928
- /**
929
- * Update a custodial transaction.
930
- *
931
- * @param transactionId - The ID of the transaction to update.
932
- * @param options - The custodial transaction options to update.
933
- * @param options.errorMessage - The error message to be assigned in case transaction status update to failed.
934
- * @param options.hash - The new hash value to be assigned.
935
- * @param options.status - The new status value to be assigned.
936
- */
937
- updateCustodialTransaction(transactionId, { errorMessage, hash, status, }) {
938
- const transactionMeta = this.getTransaction(transactionId);
939
- if (!transactionMeta) {
940
- throw new Error(`Cannot update custodial transaction as no transaction metadata found`);
941
- }
942
- if (!transactionMeta.custodyId) {
943
- throw new Error('Transaction must be a custodian transaction');
944
- }
945
- if (status &&
946
- ![
947
- types_1.TransactionStatus.submitted,
948
- types_1.TransactionStatus.signed,
949
- types_1.TransactionStatus.failed,
950
- ].includes(status)) {
951
- throw new Error(`Cannot update custodial transaction with status: ${status}`);
952
- }
953
- const updatedTransactionMeta = (0, lodash_1.merge)(transactionMeta, (0, lodash_1.pickBy)({ hash, status }));
954
- if (status === types_1.TransactionStatus.submitted) {
955
- updatedTransactionMeta.submittedTime = new Date().getTime();
956
- }
957
- if (status === types_1.TransactionStatus.failed) {
958
- updatedTransactionMeta.error = (0, utils_2.normalizeTxError)(new Error(errorMessage));
959
- }
960
- this.updateTransaction(updatedTransactionMeta, `TransactionController:updateCustodialTransaction - Custodial transaction updated`);
961
- if ([types_1.TransactionStatus.submitted, types_1.TransactionStatus.failed].includes(status)) {
962
- this.hub.emit(`${transactionMeta.id}:finished`, updatedTransactionMeta);
963
- }
964
- }
965
- /**
966
- * Creates approvals for all unapproved transactions persisted.
967
- */
968
- initApprovals() {
969
- const chainId = this.getChainId();
970
- const unapprovedTxs = this.state.transactions.filter((transaction) => transaction.status === types_1.TransactionStatus.unapproved &&
971
- transaction.chainId === chainId &&
972
- !transaction.isUserOperation);
973
- for (const txMeta of unapprovedTxs) {
974
- this.processApproval(txMeta, {
975
- shouldShowRequest: false,
976
- }).catch((error) => {
977
- if ((error === null || error === void 0 ? void 0 : error.code) === rpc_errors_1.errorCodes.provider.userRejectedRequest) {
978
- return;
979
- }
980
- console.error('Error during persisted transaction approval', error);
981
- });
982
- }
983
- }
984
- /**
985
- * Search transaction metadata for matching entries.
986
- *
987
- * @param opts - Options bag.
988
- * @param opts.searchCriteria - An object containing values or functions for transaction properties to filter transactions with.
989
- * @param opts.initialList - The transactions to search. Defaults to the current state.
990
- * @param opts.filterToCurrentNetwork - Whether to filter the results to the current network. Defaults to true.
991
- * @param opts.limit - The maximum number of transactions to return. No limit by default.
992
- * @returns An array of transactions matching the provided options.
993
- */
994
- getTransactions({ searchCriteria = {}, initialList, filterToCurrentNetwork = true, limit, } = {}) {
995
- const chainId = this.getChainId();
996
- // searchCriteria is an object that might have values that aren't predicate
997
- // methods. When providing any other value type (string, number, etc), we
998
- // consider this shorthand for "check the value at key for strict equality
999
- // with the provided value". To conform this object to be only methods, we
1000
- // mapValues (lodash) such that every value on the object is a method that
1001
- // returns a boolean.
1002
- const predicateMethods = (0, lodash_1.mapValues)(searchCriteria, (predicate) => {
1003
- return typeof predicate === 'function'
1004
- ? predicate
1005
- : // TODO: Replace `any` with type
1006
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1007
- (v) => v === predicate;
1008
- });
1009
- const transactionsToFilter = initialList !== null && initialList !== void 0 ? initialList : this.state.transactions;
1010
- // Combine sortBy and pickBy to transform our state object into an array of
1011
- // matching transactions that are sorted by time.
1012
- const filteredTransactions = (0, lodash_1.sortBy)((0, lodash_1.pickBy)(transactionsToFilter, (transaction) => {
1013
- if (filterToCurrentNetwork && transaction.chainId !== chainId) {
1014
- return false;
1015
- }
1016
- // iterate over the predicateMethods keys to check if the transaction
1017
- // matches the searchCriteria
1018
- for (const [key, predicate] of Object.entries(predicateMethods)) {
1019
- // We return false early as soon as we know that one of the specified
1020
- // search criteria do not match the transaction. This prevents
1021
- // needlessly checking all criteria when we already know the criteria
1022
- // are not fully satisfied. We check both txParams and the base
1023
- // object as predicate keys can be either.
1024
- if (key in transaction.txParams) {
1025
- // TODO: Replace `any` with type
1026
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1027
- if (predicate(transaction.txParams[key]) === false) {
1028
- return false;
1029
- }
1030
- // TODO: Replace `any` with type
1031
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1032
- }
1033
- else if (predicate(transaction[key]) === false) {
1034
- return false;
1035
- }
1036
- }
1037
- return true;
1038
- }), 'time');
1039
- if (limit !== undefined) {
1040
- // We need to have all transactions of a given nonce in order to display
1041
- // necessary details in the UI. We use the size of this set to determine
1042
- // whether we have reached the limit provided, thus ensuring that all
1043
- // transactions of nonces we include will be sent to the UI.
1044
- const nonces = new Set();
1045
- const txs = [];
1046
- // By default, the transaction list we filter from is sorted by time ASC.
1047
- // To ensure that filtered results prefers the newest transactions we
1048
- // iterate from right to left, inserting transactions into front of a new
1049
- // array. The original order is preserved, but we ensure that newest txs
1050
- // are preferred.
1051
- for (let i = filteredTransactions.length - 1; i > -1; i--) {
1052
- const txMeta = filteredTransactions[i];
1053
- const { nonce } = txMeta.txParams;
1054
- if (!nonces.has(nonce)) {
1055
- if (nonces.size < limit) {
1056
- nonces.add(nonce);
1057
- }
1058
- else {
1059
- continue;
1060
- }
1061
- }
1062
- // Push transaction into the beginning of our array to ensure the
1063
- // original order is preserved.
1064
- txs.unshift(txMeta);
1065
- }
1066
- return txs;
1067
- }
1068
- return filteredTransactions;
1069
- }
1070
- signExternalTransaction(chainId, transactionParams) {
1071
- return __awaiter(this, void 0, void 0, function* () {
1072
- if (!this.sign) {
1073
- throw new Error('No sign method defined.');
1074
- }
1075
- const normalizedTransactionParams = (0, utils_2.normalizeTxParams)(transactionParams);
1076
- const type = (0, utils_2.isEIP1559Transaction)(normalizedTransactionParams)
1077
- ? types_1.TransactionEnvelopeType.feeMarket
1078
- : types_1.TransactionEnvelopeType.legacy;
1079
- const updatedTransactionParams = Object.assign(Object.assign({}, normalizedTransactionParams), { type, gasLimit: normalizedTransactionParams.gas, chainId });
1080
- const { from } = updatedTransactionParams;
1081
- const common = this.getCommonConfiguration(chainId);
1082
- const unsignedTransaction = tx_1.TransactionFactory.fromTxData(updatedTransactionParams, { common });
1083
- const signedTransaction = yield this.sign(unsignedTransaction, from);
1084
- const rawTransaction = (0, util_1.bufferToHex)(signedTransaction.serialize());
1085
- return rawTransaction;
1086
- });
1087
- }
1088
- /**
1089
- * Removes unapproved transactions from state.
1090
- */
1091
- clearUnapprovedTransactions() {
1092
- const transactions = this.state.transactions.filter(({ status }) => status !== types_1.TransactionStatus.unapproved);
1093
- this.update({ transactions: this.trimTransactionsForState(transactions) });
1094
- }
1095
- /**
1096
- * Stop the signing process for a specific transaction.
1097
- * Throws an error causing the transaction status to be set to failed.
1098
- * @param transactionId - The ID of the transaction to stop signing.
1099
- */
1100
- abortTransactionSigning(transactionId) {
1101
- const transactionMeta = this.getTransaction(transactionId);
1102
- if (!transactionMeta) {
1103
- throw new Error(`Cannot abort signing as no transaction metadata found`);
1104
- }
1105
- const abortCallback = this.signAbortCallbacks.get(transactionId);
1106
- if (!abortCallback) {
1107
- throw new Error(`Cannot abort signing as transaction is not waiting for signing`);
1108
- }
1109
- abortCallback();
1110
- this.signAbortCallbacks.delete(transactionId);
1111
- }
1112
- addMetadata(transactionMeta) {
1113
- const { transactions } = this.state;
1114
- transactions.push(transactionMeta);
1115
- this.update({ transactions: this.trimTransactionsForState(transactions) });
1116
- }
1117
- updateGasProperties(transactionMeta) {
1118
- return __awaiter(this, void 0, void 0, function* () {
1119
- const isEIP1559Compatible = (yield this.getEIP1559Compatibility(transactionMeta.networkClientId)) &&
1120
- transactionMeta.txParams.type !== types_1.TransactionEnvelopeType.legacy;
1121
- const { networkClientId, chainId } = transactionMeta;
1122
- const isCustomNetwork = networkClientId
1123
- ? this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.type === network_controller_1.NetworkClientType.Custom
1124
- : this.getNetworkState().providerConfig.type === controller_utils_1.NetworkType.rpc;
1125
- yield (0, gas_1.updateGas)({
1126
- ethQuery: __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1127
- networkClientId,
1128
- chainId,
1129
- }),
1130
- chainId,
1131
- isCustomNetwork,
1132
- txMeta: transactionMeta,
1133
- });
1134
- yield (0, gas_fees_1.updateGasFees)({
1135
- eip1559: isEIP1559Compatible,
1136
- ethQuery: __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1137
- networkClientId,
1138
- chainId,
1139
- }),
1140
- gasFeeFlows: this.gasFeeFlows,
1141
- getGasFeeEstimates: this.getGasFeeEstimates,
1142
- getSavedGasFees: this.getSavedGasFees.bind(this),
1143
- txMeta: transactionMeta,
1144
- });
1145
- });
1146
- }
1147
- onBootCleanup() {
1148
- this.submitApprovedTransactions();
1149
- }
1150
- /**
1151
- * Force submit approved transactions for all chains.
1152
- */
1153
- submitApprovedTransactions() {
1154
- const approvedTransactions = this.state.transactions.filter((transaction) => transaction.status === types_1.TransactionStatus.approved);
1155
- for (const transactionMeta of approvedTransactions) {
1156
- if (this.beforeApproveOnInit(transactionMeta)) {
1157
- this.approveTransaction(transactionMeta.id).catch((error) => {
1158
- /* istanbul ignore next */
1159
- console.error('Error while submitting persisted transaction', error);
1160
- });
1161
- }
1162
- }
1163
- }
1164
- processApproval(transactionMeta, { isExisting = false, requireApproval, shouldShowRequest = true, actionId, }) {
1165
- return __awaiter(this, void 0, void 0, function* () {
1166
- const transactionId = transactionMeta.id;
1167
- let resultCallbacks;
1168
- const { meta, isCompleted } = this.isTransactionCompleted(transactionId);
1169
- const finishedPromise = isCompleted
1170
- ? Promise.resolve(meta)
1171
- : this.waitForTransactionFinished(transactionId);
1172
- if (meta && !isExisting && !isCompleted) {
1173
- try {
1174
- if (requireApproval !== false) {
1175
- const acceptResult = yield this.requestApproval(transactionMeta, {
1176
- shouldShowRequest,
1177
- });
1178
- resultCallbacks = acceptResult.resultCallbacks;
1179
- if (resultCallbacks) {
1180
- this.hub.once(`${transactionId}:publish-skip`, () => {
1181
- resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.success();
1182
- // Remove the reference to prevent additional reports once submitted.
1183
- resultCallbacks = undefined;
1184
- });
1185
- }
1186
- const approvalValue = acceptResult.value;
1187
- const updatedTransaction = approvalValue === null || approvalValue === void 0 ? void 0 : approvalValue.txMeta;
1188
- if (updatedTransaction) {
1189
- (0, logger_1.projectLogger)('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
- yield this.approveTransaction(transactionId);
1199
- const updatedTransactionMeta = this.getTransaction(transactionId);
1200
- this.hub.emit('transaction-approved', {
1201
- transactionMeta: updatedTransactionMeta,
1202
- actionId,
1203
- });
1204
- }
1205
- // TODO: Replace `any` with type
1206
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1207
- }
1208
- catch (error) {
1209
- const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
1210
- if (!isTxCompleted) {
1211
- if ((error === null || error === void 0 ? void 0 : error.code) === rpc_errors_1.errorCodes.provider.userRejectedRequest) {
1212
- this.cancelTransaction(transactionId, actionId);
1213
- throw rpc_errors_1.providerErrors.userRejectedRequest('MetaMask Tx Signature: User denied transaction signature.');
1214
- }
1215
- else {
1216
- this.failTransaction(meta, error, actionId);
1217
- }
1218
- }
1219
- }
1220
- }
1221
- const finalMeta = yield finishedPromise;
1222
- switch (finalMeta === null || finalMeta === void 0 ? void 0 : finalMeta.status) {
1223
- case types_1.TransactionStatus.failed:
1224
- resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.error(finalMeta.error);
1225
- throw rpc_errors_1.rpcErrors.internal(finalMeta.error.message);
1226
- case types_1.TransactionStatus.submitted:
1227
- resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.success();
1228
- return finalMeta.hash;
1229
- default:
1230
- const internalError = rpc_errors_1.rpcErrors.internal(`MetaMask Tx Signature: Unknown problem: ${JSON.stringify(finalMeta || transactionId)}`);
1231
- resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.error(internalError);
1232
- throw internalError;
1233
- }
1234
- });
1235
- }
1236
- /**
1237
- * Approves a transaction and updates it's status in state. If this is not a
1238
- * retry transaction, a nonce will be generated. The transaction is signed
1239
- * using the sign configuration property, then published to the blockchain.
1240
- * A `<tx.id>:finished` hub event is fired after success or failure.
1241
- *
1242
- * @param transactionId - The ID of the transaction to approve.
1243
- */
1244
- approveTransaction(transactionId) {
1245
- return __awaiter(this, void 0, void 0, function* () {
1246
- const { transactions } = this.state;
1247
- const releaseLock = yield this.mutex.acquire();
1248
- const index = transactions.findIndex(({ id }) => transactionId === id);
1249
- const transactionMeta = transactions[index];
1250
- const { txParams: { from }, networkClientId, } = transactionMeta;
1251
- let releaseNonceLock;
1252
- try {
1253
- if (!this.sign) {
1254
- releaseLock();
1255
- this.failTransaction(transactionMeta, new Error('No sign method defined.'));
1256
- return;
1257
- }
1258
- else if (!transactionMeta.chainId) {
1259
- releaseLock();
1260
- this.failTransaction(transactionMeta, new Error('No chainId defined.'));
1261
- return;
1262
- }
1263
- if (this.inProcessOfSigning.has(transactionId)) {
1264
- (0, logger_1.projectLogger)('Skipping approval as signing in progress', transactionId);
1265
- return;
1266
- }
1267
- const [nonce, releaseNonce] = yield (0, nonce_1.getNextNonce)(transactionMeta, (address) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId));
1268
- releaseNonceLock = releaseNonce;
1269
- transactionMeta.status = types_1.TransactionStatus.approved;
1270
- transactionMeta.txParams.nonce = nonce;
1271
- transactionMeta.txParams.chainId = transactionMeta.chainId;
1272
- const baseTxParams = Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas });
1273
- this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction approved');
1274
- this.onTransactionStatusChange(transactionMeta);
1275
- const isEIP1559 = (0, utils_2.isEIP1559Transaction)(transactionMeta.txParams);
1276
- const txParams = isEIP1559
1277
- ? Object.assign(Object.assign({}, baseTxParams), { estimatedBaseFee: transactionMeta.txParams.estimatedBaseFee, type: types_1.TransactionEnvelopeType.feeMarket }) : baseTxParams;
1278
- const rawTx = yield this.signTransaction(transactionMeta, txParams);
1279
- if (!this.beforePublish(transactionMeta)) {
1280
- (0, logger_1.projectLogger)('Skipping publishing transaction based on hook');
1281
- this.hub.emit(`${transactionMeta.id}:publish-skip`, transactionMeta);
1282
- return;
1283
- }
1284
- if (!rawTx) {
1285
- return;
1286
- }
1287
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1288
- networkClientId: transactionMeta.networkClientId,
1289
- chainId: transactionMeta.chainId,
1290
- });
1291
- if (transactionMeta.type === types_1.TransactionType.swap) {
1292
- (0, logger_1.projectLogger)('Determining pre-transaction balance');
1293
- const preTxBalance = yield (0, controller_utils_1.query)(ethQuery, 'getBalance', [from]);
1294
- transactionMeta.preTxBalance = preTxBalance;
1295
- (0, logger_1.projectLogger)('Updated pre-transaction balance', transactionMeta.preTxBalance);
1296
- }
1297
- (0, logger_1.projectLogger)('Publishing transaction', txParams);
1298
- let { transactionHash: hash } = yield this.publish(transactionMeta, rawTx);
1299
- if (hash === undefined) {
1300
- hash = yield this.publishTransaction(ethQuery, rawTx);
1301
- }
1302
- (0, logger_1.projectLogger)('Publish successful', hash);
1303
- transactionMeta.hash = hash;
1304
- transactionMeta.status = types_1.TransactionStatus.submitted;
1305
- transactionMeta.submittedTime = new Date().getTime();
1306
- this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction submitted');
1307
- this.hub.emit('transaction-submitted', {
1308
- transactionMeta,
1309
- });
1310
- this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
1311
- this.onTransactionStatusChange(transactionMeta);
1312
- // TODO: Replace `any` with type
1313
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1314
- }
1315
- catch (error) {
1316
- this.failTransaction(transactionMeta, error);
1317
- }
1318
- finally {
1319
- this.inProcessOfSigning.delete(transactionId);
1320
- // must set transaction to submitted/failed before releasing lock
1321
- releaseNonceLock === null || releaseNonceLock === void 0 ? void 0 : releaseNonceLock();
1322
- releaseLock();
1323
- }
1324
- });
1325
- }
1326
- publishTransaction(ethQuery, rawTransaction) {
1327
- return __awaiter(this, void 0, void 0, function* () {
1328
- return yield (0, controller_utils_1.query)(ethQuery, 'sendRawTransaction', [rawTransaction]);
1329
- });
1330
- }
1331
- /**
1332
- * Cancels a transaction based on its ID by setting its status to "rejected"
1333
- * and emitting a `<tx.id>:finished` hub event.
1334
- *
1335
- * @param transactionId - The ID of the transaction to cancel.
1336
- * @param actionId - The actionId passed from UI
1337
- */
1338
- cancelTransaction(transactionId, actionId) {
1339
- const transactionMeta = this.state.transactions.find(({ id }) => id === transactionId);
1340
- if (!transactionMeta) {
1341
- return;
1342
- }
1343
- transactionMeta.status = types_1.TransactionStatus.rejected;
1344
- const transactions = this.state.transactions.filter(({ id }) => id !== transactionId);
1345
- this.update({ transactions: this.trimTransactionsForState(transactions) });
1346
- this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
1347
- this.hub.emit('transaction-rejected', {
1348
- transactionMeta,
1349
- actionId,
1350
- });
1351
- this.onTransactionStatusChange(transactionMeta);
1352
- }
1353
- /**
1354
- * Trim the amount of transactions that are set on the state. Checks
1355
- * if the length of the tx history is longer then desired persistence
1356
- * limit and then if it is removes the oldest confirmed or rejected tx.
1357
- * Pending or unapproved transactions will not be removed by this
1358
- * operation. For safety of presenting a fully functional transaction UI
1359
- * representation, this function will not break apart transactions with the
1360
- * same nonce, created on the same day, per network. Not accounting for transactions of the same
1361
- * nonce, same day and network combo can result in confusing or broken experiences
1362
- * in the UI. The transactions are then updated using the BaseControllerV1 update.
1363
- *
1364
- * @param transactions - The transactions to be applied to the state.
1365
- * @returns The trimmed list of transactions.
1366
- */
1367
- trimTransactionsForState(transactions) {
1368
- const nonceNetworkSet = new Set();
1369
- const txsToKeep = transactions
1370
- .sort((a, b) => (a.time > b.time ? -1 : 1)) // Descending time order
1371
- .filter((tx) => {
1372
- const { chainId, status, txParams, time } = tx;
1373
- if (txParams) {
1374
- const key = `${txParams.nonce}-${(0, controller_utils_1.convertHexToDecimal)(chainId)}-${new Date(time).toDateString()}`;
1375
- if (nonceNetworkSet.has(key)) {
1376
- return true;
1377
- }
1378
- else if (nonceNetworkSet.size < this.config.txHistoryLimit ||
1379
- !this.isFinalState(status)) {
1380
- nonceNetworkSet.add(key);
1381
- return true;
1382
- }
1383
- }
1384
- return false;
1385
- });
1386
- txsToKeep.reverse(); // Ascending time order
1387
- return txsToKeep;
1388
- }
1389
- /**
1390
- * Determines if the transaction is in a final state.
1391
- *
1392
- * @param status - The transaction status.
1393
- * @returns Whether the transaction is in a final state.
1394
- */
1395
- isFinalState(status) {
1396
- return (status === types_1.TransactionStatus.rejected ||
1397
- status === types_1.TransactionStatus.confirmed ||
1398
- status === types_1.TransactionStatus.failed);
1399
- }
1400
- /**
1401
- * Whether the transaction has at least completed all local processing.
1402
- *
1403
- * @param status - The transaction status.
1404
- * @returns Whether the transaction is in a final state.
1405
- */
1406
- isLocalFinalState(status) {
1407
- return [
1408
- types_1.TransactionStatus.confirmed,
1409
- types_1.TransactionStatus.failed,
1410
- types_1.TransactionStatus.rejected,
1411
- types_1.TransactionStatus.submitted,
1412
- ].includes(status);
1413
- }
1414
- requestApproval(txMeta, { shouldShowRequest }) {
1415
- return __awaiter(this, void 0, void 0, function* () {
1416
- const id = this.getApprovalId(txMeta);
1417
- const { origin } = txMeta;
1418
- const type = controller_utils_1.ApprovalType.Transaction;
1419
- const requestData = { txId: txMeta.id };
1420
- return (yield this.messagingSystem.call('ApprovalController:addRequest', {
1421
- id,
1422
- origin: origin || controller_utils_1.ORIGIN_METAMASK,
1423
- type,
1424
- requestData,
1425
- expectsResult: true,
1426
- }, shouldShowRequest));
1427
- });
1428
- }
1429
- getTransaction(transactionId) {
1430
- const { transactions } = this.state;
1431
- return transactions.find(({ id }) => id === transactionId);
1432
- }
1433
- getApprovalId(txMeta) {
1434
- return String(txMeta.id);
1435
- }
1436
- isTransactionCompleted(transactionId) {
1437
- const transaction = this.getTransaction(transactionId);
1438
- if (!transaction) {
1439
- return { meta: undefined, isCompleted: false };
1440
- }
1441
- const isCompleted = this.isLocalFinalState(transaction.status);
1442
- return { meta: transaction, isCompleted };
1443
- }
1444
- getChainId(networkClientId) {
1445
- if (networkClientId) {
1446
- return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.chainId;
1447
- }
1448
- const { providerConfig } = this.getNetworkState();
1449
- return providerConfig.chainId;
1450
- }
1451
- prepareUnsignedEthTx(chainId, txParams) {
1452
- return tx_1.TransactionFactory.fromTxData(txParams, {
1453
- freeze: false,
1454
- common: this.getCommonConfiguration(chainId),
1455
- });
1456
- }
1457
- /**
1458
- * `@ethereumjs/tx` uses `@ethereumjs/common` as a configuration tool for
1459
- * specifying which chain, network, hardfork and EIPs to support for
1460
- * a transaction. By referencing this configuration, and analyzing the fields
1461
- * specified in txParams, @ethereumjs/tx is able to determine which EIP-2718
1462
- * transaction type to use.
1463
- *
1464
- * @param chainId - The chainId to use for the configuration.
1465
- * @returns common configuration object
1466
- */
1467
- getCommonConfiguration(chainId) {
1468
- const customChainParams = {
1469
- chainId: parseInt(chainId, 16),
1470
- defaultHardfork: exports.HARDFORK,
1471
- };
1472
- return common_1.Common.custom(customChainParams);
1473
- }
1474
- onIncomingTransactions({ added, updated, }) {
1475
- const { transactions: currentTransactions } = this.state;
1476
- const updatedTransactions = [
1477
- ...added,
1478
- ...currentTransactions.map((originalTransaction) => {
1479
- const updatedTransaction = updated.find(({ hash }) => hash === originalTransaction.hash);
1480
- return updatedTransaction !== null && updatedTransaction !== void 0 ? updatedTransaction : originalTransaction;
1481
- }),
1482
- ];
1483
- this.update({
1484
- transactions: this.trimTransactionsForState(updatedTransactions),
1485
- });
1486
- }
1487
- onUpdatedLastFetchedBlockNumbers({ lastFetchedBlockNumbers, blockNumber, }) {
1488
- this.update({ lastFetchedBlockNumbers });
1489
- this.hub.emit('incomingTransactionBlock', blockNumber);
1490
- }
1491
- generateDappSuggestedGasFees(txParams, origin) {
1492
- if (!origin || origin === controller_utils_1.ORIGIN_METAMASK) {
1493
- return undefined;
1494
- }
1495
- const { gasPrice, maxFeePerGas, maxPriorityFeePerGas, gas } = txParams;
1496
- if (gasPrice === undefined &&
1497
- maxFeePerGas === undefined &&
1498
- maxPriorityFeePerGas === undefined &&
1499
- gas === undefined) {
1500
- return undefined;
1501
- }
1502
- const dappSuggestedGasFees = {};
1503
- if (gasPrice !== undefined) {
1504
- dappSuggestedGasFees.gasPrice = gasPrice;
1505
- }
1506
- else if (maxFeePerGas !== undefined ||
1507
- maxPriorityFeePerGas !== undefined) {
1508
- dappSuggestedGasFees.maxFeePerGas = maxFeePerGas;
1509
- dappSuggestedGasFees.maxPriorityFeePerGas = maxPriorityFeePerGas;
1510
- }
1511
- if (gas !== undefined) {
1512
- dappSuggestedGasFees.gas = gas;
1513
- }
1514
- return dappSuggestedGasFees;
1515
- }
1516
- /**
1517
- * Validates and adds external provided transaction to state.
1518
- *
1519
- * @param transactionMeta - Nominated external transaction to be added to state.
1520
- */
1521
- addExternalTransaction(transactionMeta) {
1522
- var _a, _b;
1523
- const { chainId } = transactionMeta;
1524
- const { transactions } = this.state;
1525
- const fromAddress = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.from;
1526
- const sameFromAndNetworkTransactions = transactions.filter((transaction) => transaction.txParams.from === fromAddress &&
1527
- transaction.chainId === chainId);
1528
- const confirmedTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.confirmed);
1529
- const pendingTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.submitted);
1530
- (0, external_transactions_1.validateConfirmedExternalTransaction)(transactionMeta, confirmedTxs, pendingTxs);
1531
- // Make sure provided external transaction has non empty history array
1532
- if (!((_b = transactionMeta.history) !== null && _b !== void 0 ? _b : []).length) {
1533
- if (!this.isHistoryDisabled) {
1534
- (0, history_1.addInitialHistorySnapshot)(transactionMeta);
1535
- }
1536
- }
1537
- const updatedTransactions = [...transactions, transactionMeta];
1538
- this.update({
1539
- transactions: this.trimTransactionsForState(updatedTransactions),
1540
- });
1541
- }
1542
- /**
1543
- * Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
1544
- * in the transactions have the same nonce.
1545
- *
1546
- * @param transactionId - Used to identify original transaction.
1547
- */
1548
- markNonceDuplicatesDropped(transactionId) {
1549
- var _a, _b;
1550
- const transactionMeta = this.getTransaction(transactionId);
1551
- if (!transactionMeta) {
1552
- return;
1553
- }
1554
- const nonce = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.nonce;
1555
- const from = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.from;
1556
- const { chainId } = transactionMeta;
1557
- const sameNonceTxs = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
1558
- transaction.txParams.from === from &&
1559
- transaction.txParams.nonce === nonce &&
1560
- transaction.chainId === chainId &&
1561
- transaction.type !== types_1.TransactionType.incoming);
1562
- if (!sameNonceTxs.length) {
1563
- return;
1564
- }
1565
- // Mark all same nonce transactions as dropped and give it a replacedBy hash
1566
- for (const transaction of sameNonceTxs) {
1567
- transaction.replacedBy = transactionMeta.hash;
1568
- transaction.replacedById = transactionMeta.id;
1569
- // Drop any transaction that wasn't previously failed (off chain failure)
1570
- if (transaction.status !== types_1.TransactionStatus.failed) {
1571
- this.setTransactionStatusDropped(transaction);
1572
- }
1573
- }
1574
- }
1575
- /**
1576
- * Method to set transaction status to dropped.
1577
- *
1578
- * @param transactionMeta - TransactionMeta of transaction to be marked as dropped.
1579
- */
1580
- setTransactionStatusDropped(transactionMeta) {
1581
- transactionMeta.status = types_1.TransactionStatus.dropped;
1582
- this.hub.emit('transaction-dropped', {
1583
- transactionMeta,
1584
- });
1585
- this.updateTransaction(transactionMeta, 'TransactionController#setTransactionStatusDropped - Transaction dropped');
1586
- this.onTransactionStatusChange(transactionMeta);
1587
- }
1588
- /**
1589
- * Get transaction with provided actionId.
1590
- *
1591
- * @param actionId - Unique ID to prevent duplicate requests
1592
- * @returns the filtered transaction
1593
- */
1594
- getTransactionWithActionId(actionId) {
1595
- return this.state.transactions.find((transaction) => actionId && transaction.actionId === actionId);
1596
- }
1597
- waitForTransactionFinished(transactionId) {
1598
- return __awaiter(this, void 0, void 0, function* () {
1599
- return new Promise((resolve) => {
1600
- this.hub.once(`${transactionId}:finished`, (txMeta) => {
1601
- resolve(txMeta);
1602
- });
1603
- });
1604
- });
1605
- }
1606
- /**
1607
- * Updates the r, s, and v properties of a TransactionMeta object
1608
- * with values from a signed transaction.
1609
- *
1610
- * @param transactionMeta - The TransactionMeta object to update.
1611
- * @param signedTx - The encompassing type for all transaction types containing r, s, and v values.
1612
- */
1613
- updateTransactionMetaRSV(transactionMeta, signedTx) {
1614
- return __awaiter(this, void 0, void 0, function* () {
1615
- for (const key of ['r', 's', 'v']) {
1616
- const value = signedTx[key];
1617
- if (value === undefined || value === null) {
1618
- continue;
1619
- }
1620
- transactionMeta[key] = (0, utils_1.add0x)(value.toString(16));
1621
- }
1622
- });
1623
- }
1624
- getEIP1559Compatibility(networkClientId) {
1625
- return __awaiter(this, void 0, void 0, function* () {
1626
- const currentNetworkIsEIP1559Compatible = yield this.getCurrentNetworkEIP1559Compatibility(networkClientId);
1627
- const currentAccountIsEIP1559Compatible = yield this.getCurrentAccountEIP1559Compatibility();
1628
- return (currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible);
1629
- });
1630
- }
1631
- signTransaction(transactionMeta, txParams) {
1632
- return __awaiter(this, void 0, void 0, function* () {
1633
- (0, logger_1.projectLogger)('Signing transaction', txParams);
1634
- const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
1635
- this.inProcessOfSigning.add(transactionMeta.id);
1636
- const signedTx = yield new Promise((resolve, reject) => {
1637
- var _a;
1638
- (_a = this.sign) === null || _a === void 0 ? void 0 : _a.call(this, unsignedEthTx, txParams.from, ...this.getAdditionalSignArguments(transactionMeta)).then(resolve, reject);
1639
- this.signAbortCallbacks.set(transactionMeta.id, () => reject(new Error('Signing aborted by user')));
1640
- });
1641
- this.signAbortCallbacks.delete(transactionMeta.id);
1642
- if (!signedTx) {
1643
- (0, logger_1.projectLogger)('Skipping signed status as no signed transaction');
1644
- return undefined;
1645
- }
1646
- if (!this.afterSign(transactionMeta, signedTx)) {
1647
- this.updateTransaction(transactionMeta, 'TransactionController#signTransaction - Update after sign');
1648
- (0, logger_1.projectLogger)('Skipping signed status based on hook');
1649
- return undefined;
1650
- }
1651
- yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
1652
- transactionMeta.status = types_1.TransactionStatus.signed;
1653
- this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction signed');
1654
- this.onTransactionStatusChange(transactionMeta);
1655
- const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
1656
- transactionMeta.rawTx = rawTx;
1657
- this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - RawTransaction added');
1658
- return rawTx;
1659
- });
1660
- }
1661
- onTransactionStatusChange(transactionMeta) {
1662
- this.hub.emit('transaction-status-update', { transactionMeta });
1663
- }
1664
- getNonceTrackerTransactions(status, address, chainId = this.getChainId()) {
1665
- return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(chainId, address, status, this.state.transactions);
1666
- }
1667
- onConfirmedTransaction(transactionMeta) {
1668
- (0, logger_1.projectLogger)('Processing confirmed transaction', transactionMeta.id);
1669
- this.markNonceDuplicatesDropped(transactionMeta.id);
1670
- this.hub.emit('transaction-confirmed', { transactionMeta });
1671
- this.hub.emit(`${transactionMeta.id}:confirmed`, transactionMeta);
1672
- this.onTransactionStatusChange(transactionMeta);
1673
- // Intentional given potential duration of process.
1674
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
1675
- this.updatePostBalance(transactionMeta);
1676
- }
1677
- updatePostBalance(transactionMeta) {
1678
- return __awaiter(this, void 0, void 0, function* () {
1679
- try {
1680
- if (transactionMeta.type !== types_1.TransactionType.swap) {
1681
- return;
1682
- }
1683
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1684
- networkClientId: transactionMeta.networkClientId,
1685
- chainId: transactionMeta.chainId,
1686
- });
1687
- const { updatedTransactionMeta, approvalTransactionMeta } = yield (0, swaps_1.updatePostTransactionBalance)(transactionMeta, {
1688
- ethQuery,
1689
- getTransaction: this.getTransaction.bind(this),
1690
- updateTransaction: this.updateTransaction.bind(this),
1691
- });
1692
- this.hub.emit('post-transaction-balance-updated', {
1693
- transactionMeta: updatedTransactionMeta,
1694
- approvalTransactionMeta,
1695
- });
1696
- }
1697
- catch (error) {
1698
- /* istanbul ignore next */
1699
- (0, logger_1.projectLogger)('Error while updating post transaction balance', error);
1700
- }
1701
- });
1702
- }
1703
- publishTransactionForRetry(ethQuery, rawTx, transactionMeta) {
1704
- return __awaiter(this, void 0, void 0, function* () {
1705
- try {
1706
- const hash = yield this.publishTransaction(ethQuery, rawTx);
1707
- return hash;
1708
- }
1709
- catch (error) {
1710
- if (this.isTransactionAlreadyConfirmedError(error)) {
1711
- yield this.pendingTransactionTracker.forceCheckTransaction(transactionMeta);
1712
- throw new Error('Previous transaction is already confirmed');
1713
- }
1714
- throw error;
1715
- }
1716
- });
1717
- }
1718
- /**
1719
- * Ensures that error is a nonce issue
1720
- *
1721
- * @param error - The error to check
1722
- * @returns Whether or not the error is a nonce issue
1723
- */
1724
- // TODO: Replace `any` with type
1725
- // Some networks are returning original error in the data field
1726
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1727
- isTransactionAlreadyConfirmedError(error) {
1728
- var _a, _b, _c;
1729
- return (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('nonce too low')) ||
1730
- ((_c = (_b = error === null || error === void 0 ? void 0 : error.data) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.includes('nonce too low')));
1731
- }
1732
- }
1733
- exports.TransactionController = TransactionController;
1734
- _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionController_pendingTransactionOptions = new WeakMap(), _TransactionController_multichainTrackingHelper = new WeakMap(), _TransactionController_checkForPendingTransactionAndStartPolling = new WeakMap(), _TransactionController_instances = new WeakSet(), _TransactionController_createNonceTracker = function _TransactionController_createNonceTracker({ provider, blockTracker, chainId, }) {
1735
- return new nonce_tracker_1.NonceTracker({
1736
- // TODO: Replace `any` with type
1737
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1738
- provider: provider,
1739
- blockTracker,
1740
- getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
1741
- getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
1742
- });
1743
- }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, etherscanRemoteTransactionSource, chainId, }) {
1744
- const incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
1745
- blockTracker,
1746
- getCurrentAccount: this.getSelectedAddress,
1747
- getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
1748
- getChainId: chainId ? () => chainId : this.getChainId.bind(this),
1749
- isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
1750
- queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
1751
- remoteTransactionSource: etherscanRemoteTransactionSource,
1752
- transactionLimit: this.config.txHistoryLimit,
1753
- updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
1754
- });
1755
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
1756
- return incomingTransactionHelper;
1757
- }, _TransactionController_createPendingTransactionTracker = function _TransactionController_createPendingTransactionTracker({ provider, blockTracker, chainId, }) {
1758
- const ethQuery = new eth_query_1.default(provider);
1759
- const getChainId = chainId ? () => chainId : this.getChainId.bind(this);
1760
- const pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
1761
- approveTransaction: this.approveTransaction.bind(this),
1762
- blockTracker,
1763
- getChainId,
1764
- getEthQuery: () => ethQuery,
1765
- getTransactions: () => this.state.transactions,
1766
- isResubmitEnabled: __classPrivateFieldGet(this, _TransactionController_pendingTransactionOptions, "f").isResubmitEnabled,
1767
- getGlobalLock: () => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").acquireNonceLockForChainIdKey({
1768
- chainId: getChainId(),
1769
- }),
1770
- publishTransaction: this.publishTransaction.bind(this),
1771
- hooks: {
1772
- beforeCheckPendingTransaction: this.beforeCheckPendingTransaction.bind(this),
1773
- beforePublish: this.beforePublish.bind(this),
1774
- },
1775
- });
1776
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addPendingTransactionTrackerListeners).call(this, pendingTransactionTracker);
1777
- return pendingTransactionTracker;
1778
- }, _TransactionController_stopAllTracking = function _TransactionController_stopAllTracking() {
1779
- this.pendingTransactionTracker.stop();
1780
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).call(this, this.pendingTransactionTracker);
1781
- this.incomingTransactionHelper.stop();
1782
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).call(this, this.incomingTransactionHelper);
1783
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllTracking();
1784
- }, _TransactionController_removeIncomingTransactionHelperListeners = function _TransactionController_removeIncomingTransactionHelperListeners(incomingTransactionHelper) {
1785
- incomingTransactionHelper.hub.removeAllListeners('transactions');
1786
- incomingTransactionHelper.hub.removeAllListeners('updatedLastFetchedBlockNumbers');
1787
- }, _TransactionController_addIncomingTransactionHelperListeners = function _TransactionController_addIncomingTransactionHelperListeners(incomingTransactionHelper) {
1788
- incomingTransactionHelper.hub.on('transactions', this.onIncomingTransactions.bind(this));
1789
- incomingTransactionHelper.hub.on('updatedLastFetchedBlockNumbers', this.onUpdatedLastFetchedBlockNumbers.bind(this));
1790
- }, _TransactionController_removePendingTransactionTrackerListeners = function _TransactionController_removePendingTransactionTrackerListeners(pendingTransactionTracker) {
1791
- pendingTransactionTracker.hub.removeAllListeners('transaction-confirmed');
1792
- pendingTransactionTracker.hub.removeAllListeners('transaction-dropped');
1793
- pendingTransactionTracker.hub.removeAllListeners('transaction-failed');
1794
- pendingTransactionTracker.hub.removeAllListeners('transaction-updated');
1795
- }, _TransactionController_addPendingTransactionTrackerListeners = function _TransactionController_addPendingTransactionTrackerListeners(pendingTransactionTracker) {
1796
- pendingTransactionTracker.hub.on('transaction-confirmed', this.onConfirmedTransaction.bind(this));
1797
- pendingTransactionTracker.hub.on('transaction-dropped', this.setTransactionStatusDropped.bind(this));
1798
- pendingTransactionTracker.hub.on('transaction-failed', this.failTransaction.bind(this));
1799
- pendingTransactionTracker.hub.on('transaction-updated', this.updateTransaction.bind(this));
1800
- }, _TransactionController_getNonceTrackerPendingTransactions = function _TransactionController_getNonceTrackerPendingTransactions(chainId, address) {
1801
- const standardPendingTransactions = this.getNonceTrackerTransactions(types_1.TransactionStatus.submitted, address, chainId);
1802
- const externalPendingTransactions = this.getExternalPendingTransactions(address, chainId);
1803
- return [...standardPendingTransactions, ...externalPendingTransactions];
1804
- }, _TransactionController_getGasFeeFlows = function _TransactionController_getGasFeeFlows() {
1805
- return [new LineaGasFeeFlow_1.LineaGasFeeFlow(), new DefaultGasFeeFlow_1.DefaultGasFeeFlow()];
1806
- }, _TransactionController_updateTransactionInternal = function _TransactionController_updateTransactionInternal(transactionMeta, { note, skipHistory }) {
1807
- const { transactions } = this.state;
1808
- transactionMeta.txParams = (0, utils_2.normalizeTxParams)(transactionMeta.txParams);
1809
- (0, validation_1.validateTxParams)(transactionMeta.txParams);
1810
- if (skipHistory !== true) {
1811
- (0, history_1.updateTransactionHistory)(transactionMeta, note !== null && note !== void 0 ? note : 'Transaction updated');
1812
- }
1813
- const index = transactions.findIndex(({ id }) => transactionMeta.id === id);
1814
- transactions[index] = transactionMeta;
1815
- this.update({ transactions: this.trimTransactionsForState(transactions) });
1816
- };
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+ var _chunkBJEESIBEjs = require('./chunk-BJEESIBE.js');
8
+ require('./chunk-VH47Q6TS.js');
9
+ require('./chunk-IUBAETUH.js');
10
+ require('./chunk-QP75SWIQ.js');
11
+ require('./chunk-ZNZEJDOE.js');
12
+ require('./chunk-DTEDYRTL.js');
13
+ require('./chunk-FDJPXQTF.js');
14
+ require('./chunk-HS277C77.js');
15
+ require('./chunk-7APMBUKB.js');
16
+ require('./chunk-DTDTOMTB.js');
17
+ require('./chunk-M7455RU7.js');
18
+ require('./chunk-5XBULBP2.js');
19
+ require('./chunk-7LXE4KHV.js');
20
+ require('./chunk-I5YZ7QUK.js');
21
+ require('./chunk-ZJLZSFOZ.js');
22
+ require('./chunk-ZCQRDZ36.js');
23
+ require('./chunk-IC233ZQS.js');
24
+ require('./chunk-UGFBA4GV.js');
25
+ require('./chunk-H4M66BA3.js');
26
+ require('./chunk-GKTIFXPN.js');
27
+ require('./chunk-NUOBUW7C.js');
28
+ require('./chunk-RI6MVJJN.js');
29
+ require('./chunk-S6VGOPUY.js');
30
+ require('./chunk-HPNXIKFY.js');
31
+ require('./chunk-Z4BLTVTB.js');
32
+
33
+
34
+
35
+
36
+
37
+
38
+ exports.ApprovalState = _chunkBJEESIBEjs.ApprovalState; exports.CANCEL_RATE = _chunkBJEESIBEjs.CANCEL_RATE; exports.HARDFORK = _chunkBJEESIBEjs.HARDFORK; exports.SPEED_UP_RATE = _chunkBJEESIBEjs.SPEED_UP_RATE; exports.TransactionController = _chunkBJEESIBEjs.TransactionController;
1817
39
  //# sourceMappingURL=TransactionController.js.map