@metamask-previews/bridge-status-controller 64.1.0-preview-eb60826c → 64.1.0-preview-565dfca2
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 +1 -0
- package/dist/bridge-status-controller.cjs +406 -17
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts +16 -1
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts +16 -1
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.mjs +406 -17
- package/dist/bridge-status-controller.mjs.map +1 -1
- package/dist/intent-api.cjs +58 -0
- package/dist/intent-api.cjs.map +1 -0
- package/dist/intent-api.d.cts +19 -0
- package/dist/intent-api.d.cts.map +1 -0
- package/dist/intent-api.d.mts +19 -0
- package/dist/intent-api.d.mts.map +1 -0
- package/dist/intent-api.mjs +54 -0
- package/dist/intent-api.mjs.map +1 -0
- package/dist/intent-order-status.cjs +14 -0
- package/dist/intent-order-status.cjs.map +1 -0
- package/dist/intent-order-status.d.cts +10 -0
- package/dist/intent-order-status.d.cts.map +1 -0
- package/dist/intent-order-status.d.mts +10 -0
- package/dist/intent-order-status.d.mts.map +1 -0
- package/dist/intent-order-status.mjs +11 -0
- package/dist/intent-order-status.mjs.map +1 -0
- package/dist/intent-order.cjs +4 -0
- package/dist/intent-order.cjs.map +1 -0
- package/dist/intent-order.d.cts +10 -0
- package/dist/intent-order.d.cts.map +1 -0
- package/dist/intent-order.d.mts +10 -0
- package/dist/intent-order.d.mts.map +1 -0
- package/dist/intent-order.mjs +2 -0
- package/dist/intent-order.mjs.map +1 -0
- package/dist/types.cjs +9 -7
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +26 -16
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +26 -16
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +9 -7
- package/dist/types.mjs.map +1 -1
- package/dist/utils/transaction.d.cts +21 -2
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +21 -2
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/validators.d.cts +1 -0
- package/dist/utils/validators.d.cts.map +1 -1
- package/dist/utils/validators.d.mts +1 -0
- package/dist/utils/validators.d.mts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
11
|
|
|
12
|
+
- **BREAKING** Use CrossChain API instead of the intent manager package for intent order submission ([#6547](https://github.com/MetaMask/core/pull/6547))
|
|
12
13
|
- Bump `@metamask/transaction-controller` from `^62.5.0` to `^62.6.0` ([#7430](https://github.com/MetaMask/core/pull/7430))
|
|
13
14
|
|
|
14
15
|
## [64.1.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 _BridgeStatusController_instances, _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionFn, _BridgeStatusController_addTransactionBatchFn, _BridgeStatusController_updateTransactionFn, _BridgeStatusController_estimateGasFeeFn, _BridgeStatusController_trace, _BridgeStatusController_markTxAsFailed, _BridgeStatusController_restartPollingForIncompleteHistoryItems, _BridgeStatusController_addTxToHistory, _BridgeStatusController_startPollingForTxId, _BridgeStatusController_getMultichainSelectedAccount, _BridgeStatusController_handleFetchFailure, _BridgeStatusController_fetchBridgeTxStatus, _BridgeStatusController_getSrcTxHash, _BridgeStatusController_updateSrcTxHash, _BridgeStatusController_wipeBridgeStatusByChainId, _BridgeStatusController_handleNonEvmTx, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, _BridgeStatusController_handleApprovalTx, _BridgeStatusController_handleEvmTransaction, _BridgeStatusController_handleUSDTAllowanceReset, _BridgeStatusController_calculateGasFees, _BridgeStatusController_handleEvmTransactionBatch, _BridgeStatusController_trackUnifiedSwapBridgeEvent;
|
|
13
|
+
var _BridgeStatusController_instances, _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionFn, _BridgeStatusController_addTransactionBatchFn, _BridgeStatusController_updateTransactionFn, _BridgeStatusController_estimateGasFeeFn, _BridgeStatusController_trace, _BridgeStatusController_markTxAsFailed, _BridgeStatusController_restartPollingForIncompleteHistoryItems, _BridgeStatusController_addTxToHistory, _BridgeStatusController_startPollingForTxId, _BridgeStatusController_getMultichainSelectedAccount, _BridgeStatusController_handleFetchFailure, _BridgeStatusController_fetchBridgeTxStatus, _BridgeStatusController_fetchIntentOrderStatus, _BridgeStatusController_updateBridgeHistoryFromIntentOrder, _BridgeStatusController_getSrcTxHash, _BridgeStatusController_updateSrcTxHash, _BridgeStatusController_wipeBridgeStatusByChainId, _BridgeStatusController_handleNonEvmTx, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, _BridgeStatusController_waitForTxConfirmation, _BridgeStatusController_handleApprovalTx, _BridgeStatusController_handleEvmTransaction, _BridgeStatusController_handleUSDTAllowanceReset, _BridgeStatusController_calculateGasFees, _BridgeStatusController_handleEvmTransactionBatch, _BridgeStatusController_convertBridgeQuoteToIntentQuote, _BridgeStatusController_mapIntentOrderStatusToTransactionStatus, _BridgeStatusController_trackUnifiedSwapBridgeEvent;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.BridgeStatusController = void 0;
|
|
16
16
|
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
@@ -19,6 +19,8 @@ const polling_controller_1 = require("@metamask/polling-controller");
|
|
|
19
19
|
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
20
20
|
const utils_1 = require("@metamask/utils");
|
|
21
21
|
const constants_1 = require("./constants.cjs");
|
|
22
|
+
const intent_api_1 = require("./intent-api.cjs");
|
|
23
|
+
const intent_order_status_1 = require("./intent-order-status.cjs");
|
|
22
24
|
const types_1 = require("./types.cjs");
|
|
23
25
|
const bridge_status_1 = require("./utils/bridge-status.cjs");
|
|
24
26
|
const gas_1 = require("./utils/gas.cjs");
|
|
@@ -180,6 +182,8 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
180
182
|
// We know it's in progress but not the exact status yet
|
|
181
183
|
const txHistoryItem = {
|
|
182
184
|
txMetaId: bridgeTxMeta.id,
|
|
185
|
+
originalTransactionId: bridgeTxMeta
|
|
186
|
+
.originalTransactionId || bridgeTxMeta.id, // Keep original for intent transactions
|
|
183
187
|
batchId: bridgeTxMeta.batchId,
|
|
184
188
|
quote: quoteResponse.quote,
|
|
185
189
|
startTime,
|
|
@@ -225,8 +229,9 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
225
229
|
return;
|
|
226
230
|
}
|
|
227
231
|
const { quote } = txHistoryItem;
|
|
232
|
+
const isIntent = txId.startsWith('intent:');
|
|
228
233
|
const isBridgeTx = (0, bridge_controller_1.isCrossChain)(quote.srcChainId, quote.destChainId);
|
|
229
|
-
if (isBridgeTx) {
|
|
234
|
+
if (isBridgeTx || isIntent) {
|
|
230
235
|
__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId] = this.startPolling({
|
|
231
236
|
bridgeTxMetaId: txId,
|
|
232
237
|
});
|
|
@@ -285,6 +290,11 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
285
290
|
});
|
|
286
291
|
_BridgeStatusController_fetchBridgeTxStatus.set(this, async ({ bridgeTxMetaId, }) => {
|
|
287
292
|
const { txHistory } = this.state;
|
|
293
|
+
// Intent-based items: poll intent provider instead of Bridge API
|
|
294
|
+
if (bridgeTxMetaId.startsWith('intent:')) {
|
|
295
|
+
await __classPrivateFieldGet(this, _BridgeStatusController_fetchIntentOrderStatus, "f").call(this, { bridgeTxMetaId });
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
288
298
|
if ((0, bridge_status_1.shouldSkipFetchDueToFetchFailures)(txHistory[bridgeTxMetaId]?.attempts)) {
|
|
289
299
|
return;
|
|
290
300
|
}
|
|
@@ -341,8 +351,33 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
341
351
|
}
|
|
342
352
|
}
|
|
343
353
|
}
|
|
344
|
-
catch (
|
|
345
|
-
console.warn('Failed to fetch bridge tx status',
|
|
354
|
+
catch (error) {
|
|
355
|
+
console.warn('Failed to fetch bridge tx status', error);
|
|
356
|
+
__classPrivateFieldGet(this, _BridgeStatusController_handleFetchFailure, "f").call(this, bridgeTxMetaId);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
_BridgeStatusController_fetchIntentOrderStatus.set(this, async ({ bridgeTxMetaId, }) => {
|
|
360
|
+
const { txHistory } = this.state;
|
|
361
|
+
const historyItem = txHistory[bridgeTxMetaId];
|
|
362
|
+
if (!historyItem) {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
// Backoff handling
|
|
366
|
+
if ((0, bridge_status_1.shouldSkipFetchDueToFetchFailures)(historyItem.attempts)) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const orderId = bridgeTxMetaId.replace(/^intent:/u, '');
|
|
371
|
+
const { srcChainId } = historyItem.quote;
|
|
372
|
+
// Extract provider name from order metadata or default to empty
|
|
373
|
+
const providerName = historyItem.quote.intent?.protocol ?? '';
|
|
374
|
+
const intentApi = new intent_api_1.IntentApiImpl(__classPrivateFieldGet(this, _BridgeStatusController_config, "f").customBridgeApiBaseUrl, __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"));
|
|
375
|
+
const intentOrder = (await intentApi.getOrderStatus(orderId, providerName, srcChainId.toString()));
|
|
376
|
+
// Update bridge history with intent order status
|
|
377
|
+
__classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_updateBridgeHistoryFromIntentOrder).call(this, bridgeTxMetaId, intentOrder, historyItem);
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
console.error('Failed to fetch intent order status:', error);
|
|
346
381
|
__classPrivateFieldGet(this, _BridgeStatusController_handleFetchFailure, "f").call(this, bridgeTxMetaId);
|
|
347
382
|
}
|
|
348
383
|
});
|
|
@@ -433,6 +468,36 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
433
468
|
}
|
|
434
469
|
return finalTransactionMeta;
|
|
435
470
|
});
|
|
471
|
+
// Waits until a given transaction (by id) reaches confirmed/finalized status or fails/times out.
|
|
472
|
+
_BridgeStatusController_waitForTxConfirmation.set(this, async (txId, { timeoutMs = 5 * 60000, // 5 minutes default
|
|
473
|
+
pollMs = 2000, } = {}) => {
|
|
474
|
+
const start = Date.now();
|
|
475
|
+
// Poll the TransactionController state for status changes
|
|
476
|
+
// We intentionally keep this simple to avoid extra wiring/subscriptions in this controller
|
|
477
|
+
// and because we only need it for the rare intent+approval path.
|
|
478
|
+
while (true) {
|
|
479
|
+
const { transactions } = this.messenger.call('TransactionController:getState');
|
|
480
|
+
const meta = transactions.find((tx) => tx.id === txId);
|
|
481
|
+
if (meta) {
|
|
482
|
+
// Treat both 'confirmed' and 'finalized' as success to match TC lifecycle
|
|
483
|
+
if (meta.status === transaction_controller_1.TransactionStatus.confirmed ||
|
|
484
|
+
// Some environments move directly to finalized
|
|
485
|
+
transaction_controller_1.TransactionStatus.finalized ===
|
|
486
|
+
meta.status) {
|
|
487
|
+
return meta;
|
|
488
|
+
}
|
|
489
|
+
if (meta.status === transaction_controller_1.TransactionStatus.failed ||
|
|
490
|
+
meta.status === transaction_controller_1.TransactionStatus.dropped ||
|
|
491
|
+
meta.status === transaction_controller_1.TransactionStatus.rejected) {
|
|
492
|
+
throw new Error('Approval transaction did not confirm');
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (Date.now() - start > timeoutMs) {
|
|
496
|
+
throw new Error('Timed out waiting for approval confirmation');
|
|
497
|
+
}
|
|
498
|
+
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
499
|
+
}
|
|
500
|
+
});
|
|
436
501
|
_BridgeStatusController_handleApprovalTx.set(this, async (isBridgeTx, srcChainId, approval, resetApproval, requireApproval) => {
|
|
437
502
|
if (approval) {
|
|
438
503
|
const approveTx = async () => {
|
|
@@ -486,11 +551,17 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
486
551
|
type: transactionType,
|
|
487
552
|
origin: 'metamask',
|
|
488
553
|
};
|
|
554
|
+
// Exclude gasLimit from trade to avoid type issues (it can be null)
|
|
555
|
+
const { gasLimit: tradeGasLimit, ...tradeWithoutGasLimit } = trade;
|
|
489
556
|
const transactionParams = {
|
|
490
|
-
...
|
|
557
|
+
...tradeWithoutGasLimit,
|
|
491
558
|
chainId: hexChainId,
|
|
492
|
-
gasLimit
|
|
493
|
-
|
|
559
|
+
// Only add gasLimit and gas if they're valid (not undefined/null/zero)
|
|
560
|
+
...(tradeGasLimit &&
|
|
561
|
+
tradeGasLimit !== 0 && {
|
|
562
|
+
gasLimit: tradeGasLimit.toString(),
|
|
563
|
+
gas: tradeGasLimit.toString(),
|
|
564
|
+
}),
|
|
494
565
|
};
|
|
495
566
|
const transactionParamsWithMaxGas = {
|
|
496
567
|
...transactionParams,
|
|
@@ -737,6 +808,168 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
737
808
|
}
|
|
738
809
|
return txMeta;
|
|
739
810
|
};
|
|
811
|
+
/**
|
|
812
|
+
* UI-signed intent submission (fast path): the UI generates the EIP-712 signature and calls this with the raw signature.
|
|
813
|
+
* Here we submit the order to the intent provider and create a synthetic history entry for UX.
|
|
814
|
+
*
|
|
815
|
+
* @param params - Object containing intent submission parameters
|
|
816
|
+
* @param params.quoteResponse - Quote carrying intent data
|
|
817
|
+
* @param params.signature - Hex signature produced by eth_signTypedData_v4
|
|
818
|
+
* @param params.accountAddress - The EOA submitting the order
|
|
819
|
+
* @returns A lightweight TransactionMeta-like object for history linking
|
|
820
|
+
*/
|
|
821
|
+
this.submitIntent = async (params) => {
|
|
822
|
+
const { quoteResponse, signature, accountAddress } = params;
|
|
823
|
+
// Build pre-confirmation properties for error tracking parity with submitTx
|
|
824
|
+
const account = this.messenger.call('AccountsController:getAccountByAddress', accountAddress);
|
|
825
|
+
const isHardwareAccount = Boolean(account) && (0, bridge_controller_1.isHardwareWallet)(account);
|
|
826
|
+
const preConfirmationProperties = (0, metrics_1.getPreConfirmationPropertiesFromQuote)(quoteResponse, false, isHardwareAccount);
|
|
827
|
+
try {
|
|
828
|
+
const { intent } = quoteResponse
|
|
829
|
+
.quote;
|
|
830
|
+
if (!intent) {
|
|
831
|
+
throw new Error('submitIntent: missing intent data');
|
|
832
|
+
}
|
|
833
|
+
// If backend provided an approval tx for this intent quote, submit it first (on-chain),
|
|
834
|
+
// then proceed with off-chain intent submission.
|
|
835
|
+
let approvalTxId;
|
|
836
|
+
if (quoteResponse.approval) {
|
|
837
|
+
const isBridgeTx = (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
838
|
+
// Handle approval silently for better UX in intent flows
|
|
839
|
+
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, isBridgeTx, quoteResponse.quote.srcChainId, quoteResponse.approval && (0, bridge_controller_1.isEvmTxData)(quoteResponse.approval)
|
|
840
|
+
? quoteResponse.approval
|
|
841
|
+
: undefined, quoteResponse.resetApproval,
|
|
842
|
+
/* requireApproval */ false);
|
|
843
|
+
approvalTxId = approvalTxMeta?.id;
|
|
844
|
+
// Optionally wait for approval confirmation with timeout and graceful fallback
|
|
845
|
+
// Intent order can be created before allowance is mined, but waiting helps avoid MEV issues
|
|
846
|
+
if (approvalTxId) {
|
|
847
|
+
try {
|
|
848
|
+
// Wait with a shorter timeout and continue if it fails
|
|
849
|
+
await __classPrivateFieldGet(this, _BridgeStatusController_waitForTxConfirmation, "f").call(this, approvalTxId, {
|
|
850
|
+
timeoutMs: 30000, // 30 seconds instead of 5 minutes
|
|
851
|
+
pollMs: 3000, // Poll less frequently to avoid rate limits
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
catch (error) {
|
|
855
|
+
// Log but don't throw - continue with intent order submission
|
|
856
|
+
console.warn('Approval confirmation failed, continuing with intent submission:', error);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
// Create intent quote from bridge quote response
|
|
861
|
+
const intentQuote = __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_convertBridgeQuoteToIntentQuote).call(this, quoteResponse, intent);
|
|
862
|
+
const chainId = quoteResponse.quote.srcChainId;
|
|
863
|
+
const submissionParams = {
|
|
864
|
+
srcChainId: chainId.toString(),
|
|
865
|
+
quoteId: intentQuote.id,
|
|
866
|
+
signature,
|
|
867
|
+
order: intentQuote.metadata.order,
|
|
868
|
+
userAddress: accountAddress,
|
|
869
|
+
aggregatorId: 'cowswap',
|
|
870
|
+
};
|
|
871
|
+
const intentApi = new intent_api_1.IntentApiImpl(__classPrivateFieldGet(this, _BridgeStatusController_config, "f").customBridgeApiBaseUrl, __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"));
|
|
872
|
+
const intentOrder = (await intentApi.submitIntent(submissionParams));
|
|
873
|
+
const orderUid = intentOrder.id;
|
|
874
|
+
// Determine transaction type: swap for same-chain, bridge for cross-chain
|
|
875
|
+
const isCrossChainTx = (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
876
|
+
const transactionType = isCrossChainTx
|
|
877
|
+
? transaction_controller_1.TransactionType.bridge
|
|
878
|
+
: transaction_controller_1.TransactionType.swap;
|
|
879
|
+
// Create actual transaction in Transaction Controller first
|
|
880
|
+
const networkClientId = this.messenger.call('NetworkController:findNetworkClientIdByChainId', (0, bridge_controller_1.formatChainIdToHex)(chainId));
|
|
881
|
+
const intentTransactionParams = {
|
|
882
|
+
chainId: (0, bridge_controller_1.formatChainIdToHex)(chainId),
|
|
883
|
+
from: accountAddress,
|
|
884
|
+
to: intent.settlementContract ??
|
|
885
|
+
'0x9008D19f58AAbd9eD0D60971565AA8510560ab41', // Default settlement contract
|
|
886
|
+
data: `0x${orderUid.slice(-8)}`, // Use last 8 chars of orderUid to make each transaction unique
|
|
887
|
+
value: '0x0',
|
|
888
|
+
gas: '0x5208', // Minimal gas for display purposes
|
|
889
|
+
gasPrice: '0x3b9aca00', // 1 Gwei - will be converted to EIP-1559 fees if network supports it
|
|
890
|
+
};
|
|
891
|
+
const { transactionMeta: txMetaPromise } = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionFn, "f").call(this, intentTransactionParams, {
|
|
892
|
+
origin: 'metamask',
|
|
893
|
+
actionId: (0, transaction_1.generateActionId)(),
|
|
894
|
+
requireApproval: false,
|
|
895
|
+
networkClientId,
|
|
896
|
+
type: transactionType,
|
|
897
|
+
swaps: {
|
|
898
|
+
meta: {
|
|
899
|
+
// Add token symbols from quoteResponse for proper display
|
|
900
|
+
sourceTokenSymbol: quoteResponse.quote.srcAsset.symbol,
|
|
901
|
+
destinationTokenSymbol: quoteResponse.quote.destAsset.symbol,
|
|
902
|
+
sourceTokenAmount: quoteResponse.quote.srcTokenAmount,
|
|
903
|
+
destinationTokenAmount: quoteResponse.quote.destTokenAmount,
|
|
904
|
+
sourceTokenDecimals: quoteResponse.quote.srcAsset.decimals,
|
|
905
|
+
destinationTokenDecimals: quoteResponse.quote.destAsset.decimals,
|
|
906
|
+
sourceTokenAddress: quoteResponse.quote.srcAsset.address,
|
|
907
|
+
destinationTokenAddress: quoteResponse.quote.destAsset.address,
|
|
908
|
+
swapTokenValue: quoteResponse.sentAmount.amount,
|
|
909
|
+
approvalTxId,
|
|
910
|
+
swapMetaData: {
|
|
911
|
+
isIntentTx: true,
|
|
912
|
+
orderUid,
|
|
913
|
+
intentType: isCrossChainTx ? 'bridge' : 'swap',
|
|
914
|
+
},
|
|
915
|
+
},
|
|
916
|
+
},
|
|
917
|
+
});
|
|
918
|
+
const intentTxMeta = txMetaPromise;
|
|
919
|
+
// Map intent order status to TransactionController status
|
|
920
|
+
const initialTransactionStatus = __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_mapIntentOrderStatusToTransactionStatus).call(this, intentOrder.status);
|
|
921
|
+
// Update transaction with proper initial status based on intent order
|
|
922
|
+
const statusUpdatedTxMeta = {
|
|
923
|
+
...intentTxMeta,
|
|
924
|
+
status: initialTransactionStatus,
|
|
925
|
+
};
|
|
926
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateTransactionFn, "f").call(this, statusUpdatedTxMeta, `BridgeStatusController - Initial intent order status: ${intentOrder.status}`);
|
|
927
|
+
// Update with actual transaction metadata
|
|
928
|
+
const syntheticMeta = {
|
|
929
|
+
...statusUpdatedTxMeta,
|
|
930
|
+
isIntentTx: true,
|
|
931
|
+
orderUid,
|
|
932
|
+
intentType: isCrossChainTx ? 'bridge' : 'swap',
|
|
933
|
+
};
|
|
934
|
+
// Record in bridge history with actual transaction metadata
|
|
935
|
+
try {
|
|
936
|
+
// Use 'intent:' prefix for intent transactions
|
|
937
|
+
const bridgeHistoryKey = `intent:${orderUid}`;
|
|
938
|
+
// Create a bridge transaction metadata that includes the original txId
|
|
939
|
+
const bridgeTxMetaForHistory = {
|
|
940
|
+
...syntheticMeta,
|
|
941
|
+
id: bridgeHistoryKey, // Use intent: prefix for bridge history key
|
|
942
|
+
originalTransactionId: syntheticMeta.id, // Keep original txId for TransactionController updates
|
|
943
|
+
};
|
|
944
|
+
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
945
|
+
accountAddress,
|
|
946
|
+
bridgeTxMeta: bridgeTxMetaForHistory,
|
|
947
|
+
statusRequest: {
|
|
948
|
+
...(0, transaction_1.getStatusRequestParams)(quoteResponse),
|
|
949
|
+
srcTxHash: syntheticMeta.hash ?? '',
|
|
950
|
+
},
|
|
951
|
+
quoteResponse,
|
|
952
|
+
slippagePercentage: 0,
|
|
953
|
+
isStxEnabled: false,
|
|
954
|
+
approvalTxId,
|
|
955
|
+
});
|
|
956
|
+
// Start polling using the intent: prefixed key to route to intent manager
|
|
957
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeHistoryKey);
|
|
958
|
+
}
|
|
959
|
+
catch (error) {
|
|
960
|
+
console.error('📝 [submitIntent] Failed to add to bridge history', error);
|
|
961
|
+
// non-fatal but log the error
|
|
962
|
+
}
|
|
963
|
+
return syntheticMeta;
|
|
964
|
+
}
|
|
965
|
+
catch (error) {
|
|
966
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, undefined, {
|
|
967
|
+
error_message: error?.message,
|
|
968
|
+
...preConfirmationProperties,
|
|
969
|
+
});
|
|
970
|
+
throw error;
|
|
971
|
+
}
|
|
972
|
+
};
|
|
740
973
|
/**
|
|
741
974
|
* Tracks post-submission events for a cross-chain swap based on the history item
|
|
742
975
|
*
|
|
@@ -759,16 +992,19 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
759
992
|
this.messenger.call('BridgeController:trackUnifiedSwapBridgeEvent', eventName, eventProperties ?? {});
|
|
760
993
|
return;
|
|
761
994
|
}
|
|
995
|
+
const selectedAccount = this.messenger.call('AccountsController:getAccountByAddress', historyItem.account);
|
|
996
|
+
const { transactions } = this.messenger.call('TransactionController:getState');
|
|
997
|
+
const txMeta = transactions?.find((tx) => tx.id === txMetaId);
|
|
998
|
+
const approvalTxMeta = transactions?.find((tx) => tx.id === historyItem.approvalTxId);
|
|
762
999
|
const requestParamProperties = (0, metrics_1.getRequestParamFromHistory)(historyItem);
|
|
763
1000
|
// Always publish StatusValidationFailed event, regardless of featureId
|
|
764
1001
|
if (eventName === bridge_controller_1.UnifiedSwapBridgeEventName.StatusValidationFailed) {
|
|
765
|
-
const { chain_id_source, chain_id_destination, token_address_source, token_address_destination, } = requestParamProperties;
|
|
766
1002
|
this.messenger.call('BridgeController:trackUnifiedSwapBridgeEvent', eventName, {
|
|
767
1003
|
...baseProperties,
|
|
768
|
-
chain_id_source,
|
|
769
|
-
chain_id_destination,
|
|
770
|
-
token_address_source,
|
|
771
|
-
token_address_destination,
|
|
1004
|
+
chain_id_source: requestParamProperties.chain_id_source,
|
|
1005
|
+
chain_id_destination: requestParamProperties.chain_id_destination,
|
|
1006
|
+
token_address_source: requestParamProperties.token_address_source,
|
|
1007
|
+
token_address_destination: requestParamProperties.token_address_destination,
|
|
772
1008
|
refresh_count: historyItem.attempts?.counter ?? 0,
|
|
773
1009
|
});
|
|
774
1010
|
return;
|
|
@@ -777,10 +1013,6 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
777
1013
|
if (historyItem.featureId) {
|
|
778
1014
|
return;
|
|
779
1015
|
}
|
|
780
|
-
const selectedAccount = this.messenger.call('AccountsController:getAccountByAddress', historyItem.account);
|
|
781
|
-
const { transactions } = this.messenger.call('TransactionController:getState');
|
|
782
|
-
const txMeta = transactions?.find(({ id }) => id === txMetaId);
|
|
783
|
-
const approvalTxMeta = transactions?.find(({ id }) => id === historyItem.approvalTxId);
|
|
784
1016
|
const requiredEventProperties = {
|
|
785
1017
|
...baseProperties,
|
|
786
1018
|
...requestParamProperties,
|
|
@@ -807,12 +1039,19 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
807
1039
|
this.messenger.registerActionHandler(`${constants_1.BRIDGE_STATUS_CONTROLLER_NAME}:wipeBridgeStatus`, this.wipeBridgeStatus.bind(this));
|
|
808
1040
|
this.messenger.registerActionHandler(`${constants_1.BRIDGE_STATUS_CONTROLLER_NAME}:resetState`, this.resetState.bind(this));
|
|
809
1041
|
this.messenger.registerActionHandler(`${constants_1.BRIDGE_STATUS_CONTROLLER_NAME}:submitTx`, this.submitTx.bind(this));
|
|
1042
|
+
this.messenger.registerActionHandler(`${constants_1.BRIDGE_STATUS_CONTROLLER_NAME}:submitIntent`, this.submitIntent.bind(this));
|
|
810
1043
|
this.messenger.registerActionHandler(`${constants_1.BRIDGE_STATUS_CONTROLLER_NAME}:restartPollingForFailedAttempts`, this.restartPollingForFailedAttempts.bind(this));
|
|
811
1044
|
this.messenger.registerActionHandler(`${constants_1.BRIDGE_STATUS_CONTROLLER_NAME}:getBridgeHistoryItemByTxMetaId`, this.getBridgeHistoryItemByTxMetaId.bind(this));
|
|
812
1045
|
// Set interval
|
|
813
1046
|
this.setIntervalLength(constants_1.REFRESH_INTERVAL_MS);
|
|
814
1047
|
this.messenger.subscribe('TransactionController:transactionFailed', ({ transactionMeta }) => {
|
|
815
1048
|
const { type, status, id } = transactionMeta;
|
|
1049
|
+
// Skip intent transactions - they have their own tracking via CoW API
|
|
1050
|
+
// Skip intent transactions - they have their own tracking via CoW API
|
|
1051
|
+
if (transactionMeta
|
|
1052
|
+
.swapMetaData?.isIntentTx) {
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
816
1055
|
if (type &&
|
|
817
1056
|
[
|
|
818
1057
|
transaction_controller_1.TransactionType.bridge,
|
|
@@ -849,7 +1088,157 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
849
1088
|
}
|
|
850
1089
|
}
|
|
851
1090
|
exports.BridgeStatusController = BridgeStatusController;
|
|
852
|
-
_BridgeStatusController_pollingTokensByTxMetaId = new WeakMap(), _BridgeStatusController_clientId = new WeakMap(), _BridgeStatusController_fetchFn = new WeakMap(), _BridgeStatusController_config = new WeakMap(), _BridgeStatusController_addTransactionFn = new WeakMap(), _BridgeStatusController_addTransactionBatchFn = new WeakMap(), _BridgeStatusController_updateTransactionFn = new WeakMap(), _BridgeStatusController_estimateGasFeeFn = new WeakMap(), _BridgeStatusController_trace = new WeakMap(), _BridgeStatusController_markTxAsFailed = new WeakMap(), _BridgeStatusController_restartPollingForIncompleteHistoryItems = new WeakMap(), _BridgeStatusController_addTxToHistory = new WeakMap(), _BridgeStatusController_startPollingForTxId = new WeakMap(), _BridgeStatusController_handleFetchFailure = new WeakMap(), _BridgeStatusController_fetchBridgeTxStatus = new WeakMap(), _BridgeStatusController_getSrcTxHash = new WeakMap(), _BridgeStatusController_updateSrcTxHash = new WeakMap(), _BridgeStatusController_wipeBridgeStatusByChainId = new WeakMap(), _BridgeStatusController_handleNonEvmTx = new WeakMap(), _BridgeStatusController_waitForHashAndReturnFinalTxMeta = new WeakMap(), _BridgeStatusController_handleApprovalTx = new WeakMap(), _BridgeStatusController_handleEvmTransaction = new WeakMap(), _BridgeStatusController_handleUSDTAllowanceReset = new WeakMap(), _BridgeStatusController_calculateGasFees = new WeakMap(), _BridgeStatusController_handleEvmTransactionBatch = new WeakMap(), _BridgeStatusController_trackUnifiedSwapBridgeEvent = new WeakMap(), _BridgeStatusController_instances = new WeakSet(), _BridgeStatusController_getMultichainSelectedAccount = function _BridgeStatusController_getMultichainSelectedAccount(accountAddress) {
|
|
1091
|
+
_BridgeStatusController_pollingTokensByTxMetaId = new WeakMap(), _BridgeStatusController_clientId = new WeakMap(), _BridgeStatusController_fetchFn = new WeakMap(), _BridgeStatusController_config = new WeakMap(), _BridgeStatusController_addTransactionFn = new WeakMap(), _BridgeStatusController_addTransactionBatchFn = new WeakMap(), _BridgeStatusController_updateTransactionFn = new WeakMap(), _BridgeStatusController_estimateGasFeeFn = new WeakMap(), _BridgeStatusController_trace = new WeakMap(), _BridgeStatusController_markTxAsFailed = new WeakMap(), _BridgeStatusController_restartPollingForIncompleteHistoryItems = new WeakMap(), _BridgeStatusController_addTxToHistory = new WeakMap(), _BridgeStatusController_startPollingForTxId = new WeakMap(), _BridgeStatusController_handleFetchFailure = new WeakMap(), _BridgeStatusController_fetchBridgeTxStatus = new WeakMap(), _BridgeStatusController_fetchIntentOrderStatus = new WeakMap(), _BridgeStatusController_getSrcTxHash = new WeakMap(), _BridgeStatusController_updateSrcTxHash = new WeakMap(), _BridgeStatusController_wipeBridgeStatusByChainId = new WeakMap(), _BridgeStatusController_handleNonEvmTx = new WeakMap(), _BridgeStatusController_waitForHashAndReturnFinalTxMeta = new WeakMap(), _BridgeStatusController_waitForTxConfirmation = new WeakMap(), _BridgeStatusController_handleApprovalTx = new WeakMap(), _BridgeStatusController_handleEvmTransaction = new WeakMap(), _BridgeStatusController_handleUSDTAllowanceReset = new WeakMap(), _BridgeStatusController_calculateGasFees = new WeakMap(), _BridgeStatusController_handleEvmTransactionBatch = new WeakMap(), _BridgeStatusController_trackUnifiedSwapBridgeEvent = new WeakMap(), _BridgeStatusController_instances = new WeakSet(), _BridgeStatusController_getMultichainSelectedAccount = function _BridgeStatusController_getMultichainSelectedAccount(accountAddress) {
|
|
853
1092
|
return this.messenger.call('AccountsController:getAccountByAddress', accountAddress);
|
|
1093
|
+
}, _BridgeStatusController_updateBridgeHistoryFromIntentOrder = function _BridgeStatusController_updateBridgeHistoryFromIntentOrder(bridgeTxMetaId, intentOrder, historyItem) {
|
|
1094
|
+
const { srcChainId } = historyItem.quote;
|
|
1095
|
+
// Map intent order status to bridge status using enum values
|
|
1096
|
+
let statusType;
|
|
1097
|
+
const isComplete = [
|
|
1098
|
+
intent_order_status_1.IntentOrderStatus.CONFIRMED,
|
|
1099
|
+
intent_order_status_1.IntentOrderStatus.COMPLETED,
|
|
1100
|
+
].includes(intentOrder.status);
|
|
1101
|
+
const isFailed = [
|
|
1102
|
+
intent_order_status_1.IntentOrderStatus.FAILED,
|
|
1103
|
+
intent_order_status_1.IntentOrderStatus.EXPIRED,
|
|
1104
|
+
].includes(intentOrder.status);
|
|
1105
|
+
const isPending = [intent_order_status_1.IntentOrderStatus.PENDING].includes(intentOrder.status);
|
|
1106
|
+
const isSubmitted = [intent_order_status_1.IntentOrderStatus.SUBMITTED].includes(intentOrder.status);
|
|
1107
|
+
if (isComplete) {
|
|
1108
|
+
statusType = bridge_controller_1.StatusTypes.COMPLETE;
|
|
1109
|
+
}
|
|
1110
|
+
else if (isFailed) {
|
|
1111
|
+
statusType = bridge_controller_1.StatusTypes.FAILED;
|
|
1112
|
+
}
|
|
1113
|
+
else if (isPending) {
|
|
1114
|
+
statusType = bridge_controller_1.StatusTypes.PENDING;
|
|
1115
|
+
}
|
|
1116
|
+
else if (isSubmitted) {
|
|
1117
|
+
statusType = bridge_controller_1.StatusTypes.SUBMITTED;
|
|
1118
|
+
}
|
|
1119
|
+
else {
|
|
1120
|
+
statusType = bridge_controller_1.StatusTypes.UNKNOWN;
|
|
1121
|
+
}
|
|
1122
|
+
// Extract transaction hashes from intent order
|
|
1123
|
+
const txHash = intentOrder.txHash ?? '';
|
|
1124
|
+
// Check metadata for additional transaction hashes
|
|
1125
|
+
const metadataTxHashes = Array.isArray(intentOrder.metadata.txHashes)
|
|
1126
|
+
? intentOrder.metadata.txHashes
|
|
1127
|
+
: [];
|
|
1128
|
+
let allHashes;
|
|
1129
|
+
if (metadataTxHashes.length > 0) {
|
|
1130
|
+
allHashes = metadataTxHashes;
|
|
1131
|
+
}
|
|
1132
|
+
else if (txHash) {
|
|
1133
|
+
allHashes = [txHash];
|
|
1134
|
+
}
|
|
1135
|
+
else {
|
|
1136
|
+
allHashes = [];
|
|
1137
|
+
}
|
|
1138
|
+
const newStatus = {
|
|
1139
|
+
status: statusType,
|
|
1140
|
+
srcChain: {
|
|
1141
|
+
chainId: srcChainId,
|
|
1142
|
+
txHash: txHash ?? historyItem.status.srcChain.txHash ?? '',
|
|
1143
|
+
},
|
|
1144
|
+
};
|
|
1145
|
+
const newBridgeHistoryItem = {
|
|
1146
|
+
...historyItem,
|
|
1147
|
+
status: newStatus,
|
|
1148
|
+
completionTime: newStatus.status === bridge_controller_1.StatusTypes.COMPLETE ||
|
|
1149
|
+
newStatus.status === bridge_controller_1.StatusTypes.FAILED
|
|
1150
|
+
? Date.now()
|
|
1151
|
+
: undefined,
|
|
1152
|
+
attempts: undefined,
|
|
1153
|
+
srcTxHashes: allHashes.length > 0
|
|
1154
|
+
? Array.from(new Set([...(historyItem.srcTxHashes ?? []), ...allHashes]))
|
|
1155
|
+
: historyItem.srcTxHashes,
|
|
1156
|
+
};
|
|
1157
|
+
this.update((state) => {
|
|
1158
|
+
state.txHistory[bridgeTxMetaId] = newBridgeHistoryItem;
|
|
1159
|
+
});
|
|
1160
|
+
// Update the actual transaction in TransactionController to sync with intent status
|
|
1161
|
+
// Use the original transaction ID (not the intent: prefixed bridge history key)
|
|
1162
|
+
const originalTxId = historyItem.originalTransactionId ?? historyItem.txMetaId;
|
|
1163
|
+
if (originalTxId && !originalTxId.startsWith('intent:')) {
|
|
1164
|
+
try {
|
|
1165
|
+
const transactionStatus = __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_mapIntentOrderStatusToTransactionStatus).call(this, intentOrder.status);
|
|
1166
|
+
// Merge with existing TransactionMeta to avoid wiping required fields
|
|
1167
|
+
const { transactions } = this.messenger.call('TransactionController:getState');
|
|
1168
|
+
const existingTxMeta = transactions.find((tx) => tx.id === originalTxId);
|
|
1169
|
+
if (existingTxMeta) {
|
|
1170
|
+
const updatedTxMeta = {
|
|
1171
|
+
...existingTxMeta,
|
|
1172
|
+
status: transactionStatus,
|
|
1173
|
+
...(txHash ? { hash: txHash } : {}),
|
|
1174
|
+
...(txHash
|
|
1175
|
+
? {
|
|
1176
|
+
txReceipt: {
|
|
1177
|
+
...existingTxMeta.txReceipt,
|
|
1178
|
+
transactionHash: txHash,
|
|
1179
|
+
status: (isComplete ? '0x1' : '0x0'),
|
|
1180
|
+
},
|
|
1181
|
+
}
|
|
1182
|
+
: {}),
|
|
1183
|
+
};
|
|
1184
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateTransactionFn, "f").call(this, updatedTxMeta, `BridgeStatusController - Intent order status updated: ${intentOrder.status}`);
|
|
1185
|
+
}
|
|
1186
|
+
else {
|
|
1187
|
+
console.warn('📝 [fetchIntentOrderStatus] Skipping update; transaction not found', { originalTxId, bridgeHistoryKey: bridgeTxMetaId });
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
catch (error) {
|
|
1191
|
+
console.error('📝 [fetchIntentOrderStatus] Failed to update transaction status', {
|
|
1192
|
+
originalTxId,
|
|
1193
|
+
bridgeHistoryKey: bridgeTxMetaId,
|
|
1194
|
+
error,
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
1199
|
+
const isFinal = newStatus.status === bridge_controller_1.StatusTypes.COMPLETE ||
|
|
1200
|
+
newStatus.status === bridge_controller_1.StatusTypes.FAILED;
|
|
1201
|
+
if (isFinal && pollingToken) {
|
|
1202
|
+
this.stopPollingByPollingToken(pollingToken);
|
|
1203
|
+
delete __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
1204
|
+
if (newStatus.status === bridge_controller_1.StatusTypes.COMPLETE) {
|
|
1205
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, bridgeTxMetaId);
|
|
1206
|
+
}
|
|
1207
|
+
else if (newStatus.status === bridge_controller_1.StatusTypes.FAILED) {
|
|
1208
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, bridgeTxMetaId);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}, _BridgeStatusController_convertBridgeQuoteToIntentQuote = function _BridgeStatusController_convertBridgeQuoteToIntentQuote(quoteResponse, intent) {
|
|
1212
|
+
return {
|
|
1213
|
+
id: `bridge-${Date.now()}`,
|
|
1214
|
+
provider: intent.protocol,
|
|
1215
|
+
srcAmount: quoteResponse.quote.srcTokenAmount,
|
|
1216
|
+
destAmount: quoteResponse.quote.destTokenAmount,
|
|
1217
|
+
estimatedGas: '21000',
|
|
1218
|
+
estimatedTime: 300, // 5 minutes
|
|
1219
|
+
priceImpact: 0,
|
|
1220
|
+
fees: [],
|
|
1221
|
+
validUntil: Date.now() + 300000, // 5 minutes from now
|
|
1222
|
+
metadata: {
|
|
1223
|
+
order: intent.order,
|
|
1224
|
+
settlementContract: intent.settlementContract ?? '',
|
|
1225
|
+
chainId: quoteResponse.quote.srcChainId,
|
|
1226
|
+
bridgeQuote: quoteResponse,
|
|
1227
|
+
},
|
|
1228
|
+
};
|
|
1229
|
+
}, _BridgeStatusController_mapIntentOrderStatusToTransactionStatus = function _BridgeStatusController_mapIntentOrderStatusToTransactionStatus(intentStatus) {
|
|
1230
|
+
switch (intentStatus) {
|
|
1231
|
+
case intent_order_status_1.IntentOrderStatus.PENDING:
|
|
1232
|
+
case intent_order_status_1.IntentOrderStatus.SUBMITTED:
|
|
1233
|
+
return transaction_controller_1.TransactionStatus.submitted;
|
|
1234
|
+
case intent_order_status_1.IntentOrderStatus.CONFIRMED:
|
|
1235
|
+
case intent_order_status_1.IntentOrderStatus.COMPLETED:
|
|
1236
|
+
return transaction_controller_1.TransactionStatus.confirmed;
|
|
1237
|
+
case intent_order_status_1.IntentOrderStatus.FAILED:
|
|
1238
|
+
case intent_order_status_1.IntentOrderStatus.EXPIRED:
|
|
1239
|
+
return transaction_controller_1.TransactionStatus.failed;
|
|
1240
|
+
default:
|
|
1241
|
+
return transaction_controller_1.TransactionStatus.submitted;
|
|
1242
|
+
}
|
|
854
1243
|
};
|
|
855
1244
|
//# sourceMappingURL=bridge-status-controller.cjs.map
|