@metamask/bridge-status-controller 33.0.0 → 35.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 (40) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/dist/bridge-status-controller.cjs +142 -110
  3. package/dist/bridge-status-controller.cjs.map +1 -1
  4. package/dist/bridge-status-controller.d.cts +4 -4
  5. package/dist/bridge-status-controller.d.cts.map +1 -1
  6. package/dist/bridge-status-controller.d.mts +4 -4
  7. package/dist/bridge-status-controller.d.mts.map +1 -1
  8. package/dist/bridge-status-controller.mjs +144 -112
  9. package/dist/bridge-status-controller.mjs.map +1 -1
  10. package/dist/types.cjs.map +1 -1
  11. package/dist/types.d.cts +1 -0
  12. package/dist/types.d.cts.map +1 -1
  13. package/dist/types.d.mts +1 -0
  14. package/dist/types.d.mts.map +1 -1
  15. package/dist/types.mjs.map +1 -1
  16. package/dist/utils/gas.cjs +34 -1
  17. package/dist/utils/gas.cjs.map +1 -1
  18. package/dist/utils/gas.d.cts +7 -0
  19. package/dist/utils/gas.d.cts.map +1 -1
  20. package/dist/utils/gas.d.mts +7 -0
  21. package/dist/utils/gas.d.mts.map +1 -1
  22. package/dist/utils/gas.mjs +32 -0
  23. package/dist/utils/gas.mjs.map +1 -1
  24. package/dist/utils/metrics.cjs +9 -4
  25. package/dist/utils/metrics.cjs.map +1 -1
  26. package/dist/utils/metrics.d.cts +1 -1
  27. package/dist/utils/metrics.d.cts.map +1 -1
  28. package/dist/utils/metrics.d.mts +1 -1
  29. package/dist/utils/metrics.d.mts.map +1 -1
  30. package/dist/utils/metrics.mjs +9 -4
  31. package/dist/utils/metrics.mjs.map +1 -1
  32. package/dist/utils/transaction.cjs +100 -29
  33. package/dist/utils/transaction.cjs.map +1 -1
  34. package/dist/utils/transaction.d.cts +80 -34
  35. package/dist/utils/transaction.d.cts.map +1 -1
  36. package/dist/utils/transaction.d.mts +80 -34
  37. package/dist/utils/transaction.d.mts.map +1 -1
  38. package/dist/utils/transaction.mjs +96 -28
  39. package/dist/utils/transaction.mjs.map +1 -1
  40. package/package.json +8 -9
package/CHANGELOG.md CHANGED
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [35.0.0]
11
+
12
+ ### Changed
13
+
14
+ - **BREAKING:** Bump peer dependency `@metamask/bridge-controller` to `^35.0.0` ([#6098](https://github.com/MetaMask/core/pull/6098))
15
+ - **BREAKING** Submit Solana transactions using `onClientRequest` RPC call by default, which hides the Snap confirmation page from clients. Clients will need to remove conditional redirect the the confirmation page on tx submission ([#6077](https://github.com/MetaMask/core/pull/6077))
16
+ - Bump `@metamask/controller-utils` from `^11.10.0` to `^11.11.0` ([#6069](https://github.com/MetaMask/core/pull/6069))
17
+ - Bump `@metamask/utils` from `^11.2.0` to `^11.4.2` ([#6054](https://github.com/MetaMask/core/pull/6054))
18
+
19
+ ## [34.0.0]
20
+
21
+ ### Added
22
+
23
+ - Add `batchId` to BridgeHistoryItem to enable querying history by batchId ([#6058](https://github.com/MetaMask/core/pull/6058))
24
+
25
+ ### Changed
26
+
27
+ - **BREAKING** Add tx batching functionality, which requires an `addTransactionBatchFn` handler to be passed to the BridgeStatusController's constructor ([#6058](https://github.com/MetaMask/core/pull/6058))
28
+ - **BREAKING** Update batched txs after signing with correct tx types, which requires an `updateTransactionFn` handler to be passed to the BridgeStatusController's constructor ([#6058](https://github.com/MetaMask/core/pull/6058))
29
+ - Add approvalTxId to txHistoryItem after signing batched transaction ([#6058](https://github.com/MetaMask/core/pull/6058))
30
+ - Remove `addUserOperationFromTransaction` tx submission code and constructor arg since it is unsupported ([#6057](https://github.com/MetaMask/core/pull/6057))
31
+ - Remove @metamask/user-operation-controller dependency ([#6057](https://github.com/MetaMask/core/pull/6057))
32
+ - **BREAKING:** Bump peer dependency `@metamask/snaps-controllers` from `^12.0.0` to `^14.0.0` ([#6035](https://github.com/MetaMask/core/pull/6035))
33
+
34
+ ### Fixed
35
+
36
+ - Wait until a bridge transaction is confirmed before polling for its status. This reduces (or fully removes) premature `getTxStatus` calls, and enables adding batched bridge txs to history before its transaction Id is available ([#6052](https://github.com/MetaMask/core/pull/6052))
37
+
10
38
  ## [33.0.0]
11
39
 
12
40
  ### Changed
@@ -377,7 +405,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
377
405
 
378
406
  - Initial release ([#5317](https://github.com/MetaMask/core/pull/5317))
379
407
 
380
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@33.0.0...HEAD
408
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@35.0.0...HEAD
409
+ [35.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@34.0.0...@metamask/bridge-status-controller@35.0.0
410
+ [34.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@33.0.0...@metamask/bridge-status-controller@34.0.0
381
411
  [33.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@32.0.0...@metamask/bridge-status-controller@33.0.0
382
412
  [32.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@31.0.0...@metamask/bridge-status-controller@32.0.0
383
413
  [31.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-status-controller@30.0.0...@metamask/bridge-status-controller@31.0.0
@@ -10,16 +10,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  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");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _BridgeStatusController_instances, _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionFn, _BridgeStatusController_estimateGasFeeFn, _BridgeStatusController_addUserOperationFromTransactionFn, _BridgeStatusController_trace, _BridgeStatusController_restartPollingForIncompleteHistoryItems, _BridgeStatusController_addTxToHistory, _BridgeStatusController_getMultichainSelectedAccount, _BridgeStatusController_getMultichainSelectedAccountAddress, _BridgeStatusController_fetchBridgeTxStatus, _BridgeStatusController_getSrcTxHash, _BridgeStatusController_updateSrcTxHash, _BridgeStatusController_wipeBridgeStatusByChainId, _BridgeStatusController_handleSolanaTx, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, _BridgeStatusController_handleApprovalTx, _BridgeStatusController_handleEvmSmartTransaction, _BridgeStatusController_handleEvmTransaction, _BridgeStatusController_handleUSDTAllowanceReset, _BridgeStatusController_calculateGasFees, _BridgeStatusController_trackUnifiedSwapBridgeEvent;
13
+ var _BridgeStatusController_instances, _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionFn, _BridgeStatusController_addTransactionBatchFn, _BridgeStatusController_updateTransactionFn, _BridgeStatusController_estimateGasFeeFn, _BridgeStatusController_trace, _BridgeStatusController_markTxAsFailed, _BridgeStatusController_restartPollingForIncompleteHistoryItems, _BridgeStatusController_addTxToHistory, _BridgeStatusController_startPollingForTxId, _BridgeStatusController_getMultichainSelectedAccount, _BridgeStatusController_getMultichainSelectedAccountAddress, _BridgeStatusController_fetchBridgeTxStatus, _BridgeStatusController_getSrcTxHash, _BridgeStatusController_updateSrcTxHash, _BridgeStatusController_wipeBridgeStatusByChainId, _BridgeStatusController_handleSolanaTx, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, _BridgeStatusController_handleApprovalTx, _BridgeStatusController_handleEvmTransaction, _BridgeStatusController_handleUSDTAllowanceReset, _BridgeStatusController_calculateGasFees, _BridgeStatusController_handleEvmTransactionBatch, _BridgeStatusController_trackUnifiedSwapBridgeEvent;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.BridgeStatusController = void 0;
16
16
  const bridge_controller_1 = require("@metamask/bridge-controller");
17
17
  const controller_utils_1 = require("@metamask/controller-utils");
18
- const keyring_api_1 = require("@metamask/keyring-api");
19
18
  const polling_controller_1 = require("@metamask/polling-controller");
20
19
  const transaction_controller_1 = require("@metamask/transaction-controller");
21
20
  const utils_1 = require("@metamask/utils");
22
- const bignumber_js_1 = require("bignumber.js");
23
21
  const constants_1 = require("./constants.cjs");
24
22
  const types_1 = require("./types.cjs");
25
23
  const bridge_status_1 = require("./utils/bridge-status.cjs");
@@ -36,7 +34,7 @@ const metadata = {
36
34
  },
37
35
  };
38
36
  class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPollingController)() {
39
- constructor({ messenger, state, clientId, fetchFn, addTransactionFn, addUserOperationFromTransactionFn, estimateGasFeeFn, config, traceFn, }) {
37
+ constructor({ messenger, state, clientId, fetchFn, addTransactionFn, addTransactionBatchFn, updateTransactionFn, estimateGasFeeFn, config, traceFn, }) {
40
38
  super({
41
39
  name: constants_1.BRIDGE_STATUS_CONTROLLER_NAME,
42
40
  metadata,
@@ -53,9 +51,22 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
53
51
  _BridgeStatusController_fetchFn.set(this, void 0);
54
52
  _BridgeStatusController_config.set(this, void 0);
55
53
  _BridgeStatusController_addTransactionFn.set(this, void 0);
54
+ _BridgeStatusController_addTransactionBatchFn.set(this, void 0);
55
+ _BridgeStatusController_updateTransactionFn.set(this, void 0);
56
56
  _BridgeStatusController_estimateGasFeeFn.set(this, void 0);
57
- _BridgeStatusController_addUserOperationFromTransactionFn.set(this, void 0);
58
57
  _BridgeStatusController_trace.set(this, void 0);
58
+ // Mark tx as failed in txHistory if either the approval or trade fails
59
+ _BridgeStatusController_markTxAsFailed.set(this, ({ id }) => {
60
+ const txHistoryKey = this.state.txHistory[id]
61
+ ? id
62
+ : Object.keys(this.state.txHistory).find((key) => this.state.txHistory[key].approvalTxId === id);
63
+ if (!txHistoryKey) {
64
+ return;
65
+ }
66
+ this.update((statusState) => {
67
+ statusState.txHistory[txHistoryKey].status.status = bridge_controller_1.StatusTypes.FAILED;
68
+ });
69
+ });
59
70
  this.resetState = () => {
60
71
  this.update((state) => {
61
72
  state.txHistory = constants_1.DEFAULT_BRIDGE_STATUS_CONTROLLER_STATE.txHistory;
@@ -84,8 +95,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
84
95
  historyItem.status.status === bridge_controller_1.StatusTypes.UNKNOWN)
85
96
  .filter((historyItem) => {
86
97
  // Check if we are already polling this tx, if so, skip restarting polling for that
87
- const srcTxMetaId = historyItem.txMetaId;
88
- const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[srcTxMetaId];
98
+ const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[historyItem.txMetaId];
89
99
  return !pollingToken;
90
100
  })
91
101
  // Swap txs don't need to have their statuses polled
@@ -97,9 +107,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
97
107
  const bridgeTxMetaId = historyItem.txMetaId;
98
108
  // We manually call startPolling() here rather than go through startPollingForBridgeTxStatus()
99
109
  // because we don't want to overwrite the existing historyItem in state
100
- __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId] = this.startPolling({
101
- bridgeTxMetaId,
102
- });
110
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeTxMetaId);
103
111
  });
104
112
  });
105
113
  _BridgeStatusController_addTxToHistory.set(this, (startPollingForBridgeTxStatusArgs) => {
@@ -109,6 +117,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
109
117
  // We know it's in progress but not the exact status yet
110
118
  const txHistoryItem = {
111
119
  txMetaId: bridgeTxMeta.id,
120
+ batchId: bridgeTxMeta.batchId,
112
121
  quote: quoteResponse.quote,
113
122
  startTime,
114
123
  estimatedProcessingTimeInSeconds: quoteResponse.estimatedProcessingTimeInSeconds,
@@ -140,20 +149,33 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
140
149
  state.txHistory[bridgeTxMeta.id] = txHistoryItem;
141
150
  });
142
151
  });
152
+ _BridgeStatusController_startPollingForTxId.set(this, (txId) => {
153
+ // If we are already polling for this tx, stop polling for it before restarting
154
+ const existingPollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId];
155
+ if (existingPollingToken) {
156
+ this.stopPollingByPollingToken(existingPollingToken);
157
+ }
158
+ const txHistoryItem = this.state.txHistory[txId];
159
+ if (!txHistoryItem) {
160
+ return;
161
+ }
162
+ const { quote } = txHistoryItem;
163
+ const isBridgeTx = (0, bridge_controller_1.isCrossChain)(quote.srcChainId, quote.destChainId);
164
+ if (isBridgeTx) {
165
+ __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId] = this.startPolling({
166
+ bridgeTxMetaId: txId,
167
+ });
168
+ }
169
+ });
143
170
  /**
144
- * Starts polling for the bridge tx status
171
+ * Adds tx to history and starts polling for the bridge tx status
145
172
  *
146
173
  * @param txHistoryMeta - The parameters for creating the history item
147
174
  */
148
175
  this.startPollingForBridgeTxStatus = (txHistoryMeta) => {
149
- const { quoteResponse, bridgeTxMeta } = txHistoryMeta;
176
+ const { bridgeTxMeta } = txHistoryMeta;
150
177
  __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
151
- const isBridgeTx = (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
152
- if (isBridgeTx) {
153
- __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMeta.id] = this.startPolling({
154
- bridgeTxMetaId: bridgeTxMeta.id,
155
- });
156
- }
178
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeTxMeta.id);
157
179
  };
158
180
  // This will be called after you call this.startPolling()
159
181
  // The args passed in are the args you passed in to startPolling()
@@ -272,11 +294,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
272
294
  if (!selectedAccount?.metadata?.snap?.id) {
273
295
  throw new Error('Failed to submit cross-chain swap transaction: undefined snap id');
274
296
  }
275
- const bridgeFeatureFlags = (0, bridge_controller_1.getBridgeFeatureFlags)(this.messagingSystem);
276
- const request = bridgeFeatureFlags?.chains?.[keyring_api_1.SolScope.Mainnet]
277
- ?.isSnapConfirmationEnabled
278
- ? (0, transaction_1.getKeyringRequest)(quoteResponse, selectedAccount)
279
- : (0, transaction_1.getClientRequest)(quoteResponse, selectedAccount);
297
+ const request = (0, transaction_1.getClientRequest)(quoteResponse, selectedAccount);
280
298
  const requestResponse = (await this.messagingSystem.call('SnapController:handleRequest', request));
281
299
  // The extension client actually redirects before it can do anytyhing with this meta
282
300
  const txMeta = (0, transaction_1.handleSolanaTxResponse)(requestResponse, quoteResponse, selectedAccount);
@@ -294,7 +312,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
294
312
  }
295
313
  return finalTransactionMeta;
296
314
  });
297
- _BridgeStatusController_handleApprovalTx.set(this, async (isBridgeTx, quoteResponse, requireApproval = false) => {
315
+ _BridgeStatusController_handleApprovalTx.set(this, async (isBridgeTx, quoteResponse) => {
298
316
  const { approval } = quoteResponse;
299
317
  if (approval) {
300
318
  const approveTx = async () => {
@@ -304,8 +322,6 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
304
322
  ? transaction_controller_1.TransactionType.bridgeApproval
305
323
  : transaction_controller_1.TransactionType.swapApproval,
306
324
  trade: approval,
307
- quoteResponse,
308
- requireApproval,
309
325
  });
310
326
  await (0, transaction_1.handleLineaDelay)(quoteResponse);
311
327
  return approvalTxMeta;
@@ -322,31 +338,16 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
322
338
  }
323
339
  return undefined;
324
340
  });
325
- _BridgeStatusController_handleEvmSmartTransaction.set(this, async ({ isBridgeTx, trade, quoteResponse, approvalTxId, requireApproval = false, }) => {
326
- return await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
327
- transactionType: isBridgeTx
328
- ? transaction_controller_1.TransactionType.bridge
329
- : transaction_controller_1.TransactionType.swap,
330
- trade,
331
- quoteResponse,
332
- approvalTxId,
333
- shouldWaitForHash: false,
334
- requireApproval,
335
- });
336
- });
337
341
  /**
338
342
  * Submits an EVM transaction to the TransactionController
339
343
  *
340
344
  * @param params - The parameters for the transaction
341
345
  * @param params.transactionType - The type of transaction to submit
342
346
  * @param params.trade - The trade data to confirm
343
- * @param params.quoteResponse - The quote response
344
- * @param params.approvalTxId - The tx id of the approval tx
345
- * @param params.shouldWaitForHash - Whether to wait for the hash of the transaction
346
347
  * @param params.requireApproval - Whether to require approval for the transaction
347
348
  * @returns The transaction meta
348
349
  */
349
- _BridgeStatusController_handleEvmTransaction.set(this, async ({ transactionType, trade, quoteResponse, approvalTxId, shouldWaitForHash = true, requireApproval = false, }) => {
350
+ _BridgeStatusController_handleEvmTransaction.set(this, async ({ transactionType, trade, requireApproval = false, }) => {
350
351
  const actionId = (0, transaction_2.generateActionId)().toString();
351
352
  const selectedAccount = this.messagingSystem.call('AccountsController:getAccountByAddress', trade.from);
352
353
  if (!selectedAccount) {
@@ -371,47 +372,16 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
371
372
  ...transactionParams,
372
373
  ...(await __classPrivateFieldGet(this, _BridgeStatusController_calculateGasFees, "f").call(this, transactionParams, networkClientId, hexChainId)),
373
374
  };
374
- let result;
375
- let transactionMeta;
376
- const isSmartContractAccount = selectedAccount.type === keyring_api_1.EthAccountType.Erc4337;
377
- if (isSmartContractAccount && __classPrivateFieldGet(this, _BridgeStatusController_addUserOperationFromTransactionFn, "f")) {
378
- const smartAccountTxResult = await __classPrivateFieldGet(this, _BridgeStatusController_addUserOperationFromTransactionFn, "f").call(this, transactionParamsWithMaxGas, requestOptions);
379
- result = smartAccountTxResult.transactionHash;
380
- transactionMeta = {
381
- ...requestOptions,
382
- chainId: hexChainId,
383
- txParams: transactionParamsWithMaxGas,
384
- time: Date.now(),
385
- id: smartAccountTxResult.id,
386
- status: transaction_controller_1.TransactionStatus.confirmed,
387
- };
388
- }
389
- else {
390
- const addTransactionResult = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionFn, "f").call(this, transactionParamsWithMaxGas, requestOptions);
391
- result = addTransactionResult.result;
392
- transactionMeta = addTransactionResult.transactionMeta;
393
- }
394
- if (shouldWaitForHash) {
395
- return await __classPrivateFieldGet(this, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, "f").call(this, result);
396
- }
397
- return {
398
- ...(0, transaction_1.getTxMetaFields)(quoteResponse, approvalTxId),
399
- ...transactionMeta,
400
- };
375
+ const { result } = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionFn, "f").call(this, transactionParamsWithMaxGas, requestOptions);
376
+ return await __classPrivateFieldGet(this, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, "f").call(this, result);
401
377
  });
402
378
  _BridgeStatusController_handleUSDTAllowanceReset.set(this, async (quoteResponse) => {
403
- const hexChainId = (0, bridge_controller_1.formatChainIdToHex)(quoteResponse.quote.srcChainId);
404
- if (quoteResponse.approval &&
405
- (0, bridge_controller_1.isEthUsdt)(hexChainId, quoteResponse.quote.srcAsset.address)) {
406
- const allowance = new bignumber_js_1.BigNumber(await this.messagingSystem.call('BridgeController:getBridgeERC20Allowance', quoteResponse.quote.srcAsset.address, hexChainId));
407
- const shouldResetApproval = allowance.lt(quoteResponse.sentAmount.amount) && allowance.gt(0);
408
- if (shouldResetApproval) {
409
- await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
410
- transactionType: transaction_controller_1.TransactionType.bridgeApproval,
411
- trade: { ...quoteResponse.approval, data: (0, bridge_controller_1.getEthUsdtResetData)() },
412
- quoteResponse,
413
- });
414
- }
379
+ const resetApproval = await (0, transaction_1.getUSDTAllowanceResetTx)(this.messagingSystem, quoteResponse);
380
+ if (resetApproval) {
381
+ await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
382
+ transactionType: transaction_controller_1.TransactionType.bridgeApproval,
383
+ trade: resetApproval,
384
+ });
415
385
  }
416
386
  });
417
387
  _BridgeStatusController_calculateGasFees.set(this, async (transactionParams, networkClientId, chainId) => {
@@ -432,6 +402,42 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
432
402
  gas: maxGasLimit,
433
403
  };
434
404
  });
405
+ /**
406
+ * Submits batched EVM transactions to the TransactionController
407
+ *
408
+ * @param args - The parameters for the transaction
409
+ * @param args.isBridgeTx - Whether the transaction is a bridge transaction
410
+ * @param args.trade - The trade data to confirm
411
+ * @param args.approval - The approval data to confirm
412
+ * @param args.resetApproval - The ethereum:USDT reset approval data to confirm
413
+ * @param args.quoteResponse - The quote response
414
+ * @param args.requireApproval - Whether to require approval for the transaction
415
+ * @returns The approvalMeta and tradeMeta for the batched transaction
416
+ */
417
+ _BridgeStatusController_handleEvmTransactionBatch.set(this, async (args) => {
418
+ const transactionParams = await (0, transaction_1.getAddTransactionBatchParams)({
419
+ messagingSystem: this.messagingSystem,
420
+ estimateGasFeeFn: __classPrivateFieldGet(this, _BridgeStatusController_estimateGasFeeFn, "f"),
421
+ ...args,
422
+ });
423
+ const txDataByType = {
424
+ [transaction_controller_1.TransactionType.bridgeApproval]: transactionParams.transactions.find(({ type }) => type === transaction_controller_1.TransactionType.bridgeApproval)?.params.data,
425
+ [transaction_controller_1.TransactionType.swapApproval]: transactionParams.transactions.find(({ type }) => type === transaction_controller_1.TransactionType.swapApproval)?.params.data,
426
+ [transaction_controller_1.TransactionType.bridge]: transactionParams.transactions.find(({ type }) => type === transaction_controller_1.TransactionType.bridge)?.params.data,
427
+ [transaction_controller_1.TransactionType.swap]: transactionParams.transactions.find(({ type }) => type === transaction_controller_1.TransactionType.swap)?.params.data,
428
+ };
429
+ const { batchId } = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionBatchFn, "f").call(this, transactionParams);
430
+ const { approvalMeta, tradeMeta } = (0, transaction_1.findAndUpdateTransactionsInBatch)({
431
+ messagingSystem: this.messagingSystem,
432
+ updateTransactionFn: __classPrivateFieldGet(this, _BridgeStatusController_updateTransactionFn, "f"),
433
+ batchId,
434
+ txDataByType,
435
+ });
436
+ if (!tradeMeta) {
437
+ throw new Error('Failed to update cross-chain swap transaction batch: tradeMeta not found');
438
+ }
439
+ return { approvalMeta, tradeMeta };
440
+ });
435
441
  /**
436
442
  * Submits a cross-chain swap transaction
437
443
  *
@@ -454,7 +460,8 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
454
460
  // Emit Submitted event after submit button is clicked
455
461
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Submitted, undefined, preConfirmationProperties);
456
462
  let txMeta;
457
- let approvalTime, approvalTxId;
463
+ let approvalTxId;
464
+ const startTime = Date.now();
458
465
  const isBridgeTx = (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
459
466
  // Submit SOLANA tx
460
467
  if ((0, bridge_controller_1.isSolanaChainId)(quoteResponse.quote.srcChainId) &&
@@ -486,10 +493,6 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
486
493
  // Extension does not have this issue
487
494
  const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === types_1.BridgeClientId.MOBILE &&
488
495
  (0, bridge_controller_1.isHardwareWallet)(__classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_getMultichainSelectedAccount).call(this));
489
- // Set approval time and id if an approval tx is needed
490
- const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, isBridgeTx, quoteResponse, requireApproval);
491
- approvalTime = approvalTxMeta?.time;
492
- approvalTxId = approvalTxMeta?.id;
493
496
  // Handle smart transactions if enabled
494
497
  txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, {
495
498
  name: isBridgeTx
@@ -499,27 +502,34 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
499
502
  srcChainId: (0, bridge_controller_1.formatChainIdToCaip)(quoteResponse.quote.srcChainId),
500
503
  stxEnabled: isStxEnabledOnClient,
501
504
  },
502
- }, async () => isStxEnabledOnClient
503
- ? await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmSmartTransaction, "f").call(this, {
504
- isBridgeTx,
505
- trade: quoteResponse.trade,
506
- quoteResponse,
507
- approvalTxId,
508
- requireApproval,
509
- })
510
- : await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
505
+ }, async () => {
506
+ if (isStxEnabledOnClient) {
507
+ const { tradeMeta, approvalMeta } = await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransactionBatch, "f").call(this, {
508
+ isBridgeTx,
509
+ resetApproval: await (0, transaction_1.getUSDTAllowanceResetTx)(this.messagingSystem, quoteResponse),
510
+ approval: quoteResponse.approval,
511
+ trade: quoteResponse.trade,
512
+ quoteResponse,
513
+ requireApproval,
514
+ });
515
+ approvalTxId = approvalMeta?.id;
516
+ return tradeMeta;
517
+ }
518
+ // Set approval time and id if an approval tx is needed
519
+ const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, isBridgeTx, quoteResponse);
520
+ approvalTxId = approvalTxMeta?.id;
521
+ return await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
511
522
  transactionType: isBridgeTx
512
523
  ? transaction_controller_1.TransactionType.bridge
513
524
  : transaction_controller_1.TransactionType.swap,
514
525
  trade: quoteResponse.trade,
515
- quoteResponse,
516
- approvalTxId,
517
526
  requireApproval,
518
- }));
527
+ });
528
+ });
519
529
  }
520
530
  try {
521
- // Start polling for bridge tx status
522
- this.startPollingForBridgeTxStatus({
531
+ // Add swap or bridge tx to history
532
+ __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
523
533
  bridgeTxMeta: txMeta,
524
534
  statusRequest: {
525
535
  ...(0, transaction_1.getStatusRequestParams)(quoteResponse),
@@ -528,12 +538,16 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
528
538
  quoteResponse,
529
539
  slippagePercentage: 0,
530
540
  isStxEnabled: isStxEnabledOnClient,
531
- startTime: approvalTime ?? Date.now(),
541
+ startTime,
532
542
  approvalTxId,
533
543
  });
534
- // Track Solana Swap completed event
535
- if ((0, bridge_controller_1.isSolanaChainId)(quoteResponse.quote.srcChainId) && !isBridgeTx) {
536
- __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, txMeta.id);
544
+ if ((0, bridge_controller_1.isSolanaChainId)(quoteResponse.quote.srcChainId)) {
545
+ // Start polling for bridge tx status
546
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, txMeta.id);
547
+ // Track Solana Swap completed event
548
+ if (!isBridgeTx) {
549
+ __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, txMeta.id);
550
+ }
537
551
  }
538
552
  }
539
553
  catch {
@@ -574,7 +588,8 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
574
588
  __classPrivateFieldSet(this, _BridgeStatusController_clientId, clientId, "f");
575
589
  __classPrivateFieldSet(this, _BridgeStatusController_fetchFn, fetchFn, "f");
576
590
  __classPrivateFieldSet(this, _BridgeStatusController_addTransactionFn, addTransactionFn, "f");
577
- __classPrivateFieldSet(this, _BridgeStatusController_addUserOperationFromTransactionFn, addUserOperationFromTransactionFn, "f");
591
+ __classPrivateFieldSet(this, _BridgeStatusController_addTransactionBatchFn, addTransactionBatchFn, "f");
592
+ __classPrivateFieldSet(this, _BridgeStatusController_updateTransactionFn, updateTransactionFn, "f");
578
593
  __classPrivateFieldSet(this, _BridgeStatusController_estimateGasFeeFn, estimateGasFeeFn, "f");
579
594
  __classPrivateFieldSet(this, _BridgeStatusController_config, {
580
595
  customBridgeApiBaseUrl: config?.customBridgeApiBaseUrl ?? constants_1.BRIDGE_PROD_API_BASE_URL,
@@ -590,16 +605,33 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
590
605
  this.messagingSystem.subscribe('TransactionController:transactionFailed', ({ transactionMeta }) => {
591
606
  const { type, status, id } = transactionMeta;
592
607
  if (type &&
593
- [transaction_controller_1.TransactionType.bridge, transaction_controller_1.TransactionType.swap].includes(type) &&
594
- ![transaction_controller_1.TransactionStatus.signed, transaction_controller_1.TransactionStatus.approved].includes(status)) {
595
- __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, id, (0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(transactionMeta));
608
+ [
609
+ transaction_controller_1.TransactionType.bridge,
610
+ transaction_controller_1.TransactionType.swap,
611
+ transaction_controller_1.TransactionType.bridgeApproval,
612
+ transaction_controller_1.TransactionType.swapApproval,
613
+ ].includes(type) &&
614
+ [
615
+ transaction_controller_1.TransactionStatus.failed,
616
+ transaction_controller_1.TransactionStatus.dropped,
617
+ transaction_controller_1.TransactionStatus.rejected,
618
+ ].includes(status)) {
619
+ // Mark tx as failed in txHistory
620
+ __classPrivateFieldGet(this, _BridgeStatusController_markTxAsFailed, "f").call(this, transactionMeta);
621
+ // Track failed event
622
+ if (status !== transaction_controller_1.TransactionStatus.rejected) {
623
+ __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, id, (0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(transactionMeta));
624
+ }
596
625
  }
597
626
  });
598
627
  this.messagingSystem.subscribe('TransactionController:transactionConfirmed', (transactionMeta) => {
599
- const { type, id } = transactionMeta;
628
+ const { type, id, chainId } = transactionMeta;
600
629
  if (type === transaction_controller_1.TransactionType.swap) {
601
630
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, id, (0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(transactionMeta));
602
631
  }
632
+ if (type === transaction_controller_1.TransactionType.bridge && !(0, bridge_controller_1.isSolanaChainId)(chainId)) {
633
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, id);
634
+ }
603
635
  });
604
636
  // If you close the extension, but keep the browser open, the polling continues
605
637
  // If you close the browser, the polling stops
@@ -608,7 +640,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
608
640
  }
609
641
  }
610
642
  exports.BridgeStatusController = BridgeStatusController;
611
- _BridgeStatusController_pollingTokensByTxMetaId = new WeakMap(), _BridgeStatusController_clientId = new WeakMap(), _BridgeStatusController_fetchFn = new WeakMap(), _BridgeStatusController_config = new WeakMap(), _BridgeStatusController_addTransactionFn = new WeakMap(), _BridgeStatusController_estimateGasFeeFn = new WeakMap(), _BridgeStatusController_addUserOperationFromTransactionFn = new WeakMap(), _BridgeStatusController_trace = new WeakMap(), _BridgeStatusController_restartPollingForIncompleteHistoryItems = new WeakMap(), _BridgeStatusController_addTxToHistory = new WeakMap(), _BridgeStatusController_fetchBridgeTxStatus = new WeakMap(), _BridgeStatusController_getSrcTxHash = new WeakMap(), _BridgeStatusController_updateSrcTxHash = new WeakMap(), _BridgeStatusController_wipeBridgeStatusByChainId = new WeakMap(), _BridgeStatusController_handleSolanaTx = new WeakMap(), _BridgeStatusController_waitForHashAndReturnFinalTxMeta = new WeakMap(), _BridgeStatusController_handleApprovalTx = new WeakMap(), _BridgeStatusController_handleEvmSmartTransaction = new WeakMap(), _BridgeStatusController_handleEvmTransaction = new WeakMap(), _BridgeStatusController_handleUSDTAllowanceReset = new WeakMap(), _BridgeStatusController_calculateGasFees = new WeakMap(), _BridgeStatusController_trackUnifiedSwapBridgeEvent = new WeakMap(), _BridgeStatusController_instances = new WeakSet(), _BridgeStatusController_getMultichainSelectedAccount = function _BridgeStatusController_getMultichainSelectedAccount() {
643
+ _BridgeStatusController_pollingTokensByTxMetaId = new WeakMap(), _BridgeStatusController_clientId = new WeakMap(), _BridgeStatusController_fetchFn = new WeakMap(), _BridgeStatusController_config = new WeakMap(), _BridgeStatusController_addTransactionFn = new WeakMap(), _BridgeStatusController_addTransactionBatchFn = new WeakMap(), _BridgeStatusController_updateTransactionFn = new WeakMap(), _BridgeStatusController_estimateGasFeeFn = new WeakMap(), _BridgeStatusController_trace = new WeakMap(), _BridgeStatusController_markTxAsFailed = new WeakMap(), _BridgeStatusController_restartPollingForIncompleteHistoryItems = new WeakMap(), _BridgeStatusController_addTxToHistory = new WeakMap(), _BridgeStatusController_startPollingForTxId = new WeakMap(), _BridgeStatusController_fetchBridgeTxStatus = new WeakMap(), _BridgeStatusController_getSrcTxHash = new WeakMap(), _BridgeStatusController_updateSrcTxHash = new WeakMap(), _BridgeStatusController_wipeBridgeStatusByChainId = new WeakMap(), _BridgeStatusController_handleSolanaTx = new WeakMap(), _BridgeStatusController_waitForHashAndReturnFinalTxMeta = new WeakMap(), _BridgeStatusController_handleApprovalTx = new WeakMap(), _BridgeStatusController_handleEvmTransaction = new WeakMap(), _BridgeStatusController_handleUSDTAllowanceReset = new WeakMap(), _BridgeStatusController_calculateGasFees = new WeakMap(), _BridgeStatusController_handleEvmTransactionBatch = new WeakMap(), _BridgeStatusController_trackUnifiedSwapBridgeEvent = new WeakMap(), _BridgeStatusController_instances = new WeakSet(), _BridgeStatusController_getMultichainSelectedAccount = function _BridgeStatusController_getMultichainSelectedAccount() {
612
644
  return this.messagingSystem.call('AccountsController:getSelectedMultichainAccount');
613
645
  }, _BridgeStatusController_getMultichainSelectedAccountAddress = function _BridgeStatusController_getMultichainSelectedAccountAddress() {
614
646
  return __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_getMultichainSelectedAccount).call(this)?.address ?? '';