@metamask-previews/bridge-controller 71.1.1-preview-ef7075b96 → 72.0.1-preview-c4c6220ef
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.
- package/CHANGELOG.md +21 -1
- package/dist/bridge-controller.cjs +150 -102
- package/dist/bridge-controller.cjs.map +1 -1
- package/dist/bridge-controller.d.cts +14 -4
- package/dist/bridge-controller.d.cts.map +1 -1
- package/dist/bridge-controller.d.mts +14 -4
- package/dist/bridge-controller.d.mts.map +1 -1
- package/dist/bridge-controller.mjs +151 -103
- package/dist/bridge-controller.mjs.map +1 -1
- package/dist/constants/bridge.cjs +5 -3
- package/dist/constants/bridge.cjs.map +1 -1
- package/dist/constants/bridge.d.cts.map +1 -1
- package/dist/constants/bridge.d.mts.map +1 -1
- package/dist/constants/bridge.mjs +5 -3
- package/dist/constants/bridge.mjs.map +1 -1
- package/dist/constants/traces.cjs +1 -0
- package/dist/constants/traces.cjs.map +1 -1
- package/dist/constants/traces.d.cts +1 -0
- package/dist/constants/traces.d.cts.map +1 -1
- package/dist/constants/traces.d.mts +1 -0
- package/dist/constants/traces.d.mts.map +1 -1
- package/dist/constants/traces.mjs +1 -0
- package/dist/constants/traces.mjs.map +1 -1
- package/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/selectors.cjs +89 -33
- package/dist/selectors.cjs.map +1 -1
- package/dist/selectors.d.cts +7163 -76
- package/dist/selectors.d.cts.map +1 -1
- package/dist/selectors.d.mts +7163 -76
- package/dist/selectors.d.mts.map +1 -1
- package/dist/selectors.mjs +88 -32
- package/dist/selectors.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +6 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +6 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/fetch.cjs +61 -17
- package/dist/utils/fetch.cjs.map +1 -1
- package/dist/utils/fetch.d.cts +3 -4
- package/dist/utils/fetch.d.cts.map +1 -1
- package/dist/utils/fetch.d.mts +3 -4
- package/dist/utils/fetch.d.mts.map +1 -1
- package/dist/utils/fetch.mjs +62 -18
- package/dist/utils/fetch.mjs.map +1 -1
- package/dist/utils/metrics/properties.cjs +1 -1
- package/dist/utils/metrics/properties.cjs.map +1 -1
- package/dist/utils/metrics/properties.mjs +1 -1
- package/dist/utils/metrics/properties.mjs.map +1 -1
- package/dist/utils/quote.cjs +3 -1
- package/dist/utils/quote.cjs.map +1 -1
- package/dist/utils/quote.d.cts +1 -0
- package/dist/utils/quote.d.cts.map +1 -1
- package/dist/utils/quote.d.mts +1 -0
- package/dist/utils/quote.d.mts.map +1 -1
- package/dist/utils/quote.mjs +1 -0
- package/dist/utils/quote.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [72.0.1]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Bump `@metamask/assets-controller` from `^6.4.0` to `^7.0.0` ([#8738](https://github.com/MetaMask/core/pull/8738))
|
|
15
|
+
|
|
16
|
+
## [72.0.0]
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **BREAKING:** Add support for BatchSell quotes ([#8711](https://github.com/MetaMask/core/pull/8711))
|
|
21
|
+
- change `quoteRequest`'s type from `QuoteRequest` to `QuoteRequest[]`
|
|
22
|
+
- allow callers to update specific quote requests within a batch by adding 2 optional parameters to `updateBridgeQuoteRequest`: quoteRequestIndex and quoteRequestCount
|
|
23
|
+
- export `isValidBatchSellQuoteRequest` request validator
|
|
24
|
+
- fetch multiple swap quotes through a single SSE stream and append `quoteRequestIndex` to link each one to its originating quoteRequest
|
|
25
|
+
- implement `selectBatchSellQuotes` selector which returns the recommended quote for each batched quote, and their aggregated fees and received amounts
|
|
26
|
+
- trace BatchSell quote fetch operations in Sentry using label `Batch Sell Quotes Fetched`
|
|
27
|
+
|
|
10
28
|
### Changed
|
|
11
29
|
|
|
12
30
|
- Bump `@metamask/gas-fee-controller` from `^26.1.1` to `^26.2.0` ([#8722](https://github.com/MetaMask/core/pull/8722))
|
|
@@ -1421,7 +1439,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1421
1439
|
|
|
1422
1440
|
- Initial release ([#5317](https://github.com/MetaMask/core/pull/5317))
|
|
1423
1441
|
|
|
1424
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@
|
|
1442
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@72.0.1...HEAD
|
|
1443
|
+
[72.0.1]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@72.0.0...@metamask/bridge-controller@72.0.1
|
|
1444
|
+
[72.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@71.1.1...@metamask/bridge-controller@72.0.0
|
|
1425
1445
|
[71.1.1]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@71.1.0...@metamask/bridge-controller@71.1.1
|
|
1426
1446
|
[71.1.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@71.0.0...@metamask/bridge-controller@71.1.0
|
|
1427
1447
|
[71.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@70.2.0...@metamask/bridge-controller@71.0.0
|
|
@@ -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_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_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;
|
|
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,54 +156,48 @@ 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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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);
|
|
166
175
|
this.update((state) => {
|
|
167
|
-
|
|
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));
|
|
168
184
|
state.tokenSecurityTypeDestination =
|
|
169
185
|
context.token_security_type_destination ?? null;
|
|
170
186
|
});
|
|
171
|
-
|
|
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)) {
|
|
172
190
|
__classPrivateFieldSet(this, _BridgeController_quotesFirstFetched, Date.now(), "f");
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
}
|
|
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
|
+
});
|
|
199
197
|
// Set refresh rate based on the source chain before starting polling
|
|
200
198
|
this.setChainIntervalLength();
|
|
201
199
|
this.startPolling({
|
|
202
|
-
|
|
203
|
-
...updatedQuoteRequest,
|
|
204
|
-
insufficientBal,
|
|
205
|
-
resetApproval,
|
|
206
|
-
},
|
|
200
|
+
quoteRequests: this.state.quoteRequest,
|
|
207
201
|
context,
|
|
208
202
|
});
|
|
209
203
|
}
|
|
@@ -261,25 +255,21 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
261
255
|
* Fetches the exchange rates for the assets in the quote request if they are not already in the state
|
|
262
256
|
* In addition to the selected tokens, this also fetches the native asset for the source and destination chains
|
|
263
257
|
*
|
|
264
|
-
* @param
|
|
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
|
|
258
|
+
* @param quoteRequests - The quote requests to fetch the exchange rates for
|
|
269
259
|
*/
|
|
270
|
-
_BridgeController_fetchAssetExchangeRates.set(this, async (
|
|
271
|
-
const assetIds = new Set([]);
|
|
260
|
+
_BridgeController_fetchAssetExchangeRates.set(this, async (quoteRequests) => {
|
|
272
261
|
const exchangeRateSources = __classPrivateFieldGet(this, _BridgeController_getExchangeRateSources, "f").call(this);
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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)));
|
|
283
273
|
const currency = __classPrivateFieldGet(this, _BridgeController_getUseAssetsControllerForRates, "f").call(this)
|
|
284
274
|
? this.messenger.call('AssetsController:getExchangeRatesForBridge')
|
|
285
275
|
.currentCurrency
|
|
@@ -320,6 +310,39 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
320
310
|
return true;
|
|
321
311
|
}
|
|
322
312
|
});
|
|
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
|
+
});
|
|
323
346
|
_BridgeController_shouldResetApproval.set(this, async (quoteRequest) => {
|
|
324
347
|
if ((0, bridge_2.isNonEvmChainId)(quoteRequest.srcChainId)) {
|
|
325
348
|
return false;
|
|
@@ -357,11 +380,21 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
357
380
|
this.setLocation = (location) => {
|
|
358
381
|
__classPrivateFieldSet(this, _BridgeController_location, location, "f");
|
|
359
382
|
};
|
|
360
|
-
this.resetState = (reason = constants_1.AbortReason.ResetState) => {
|
|
383
|
+
this.resetState = (reason = constants_1.AbortReason.ResetState, quoteRequestIndex = null) => {
|
|
361
384
|
this.stopPollingForQuotes(reason);
|
|
362
385
|
this.update((state) => {
|
|
363
386
|
// Cannot do direct assignment to state, i.e. state = {... }, need to manually assign each field
|
|
364
|
-
|
|
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
|
+
}
|
|
365
398
|
state.quotesInitialLoadTime =
|
|
366
399
|
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
|
|
367
400
|
state.quotes = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
|
|
@@ -388,7 +421,9 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
388
421
|
*/
|
|
389
422
|
this.setChainIntervalLength = () => {
|
|
390
423
|
const { state } = this;
|
|
391
|
-
|
|
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];
|
|
392
427
|
const bridgeFeatureFlags = (0, feature_flags_1.getBridgeFeatureFlags)(this.messenger);
|
|
393
428
|
const refreshRateOverride = srcChainId
|
|
394
429
|
? bridgeFeatureFlags.chains[(0, caip_formatters_1.formatChainIdToCaip)(srcChainId)]?.refreshRate
|
|
@@ -396,16 +431,16 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
396
431
|
const defaultRefreshRate = bridgeFeatureFlags.refreshRate;
|
|
397
432
|
this.setIntervalLength(refreshRateOverride ?? defaultRefreshRate);
|
|
398
433
|
};
|
|
399
|
-
_BridgeController_fetchBridgeQuotes.set(this, async ({
|
|
434
|
+
_BridgeController_fetchBridgeQuotes.set(this, async ({ quoteRequests, context, }) => {
|
|
400
435
|
__classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort(constants_1.AbortReason.NewQuoteRequest);
|
|
401
436
|
__classPrivateFieldSet(this, _BridgeController_abortController, new AbortController(), "f");
|
|
402
|
-
__classPrivateFieldGet(this, _BridgeController_fetchAssetExchangeRates, "f").call(this,
|
|
437
|
+
__classPrivateFieldGet(this, _BridgeController_fetchAssetExchangeRates, "f").call(this, quoteRequests).catch((error) => console.warn('Failed to fetch asset exchange rates', error));
|
|
403
438
|
this.trackUnifiedSwapBridgeEvent(constants_1.UnifiedSwapBridgeEventName.QuotesRequested, context);
|
|
404
439
|
const { sse, maxRefreshCount } = (0, feature_flags_1.getBridgeFeatureFlags)(this.messenger);
|
|
405
440
|
const shouldStream = sse?.enabled &&
|
|
406
441
|
(0, feature_flags_1.hasMinimumRequiredVersion)(__classPrivateFieldGet(this, _BridgeController_clientVersion, "f"), sse.minimumVersion);
|
|
442
|
+
const isBatchSellRequest = quoteRequests.length > 1;
|
|
407
443
|
this.update((state) => {
|
|
408
|
-
state.quoteRequest = updatedQuoteRequest;
|
|
409
444
|
state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
|
|
410
445
|
state.tokenWarnings = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.tokenWarnings;
|
|
411
446
|
state.quoteStreamComplete =
|
|
@@ -415,26 +450,30 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
415
450
|
});
|
|
416
451
|
const jwt = await __classPrivateFieldGet(this, _BridgeController_getJwt, "f").call(this);
|
|
417
452
|
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;
|
|
418
457
|
await __classPrivateFieldGet(this, _BridgeController_trace, "f").call(this, {
|
|
419
|
-
name:
|
|
420
|
-
? traces_1.TraceName.
|
|
421
|
-
:
|
|
458
|
+
name: isBatchSellRequest
|
|
459
|
+
? traces_1.TraceName.BatchSellQuotesFetched
|
|
460
|
+
: unifiedSwapTraceName,
|
|
422
461
|
data: {
|
|
423
|
-
srcChainId: (0, caip_formatters_1.formatChainIdToCaip)(
|
|
424
|
-
destChainId: (0, caip_formatters_1.formatChainIdToCaip)(
|
|
462
|
+
srcChainId: (0, caip_formatters_1.formatChainIdToCaip)(firstQuoteRequest.srcChainId),
|
|
463
|
+
destChainId: (0, caip_formatters_1.formatChainIdToCaip)(firstQuoteRequest.destChainId),
|
|
425
464
|
},
|
|
426
465
|
}, async () => {
|
|
427
|
-
const selectedAccount = __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getMultichainSelectedAccount).call(this,
|
|
466
|
+
const selectedAccount = __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getMultichainSelectedAccount).call(this, firstQuoteRequest.walletAddress);
|
|
428
467
|
// This call is not awaited to prevent blocking quote fetching if the snap takes too long to respond
|
|
429
468
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
430
|
-
__classPrivateFieldGet(this, _BridgeController_setMinimumBalanceForRentExemptionInLamports, "f").call(this,
|
|
469
|
+
__classPrivateFieldGet(this, _BridgeController_setMinimumBalanceForRentExemptionInLamports, "f").call(this, firstQuoteRequest.srcChainId, selectedAccount?.metadata?.snap?.id);
|
|
431
470
|
// Use SSE if enabled and return early
|
|
432
|
-
if (shouldStream) {
|
|
433
|
-
await __classPrivateFieldGet(this, _BridgeController_handleQuoteStreaming, "f").call(this,
|
|
471
|
+
if (shouldStream || isBatchSellRequest) {
|
|
472
|
+
await __classPrivateFieldGet(this, _BridgeController_handleQuoteStreaming, "f").call(this, quoteRequests, jwt, selectedAccount);
|
|
434
473
|
return;
|
|
435
474
|
}
|
|
436
475
|
// Otherwise use regular fetch
|
|
437
|
-
const quotes = await this.fetchQuotes(
|
|
476
|
+
const quotes = await this.fetchQuotes(firstQuoteRequest, __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.signal);
|
|
438
477
|
this.update((state) => {
|
|
439
478
|
// Set the initial load time if this is the first fetch
|
|
440
479
|
if (state.quotesRefreshCount ===
|
|
@@ -490,14 +529,17 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
490
529
|
this.update((state) => {
|
|
491
530
|
state.quotesRefreshCount += 1;
|
|
492
531
|
});
|
|
493
|
-
|
|
494
|
-
if (
|
|
495
|
-
|
|
496
|
-
|
|
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) {
|
|
497
539
|
this.stopAllPolling();
|
|
498
540
|
}
|
|
499
541
|
});
|
|
500
|
-
_BridgeController_handleQuoteStreaming.set(this, async (
|
|
542
|
+
_BridgeController_handleQuoteStreaming.set(this, async (quoteRequests, jwt, selectedAccount) => {
|
|
501
543
|
/**
|
|
502
544
|
* Tracks the number of valid quotes received from the current stream, which is used
|
|
503
545
|
* to determine when to clear the quotes list and set the initial load time
|
|
@@ -508,7 +550,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
508
550
|
* before setting quotesLoadingStatus to FETCHED
|
|
509
551
|
*/
|
|
510
552
|
const pendingFeeAppendPromises = new Set();
|
|
511
|
-
await (0, fetch_1.fetchBridgeQuoteStream)(__classPrivateFieldGet(this, _BridgeController_fetchFn, "f"),
|
|
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, {
|
|
512
554
|
onQuoteValidationFailure: __classPrivateFieldGet(this, _BridgeController_trackQuoteValidationFailures, "f"),
|
|
513
555
|
onValidQuoteReceived: async (quote) => {
|
|
514
556
|
const feeAppendPromise = (async () => {
|
|
@@ -595,15 +637,16 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
595
637
|
return undefined;
|
|
596
638
|
}
|
|
597
639
|
});
|
|
598
|
-
_BridgeController_getRequestMetadata.set(this, () => {
|
|
599
|
-
const
|
|
640
|
+
_BridgeController_getRequestMetadata.set(this, (quoteRequestIndex = 0) => {
|
|
641
|
+
const quoteRequest = this.state.quoteRequest[quoteRequestIndex];
|
|
642
|
+
const { walletAddress } = quoteRequest;
|
|
600
643
|
const accountHardwareType = (0, properties_1.getAccountHardwareType)(walletAddress
|
|
601
644
|
? __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getMultichainSelectedAccount).call(this, walletAddress)
|
|
602
645
|
: undefined);
|
|
603
646
|
return {
|
|
604
|
-
slippage_limit:
|
|
605
|
-
swap_type: (0, properties_1.getSwapTypeFromQuote)(
|
|
606
|
-
custom_slippage: (0, properties_1.isCustomSlippage)(
|
|
647
|
+
slippage_limit: quoteRequest.slippage,
|
|
648
|
+
swap_type: (0, properties_1.getSwapTypeFromQuote)(quoteRequest),
|
|
649
|
+
custom_slippage: (0, properties_1.isCustomSlippage)(quoteRequest.slippage),
|
|
607
650
|
account_hardware_type: accountHardwareType,
|
|
608
651
|
is_hardware_wallet: accountHardwareType !== null,
|
|
609
652
|
};
|
|
@@ -616,34 +659,35 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
616
659
|
has_gas_included_quote: this.state.quotes.some(({ quote }) => quote.gasIncluded),
|
|
617
660
|
};
|
|
618
661
|
});
|
|
619
|
-
_BridgeController_getEventProperties.set(this, (eventName, propertiesFromClient) => {
|
|
662
|
+
_BridgeController_getEventProperties.set(this, (eventName, propertiesFromClient, quoteRequestIndex = 0) => {
|
|
620
663
|
const clientProps = propertiesFromClient;
|
|
621
664
|
const baseProperties = {
|
|
622
665
|
...propertiesFromClient,
|
|
623
666
|
location: clientProps?.location ?? __classPrivateFieldGet(this, _BridgeController_location, "f"),
|
|
624
667
|
action_type: constants_1.MetricsActionType.SWAPBRIDGE_V1,
|
|
625
668
|
};
|
|
669
|
+
const quoteRequest = this.state.quoteRequest[quoteRequestIndex];
|
|
626
670
|
switch (eventName) {
|
|
627
671
|
case constants_1.UnifiedSwapBridgeEventName.ButtonClicked:
|
|
628
672
|
return {
|
|
629
|
-
...(0, properties_1.getRequestParams)(
|
|
673
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
630
674
|
...baseProperties,
|
|
631
675
|
};
|
|
632
676
|
case constants_1.UnifiedSwapBridgeEventName.PageViewed:
|
|
633
677
|
return {
|
|
634
|
-
...(0, properties_1.getRequestParams)(
|
|
678
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
635
679
|
...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
|
|
636
680
|
...baseProperties,
|
|
637
681
|
};
|
|
638
682
|
case constants_1.UnifiedSwapBridgeEventName.QuotesValidationFailed:
|
|
639
683
|
return {
|
|
640
|
-
...(0, properties_1.getRequestParams)(
|
|
684
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
641
685
|
refresh_count: this.state.quotesRefreshCount,
|
|
642
686
|
...baseProperties,
|
|
643
687
|
};
|
|
644
688
|
case constants_1.UnifiedSwapBridgeEventName.QuotesReceived:
|
|
645
689
|
return {
|
|
646
|
-
...(0, properties_1.getRequestParams)(
|
|
690
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
647
691
|
...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
|
|
648
692
|
...__classPrivateFieldGet(this, _BridgeController_getQuoteFetchData, "f").call(this),
|
|
649
693
|
refresh_count: this.state.quotesRefreshCount,
|
|
@@ -651,24 +695,24 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
651
695
|
};
|
|
652
696
|
case constants_1.UnifiedSwapBridgeEventName.QuotesRequested:
|
|
653
697
|
return {
|
|
654
|
-
...(0, properties_1.getRequestParams)(
|
|
698
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
655
699
|
...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
|
|
656
|
-
has_sufficient_funds: !
|
|
700
|
+
has_sufficient_funds: !quoteRequest.insufficientBal,
|
|
657
701
|
...baseProperties,
|
|
658
702
|
};
|
|
659
703
|
case constants_1.UnifiedSwapBridgeEventName.QuotesError:
|
|
660
704
|
return {
|
|
661
|
-
...(0, properties_1.getRequestParams)(
|
|
705
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
662
706
|
...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
|
|
663
707
|
error_message: this.state.quoteFetchError,
|
|
664
|
-
has_sufficient_funds: !
|
|
708
|
+
has_sufficient_funds: !quoteRequest.insufficientBal,
|
|
665
709
|
...baseProperties,
|
|
666
710
|
};
|
|
667
711
|
case constants_1.UnifiedSwapBridgeEventName.AllQuotesOpened:
|
|
668
712
|
case constants_1.UnifiedSwapBridgeEventName.AllQuotesSorted:
|
|
669
713
|
case constants_1.UnifiedSwapBridgeEventName.QuoteSelected:
|
|
670
714
|
return {
|
|
671
|
-
...(0, properties_1.getRequestParams)(
|
|
715
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
672
716
|
...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
|
|
673
717
|
...__classPrivateFieldGet(this, _BridgeController_getQuoteFetchData, "f").call(this),
|
|
674
718
|
...baseProperties,
|
|
@@ -677,7 +721,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
677
721
|
// Populate the properties that the error occurred before the tx was submitted
|
|
678
722
|
return {
|
|
679
723
|
...baseProperties,
|
|
680
|
-
...(0, properties_1.getRequestParams)(
|
|
724
|
+
...(0, properties_1.getRequestParams)(quoteRequest, this.state.tokenSecurityTypeDestination),
|
|
681
725
|
...__classPrivateFieldGet(this, _BridgeController_getRequestMetadata, "f").call(this),
|
|
682
726
|
...__classPrivateFieldGet(this, _BridgeController_getQuoteFetchData, "f").call(this),
|
|
683
727
|
...propertiesFromClient,
|
|
@@ -704,13 +748,15 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
704
748
|
return baseProperties;
|
|
705
749
|
}
|
|
706
750
|
});
|
|
707
|
-
_BridgeController_trackInputChangedEvents.set(this, (paramsToUpdate) => {
|
|
751
|
+
_BridgeController_trackInputChangedEvents.set(this, (paramsToUpdate, quoteRequestIndex = 0) => {
|
|
708
752
|
Object.entries(paramsToUpdate).forEach(([key, value]) => {
|
|
709
753
|
const inputKey = properties_1.toInputChangedPropertyKey[key];
|
|
710
754
|
const inputValue = properties_1.toInputChangedPropertyValue[key]?.(paramsToUpdate);
|
|
711
755
|
if (inputKey &&
|
|
712
756
|
inputValue !== undefined &&
|
|
713
|
-
|
|
757
|
+
this.state.quoteRequest[quoteRequestIndex] &&
|
|
758
|
+
value !==
|
|
759
|
+
this.state.quoteRequest[quoteRequestIndex][key]) {
|
|
714
760
|
this.trackUnifiedSwapBridgeEvent(constants_1.UnifiedSwapBridgeEventName.InputChanged, {
|
|
715
761
|
input: inputKey,
|
|
716
762
|
input_value: inputValue,
|
|
@@ -724,14 +770,15 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
724
770
|
*
|
|
725
771
|
* @param eventName - The name of the event to track
|
|
726
772
|
* @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
|
|
727
774
|
* @example
|
|
728
775
|
* this.trackUnifiedSwapBridgeEvent(UnifiedSwapBridgeEventName.ActionOpened, {
|
|
729
776
|
* location: MetaMetricsSwapsEventSource.MainView,
|
|
730
777
|
* });
|
|
731
778
|
*/
|
|
732
|
-
this.trackUnifiedSwapBridgeEvent = (eventName, propertiesFromClient) => {
|
|
779
|
+
this.trackUnifiedSwapBridgeEvent = (eventName, propertiesFromClient, quoteRequestIndex = 0) => {
|
|
733
780
|
try {
|
|
734
|
-
const combinedPropertiesForEvent = __classPrivateFieldGet(this, _BridgeController_getEventProperties, "f").call(this, eventName, propertiesFromClient);
|
|
781
|
+
const combinedPropertiesForEvent = __classPrivateFieldGet(this, _BridgeController_getEventProperties, "f").call(this, eventName, propertiesFromClient, quoteRequestIndex);
|
|
735
782
|
__classPrivateFieldGet(this, _BridgeController_trackMetaMetricsFn, "f").call(this, eventName, combinedPropertiesForEvent);
|
|
736
783
|
}
|
|
737
784
|
catch (error) {
|
|
@@ -773,8 +820,9 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
773
820
|
}
|
|
774
821
|
}
|
|
775
822
|
exports.BridgeController = BridgeController;
|
|
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
|
-
|
|
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;
|
|
778
826
|
if (!addressToUse) {
|
|
779
827
|
throw new Error('Account address is required');
|
|
780
828
|
}
|