@metamask/bridge-status-controller 71.2.1 → 72.0.1

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 (126) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/dist/bridge-status-controller-method-action-types.cjs.map +1 -1
  3. package/dist/bridge-status-controller-method-action-types.d.cts +5 -1
  4. package/dist/bridge-status-controller-method-action-types.d.cts.map +1 -1
  5. package/dist/bridge-status-controller-method-action-types.d.mts +5 -1
  6. package/dist/bridge-status-controller-method-action-types.d.mts.map +1 -1
  7. package/dist/bridge-status-controller-method-action-types.mjs.map +1 -1
  8. package/dist/bridge-status-controller.cjs +161 -366
  9. package/dist/bridge-status-controller.cjs.map +1 -1
  10. package/dist/bridge-status-controller.d.cts +27 -7
  11. package/dist/bridge-status-controller.d.cts.map +1 -1
  12. package/dist/bridge-status-controller.d.mts +27 -7
  13. package/dist/bridge-status-controller.d.mts.map +1 -1
  14. package/dist/bridge-status-controller.mjs +162 -370
  15. package/dist/bridge-status-controller.mjs.map +1 -1
  16. package/dist/index.cjs +4 -1
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +1 -0
  19. package/dist/index.d.cts.map +1 -1
  20. package/dist/index.d.mts +1 -0
  21. package/dist/index.d.mts.map +1 -1
  22. package/dist/index.mjs +1 -0
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/strategy/batch-sell-strategy.cjs +103 -0
  25. package/dist/strategy/batch-sell-strategy.cjs.map +1 -0
  26. package/dist/strategy/batch-sell-strategy.d.cts +10 -0
  27. package/dist/strategy/batch-sell-strategy.d.cts.map +1 -0
  28. package/dist/strategy/batch-sell-strategy.d.mts +10 -0
  29. package/dist/strategy/batch-sell-strategy.d.mts.map +1 -0
  30. package/dist/strategy/batch-sell-strategy.mjs +99 -0
  31. package/dist/strategy/batch-sell-strategy.mjs.map +1 -0
  32. package/dist/strategy/batch-strategy.cjs +74 -0
  33. package/dist/strategy/batch-strategy.cjs.map +1 -0
  34. package/dist/strategy/batch-strategy.d.cts +10 -0
  35. package/dist/strategy/batch-strategy.d.cts.map +1 -0
  36. package/dist/strategy/batch-strategy.d.mts +10 -0
  37. package/dist/strategy/batch-strategy.d.mts.map +1 -0
  38. package/dist/strategy/batch-strategy.mjs +70 -0
  39. package/dist/strategy/batch-strategy.mjs.map +1 -0
  40. package/dist/strategy/evm-strategy.cjs +149 -0
  41. package/dist/strategy/evm-strategy.cjs.map +1 -0
  42. package/dist/strategy/evm-strategy.d.cts +38 -0
  43. package/dist/strategy/evm-strategy.d.cts.map +1 -0
  44. package/dist/strategy/evm-strategy.d.mts +38 -0
  45. package/dist/strategy/evm-strategy.d.mts.map +1 -0
  46. package/dist/strategy/evm-strategy.mjs +143 -0
  47. package/dist/strategy/evm-strategy.mjs.map +1 -0
  48. package/dist/strategy/index.cjs +70 -0
  49. package/dist/strategy/index.cjs.map +1 -0
  50. package/dist/strategy/index.d.cts +12 -0
  51. package/dist/strategy/index.d.cts.map +1 -0
  52. package/dist/strategy/index.d.mts +12 -0
  53. package/dist/strategy/index.d.mts.map +1 -0
  54. package/dist/strategy/index.mjs +68 -0
  55. package/dist/strategy/index.mjs.map +1 -0
  56. package/dist/strategy/intent-strategy.cjs +160 -0
  57. package/dist/strategy/intent-strategy.cjs.map +1 -0
  58. package/dist/strategy/intent-strategy.d.cts +17 -0
  59. package/dist/strategy/intent-strategy.d.cts.map +1 -0
  60. package/dist/strategy/intent-strategy.d.mts +17 -0
  61. package/dist/strategy/intent-strategy.d.mts.map +1 -0
  62. package/dist/strategy/intent-strategy.mjs +156 -0
  63. package/dist/strategy/intent-strategy.mjs.map +1 -0
  64. package/dist/strategy/non-evm-strategy.cjs +80 -0
  65. package/dist/strategy/non-evm-strategy.cjs.map +1 -0
  66. package/dist/strategy/non-evm-strategy.d.cts +15 -0
  67. package/dist/strategy/non-evm-strategy.d.cts.map +1 -0
  68. package/dist/strategy/non-evm-strategy.d.mts +15 -0
  69. package/dist/strategy/non-evm-strategy.d.mts.map +1 -0
  70. package/dist/strategy/non-evm-strategy.mjs +76 -0
  71. package/dist/strategy/non-evm-strategy.mjs.map +1 -0
  72. package/dist/strategy/types.cjs +13 -0
  73. package/dist/strategy/types.cjs.map +1 -0
  74. package/dist/strategy/types.d.cts +77 -0
  75. package/dist/strategy/types.d.cts.map +1 -0
  76. package/dist/strategy/types.d.mts +77 -0
  77. package/dist/strategy/types.d.mts.map +1 -0
  78. package/dist/strategy/types.mjs +10 -0
  79. package/dist/strategy/types.mjs.map +1 -0
  80. package/dist/types.cjs.map +1 -1
  81. package/dist/types.d.cts +41 -6
  82. package/dist/types.d.cts.map +1 -1
  83. package/dist/types.d.mts +41 -6
  84. package/dist/types.d.mts.map +1 -1
  85. package/dist/types.mjs.map +1 -1
  86. package/dist/utils/bridge.cjs +5 -1
  87. package/dist/utils/bridge.cjs.map +1 -1
  88. package/dist/utils/bridge.d.cts +2 -2
  89. package/dist/utils/bridge.d.cts.map +1 -1
  90. package/dist/utils/bridge.d.mts +2 -2
  91. package/dist/utils/bridge.d.mts.map +1 -1
  92. package/dist/utils/bridge.mjs +3 -0
  93. package/dist/utils/bridge.mjs.map +1 -1
  94. package/dist/utils/history.cjs +72 -20
  95. package/dist/utils/history.cjs.map +1 -1
  96. package/dist/utils/history.d.cts +19 -5
  97. package/dist/utils/history.d.cts.map +1 -1
  98. package/dist/utils/history.d.mts +19 -5
  99. package/dist/utils/history.d.mts.map +1 -1
  100. package/dist/utils/history.mjs +69 -19
  101. package/dist/utils/history.mjs.map +1 -1
  102. package/dist/utils/metrics.cjs +10 -7
  103. package/dist/utils/metrics.cjs.map +1 -1
  104. package/dist/utils/metrics.d.cts +7 -6
  105. package/dist/utils/metrics.d.cts.map +1 -1
  106. package/dist/utils/metrics.d.mts +7 -6
  107. package/dist/utils/metrics.d.mts.map +1 -1
  108. package/dist/utils/metrics.mjs +10 -7
  109. package/dist/utils/metrics.mjs.map +1 -1
  110. package/dist/utils/trace.cjs +4 -4
  111. package/dist/utils/trace.cjs.map +1 -1
  112. package/dist/utils/trace.d.cts +2 -2
  113. package/dist/utils/trace.d.cts.map +1 -1
  114. package/dist/utils/trace.d.mts +2 -2
  115. package/dist/utils/trace.d.mts.map +1 -1
  116. package/dist/utils/trace.mjs +4 -4
  117. package/dist/utils/trace.mjs.map +1 -1
  118. package/dist/utils/transaction.cjs +222 -253
  119. package/dist/utils/transaction.cjs.map +1 -1
  120. package/dist/utils/transaction.d.cts +68 -147
  121. package/dist/utils/transaction.d.cts.map +1 -1
  122. package/dist/utils/transaction.d.mts +68 -147
  123. package/dist/utils/transaction.d.mts.map +1 -1
  124. package/dist/utils/transaction.mjs +213 -248
  125. package/dist/utils/transaction.mjs.map +1 -1
  126. package/package.json +2 -2
@@ -1,88 +1,62 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.submitEvmTransaction = exports.addTransactionBatch = exports.findAndUpdateTransactionsInBatch = exports.getAddTransactionBatchParams = exports.toBatchTxParams = exports.waitForTxConfirmation = exports.handleMobileHardwareWalletDelay = exports.handleApprovalDelay = exports.addSyntheticTransaction = exports.generateActionId = exports.addTransaction = exports.checkIsDelegatedAccount = exports.updateTransaction = exports.getTransactionMetaByHash = exports.getTransactionMetaById = exports.getTransactions = exports.calculateGasFees = exports.getTxGasEstimates = exports.getGasFeeEstimates = exports.isCrossChainTx = void 0;
3
+ exports.updateTransactionsInBatch = exports.findAllTransactionsInBatch = exports.getAddTransactionBatchParams = exports.toTransactionParams = exports.toQuoteAndTxMetadataBatch = exports.toQuoteAndTxMetadata = exports.waitForTxConfirmation = exports.handleMobileHardwareWalletDelay = exports.handleApprovalDelay = exports.addSyntheticTransaction = exports.generateActionId = exports.addTransaction = exports.checkIsDelegatedAccount = exports.updateTransaction = exports.getTransactionMetaByHash = exports.getTransactionMetaById = exports.getTransactions = exports.getGasFeeEstimates = exports.hasNestedSwapTransactions = exports.shouldDisable7702 = exports.is7702Tx = exports.isCrossChainTx = exports.isTradeTx = exports.isApprovalTx = void 0;
4
4
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
5
5
  const bridge_controller_1 = require("@metamask/bridge-controller");
6
6
  const controller_utils_1 = require("@metamask/controller-utils");
7
7
  const transaction_controller_1 = require("@metamask/transaction-controller");
8
8
  const utils_1 = require("@metamask/utils");
9
- const bignumber_js_1 = require("bignumber.js");
10
9
  const constants_1 = require("../constants.cjs");
11
10
  const accounts_1 = require("./accounts.cjs");
12
11
  const network_1 = require("./network.cjs");
13
12
  const isApprovalTx = (type) => type === transaction_controller_1.TransactionType.bridgeApproval ||
14
13
  type === transaction_controller_1.TransactionType.swapApproval;
14
+ exports.isApprovalTx = isApprovalTx;
15
15
  const isTradeTx = (type) => type === transaction_controller_1.TransactionType.bridge || type === transaction_controller_1.TransactionType.swap;
16
- const isCrossChainTx = (type) => isTradeTx(type) || isApprovalTx(type);
16
+ exports.isTradeTx = isTradeTx;
17
+ const isCrossChainTx = (type) => (0, exports.isTradeTx)(type) || (0, exports.isApprovalTx)(type);
17
18
  exports.isCrossChainTx = isCrossChainTx;
18
- const getGasFeeEstimates = async (messenger, args) => {
19
- const { estimates } = await messenger.call('TransactionController:estimateGasFee', args);
20
- if (bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE in estimates &&
21
- typeof estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE] === 'object' &&
22
- 'maxFeePerGas' in estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE] &&
23
- 'maxPriorityFeePerGas' in estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE]) {
24
- return estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE];
25
- }
26
- return {};
27
- };
28
- exports.getGasFeeEstimates = getGasFeeEstimates;
29
19
  /**
30
- * Get the gas fee estimates for a transaction
20
+ * For 7702 delegated transactions, check for delegation-specific fields
21
+ * These transactions might have authorizationList or delegationAddress
31
22
  *
32
- * @param messenger - The messenger for the gas fee estimates
33
- * @param estimateGasFeeParams - The parameters for the {@link TransactionController.estimateGasFee} method
34
-
35
- * @returns The gas fee estimates for the transaction
23
+ * @param tx - The transaction meta
24
+ * @returns Whether the transaction is a 7702 transaction
36
25
  */
37
- const getTxGasEstimates = async (messenger, estimateGasFeeParams) => {
38
- const { gasFeeEstimates } = messenger.call('GasFeeController:getState');
39
- const estimatedBaseFee = 'estimatedBaseFee' in gasFeeEstimates
40
- ? gasFeeEstimates.estimatedBaseFee
41
- : '0';
42
- // Get transaction's 1559 gas fee estimates
43
- const { maxFeePerGas, maxPriorityFeePerGas } = await (0, exports.getGasFeeEstimates)(messenger, estimateGasFeeParams);
26
+ const is7702Tx = (tx) => {
27
+ return ((Array.isArray(tx.txParams.authorizationList) &&
28
+ tx.txParams.authorizationList.length > 0) ||
29
+ Boolean(tx.delegationAddress));
30
+ };
31
+ exports.is7702Tx = is7702Tx;
32
+ const shouldDisable7702 = (gasIncluded7702 = false, gasIncluded = false, isDelegatedAccount = false) => {
33
+ // Enable 7702 batching when the quote includes gasless 7702 support
34
+ if (gasIncluded7702) {
35
+ return false;
36
+ }
37
+ // Enable batching when the account is already delegated (to avoid the in-flight transaction limit for delegated accounts)
38
+ // For gasless transactions with STX/sendBundle we keep disabling 7702
39
+ if (isDelegatedAccount && !gasIncluded) {
40
+ return false;
41
+ }
44
42
  /**
45
- * @deprecated this is unused
43
+ * Explicitly return default instead of falsy value (see TransactionBatchRequest.disable7702)
46
44
  */
47
- const baseAndPriorityFeePerGas = maxPriorityFeePerGas
48
- ? new bignumber_js_1.BigNumber(estimatedBaseFee, 10)
49
- .times(10 ** 9)
50
- .plus(maxPriorityFeePerGas, 16)
51
- : undefined;
52
- return {
53
- baseAndPriorityFeePerGas,
54
- maxFeePerGas,
55
- maxPriorityFeePerGas,
56
- };
45
+ return true;
57
46
  };
58
- exports.getTxGasEstimates = getTxGasEstimates;
59
- const calculateGasFees = async (skipGasFields, messenger, { chainId: _, gasLimit, ...trade }, networkClientId, chainId, txFee) => {
60
- if (skipGasFields) {
61
- return {};
62
- }
63
- if (txFee) {
64
- return { ...txFee, gas: gasLimit?.toString() };
47
+ exports.shouldDisable7702 = shouldDisable7702;
48
+ const hasNestedSwapTransactions = (txMeta) => {
49
+ return Boolean(txMeta?.nestedTransactions?.some((tx) => tx.type === transaction_controller_1.TransactionType.swap));
50
+ };
51
+ exports.hasNestedSwapTransactions = hasNestedSwapTransactions;
52
+ const getGasFeeEstimates = async (messenger, args) => {
53
+ const { estimates } = await messenger.call('TransactionController:estimateGasFee', args);
54
+ if (estimates?.type === transaction_controller_1.GasFeeEstimateType.FeeMarket) {
55
+ return estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE];
65
56
  }
66
- const transactionParams = {
67
- ...trade,
68
- gas: gasLimit?.toString(),
69
- data: trade.data,
70
- to: trade.to,
71
- value: trade.value,
72
- };
73
- const { maxFeePerGas, maxPriorityFeePerGas } = await (0, exports.getTxGasEstimates)(messenger, {
74
- transactionParams,
75
- networkClientId,
76
- chainId,
77
- });
78
- const maxGasLimit = (0, controller_utils_1.toHex)(transactionParams.gas ?? 0);
79
- return {
80
- maxFeePerGas,
81
- maxPriorityFeePerGas,
82
- gas: maxGasLimit,
83
- };
57
+ return undefined;
84
58
  };
85
- exports.calculateGasFees = calculateGasFees;
59
+ exports.getGasFeeEstimates = getGasFeeEstimates;
86
60
  const getTransactions = (messenger) => {
87
61
  return messenger.call('TransactionController:getState').transactions ?? [];
88
62
  };
@@ -200,227 +174,222 @@ const waitForTxConfirmation = async (messenger, txId, { timeoutMs = 5 * 60000, p
200
174
  }
201
175
  };
202
176
  exports.waitForTxConfirmation = waitForTxConfirmation;
203
- const toBatchTxParams = (skipGasFields, { chainId, gasLimit, ...trade }, { maxFeePerGas, maxPriorityFeePerGas, gas, }) => {
204
- const params = {
205
- ...trade,
206
- data: trade.data,
207
- to: trade.to,
208
- value: trade.value,
209
- };
210
- if (skipGasFields) {
211
- return params;
212
- }
213
- return {
214
- ...params,
215
- gas: (0, controller_utils_1.toHex)(gas ?? 0),
216
- maxFeePerGas: (0, controller_utils_1.toHex)(maxFeePerGas ?? 0),
217
- maxPriorityFeePerGas: (0, controller_utils_1.toHex)(maxPriorityFeePerGas ?? 0),
218
- };
219
- };
220
- exports.toBatchTxParams = toBatchTxParams;
221
- const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, approval, resetApproval, trade, quoteResponse: { quote: { feeData: { txFee }, gasIncluded, gasIncluded7702, gasSponsored, }, sentAmount, toTokenAmount, }, requireApproval = false, isDelegatedAccount = false, }) => {
222
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
223
- const isGasless = gasIncluded || gasIncluded7702;
224
- const selectedAccount = (0, accounts_1.getAccountByAddress)(messenger, trade.from);
225
- if (!selectedAccount) {
226
- throw new Error('Failed to submit cross-chain swap batch transaction: unknown account in trade data');
227
- }
228
- const hexChainId = (0, bridge_controller_1.formatChainIdToHex)(trade.chainId);
229
- const networkClientId = (0, network_1.getNetworkClientIdByChainId)(messenger, hexChainId);
230
- // Gas fields should be omitted only when gas is sponsored via 7702
231
- const skipGasFields = gasIncluded7702 === true;
232
- // Enable 7702 batching when the quote includes gasless 7702 support,
233
- // or when the account is already delegated (to avoid the in-flight
234
- // transaction limit for delegated accounts)
235
- let disable7702 = !skipGasFields && !isDelegatedAccount;
236
- // For gasless transactions with STX/sendBundle we keep disabling 7702.
237
- if (gasIncluded && !gasIncluded7702) {
238
- disable7702 = true;
239
- }
240
- const transactions = [];
241
- if (resetApproval) {
242
- const gasFees = await (0, exports.calculateGasFees)(skipGasFields, messenger, resetApproval, networkClientId, hexChainId, isGasless ? txFee : undefined);
243
- transactions.push({
244
- type: isBridgeTx
245
- ? transaction_controller_1.TransactionType.bridgeApproval
246
- : transaction_controller_1.TransactionType.swapApproval,
247
- params: (0, exports.toBatchTxParams)(skipGasFields, resetApproval, gasFees),
177
+ const toQuoteAndTxMetadata = ({ quoteResponse, isBridgeTx, }) => {
178
+ const tradeData = [];
179
+ const approvalTxType = isBridgeTx
180
+ ? transaction_controller_1.TransactionType.bridgeApproval
181
+ : transaction_controller_1.TransactionType.swapApproval;
182
+ if (quoteResponse.resetApproval) {
183
+ tradeData.push({
184
+ quoteResponse,
185
+ tx: quoteResponse.resetApproval,
186
+ type: approvalTxType,
187
+ txFee: quoteResponse.quote.feeData[bridge_controller_1.FeeType.TX_FEE],
248
188
  });
249
189
  }
250
- if (approval) {
251
- const gasFees = await (0, exports.calculateGasFees)(skipGasFields, messenger, approval, networkClientId, hexChainId, isGasless ? txFee : undefined);
252
- transactions.push({
253
- type: isBridgeTx
254
- ? transaction_controller_1.TransactionType.bridgeApproval
255
- : transaction_controller_1.TransactionType.swapApproval,
256
- params: (0, exports.toBatchTxParams)(skipGasFields, approval, gasFees),
190
+ if (quoteResponse.approval && (0, bridge_controller_1.isEvmTxData)(quoteResponse.approval)) {
191
+ tradeData.push({
192
+ quoteResponse,
193
+ tx: quoteResponse.approval,
194
+ type: approvalTxType,
195
+ txFee: quoteResponse.quote.feeData[bridge_controller_1.FeeType.TX_FEE],
257
196
  });
258
197
  }
259
- const gasFees = await (0, exports.calculateGasFees)(skipGasFields, messenger, trade, networkClientId, hexChainId, isGasless ? txFee : undefined);
260
- transactions.push({
198
+ tradeData.push({
199
+ quoteResponse,
200
+ tx: quoteResponse.trade,
261
201
  type: isBridgeTx ? transaction_controller_1.TransactionType.bridge : transaction_controller_1.TransactionType.swap,
262
- params: (0, exports.toBatchTxParams)(skipGasFields, trade, gasFees),
263
202
  assetsFiatValues: {
264
- sending: sentAmount?.valueInCurrency?.toString(),
265
- receiving: toTokenAmount?.valueInCurrency?.toString(),
203
+ sending: quoteResponse.sentAmount?.valueInCurrency?.toString(),
204
+ receiving: quoteResponse.toTokenAmount?.valueInCurrency?.toString(),
266
205
  },
206
+ txFee: quoteResponse.quote.feeData[bridge_controller_1.FeeType.TX_FEE],
267
207
  });
268
- const transactionParams = {
269
- disable7702,
270
- isGasFeeIncluded: Boolean(gasIncluded7702),
271
- isGasFeeSponsored: Boolean(gasSponsored),
272
- networkClientId,
273
- requireApproval,
274
- origin: 'metamask',
275
- from: trade.from,
276
- isInternal: true,
277
- transactions,
278
- };
279
- return transactionParams;
208
+ return tradeData;
280
209
  };
281
- exports.getAddTransactionBatchParams = getAddTransactionBatchParams;
282
- const findAndUpdateTransactionsInBatch = ({ messenger, batchId, txDataByType, }) => {
283
- const txs = (0, exports.getTransactions)(messenger);
284
- const txBatch = {
285
- approvalMeta: undefined,
286
- tradeMeta: undefined,
287
- };
288
- // This is a workaround to update the tx type after the tx is signed
289
- // TODO: remove this once the tx type for batch txs is preserved in the tx controller
290
- const txEntries = Object.entries(txDataByType);
291
- txEntries.forEach(([txType, txData]) => {
292
- // Skip types not present in the batch (e.g. swap entry is undefined for bridge txs)
293
- if (txData === undefined) {
294
- return;
210
+ exports.toQuoteAndTxMetadata = toQuoteAndTxMetadata;
211
+ /**
212
+ * Build the trade+quote metadata array for the batch sell transaction
213
+ * This ties together the quote, the tx params and the txMeta after submission
214
+ *
215
+ * @param options - The options for the batch sell transaction
216
+ * @param options.quoteResponses - The quote responses for the batch sell transaction
217
+ * @param options.batchSellTrades - The batch sell trades for the batch sell transaction
218
+ * @returns The trade+quote metadata array for the batch sell transaction
219
+ */
220
+ const toQuoteAndTxMetadataBatch = ({ quoteResponses, batchSellTrades, }) => {
221
+ const tradeData = [];
222
+ const { transactions, gasIncluded7702, gasIncluded, gasSponsored = false, } = batchSellTrades;
223
+ for (const transaction of transactions) {
224
+ const { type, maxFeePerGas, maxPriorityFeePerGas, ...tx } = transaction;
225
+ // Match the trade or approval tx data with the quote response
226
+ const matchingQuoteResponse = quoteResponses.find(({ approval, trade }) => trade?.data.toLowerCase() === tx.data.toLowerCase() ||
227
+ approval?.data.toLowerCase() === tx.data.toLowerCase()) ?? quoteResponses[0];
228
+ // Include gasIncluded and gasIncluded7702 from the gasless batch
229
+ const normalizedQuote = {
230
+ ...matchingQuoteResponse,
231
+ quote: {
232
+ ...matchingQuoteResponse.quote,
233
+ gasIncluded,
234
+ gasIncluded7702,
235
+ gasSponsored,
236
+ },
237
+ };
238
+ const commonTradeData = {
239
+ tx,
240
+ quoteResponse: normalizedQuote,
241
+ txFee: { maxFeePerGas, maxPriorityFeePerGas },
242
+ };
243
+ if (type === bridge_controller_1.BatchSellTransactionType.TRADE) {
244
+ tradeData.push({
245
+ ...commonTradeData,
246
+ type: transaction_controller_1.TransactionType.swap,
247
+ assetsFiatValues: {
248
+ sending: matchingQuoteResponse.sentAmount?.valueInCurrency?.toString(),
249
+ receiving: matchingQuoteResponse.toTokenAmount?.valueInCurrency?.toString(),
250
+ },
251
+ });
295
252
  }
296
- // Find transaction by batchId and either matching data or delegation characteristics
297
- const txMeta = txs.find((tx) => {
298
- if (tx.batchId !== batchId) {
299
- return false;
300
- }
301
- // For 7702 delegated transactions, check for delegation-specific fields
302
- // These transactions might have authorizationList or delegationAddress
303
- const is7702Transaction = (Array.isArray(tx.txParams.authorizationList) &&
304
- tx.txParams.authorizationList.length > 0) ||
305
- Boolean(tx.delegationAddress);
306
- if (is7702Transaction) {
307
- // For 7702 transactions, we need to match based on transaction type
308
- // since the data field might be different (batch execute call)
309
- if (isTradeTx(txType) && tx.type === transaction_controller_1.TransactionType.batch) {
310
- return true;
311
- }
312
- // Also check if it's an approval transaction for 7702
313
- if (isApprovalTx(txType) && tx.txParams.data === txData) {
314
- return true;
315
- }
316
- }
317
- // Default matching logic for non-7702 transactions
318
- return tx.txParams.data === txData;
319
- });
320
- if (txMeta) {
321
- const updatedTx = { ...txMeta, type: txType };
322
- (0, exports.updateTransaction)(messenger, txMeta, { type: txType }, `Update tx type to ${txType}`);
323
- const txTypes = [
324
- transaction_controller_1.TransactionType.bridgeApproval,
325
- transaction_controller_1.TransactionType.swapApproval,
326
- ];
327
- txBatch[txTypes.includes(txType) ? 'approvalMeta' : 'tradeMeta'] =
328
- updatedTx;
253
+ else {
254
+ tradeData.push({
255
+ ...commonTradeData,
256
+ type: type === bridge_controller_1.BatchSellTransactionType.APPROVAL
257
+ ? transaction_controller_1.TransactionType.swapApproval
258
+ : transaction_controller_1.TransactionType.tokenMethodTransfer,
259
+ });
329
260
  }
330
- });
331
- return txBatch;
332
- };
333
- exports.findAndUpdateTransactionsInBatch = findAndUpdateTransactionsInBatch;
334
- const addTransactionBatch = async (messenger, addTransactionBatchFn, ...args) => {
335
- const txDataByType = {
336
- [transaction_controller_1.TransactionType.bridgeApproval]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.bridgeApproval)?.params.data,
337
- [transaction_controller_1.TransactionType.swapApproval]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.swapApproval)?.params.data,
338
- [transaction_controller_1.TransactionType.bridge]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.bridge)?.params.data,
339
- [transaction_controller_1.TransactionType.swap]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.swap)?.params.data,
340
- };
341
- const { batchId } = await addTransactionBatchFn(...args);
342
- const { approvalMeta, tradeMeta } = (0, exports.findAndUpdateTransactionsInBatch)({
343
- messenger,
344
- batchId,
345
- txDataByType,
346
- });
347
- if (!tradeMeta) {
348
- throw new Error('Failed to update cross-chain swap transaction batch: tradeMeta not found');
349
261
  }
350
- return { approvalMeta, tradeMeta };
262
+ return tradeData;
351
263
  };
352
- exports.addTransactionBatch = addTransactionBatch;
353
- // TODO rename
354
- const getGasFeesForSubmission = async (messenger, transactionParams, networkClientId, chainId, txFee) => {
355
- const { gas } = transactionParams;
356
- // If txFee is provided (gasIncluded case), use the quote's gas fees
357
- // Convert to hex since txFee values from the quote are decimal strings
358
- if (txFee) {
264
+ exports.toQuoteAndTxMetadataBatch = toQuoteAndTxMetadataBatch;
265
+ /**
266
+ * Appends the gas fee estimates for a transaction and normalizes the trade data
267
+ *
268
+ * @param messenger - The messenger for the gas fee estimates
269
+ * @param trade - the trade data to append gas fees to
270
+ * @param trade.chainId - ignored, use chainId instead
271
+ * @param trade.gasLimit - the gas limit to use for the gas fee estimates
272
+ * @param networkClientId - the network client ID to use for the gas fee estimates
273
+ * @param chainId - the chain ID to use for the gas fee estimates
274
+ * @param simulatedGasFeeLimits - either the txFee from the quote or the simulated gas fee limits for the batch sell
275
+ * @returns The gas fee estimates for the transaction
276
+ */
277
+ const toTransactionParams = async (messenger, { chainId: tradeChainId, gasLimit, ...trade }, networkClientId, chainId, simulatedGasFeeLimits) => {
278
+ const transactionParams = {
279
+ data: trade.data,
280
+ to: trade.to,
281
+ from: trade.from,
282
+ value: trade.value,
283
+ // Only add gas if it's truthy
284
+ gas: gasLimit ? (0, controller_utils_1.toHex)(gasLimit) : undefined,
285
+ };
286
+ // Use bridge-api's provided gas fee estimates
287
+ if (simulatedGasFeeLimits) {
359
288
  return {
360
- maxFeePerGas: (0, controller_utils_1.toHex)(txFee.maxFeePerGas),
361
- maxPriorityFeePerGas: (0, controller_utils_1.toHex)(txFee.maxPriorityFeePerGas),
362
- gas: gas ? (0, controller_utils_1.toHex)(gas) : undefined,
289
+ ...transactionParams,
290
+ // Sometimes estimates are hex, somethings numeric strings
291
+ maxFeePerGas: (0, utils_1.isStrictHexString)(simulatedGasFeeLimits.maxFeePerGas)
292
+ ? simulatedGasFeeLimits.maxFeePerGas
293
+ : (0, controller_utils_1.toHex)(simulatedGasFeeLimits.maxFeePerGas),
294
+ maxPriorityFeePerGas: (0, utils_1.isStrictHexString)(simulatedGasFeeLimits.maxPriorityFeePerGas)
295
+ ? simulatedGasFeeLimits.maxPriorityFeePerGas
296
+ : (0, controller_utils_1.toHex)(simulatedGasFeeLimits.maxPriorityFeePerGas),
363
297
  };
364
298
  }
365
- const { maxFeePerGas, maxPriorityFeePerGas } = await (0, exports.getTxGasEstimates)(messenger, {
299
+ // Get transaction's 1559 gas fee estimates
300
+ const gasFeeEstimates = await (0, exports.getGasFeeEstimates)(messenger, {
366
301
  transactionParams,
367
- chainId,
368
302
  networkClientId,
303
+ chainId,
369
304
  });
370
305
  return {
371
- maxFeePerGas,
372
- maxPriorityFeePerGas,
373
- gas: gas ? (0, controller_utils_1.toHex)(gas) : undefined,
306
+ ...transactionParams,
307
+ maxFeePerGas: gasFeeEstimates?.maxFeePerGas,
308
+ maxPriorityFeePerGas: gasFeeEstimates?.maxPriorityFeePerGas,
374
309
  };
375
310
  };
376
- /**
377
- * Submits an EVM transaction to the TransactionController
378
- *
379
- * @param params - The parameters for the transaction
380
- * @param params.transactionType - The type of transaction to submit
381
- * @param params.trade - The trade data to confirm
382
- * @param params.requireApproval - Whether to require approval for the transaction
383
- * @param params.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)
384
- * @param params.txFee.maxFeePerGas - The maximum fee per gas from the quote
385
- * @param params.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote
386
- * @param params.actionId - Optional actionId for pre-submission history (if not provided, one is generated)
387
- * @param params.messenger - The messenger to use for the transaction
388
- * @returns The transaction meta
389
- */
390
- const submitEvmTransaction = async ({ messenger, trade, transactionType, requireApproval = false, txFee,
391
- // Use provided actionId (for pre-submission history) or generate one
392
- actionId = (0, exports.generateActionId)(), }) => {
311
+ exports.toTransactionParams = toTransactionParams;
312
+ const getAddTransactionBatchParams = async ({ messenger, tradeData, requireApproval = false, isDelegatedAccount, ...addTransactionBatchParams }) => {
313
+ const trade = tradeData[0].tx;
393
314
  const selectedAccount = (0, accounts_1.getAccountByAddress)(messenger, trade.from);
394
315
  if (!selectedAccount) {
395
- throw new Error('Failed to submit cross-chain swap transaction: unknown account in trade data');
316
+ throw new Error('Failed to submit cross-chain swap batch transaction: unknown account in trade data');
396
317
  }
397
318
  const hexChainId = (0, bridge_controller_1.formatChainIdToHex)(trade.chainId);
398
319
  const networkClientId = (0, network_1.getNetworkClientIdByChainId)(messenger, hexChainId);
399
- const requestOptions = {
400
- actionId,
320
+ const transactions = await Promise.all(tradeData.map(async ({ tx, txFee, assetsFiatValues, type }) => ({
321
+ params: await (0, exports.toTransactionParams)(messenger, tx, networkClientId, hexChainId, txFee),
322
+ assetsFiatValues,
323
+ type,
324
+ })));
325
+ return {
401
326
  networkClientId,
402
327
  requireApproval,
403
- type: transactionType,
404
328
  origin: 'metamask',
329
+ from: selectedAccount.address,
405
330
  isInternal: true,
331
+ transactions,
332
+ ...addTransactionBatchParams,
406
333
  };
407
- // Exclude gasLimit from trade to avoid type issues (it can be null)
408
- const { gasLimit: tradeGasLimit, ...tradeWithoutGasLimit } = trade;
409
- const transactionParams = {
410
- ...tradeWithoutGasLimit,
411
- chainId: hexChainId,
412
- // Only add gasLimit and gas if they're valid (not undefined/null/zero)
413
- ...(tradeGasLimit &&
414
- tradeGasLimit !== 0 && {
415
- gasLimit: tradeGasLimit.toString(),
416
- gas: tradeGasLimit.toString(),
417
- }),
418
- };
419
- const transactionParamsWithMaxGas = {
420
- ...transactionParams,
421
- ...(await getGasFeesForSubmission(messenger, transactionParams, networkClientId, hexChainId, txFee)),
422
- };
423
- return await (0, exports.addTransaction)(messenger, transactionParamsWithMaxGas, requestOptions);
424
334
  };
425
- exports.submitEvmTransaction = submitEvmTransaction;
335
+ exports.getAddTransactionBatchParams = getAddTransactionBatchParams;
336
+ const findAllTransactionsInBatch = ({ messenger, batchId, tradeData, }) => {
337
+ // Filter for transactions with batchId
338
+ const txs = (0, exports.getTransactions)(messenger).filter((tx) => tx.batchId === batchId);
339
+ return tradeData.map((tradeWithMetadata) => {
340
+ const { tx, type } = tradeWithMetadata;
341
+ return {
342
+ ...tradeWithMetadata,
343
+ txMeta: txs.find((txMeta) => {
344
+ if ((0, exports.is7702Tx)(txMeta)) {
345
+ // For 7702 transactions, we need to match based on transaction type
346
+ // since the data field might be different (batch execute call)
347
+ if ((0, exports.isTradeTx)(type) && txMeta.type === transaction_controller_1.TransactionType.batch) {
348
+ return true;
349
+ }
350
+ // Also check if it's an approval transaction for 7702
351
+ if ((0, exports.isApprovalTx)(type) && txMeta.txParams.data === tx.data) {
352
+ return true;
353
+ }
354
+ }
355
+ // Default matching logic for non-7702 transactions
356
+ if (txMeta.txParams.data === tx.data) {
357
+ return true;
358
+ }
359
+ return false;
360
+ }),
361
+ };
362
+ });
363
+ };
364
+ exports.findAllTransactionsInBatch = findAllTransactionsInBatch;
365
+ /**
366
+ * This is a workaround to update the tx type after submission. Batch txs are submitted with
367
+ * the "batch" type, but we need to update to swap/bridge for display purposes.
368
+ *
369
+ * @param params - The parameters for the transaction search
370
+ * @param params.messenger - The messenger to use for the transaction
371
+ * @param params.allTradesWithMetadata - The quote, tx data and type for each transaction in the batch
372
+ * @returns A list of transaction metas for each trade in the batch]
373
+ *
374
+ * @example
375
+ * [
376
+ * {...tradeData[0], tradeMeta: TransactionMeta}
377
+ * {...tradeData[1], tradeMeta: TransactionMeta}
378
+ * {...tradeData[2], tradeMeta: TransactionMeta}
379
+ * {...tradeData[3], tradeMeta: TransactionMeta}
380
+ * ]
381
+ */
382
+ const updateTransactionsInBatch = ({ messenger, allTradesWithMetadata, }) => {
383
+ return allTradesWithMetadata.map((tradeWithMetadata) => {
384
+ const { txMeta, type } = tradeWithMetadata;
385
+ if (txMeta) {
386
+ // Update the tx type from batch to swap/bridge
387
+ (0, exports.updateTransaction)(messenger, txMeta, { type }, `Update tx type to ${type}`);
388
+ const updatedTx = { ...txMeta, type };
389
+ return { ...tradeWithMetadata, txMeta: updatedTx, type };
390
+ }
391
+ return tradeWithMetadata;
392
+ });
393
+ };
394
+ exports.updateTransactionsInBatch = updateTransactionsInBatch;
426
395
  //# sourceMappingURL=transaction.cjs.map