@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
@@ -9,20 +9,18 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  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");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- 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
- import { formatChainIdToHex, getEthUsdtResetData, isEthUsdt, isSolanaChainId, StatusTypes, UnifiedSwapBridgeEventName, getActionType, formatChainIdToCaip, isCrossChain, getBridgeFeatureFlags, isHardwareWallet } from "@metamask/bridge-controller";
12
+ 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;
13
+ import { formatChainIdToHex, isSolanaChainId, StatusTypes, UnifiedSwapBridgeEventName, getActionType, formatChainIdToCaip, isCrossChain, isHardwareWallet } from "@metamask/bridge-controller";
14
14
  import { toHex } from "@metamask/controller-utils";
15
- import { EthAccountType, SolScope } from "@metamask/keyring-api";
16
15
  import { StaticIntervalPollingController } from "@metamask/polling-controller";
17
16
  import { TransactionStatus, TransactionType } from "@metamask/transaction-controller";
18
17
  import { numberToHex } from "@metamask/utils";
19
- import { BigNumber } from "bignumber.js";
20
18
  import { BRIDGE_PROD_API_BASE_URL, BRIDGE_STATUS_CONTROLLER_NAME, DEFAULT_BRIDGE_STATUS_CONTROLLER_STATE, REFRESH_INTERVAL_MS, TraceName } from "./constants.mjs";
21
19
  import { BridgeClientId } from "./types.mjs";
22
20
  import { fetchBridgeTxStatus, getStatusRequestWithSrcTxHash } from "./utils/bridge-status.mjs";
23
21
  import { getTxGasEstimates } from "./utils/gas.mjs";
24
22
  import { getFinalizedTxProperties, getPriceImpactFromQuote, getRequestMetadataFromHistory, getRequestParamFromHistory, getTradeDataFromHistory, getTradeDataFromQuote, getEVMTxPropertiesFromTransactionMeta, getTxStatusesFromHistory } from "./utils/metrics.mjs";
25
- import { getClientRequest, getKeyringRequest, getStatusRequestParams, getTxMetaFields, handleLineaDelay, handleSolanaTxResponse } from "./utils/transaction.mjs";
23
+ import { findAndUpdateTransactionsInBatch, getAddTransactionBatchParams, getClientRequest, getStatusRequestParams, getUSDTAllowanceResetTx, handleLineaDelay, handleSolanaTxResponse } from "./utils/transaction.mjs";
26
24
  import { generateActionId } from "./utils/transaction.mjs";
27
25
  const metadata = {
28
26
  // We want to persist the bridge status state so that we can show the proper data for the Activity list
@@ -33,7 +31,7 @@ const metadata = {
33
31
  },
34
32
  };
35
33
  export class BridgeStatusController extends StaticIntervalPollingController() {
36
- constructor({ messenger, state, clientId, fetchFn, addTransactionFn, addUserOperationFromTransactionFn, estimateGasFeeFn, config, traceFn, }) {
34
+ constructor({ messenger, state, clientId, fetchFn, addTransactionFn, addTransactionBatchFn, updateTransactionFn, estimateGasFeeFn, config, traceFn, }) {
37
35
  super({
38
36
  name: BRIDGE_STATUS_CONTROLLER_NAME,
39
37
  metadata,
@@ -50,9 +48,22 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
50
48
  _BridgeStatusController_fetchFn.set(this, void 0);
51
49
  _BridgeStatusController_config.set(this, void 0);
52
50
  _BridgeStatusController_addTransactionFn.set(this, void 0);
51
+ _BridgeStatusController_addTransactionBatchFn.set(this, void 0);
52
+ _BridgeStatusController_updateTransactionFn.set(this, void 0);
53
53
  _BridgeStatusController_estimateGasFeeFn.set(this, void 0);
54
- _BridgeStatusController_addUserOperationFromTransactionFn.set(this, void 0);
55
54
  _BridgeStatusController_trace.set(this, void 0);
55
+ // Mark tx as failed in txHistory if either the approval or trade fails
56
+ _BridgeStatusController_markTxAsFailed.set(this, ({ id }) => {
57
+ const txHistoryKey = this.state.txHistory[id]
58
+ ? id
59
+ : Object.keys(this.state.txHistory).find((key) => this.state.txHistory[key].approvalTxId === id);
60
+ if (!txHistoryKey) {
61
+ return;
62
+ }
63
+ this.update((statusState) => {
64
+ statusState.txHistory[txHistoryKey].status.status = StatusTypes.FAILED;
65
+ });
66
+ });
56
67
  this.resetState = () => {
57
68
  this.update((state) => {
58
69
  state.txHistory = DEFAULT_BRIDGE_STATUS_CONTROLLER_STATE.txHistory;
@@ -81,8 +92,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
81
92
  historyItem.status.status === StatusTypes.UNKNOWN)
82
93
  .filter((historyItem) => {
83
94
  // Check if we are already polling this tx, if so, skip restarting polling for that
84
- const srcTxMetaId = historyItem.txMetaId;
85
- const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[srcTxMetaId];
95
+ const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[historyItem.txMetaId];
86
96
  return !pollingToken;
87
97
  })
88
98
  // Swap txs don't need to have their statuses polled
@@ -94,9 +104,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
94
104
  const bridgeTxMetaId = historyItem.txMetaId;
95
105
  // We manually call startPolling() here rather than go through startPollingForBridgeTxStatus()
96
106
  // because we don't want to overwrite the existing historyItem in state
97
- __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId] = this.startPolling({
98
- bridgeTxMetaId,
99
- });
107
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeTxMetaId);
100
108
  });
101
109
  });
102
110
  _BridgeStatusController_addTxToHistory.set(this, (startPollingForBridgeTxStatusArgs) => {
@@ -106,6 +114,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
106
114
  // We know it's in progress but not the exact status yet
107
115
  const txHistoryItem = {
108
116
  txMetaId: bridgeTxMeta.id,
117
+ batchId: bridgeTxMeta.batchId,
109
118
  quote: quoteResponse.quote,
110
119
  startTime,
111
120
  estimatedProcessingTimeInSeconds: quoteResponse.estimatedProcessingTimeInSeconds,
@@ -137,20 +146,33 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
137
146
  state.txHistory[bridgeTxMeta.id] = txHistoryItem;
138
147
  });
139
148
  });
149
+ _BridgeStatusController_startPollingForTxId.set(this, (txId) => {
150
+ // If we are already polling for this tx, stop polling for it before restarting
151
+ const existingPollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId];
152
+ if (existingPollingToken) {
153
+ this.stopPollingByPollingToken(existingPollingToken);
154
+ }
155
+ const txHistoryItem = this.state.txHistory[txId];
156
+ if (!txHistoryItem) {
157
+ return;
158
+ }
159
+ const { quote } = txHistoryItem;
160
+ const isBridgeTx = isCrossChain(quote.srcChainId, quote.destChainId);
161
+ if (isBridgeTx) {
162
+ __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId] = this.startPolling({
163
+ bridgeTxMetaId: txId,
164
+ });
165
+ }
166
+ });
140
167
  /**
141
- * Starts polling for the bridge tx status
168
+ * Adds tx to history and starts polling for the bridge tx status
142
169
  *
143
170
  * @param txHistoryMeta - The parameters for creating the history item
144
171
  */
145
172
  this.startPollingForBridgeTxStatus = (txHistoryMeta) => {
146
- const { quoteResponse, bridgeTxMeta } = txHistoryMeta;
173
+ const { bridgeTxMeta } = txHistoryMeta;
147
174
  __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
148
- const isBridgeTx = isCrossChain(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
149
- if (isBridgeTx) {
150
- __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMeta.id] = this.startPolling({
151
- bridgeTxMetaId: bridgeTxMeta.id,
152
- });
153
- }
175
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeTxMeta.id);
154
176
  };
155
177
  // This will be called after you call this.startPolling()
156
178
  // The args passed in are the args you passed in to startPolling()
@@ -269,11 +291,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
269
291
  if (!selectedAccount?.metadata?.snap?.id) {
270
292
  throw new Error('Failed to submit cross-chain swap transaction: undefined snap id');
271
293
  }
272
- const bridgeFeatureFlags = getBridgeFeatureFlags(this.messagingSystem);
273
- const request = bridgeFeatureFlags?.chains?.[SolScope.Mainnet]
274
- ?.isSnapConfirmationEnabled
275
- ? getKeyringRequest(quoteResponse, selectedAccount)
276
- : getClientRequest(quoteResponse, selectedAccount);
294
+ const request = getClientRequest(quoteResponse, selectedAccount);
277
295
  const requestResponse = (await this.messagingSystem.call('SnapController:handleRequest', request));
278
296
  // The extension client actually redirects before it can do anytyhing with this meta
279
297
  const txMeta = handleSolanaTxResponse(requestResponse, quoteResponse, selectedAccount);
@@ -291,7 +309,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
291
309
  }
292
310
  return finalTransactionMeta;
293
311
  });
294
- _BridgeStatusController_handleApprovalTx.set(this, async (isBridgeTx, quoteResponse, requireApproval = false) => {
312
+ _BridgeStatusController_handleApprovalTx.set(this, async (isBridgeTx, quoteResponse) => {
295
313
  const { approval } = quoteResponse;
296
314
  if (approval) {
297
315
  const approveTx = async () => {
@@ -301,8 +319,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
301
319
  ? TransactionType.bridgeApproval
302
320
  : TransactionType.swapApproval,
303
321
  trade: approval,
304
- quoteResponse,
305
- requireApproval,
306
322
  });
307
323
  await handleLineaDelay(quoteResponse);
308
324
  return approvalTxMeta;
@@ -319,31 +335,16 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
319
335
  }
320
336
  return undefined;
321
337
  });
322
- _BridgeStatusController_handleEvmSmartTransaction.set(this, async ({ isBridgeTx, trade, quoteResponse, approvalTxId, requireApproval = false, }) => {
323
- return await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
324
- transactionType: isBridgeTx
325
- ? TransactionType.bridge
326
- : TransactionType.swap,
327
- trade,
328
- quoteResponse,
329
- approvalTxId,
330
- shouldWaitForHash: false,
331
- requireApproval,
332
- });
333
- });
334
338
  /**
335
339
  * Submits an EVM transaction to the TransactionController
336
340
  *
337
341
  * @param params - The parameters for the transaction
338
342
  * @param params.transactionType - The type of transaction to submit
339
343
  * @param params.trade - The trade data to confirm
340
- * @param params.quoteResponse - The quote response
341
- * @param params.approvalTxId - The tx id of the approval tx
342
- * @param params.shouldWaitForHash - Whether to wait for the hash of the transaction
343
344
  * @param params.requireApproval - Whether to require approval for the transaction
344
345
  * @returns The transaction meta
345
346
  */
346
- _BridgeStatusController_handleEvmTransaction.set(this, async ({ transactionType, trade, quoteResponse, approvalTxId, shouldWaitForHash = true, requireApproval = false, }) => {
347
+ _BridgeStatusController_handleEvmTransaction.set(this, async ({ transactionType, trade, requireApproval = false, }) => {
347
348
  const actionId = generateActionId().toString();
348
349
  const selectedAccount = this.messagingSystem.call('AccountsController:getAccountByAddress', trade.from);
349
350
  if (!selectedAccount) {
@@ -368,47 +369,16 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
368
369
  ...transactionParams,
369
370
  ...(await __classPrivateFieldGet(this, _BridgeStatusController_calculateGasFees, "f").call(this, transactionParams, networkClientId, hexChainId)),
370
371
  };
371
- let result;
372
- let transactionMeta;
373
- const isSmartContractAccount = selectedAccount.type === EthAccountType.Erc4337;
374
- if (isSmartContractAccount && __classPrivateFieldGet(this, _BridgeStatusController_addUserOperationFromTransactionFn, "f")) {
375
- const smartAccountTxResult = await __classPrivateFieldGet(this, _BridgeStatusController_addUserOperationFromTransactionFn, "f").call(this, transactionParamsWithMaxGas, requestOptions);
376
- result = smartAccountTxResult.transactionHash;
377
- transactionMeta = {
378
- ...requestOptions,
379
- chainId: hexChainId,
380
- txParams: transactionParamsWithMaxGas,
381
- time: Date.now(),
382
- id: smartAccountTxResult.id,
383
- status: TransactionStatus.confirmed,
384
- };
385
- }
386
- else {
387
- const addTransactionResult = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionFn, "f").call(this, transactionParamsWithMaxGas, requestOptions);
388
- result = addTransactionResult.result;
389
- transactionMeta = addTransactionResult.transactionMeta;
390
- }
391
- if (shouldWaitForHash) {
392
- return await __classPrivateFieldGet(this, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, "f").call(this, result);
393
- }
394
- return {
395
- ...getTxMetaFields(quoteResponse, approvalTxId),
396
- ...transactionMeta,
397
- };
372
+ const { result } = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionFn, "f").call(this, transactionParamsWithMaxGas, requestOptions);
373
+ return await __classPrivateFieldGet(this, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, "f").call(this, result);
398
374
  });
399
375
  _BridgeStatusController_handleUSDTAllowanceReset.set(this, async (quoteResponse) => {
400
- const hexChainId = formatChainIdToHex(quoteResponse.quote.srcChainId);
401
- if (quoteResponse.approval &&
402
- isEthUsdt(hexChainId, quoteResponse.quote.srcAsset.address)) {
403
- const allowance = new BigNumber(await this.messagingSystem.call('BridgeController:getBridgeERC20Allowance', quoteResponse.quote.srcAsset.address, hexChainId));
404
- const shouldResetApproval = allowance.lt(quoteResponse.sentAmount.amount) && allowance.gt(0);
405
- if (shouldResetApproval) {
406
- await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
407
- transactionType: TransactionType.bridgeApproval,
408
- trade: { ...quoteResponse.approval, data: getEthUsdtResetData() },
409
- quoteResponse,
410
- });
411
- }
376
+ const resetApproval = await getUSDTAllowanceResetTx(this.messagingSystem, quoteResponse);
377
+ if (resetApproval) {
378
+ await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
379
+ transactionType: TransactionType.bridgeApproval,
380
+ trade: resetApproval,
381
+ });
412
382
  }
413
383
  });
414
384
  _BridgeStatusController_calculateGasFees.set(this, async (transactionParams, networkClientId, chainId) => {
@@ -429,6 +399,42 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
429
399
  gas: maxGasLimit,
430
400
  };
431
401
  });
402
+ /**
403
+ * Submits batched EVM transactions to the TransactionController
404
+ *
405
+ * @param args - The parameters for the transaction
406
+ * @param args.isBridgeTx - Whether the transaction is a bridge transaction
407
+ * @param args.trade - The trade data to confirm
408
+ * @param args.approval - The approval data to confirm
409
+ * @param args.resetApproval - The ethereum:USDT reset approval data to confirm
410
+ * @param args.quoteResponse - The quote response
411
+ * @param args.requireApproval - Whether to require approval for the transaction
412
+ * @returns The approvalMeta and tradeMeta for the batched transaction
413
+ */
414
+ _BridgeStatusController_handleEvmTransactionBatch.set(this, async (args) => {
415
+ const transactionParams = await getAddTransactionBatchParams({
416
+ messagingSystem: this.messagingSystem,
417
+ estimateGasFeeFn: __classPrivateFieldGet(this, _BridgeStatusController_estimateGasFeeFn, "f"),
418
+ ...args,
419
+ });
420
+ const txDataByType = {
421
+ [TransactionType.bridgeApproval]: transactionParams.transactions.find(({ type }) => type === TransactionType.bridgeApproval)?.params.data,
422
+ [TransactionType.swapApproval]: transactionParams.transactions.find(({ type }) => type === TransactionType.swapApproval)?.params.data,
423
+ [TransactionType.bridge]: transactionParams.transactions.find(({ type }) => type === TransactionType.bridge)?.params.data,
424
+ [TransactionType.swap]: transactionParams.transactions.find(({ type }) => type === TransactionType.swap)?.params.data,
425
+ };
426
+ const { batchId } = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionBatchFn, "f").call(this, transactionParams);
427
+ const { approvalMeta, tradeMeta } = findAndUpdateTransactionsInBatch({
428
+ messagingSystem: this.messagingSystem,
429
+ updateTransactionFn: __classPrivateFieldGet(this, _BridgeStatusController_updateTransactionFn, "f"),
430
+ batchId,
431
+ txDataByType,
432
+ });
433
+ if (!tradeMeta) {
434
+ throw new Error('Failed to update cross-chain swap transaction batch: tradeMeta not found');
435
+ }
436
+ return { approvalMeta, tradeMeta };
437
+ });
432
438
  /**
433
439
  * Submits a cross-chain swap transaction
434
440
  *
@@ -451,7 +457,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
451
457
  // Emit Submitted event after submit button is clicked
452
458
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Submitted, undefined, preConfirmationProperties);
453
459
  let txMeta;
454
- let approvalTime, approvalTxId;
460
+ let approvalTxId;
461
+ const startTime = Date.now();
455
462
  const isBridgeTx = isCrossChain(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
456
463
  // Submit SOLANA tx
457
464
  if (isSolanaChainId(quoteResponse.quote.srcChainId) &&
@@ -483,10 +490,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
483
490
  // Extension does not have this issue
484
491
  const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE &&
485
492
  isHardwareWallet(__classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_getMultichainSelectedAccount).call(this));
486
- // Set approval time and id if an approval tx is needed
487
- const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, isBridgeTx, quoteResponse, requireApproval);
488
- approvalTime = approvalTxMeta?.time;
489
- approvalTxId = approvalTxMeta?.id;
490
493
  // Handle smart transactions if enabled
491
494
  txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, {
492
495
  name: isBridgeTx
@@ -496,27 +499,34 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
496
499
  srcChainId: formatChainIdToCaip(quoteResponse.quote.srcChainId),
497
500
  stxEnabled: isStxEnabledOnClient,
498
501
  },
499
- }, async () => isStxEnabledOnClient
500
- ? await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmSmartTransaction, "f").call(this, {
501
- isBridgeTx,
502
- trade: quoteResponse.trade,
503
- quoteResponse,
504
- approvalTxId,
505
- requireApproval,
506
- })
507
- : await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
502
+ }, async () => {
503
+ if (isStxEnabledOnClient) {
504
+ const { tradeMeta, approvalMeta } = await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransactionBatch, "f").call(this, {
505
+ isBridgeTx,
506
+ resetApproval: await getUSDTAllowanceResetTx(this.messagingSystem, quoteResponse),
507
+ approval: quoteResponse.approval,
508
+ trade: quoteResponse.trade,
509
+ quoteResponse,
510
+ requireApproval,
511
+ });
512
+ approvalTxId = approvalMeta?.id;
513
+ return tradeMeta;
514
+ }
515
+ // Set approval time and id if an approval tx is needed
516
+ const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, isBridgeTx, quoteResponse);
517
+ approvalTxId = approvalTxMeta?.id;
518
+ return await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
508
519
  transactionType: isBridgeTx
509
520
  ? TransactionType.bridge
510
521
  : TransactionType.swap,
511
522
  trade: quoteResponse.trade,
512
- quoteResponse,
513
- approvalTxId,
514
523
  requireApproval,
515
- }));
524
+ });
525
+ });
516
526
  }
517
527
  try {
518
- // Start polling for bridge tx status
519
- this.startPollingForBridgeTxStatus({
528
+ // Add swap or bridge tx to history
529
+ __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
520
530
  bridgeTxMeta: txMeta,
521
531
  statusRequest: {
522
532
  ...getStatusRequestParams(quoteResponse),
@@ -525,12 +535,16 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
525
535
  quoteResponse,
526
536
  slippagePercentage: 0,
527
537
  isStxEnabled: isStxEnabledOnClient,
528
- startTime: approvalTime ?? Date.now(),
538
+ startTime,
529
539
  approvalTxId,
530
540
  });
531
- // Track Solana Swap completed event
532
- if (isSolanaChainId(quoteResponse.quote.srcChainId) && !isBridgeTx) {
533
- __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, txMeta.id);
541
+ if (isSolanaChainId(quoteResponse.quote.srcChainId)) {
542
+ // Start polling for bridge tx status
543
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, txMeta.id);
544
+ // Track Solana Swap completed event
545
+ if (!isBridgeTx) {
546
+ __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, txMeta.id);
547
+ }
534
548
  }
535
549
  }
536
550
  catch {
@@ -571,7 +585,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
571
585
  __classPrivateFieldSet(this, _BridgeStatusController_clientId, clientId, "f");
572
586
  __classPrivateFieldSet(this, _BridgeStatusController_fetchFn, fetchFn, "f");
573
587
  __classPrivateFieldSet(this, _BridgeStatusController_addTransactionFn, addTransactionFn, "f");
574
- __classPrivateFieldSet(this, _BridgeStatusController_addUserOperationFromTransactionFn, addUserOperationFromTransactionFn, "f");
588
+ __classPrivateFieldSet(this, _BridgeStatusController_addTransactionBatchFn, addTransactionBatchFn, "f");
589
+ __classPrivateFieldSet(this, _BridgeStatusController_updateTransactionFn, updateTransactionFn, "f");
575
590
  __classPrivateFieldSet(this, _BridgeStatusController_estimateGasFeeFn, estimateGasFeeFn, "f");
576
591
  __classPrivateFieldSet(this, _BridgeStatusController_config, {
577
592
  customBridgeApiBaseUrl: config?.customBridgeApiBaseUrl ?? BRIDGE_PROD_API_BASE_URL,
@@ -587,16 +602,33 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
587
602
  this.messagingSystem.subscribe('TransactionController:transactionFailed', ({ transactionMeta }) => {
588
603
  const { type, status, id } = transactionMeta;
589
604
  if (type &&
590
- [TransactionType.bridge, TransactionType.swap].includes(type) &&
591
- ![TransactionStatus.signed, TransactionStatus.approved].includes(status)) {
592
- __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed, id, getEVMTxPropertiesFromTransactionMeta(transactionMeta));
605
+ [
606
+ TransactionType.bridge,
607
+ TransactionType.swap,
608
+ TransactionType.bridgeApproval,
609
+ TransactionType.swapApproval,
610
+ ].includes(type) &&
611
+ [
612
+ TransactionStatus.failed,
613
+ TransactionStatus.dropped,
614
+ TransactionStatus.rejected,
615
+ ].includes(status)) {
616
+ // Mark tx as failed in txHistory
617
+ __classPrivateFieldGet(this, _BridgeStatusController_markTxAsFailed, "f").call(this, transactionMeta);
618
+ // Track failed event
619
+ if (status !== TransactionStatus.rejected) {
620
+ __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed, id, getEVMTxPropertiesFromTransactionMeta(transactionMeta));
621
+ }
593
622
  }
594
623
  });
595
624
  this.messagingSystem.subscribe('TransactionController:transactionConfirmed', (transactionMeta) => {
596
- const { type, id } = transactionMeta;
625
+ const { type, id, chainId } = transactionMeta;
597
626
  if (type === TransactionType.swap) {
598
627
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, id, getEVMTxPropertiesFromTransactionMeta(transactionMeta));
599
628
  }
629
+ if (type === TransactionType.bridge && !isSolanaChainId(chainId)) {
630
+ __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, id);
631
+ }
600
632
  });
601
633
  // If you close the extension, but keep the browser open, the polling continues
602
634
  // If you close the browser, the polling stops
@@ -604,7 +636,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
604
636
  __classPrivateFieldGet(this, _BridgeStatusController_restartPollingForIncompleteHistoryItems, "f").call(this);
605
637
  }
606
638
  }
607
- _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() {
639
+ _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() {
608
640
  return this.messagingSystem.call('AccountsController:getSelectedMultichainAccount');
609
641
  }, _BridgeStatusController_getMultichainSelectedAccountAddress = function _BridgeStatusController_getMultichainSelectedAccountAddress() {
610
642
  return __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_getMultichainSelectedAccount).call(this)?.address ?? '';