@metamask-previews/bridge-controller 71.1.1-preview-9e2a7fac5 → 71.1.1-preview-2b316ced3

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 (66) hide show
  1. package/CHANGELOG.md +0 -10
  2. package/dist/bridge-controller.cjs +102 -150
  3. package/dist/bridge-controller.cjs.map +1 -1
  4. package/dist/bridge-controller.d.cts +4 -14
  5. package/dist/bridge-controller.d.cts.map +1 -1
  6. package/dist/bridge-controller.d.mts +4 -14
  7. package/dist/bridge-controller.d.mts.map +1 -1
  8. package/dist/bridge-controller.mjs +103 -151
  9. package/dist/bridge-controller.mjs.map +1 -1
  10. package/dist/constants/bridge.cjs +3 -5
  11. package/dist/constants/bridge.cjs.map +1 -1
  12. package/dist/constants/bridge.d.cts.map +1 -1
  13. package/dist/constants/bridge.d.mts.map +1 -1
  14. package/dist/constants/bridge.mjs +3 -5
  15. package/dist/constants/bridge.mjs.map +1 -1
  16. package/dist/constants/traces.cjs +0 -1
  17. package/dist/constants/traces.cjs.map +1 -1
  18. package/dist/constants/traces.d.cts +0 -1
  19. package/dist/constants/traces.d.cts.map +1 -1
  20. package/dist/constants/traces.d.mts +0 -1
  21. package/dist/constants/traces.d.mts.map +1 -1
  22. package/dist/constants/traces.mjs +0 -1
  23. package/dist/constants/traces.mjs.map +1 -1
  24. package/dist/index.cjs +2 -4
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +2 -2
  27. package/dist/index.d.cts.map +1 -1
  28. package/dist/index.d.mts +2 -2
  29. package/dist/index.d.mts.map +1 -1
  30. package/dist/index.mjs +2 -2
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/selectors.cjs +33 -89
  33. package/dist/selectors.cjs.map +1 -1
  34. package/dist/selectors.d.cts +76 -7163
  35. package/dist/selectors.d.cts.map +1 -1
  36. package/dist/selectors.d.mts +76 -7163
  37. package/dist/selectors.d.mts.map +1 -1
  38. package/dist/selectors.mjs +32 -88
  39. package/dist/selectors.mjs.map +1 -1
  40. package/dist/types.cjs.map +1 -1
  41. package/dist/types.d.cts +1 -6
  42. package/dist/types.d.cts.map +1 -1
  43. package/dist/types.d.mts +1 -6
  44. package/dist/types.d.mts.map +1 -1
  45. package/dist/types.mjs.map +1 -1
  46. package/dist/utils/fetch.cjs +17 -61
  47. package/dist/utils/fetch.cjs.map +1 -1
  48. package/dist/utils/fetch.d.cts +4 -3
  49. package/dist/utils/fetch.d.cts.map +1 -1
  50. package/dist/utils/fetch.d.mts +4 -3
  51. package/dist/utils/fetch.d.mts.map +1 -1
  52. package/dist/utils/fetch.mjs +18 -62
  53. package/dist/utils/fetch.mjs.map +1 -1
  54. package/dist/utils/metrics/properties.cjs +1 -1
  55. package/dist/utils/metrics/properties.cjs.map +1 -1
  56. package/dist/utils/metrics/properties.mjs +1 -1
  57. package/dist/utils/metrics/properties.mjs.map +1 -1
  58. package/dist/utils/quote.cjs +1 -3
  59. package/dist/utils/quote.cjs.map +1 -1
  60. package/dist/utils/quote.d.cts +0 -1
  61. package/dist/utils/quote.d.cts.map +1 -1
  62. package/dist/utils/quote.d.mts +0 -1
  63. package/dist/utils/quote.d.mts.map +1 -1
  64. package/dist/utils/quote.mjs +0 -1
  65. package/dist/utils/quote.mjs.map +1 -1
  66. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,16 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Added
11
-
12
- - **BREAKING:** Add support for BatchSell quotes ([#8711](https://github.com/MetaMask/core/pull/8711))
13
- - change `quoteRequest`'s type from `QuoteRequest` to `QuoteRequest[]`
14
- - allow callers to update specific quote requests within a batch by adding 2 optional parameters to `updateBridgeQuoteRequest`: quoteRequestIndex and quoteRequestCount
15
- - export `isValidBatchSellQuoteRequest` request validator
16
- - fetch multiple swap quotes through a single SSE stream and append `quoteRequestIndex` to link each one to its originating quoteRequest
17
- - implement `selectBatchSellQuotes` selector which returns the recommended quote for each batched quote, and their aggregated fees and received amounts
18
- - trace BatchSell quote fetch operations in Sentry using label `Batch Sell Quotes Fetched`
19
-
20
10
  ### Changed
21
11
 
22
12
  - Bump `@metamask/gas-fee-controller` from `^26.1.1` to `^26.2.0` ([#8722](https://github.com/MetaMask/core/pull/8722))
@@ -10,7 +10,7 @@ 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 _BridgeController_instances, _BridgeController_abortController, _BridgeController_quotesFirstFetched, _BridgeController_location, _BridgeController_clientId, _BridgeController_clientVersion, _BridgeController_getLayer1GasFee, _BridgeController_fetchFn, _BridgeController_trackMetaMetricsFn, _BridgeController_trace, _BridgeController_config, _BridgeController_getUseAssetsControllerForRates, _BridgeController_trackQuoteValidationFailures, _BridgeController_getExchangeRateSources, _BridgeController_fetchAssetExchangeRates, _BridgeController_hasInsufficientBalance, _BridgeController_appendInsufficientBalAndResetApproval, _BridgeController_shouldResetApproval, _BridgeController_fetchBridgeQuotes, _BridgeController_handleQuoteStreaming, _BridgeController_setMinimumBalanceForRentExemptionInLamports, _BridgeController_getMultichainSelectedAccount, _BridgeController_getNetworkClientByChainId, _BridgeController_getJwt, _BridgeController_getRequestMetadata, _BridgeController_getQuoteFetchData, _BridgeController_getEventProperties, _BridgeController_trackInputChangedEvents, _BridgeController_getUSDTMainnetAllowance;
13
+ var _BridgeController_instances, _BridgeController_abortController, _BridgeController_quotesFirstFetched, _BridgeController_location, _BridgeController_clientId, _BridgeController_clientVersion, _BridgeController_getLayer1GasFee, _BridgeController_fetchFn, _BridgeController_trackMetaMetricsFn, _BridgeController_trace, _BridgeController_config, _BridgeController_getUseAssetsControllerForRates, _BridgeController_trackQuoteValidationFailures, _BridgeController_getExchangeRateSources, _BridgeController_fetchAssetExchangeRates, _BridgeController_hasInsufficientBalance, _BridgeController_shouldResetApproval, _BridgeController_fetchBridgeQuotes, _BridgeController_handleQuoteStreaming, _BridgeController_setMinimumBalanceForRentExemptionInLamports, _BridgeController_getMultichainSelectedAccount, _BridgeController_getNetworkClientByChainId, _BridgeController_getJwt, _BridgeController_getRequestMetadata, _BridgeController_getQuoteFetchData, _BridgeController_getEventProperties, _BridgeController_trackInputChangedEvents, _BridgeController_getUSDTMainnetAllowance;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.BridgeController = void 0;
16
16
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
@@ -156,48 +156,54 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
156
156
  this._executePoll = async (pollingInput) => {
157
157
  await __classPrivateFieldGet(this, _BridgeController_fetchBridgeQuotes, "f").call(this, pollingInput);
158
158
  };
159
- /**
160
- * Updates the quote request at the specified index with the given parameters, then starts
161
- * polling for quotes.
162
- *
163
- * @param paramsToUpdate - The parameters to update in the quote request at the specified index
164
- * @param context - metrics context
165
- * @param quoteRequestIndex - The index of the quote request to update
166
- * @param quoteRequestCount - The number of quote requests in the UI
167
- */
168
- this.updateBridgeQuoteRequestParams = async (paramsToUpdate, context, quoteRequestIndex = 0, quoteRequestCount = 1) => {
169
- // Guard against updating a quote request that doesn't exist
170
- if (quoteRequestIndex >= quoteRequestCount) {
171
- return;
172
- }
173
- __classPrivateFieldGet(this, _BridgeController_trackInputChangedEvents, "f").call(this, paramsToUpdate, quoteRequestIndex);
174
- this.resetState(constants_1.AbortReason.QuoteRequestUpdated, quoteRequestIndex);
159
+ this.updateBridgeQuoteRequestParams = async (paramsToUpdate, context) => {
160
+ __classPrivateFieldGet(this, _BridgeController_trackInputChangedEvents, "f").call(this, paramsToUpdate);
161
+ this.resetState(constants_1.AbortReason.QuoteRequestUpdated);
162
+ const updatedQuoteRequest = {
163
+ ...bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest,
164
+ ...paramsToUpdate,
165
+ };
175
166
  this.update((state) => {
176
- // Update only the specified quote request and keep the rest of the quote requests unchanged
177
- state.quoteRequest = state.quoteRequest
178
- .slice(0, quoteRequestIndex)
179
- .concat({
180
- ...bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest[0],
181
- ...paramsToUpdate,
182
- })
183
- .concat(state.quoteRequest.slice(quoteRequestIndex + 1, quoteRequestCount));
167
+ state.quoteRequest = updatedQuoteRequest;
184
168
  state.tokenSecurityTypeDestination =
185
169
  context.token_security_type_destination ?? null;
186
170
  });
187
- // BatchSell and Unified swaps both use the same polling logic so both validations should pass
188
- if ((0, quote_1.isValidQuoteRequest)(paramsToUpdate) &&
189
- (0, quote_1.isValidBatchSellQuoteRequest)(this.state.quoteRequest)) {
171
+ if ((0, quote_1.isValidQuoteRequest)(updatedQuoteRequest)) {
190
172
  __classPrivateFieldSet(this, _BridgeController_quotesFirstFetched, Date.now(), "f");
191
- // Update the insufficientBal and resetApproval params for the quote request
192
- const quoteWithInsufficientBalAndResetApproval = await __classPrivateFieldGet(this, _BridgeController_appendInsufficientBalAndResetApproval, "f").call(this, paramsToUpdate);
193
- this.update((state) => {
194
- state.quoteRequest[quoteRequestIndex] =
195
- quoteWithInsufficientBalAndResetApproval;
196
- });
173
+ const isSrcChainNonEVM = (0, bridge_2.isNonEvmChainId)(updatedQuoteRequest.srcChainId);
174
+ const providerConfig = isSrcChainNonEVM
175
+ ? undefined
176
+ : __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getNetworkClientByChainId).call(this, (0, caip_formatters_1.formatChainIdToHex)(updatedQuoteRequest.srcChainId))?.configuration;
177
+ let insufficientBal;
178
+ let resetApproval = Boolean(paramsToUpdate.resetApproval);
179
+ if (isSrcChainNonEVM) {
180
+ // If the source chain is not an EVM network, use value from params
181
+ insufficientBal = paramsToUpdate.insufficientBal;
182
+ }
183
+ else if (providerConfig?.rpcUrl?.includes('tenderly')) {
184
+ // If the rpcUrl is a tenderly fork (e2e tests), set insufficientBal=true
185
+ // The bridge-api filters out quotes if the balance on mainnet is insufficient so this override allows quotes to always be returned
186
+ insufficientBal = true;
187
+ }
188
+ else {
189
+ // Set loading status if RPC calls are made before the quotes are fetched
190
+ this.update((state) => {
191
+ state.quotesLoadingStatus = types_1.RequestStatus.LOADING;
192
+ });
193
+ resetApproval = await __classPrivateFieldGet(this, _BridgeController_shouldResetApproval, "f").call(this, updatedQuoteRequest);
194
+ // Otherwise query the src token balance from the RPC provider
195
+ insufficientBal =
196
+ paramsToUpdate.insufficientBal ??
197
+ (await __classPrivateFieldGet(this, _BridgeController_hasInsufficientBalance, "f").call(this, updatedQuoteRequest));
198
+ }
197
199
  // Set refresh rate based on the source chain before starting polling
198
200
  this.setChainIntervalLength();
199
201
  this.startPolling({
200
- quoteRequests: this.state.quoteRequest,
202
+ updatedQuoteRequest: {
203
+ ...updatedQuoteRequest,
204
+ insufficientBal,
205
+ resetApproval,
206
+ },
201
207
  context,
202
208
  });
203
209
  }
@@ -255,21 +261,25 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
255
261
  * Fetches the exchange rates for the assets in the quote request if they are not already in the state
256
262
  * In addition to the selected tokens, this also fetches the native asset for the source and destination chains
257
263
  *
258
- * @param quoteRequests - The quote requests to fetch the exchange rates for
264
+ * @param quoteRequest - The quote request
265
+ * @param quoteRequest.srcChainId - The source chain ID
266
+ * @param quoteRequest.srcTokenAddress - The source token address
267
+ * @param quoteRequest.destChainId - The destination chain ID
268
+ * @param quoteRequest.destTokenAddress - The destination token address
259
269
  */
260
- _BridgeController_fetchAssetExchangeRates.set(this, async (quoteRequests) => {
270
+ _BridgeController_fetchAssetExchangeRates.set(this, async ({ srcChainId, srcTokenAddress, destChainId, destTokenAddress, }) => {
271
+ const assetIds = new Set([]);
261
272
  const exchangeRateSources = __classPrivateFieldGet(this, _BridgeController_getExchangeRateSources, "f").call(this);
262
- // Get unique assetIds for all quote requests
263
- const assetIds = new Set(quoteRequests
264
- .flatMap((quoteRequest) => [
265
- quoteRequest.srcTokenAddress && quoteRequest.srcChainId
266
- ? (0, assets_1.getAssetIdsForToken)(quoteRequest.srcTokenAddress, quoteRequest.srcChainId)
267
- : undefined,
268
- quoteRequest.destTokenAddress && quoteRequest.destChainId
269
- ? (0, assets_1.getAssetIdsForToken)(quoteRequest.destTokenAddress, quoteRequest.destChainId)
270
- : undefined,
271
- ].flat())
272
- .filter((assetId) => !(0, selectors_1.selectIsAssetExchangeRateInState)(exchangeRateSources, assetId)));
273
+ if (srcTokenAddress &&
274
+ srcChainId &&
275
+ !(0, selectors_1.selectIsAssetExchangeRateInState)(exchangeRateSources, srcChainId, srcTokenAddress)) {
276
+ (0, assets_1.getAssetIdsForToken)(srcTokenAddress, srcChainId).forEach((assetId) => assetIds.add(assetId));
277
+ }
278
+ if (destTokenAddress &&
279
+ destChainId &&
280
+ !(0, selectors_1.selectIsAssetExchangeRateInState)(exchangeRateSources, destChainId, destTokenAddress)) {
281
+ (0, assets_1.getAssetIdsForToken)(destTokenAddress, destChainId).forEach((assetId) => assetIds.add(assetId));
282
+ }
273
283
  const currency = __classPrivateFieldGet(this, _BridgeController_getUseAssetsControllerForRates, "f").call(this)
274
284
  ? this.messenger.call('AssetsController:getExchangeRatesForBridge')
275
285
  .currentCurrency
@@ -310,39 +320,6 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
310
320
  return true;
311
321
  }
312
322
  });
313
- _BridgeController_appendInsufficientBalAndResetApproval.set(this, async (quoteRequest) => {
314
- const isSrcChainNonEVM = (0, bridge_2.isNonEvmChainId)(quoteRequest.srcChainId);
315
- const providerConfig = isSrcChainNonEVM
316
- ? undefined
317
- : __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getNetworkClientByChainId).call(this, (0, caip_formatters_1.formatChainIdToHex)(quoteRequest.srcChainId))?.configuration;
318
- let insufficientBal;
319
- let resetApproval = Boolean(quoteRequest.resetApproval);
320
- if (isSrcChainNonEVM) {
321
- // If the source chain is not an EVM network, use value from params
322
- insufficientBal = quoteRequest.insufficientBal;
323
- }
324
- else if (providerConfig?.rpcUrl?.includes('tenderly')) {
325
- // If the rpcUrl is a tenderly fork (e2e tests), set insufficientBal=true
326
- // The bridge-api filters out quotes if the balance on mainnet is insufficient so this override allows quotes to always be returned
327
- insufficientBal = true;
328
- }
329
- else {
330
- // Set loading status if RPC calls are made before the quotes are fetched
331
- this.update((state) => {
332
- state.quotesLoadingStatus = types_1.RequestStatus.LOADING;
333
- });
334
- resetApproval = await __classPrivateFieldGet(this, _BridgeController_shouldResetApproval, "f").call(this, quoteRequest);
335
- // Otherwise query the src token balance from the RPC provider
336
- insufficientBal =
337
- quoteRequest.insufficientBal ??
338
- (await __classPrivateFieldGet(this, _BridgeController_hasInsufficientBalance, "f").call(this, quoteRequest));
339
- }
340
- return {
341
- ...quoteRequest,
342
- insufficientBal,
343
- resetApproval,
344
- };
345
- });
346
323
  _BridgeController_shouldResetApproval.set(this, async (quoteRequest) => {
347
324
  if ((0, bridge_2.isNonEvmChainId)(quoteRequest.srcChainId)) {
348
325
  return false;
@@ -380,21 +357,11 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
380
357
  this.setLocation = (location) => {
381
358
  __classPrivateFieldSet(this, _BridgeController_location, location, "f");
382
359
  };
383
- this.resetState = (reason = constants_1.AbortReason.ResetState, quoteRequestIndex = null) => {
360
+ this.resetState = (reason = constants_1.AbortReason.ResetState) => {
384
361
  this.stopPollingForQuotes(reason);
385
362
  this.update((state) => {
386
363
  // Cannot do direct assignment to state, i.e. state = {... }, need to manually assign each field
387
- if (quoteRequestIndex === null) {
388
- // Clear all requests if index is null
389
- state.quoteRequest = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest;
390
- }
391
- else {
392
- // Otherwise only clear the specified request
393
- state.quoteRequest = state.quoteRequest
394
- .slice(0, quoteRequestIndex)
395
- .concat(bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest[0])
396
- .concat(state.quoteRequest.slice(quoteRequestIndex + 1));
397
- }
364
+ state.quoteRequest = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest;
398
365
  state.quotesInitialLoadTime =
399
366
  bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
400
367
  state.quotes = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
@@ -421,9 +388,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
421
388
  */
422
389
  this.setChainIntervalLength = () => {
423
390
  const { state } = this;
424
- // Assume that BatchSell quote requests all have the same source chain
425
- // Use the first one to determine refresh rate
426
- const { srcChainId } = state.quoteRequest[0];
391
+ const { srcChainId } = state.quoteRequest;
427
392
  const bridgeFeatureFlags = (0, feature_flags_1.getBridgeFeatureFlags)(this.messenger);
428
393
  const refreshRateOverride = srcChainId
429
394
  ? bridgeFeatureFlags.chains[(0, caip_formatters_1.formatChainIdToCaip)(srcChainId)]?.refreshRate
@@ -431,16 +396,16 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
431
396
  const defaultRefreshRate = bridgeFeatureFlags.refreshRate;
432
397
  this.setIntervalLength(refreshRateOverride ?? defaultRefreshRate);
433
398
  };
434
- _BridgeController_fetchBridgeQuotes.set(this, async ({ quoteRequests, context, }) => {
399
+ _BridgeController_fetchBridgeQuotes.set(this, async ({ updatedQuoteRequest, context, }) => {
435
400
  __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort(constants_1.AbortReason.NewQuoteRequest);
436
401
  __classPrivateFieldSet(this, _BridgeController_abortController, new AbortController(), "f");
437
- __classPrivateFieldGet(this, _BridgeController_fetchAssetExchangeRates, "f").call(this, quoteRequests).catch((error) => console.warn('Failed to fetch asset exchange rates', error));
402
+ __classPrivateFieldGet(this, _BridgeController_fetchAssetExchangeRates, "f").call(this, updatedQuoteRequest).catch((error) => console.warn('Failed to fetch asset exchange rates', error));
438
403
  this.trackUnifiedSwapBridgeEvent(constants_1.UnifiedSwapBridgeEventName.QuotesRequested, context);
439
404
  const { sse, maxRefreshCount } = (0, feature_flags_1.getBridgeFeatureFlags)(this.messenger);
440
405
  const shouldStream = sse?.enabled &&
441
406
  (0, feature_flags_1.hasMinimumRequiredVersion)(__classPrivateFieldGet(this, _BridgeController_clientVersion, "f"), sse.minimumVersion);
442
- const isBatchSellRequest = quoteRequests.length > 1;
443
407
  this.update((state) => {
408
+ state.quoteRequest = updatedQuoteRequest;
444
409
  state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
445
410
  state.tokenWarnings = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.tokenWarnings;
446
411
  state.quoteStreamComplete =
@@ -450,30 +415,26 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
450
415
  });
451
416
  const jwt = await __classPrivateFieldGet(this, _BridgeController_getJwt, "f").call(this);
452
417
  try {
453
- const [firstQuoteRequest] = quoteRequests;
454
- const unifiedSwapTraceName = (0, bridge_2.isCrossChain)(firstQuoteRequest.srcChainId, firstQuoteRequest.destChainId)
455
- ? traces_1.TraceName.BridgeQuotesFetched
456
- : traces_1.TraceName.SwapQuotesFetched;
457
418
  await __classPrivateFieldGet(this, _BridgeController_trace, "f").call(this, {
458
- name: isBatchSellRequest
459
- ? traces_1.TraceName.BatchSellQuotesFetched
460
- : unifiedSwapTraceName,
419
+ name: (0, bridge_2.isCrossChain)(updatedQuoteRequest.srcChainId, updatedQuoteRequest.destChainId)
420
+ ? traces_1.TraceName.BridgeQuotesFetched
421
+ : traces_1.TraceName.SwapQuotesFetched,
461
422
  data: {
462
- srcChainId: (0, caip_formatters_1.formatChainIdToCaip)(firstQuoteRequest.srcChainId),
463
- destChainId: (0, caip_formatters_1.formatChainIdToCaip)(firstQuoteRequest.destChainId),
423
+ srcChainId: (0, caip_formatters_1.formatChainIdToCaip)(updatedQuoteRequest.srcChainId),
424
+ destChainId: (0, caip_formatters_1.formatChainIdToCaip)(updatedQuoteRequest.destChainId),
464
425
  },
465
426
  }, async () => {
466
- const selectedAccount = __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getMultichainSelectedAccount).call(this, firstQuoteRequest.walletAddress);
427
+ const selectedAccount = __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getMultichainSelectedAccount).call(this, updatedQuoteRequest.walletAddress);
467
428
  // This call is not awaited to prevent blocking quote fetching if the snap takes too long to respond
468
429
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
469
- __classPrivateFieldGet(this, _BridgeController_setMinimumBalanceForRentExemptionInLamports, "f").call(this, firstQuoteRequest.srcChainId, selectedAccount?.metadata?.snap?.id);
430
+ __classPrivateFieldGet(this, _BridgeController_setMinimumBalanceForRentExemptionInLamports, "f").call(this, updatedQuoteRequest.srcChainId, selectedAccount?.metadata?.snap?.id);
470
431
  // Use SSE if enabled and return early
471
- if (shouldStream || isBatchSellRequest) {
472
- await __classPrivateFieldGet(this, _BridgeController_handleQuoteStreaming, "f").call(this, quoteRequests, jwt, selectedAccount);
432
+ if (shouldStream) {
433
+ await __classPrivateFieldGet(this, _BridgeController_handleQuoteStreaming, "f").call(this, updatedQuoteRequest, jwt, selectedAccount);
473
434
  return;
474
435
  }
475
436
  // Otherwise use regular fetch
476
- const quotes = await this.fetchQuotes(firstQuoteRequest, __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.signal);
437
+ const quotes = await this.fetchQuotes(updatedQuoteRequest, __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.signal);
477
438
  this.update((state) => {
478
439
  // Set the initial load time if this is the first fetch
479
440
  if (state.quotesRefreshCount ===
@@ -529,17 +490,14 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
529
490
  this.update((state) => {
530
491
  state.quotesRefreshCount += 1;
531
492
  });
532
- const hasNoFundedQuoteRequests = quoteRequests.every(({ insufficientBal }) => Boolean(insufficientBal));
533
- if (hasNoFundedQuoteRequests
534
- ? // If all quote requests are insufficiently funded, stop polling
535
- // So if a BatchSell has at least 1 sufficiently funded quote request, polling continues
536
- true
537
- : // Otherwise continue polling until the maximum number of refreshes has been reached
538
- this.state.quotesRefreshCount >= maxRefreshCount) {
493
+ // Stop polling if the maximum number of refreshes has been reached
494
+ if (updatedQuoteRequest.insufficientBal ||
495
+ (!updatedQuoteRequest.insufficientBal &&
496
+ this.state.quotesRefreshCount >= maxRefreshCount)) {
539
497
  this.stopAllPolling();
540
498
  }
541
499
  });
542
- _BridgeController_handleQuoteStreaming.set(this, async (quoteRequests, jwt, selectedAccount) => {
500
+ _BridgeController_handleQuoteStreaming.set(this, async (updatedQuoteRequest, jwt, selectedAccount) => {
543
501
  /**
544
502
  * Tracks the number of valid quotes received from the current stream, which is used
545
503
  * to determine when to clear the quotes list and set the initial load time
@@ -550,7 +508,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
550
508
  * before setting quotesLoadingStatus to FETCHED
551
509
  */
552
510
  const pendingFeeAppendPromises = new Set();
553
- await (0, fetch_1.fetchBridgeQuoteStream)(__classPrivateFieldGet(this, _BridgeController_fetchFn, "f"), quoteRequests, __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.signal, __classPrivateFieldGet(this, _BridgeController_clientId, "f"), jwt, __classPrivateFieldGet(this, _BridgeController_config, "f").customBridgeApiBaseUrl ?? bridge_1.BRIDGE_PROD_API_BASE_URL, {
511
+ await (0, fetch_1.fetchBridgeQuoteStream)(__classPrivateFieldGet(this, _BridgeController_fetchFn, "f"), updatedQuoteRequest, __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.signal, __classPrivateFieldGet(this, _BridgeController_clientId, "f"), jwt, __classPrivateFieldGet(this, _BridgeController_config, "f").customBridgeApiBaseUrl ?? bridge_1.BRIDGE_PROD_API_BASE_URL, {
554
512
  onQuoteValidationFailure: __classPrivateFieldGet(this, _BridgeController_trackQuoteValidationFailures, "f"),
555
513
  onValidQuoteReceived: async (quote) => {
556
514
  const feeAppendPromise = (async () => {
@@ -637,16 +595,15 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
637
595
  return undefined;
638
596
  }
639
597
  });
640
- _BridgeController_getRequestMetadata.set(this, (quoteRequestIndex = 0) => {
641
- const quoteRequest = this.state.quoteRequest[quoteRequestIndex];
642
- const { walletAddress } = quoteRequest;
598
+ _BridgeController_getRequestMetadata.set(this, () => {
599
+ const { walletAddress } = this.state.quoteRequest;
643
600
  const accountHardwareType = (0, properties_1.getAccountHardwareType)(walletAddress
644
601
  ? __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getMultichainSelectedAccount).call(this, walletAddress)
645
602
  : undefined);
646
603
  return {
647
- slippage_limit: quoteRequest.slippage,
648
- swap_type: (0, properties_1.getSwapTypeFromQuote)(quoteRequest),
649
- custom_slippage: (0, properties_1.isCustomSlippage)(quoteRequest.slippage),
604
+ slippage_limit: this.state.quoteRequest.slippage,
605
+ swap_type: (0, properties_1.getSwapTypeFromQuote)(this.state.quoteRequest),
606
+ custom_slippage: (0, properties_1.isCustomSlippage)(this.state.quoteRequest.slippage),
650
607
  account_hardware_type: accountHardwareType,
651
608
  is_hardware_wallet: accountHardwareType !== null,
652
609
  };
@@ -659,35 +616,34 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
659
616
  has_gas_included_quote: this.state.quotes.some(({ quote }) => quote.gasIncluded),
660
617
  };
661
618
  });
662
- _BridgeController_getEventProperties.set(this, (eventName, propertiesFromClient, quoteRequestIndex = 0) => {
619
+ _BridgeController_getEventProperties.set(this, (eventName, propertiesFromClient) => {
663
620
  const clientProps = propertiesFromClient;
664
621
  const baseProperties = {
665
622
  ...propertiesFromClient,
666
623
  location: clientProps?.location ?? __classPrivateFieldGet(this, _BridgeController_location, "f"),
667
624
  action_type: constants_1.MetricsActionType.SWAPBRIDGE_V1,
668
625
  };
669
- const quoteRequest = this.state.quoteRequest[quoteRequestIndex];
670
626
  switch (eventName) {
671
627
  case constants_1.UnifiedSwapBridgeEventName.ButtonClicked:
672
628
  return {
673
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
629
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
674
630
  ...baseProperties,
675
631
  };
676
632
  case constants_1.UnifiedSwapBridgeEventName.PageViewed:
677
633
  return {
678
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
634
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
679
635
  ...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
680
636
  ...baseProperties,
681
637
  };
682
638
  case constants_1.UnifiedSwapBridgeEventName.QuotesValidationFailed:
683
639
  return {
684
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
640
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
685
641
  refresh_count: this.state.quotesRefreshCount,
686
642
  ...baseProperties,
687
643
  };
688
644
  case constants_1.UnifiedSwapBridgeEventName.QuotesReceived:
689
645
  return {
690
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
646
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
691
647
  ...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
692
648
  ...__classPrivateFieldGet(this, _BridgeController_getQuoteFetchData, "f").call(this),
693
649
  refresh_count: this.state.quotesRefreshCount,
@@ -695,24 +651,24 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
695
651
  };
696
652
  case constants_1.UnifiedSwapBridgeEventName.QuotesRequested:
697
653
  return {
698
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
654
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
699
655
  ...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
700
- has_sufficient_funds: !quoteRequest.insufficientBal,
656
+ has_sufficient_funds: !this.state.quoteRequest.insufficientBal,
701
657
  ...baseProperties,
702
658
  };
703
659
  case constants_1.UnifiedSwapBridgeEventName.QuotesError:
704
660
  return {
705
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
661
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
706
662
  ...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
707
663
  error_message: this.state.quoteFetchError,
708
- has_sufficient_funds: !quoteRequest.insufficientBal,
664
+ has_sufficient_funds: !this.state.quoteRequest.insufficientBal,
709
665
  ...baseProperties,
710
666
  };
711
667
  case constants_1.UnifiedSwapBridgeEventName.AllQuotesOpened:
712
668
  case constants_1.UnifiedSwapBridgeEventName.AllQuotesSorted:
713
669
  case constants_1.UnifiedSwapBridgeEventName.QuoteSelected:
714
670
  return {
715
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
671
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
716
672
  ...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
717
673
  ...__classPrivateFieldGet(this, _BridgeController_getQuoteFetchData, "f").call(this),
718
674
  ...baseProperties,
@@ -721,7 +677,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
721
677
  // Populate the properties that the error occurred before the tx was submitted
722
678
  return {
723
679
  ...baseProperties,
724
- ...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
680
+ ...(0, properties_1.getRequestParams)(this.state.quoteRequest, this.state.tokenSecurityTypeDestination),
725
681
  ...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
726
682
  ...__classPrivateFieldGet(this, _BridgeController_getQuoteFetchData, "f").call(this),
727
683
  ...propertiesFromClient,
@@ -748,15 +704,13 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
748
704
  return baseProperties;
749
705
  }
750
706
  });
751
- _BridgeController_trackInputChangedEvents.set(this, (paramsToUpdate, quoteRequestIndex = 0) => {
707
+ _BridgeController_trackInputChangedEvents.set(this, (paramsToUpdate) => {
752
708
  Object.entries(paramsToUpdate).forEach(([key, value]) => {
753
709
  const inputKey = properties_1.toInputChangedPropertyKey[key];
754
710
  const inputValue = properties_1.toInputChangedPropertyValue[key]?.(paramsToUpdate);
755
711
  if (inputKey &&
756
712
  inputValue !== undefined &&
757
- this.state.quoteRequest[quoteRequestIndex] &&
758
- value !==
759
- this.state.quoteRequest[quoteRequestIndex][key]) {
713
+ value !== this.state.quoteRequest[key]) {
760
714
  this.trackUnifiedSwapBridgeEvent(constants_1.UnifiedSwapBridgeEventName.InputChanged, {
761
715
  input: inputKey,
762
716
  input_value: inputValue,
@@ -770,15 +724,14 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
770
724
  *
771
725
  * @param eventName - The name of the event to track
772
726
  * @param propertiesFromClient - Properties that can't be calculated from the event name and need to be provided by the client
773
- * @param quoteRequestIndex - The index of the quote request to track the event for
774
727
  * @example
775
728
  * this.trackUnifiedSwapBridgeEvent(UnifiedSwapBridgeEventName.ActionOpened, {
776
729
  * location: MetaMetricsSwapsEventSource.MainView,
777
730
  * });
778
731
  */
779
- this.trackUnifiedSwapBridgeEvent = (eventName, propertiesFromClient, quoteRequestIndex = 0) => {
732
+ this.trackUnifiedSwapBridgeEvent = (eventName, propertiesFromClient) => {
780
733
  try {
781
- const combinedPropertiesForEvent = __classPrivateFieldGet(this, _BridgeController_getEventProperties, "f").call(this, eventName, propertiesFromClient, quoteRequestIndex);
734
+ const combinedPropertiesForEvent = __classPrivateFieldGet(this, _BridgeController_getEventProperties, "f").call(this, eventName, propertiesFromClient);
782
735
  __classPrivateFieldGet(this, _BridgeController_trackMetaMetricsFn, "f").call(this, eventName, combinedPropertiesForEvent);
783
736
  }
784
737
  catch (error) {
@@ -820,9 +773,8 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
820
773
  }
821
774
  }
822
775
  exports.BridgeController = BridgeController;
823
- _BridgeController_abortController = new WeakMap(), _BridgeController_quotesFirstFetched = new WeakMap(), _BridgeController_location = new WeakMap(), _BridgeController_clientId = new WeakMap(), _BridgeController_clientVersion = new WeakMap(), _BridgeController_getLayer1GasFee = new WeakMap(), _BridgeController_fetchFn = new WeakMap(), _BridgeController_trackMetaMetricsFn = new WeakMap(), _BridgeController_trace = new WeakMap(), _BridgeController_config = new WeakMap(), _BridgeController_getUseAssetsControllerForRates = new WeakMap(), _BridgeController_trackQuoteValidationFailures = new WeakMap(), _BridgeController_getExchangeRateSources = new WeakMap(), _BridgeController_fetchAssetExchangeRates = new WeakMap(), _BridgeController_hasInsufficientBalance = new WeakMap(), _BridgeController_appendInsufficientBalAndResetApproval = new WeakMap(), _BridgeController_shouldResetApproval = new WeakMap(), _BridgeController_fetchBridgeQuotes = new WeakMap(), _BridgeController_handleQuoteStreaming = new WeakMap(), _BridgeController_setMinimumBalanceForRentExemptionInLamports = new WeakMap(), _BridgeController_getJwt = new WeakMap(), _BridgeController_getRequestMetadata = new WeakMap(), _BridgeController_getQuoteFetchData = new WeakMap(), _BridgeController_getEventProperties = new WeakMap(), _BridgeController_trackInputChangedEvents = new WeakMap(), _BridgeController_getUSDTMainnetAllowance = new WeakMap(), _BridgeController_instances = new WeakSet(), _BridgeController_getMultichainSelectedAccount = function _BridgeController_getMultichainSelectedAccount(walletAddress) {
824
- // Assume that all quotes in a batch are for the same account
825
- const addressToUse = walletAddress ?? this.state.quoteRequest[0].walletAddress;
776
+ _BridgeController_abortController = new WeakMap(), _BridgeController_quotesFirstFetched = new WeakMap(), _BridgeController_location = new WeakMap(), _BridgeController_clientId = new WeakMap(), _BridgeController_clientVersion = new WeakMap(), _BridgeController_getLayer1GasFee = new WeakMap(), _BridgeController_fetchFn = new WeakMap(), _BridgeController_trackMetaMetricsFn = new WeakMap(), _BridgeController_trace = new WeakMap(), _BridgeController_config = new WeakMap(), _BridgeController_getUseAssetsControllerForRates = new WeakMap(), _BridgeController_trackQuoteValidationFailures = new WeakMap(), _BridgeController_getExchangeRateSources = new WeakMap(), _BridgeController_fetchAssetExchangeRates = new WeakMap(), _BridgeController_hasInsufficientBalance = new WeakMap(), _BridgeController_shouldResetApproval = new WeakMap(), _BridgeController_fetchBridgeQuotes = new WeakMap(), _BridgeController_handleQuoteStreaming = new WeakMap(), _BridgeController_setMinimumBalanceForRentExemptionInLamports = new WeakMap(), _BridgeController_getJwt = new WeakMap(), _BridgeController_getRequestMetadata = new WeakMap(), _BridgeController_getQuoteFetchData = new WeakMap(), _BridgeController_getEventProperties = new WeakMap(), _BridgeController_trackInputChangedEvents = new WeakMap(), _BridgeController_getUSDTMainnetAllowance = new WeakMap(), _BridgeController_instances = new WeakSet(), _BridgeController_getMultichainSelectedAccount = function _BridgeController_getMultichainSelectedAccount(walletAddress) {
777
+ const addressToUse = walletAddress ?? this.state.quoteRequest.walletAddress;
826
778
  if (!addressToUse) {
827
779
  throw new Error('Account address is required');
828
780
  }