@metamask/bridge-status-controller 71.2.0 → 72.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -1
- package/dist/bridge-status-controller-method-action-types.cjs.map +1 -1
- package/dist/bridge-status-controller-method-action-types.d.cts +5 -1
- package/dist/bridge-status-controller-method-action-types.d.cts.map +1 -1
- package/dist/bridge-status-controller-method-action-types.d.mts +5 -1
- package/dist/bridge-status-controller-method-action-types.d.mts.map +1 -1
- package/dist/bridge-status-controller-method-action-types.mjs.map +1 -1
- package/dist/bridge-status-controller.cjs +161 -366
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts +27 -7
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts +27 -7
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.mjs +162 -370
- package/dist/bridge-status-controller.mjs.map +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/strategy/batch-sell-strategy.cjs +101 -0
- package/dist/strategy/batch-sell-strategy.cjs.map +1 -0
- package/dist/strategy/batch-sell-strategy.d.cts +10 -0
- package/dist/strategy/batch-sell-strategy.d.cts.map +1 -0
- package/dist/strategy/batch-sell-strategy.d.mts +10 -0
- package/dist/strategy/batch-sell-strategy.d.mts.map +1 -0
- package/dist/strategy/batch-sell-strategy.mjs +97 -0
- package/dist/strategy/batch-sell-strategy.mjs.map +1 -0
- package/dist/strategy/batch-strategy.cjs +64 -0
- package/dist/strategy/batch-strategy.cjs.map +1 -0
- package/dist/strategy/batch-strategy.d.cts +10 -0
- package/dist/strategy/batch-strategy.d.cts.map +1 -0
- package/dist/strategy/batch-strategy.d.mts +10 -0
- package/dist/strategy/batch-strategy.d.mts.map +1 -0
- package/dist/strategy/batch-strategy.mjs +60 -0
- package/dist/strategy/batch-strategy.mjs.map +1 -0
- package/dist/strategy/evm-strategy.cjs +149 -0
- package/dist/strategy/evm-strategy.cjs.map +1 -0
- package/dist/strategy/evm-strategy.d.cts +38 -0
- package/dist/strategy/evm-strategy.d.cts.map +1 -0
- package/dist/strategy/evm-strategy.d.mts +38 -0
- package/dist/strategy/evm-strategy.d.mts.map +1 -0
- package/dist/strategy/evm-strategy.mjs +143 -0
- package/dist/strategy/evm-strategy.mjs.map +1 -0
- package/dist/strategy/index.cjs +70 -0
- package/dist/strategy/index.cjs.map +1 -0
- package/dist/strategy/index.d.cts +12 -0
- package/dist/strategy/index.d.cts.map +1 -0
- package/dist/strategy/index.d.mts +12 -0
- package/dist/strategy/index.d.mts.map +1 -0
- package/dist/strategy/index.mjs +68 -0
- package/dist/strategy/index.mjs.map +1 -0
- package/dist/strategy/intent-strategy.cjs +160 -0
- package/dist/strategy/intent-strategy.cjs.map +1 -0
- package/dist/strategy/intent-strategy.d.cts +17 -0
- package/dist/strategy/intent-strategy.d.cts.map +1 -0
- package/dist/strategy/intent-strategy.d.mts +17 -0
- package/dist/strategy/intent-strategy.d.mts.map +1 -0
- package/dist/strategy/intent-strategy.mjs +156 -0
- package/dist/strategy/intent-strategy.mjs.map +1 -0
- package/dist/strategy/non-evm-strategy.cjs +80 -0
- package/dist/strategy/non-evm-strategy.cjs.map +1 -0
- package/dist/strategy/non-evm-strategy.d.cts +15 -0
- package/dist/strategy/non-evm-strategy.d.cts.map +1 -0
- package/dist/strategy/non-evm-strategy.d.mts +15 -0
- package/dist/strategy/non-evm-strategy.d.mts.map +1 -0
- package/dist/strategy/non-evm-strategy.mjs +76 -0
- package/dist/strategy/non-evm-strategy.mjs.map +1 -0
- package/dist/strategy/types.cjs +13 -0
- package/dist/strategy/types.cjs.map +1 -0
- package/dist/strategy/types.d.cts +77 -0
- package/dist/strategy/types.d.cts.map +1 -0
- package/dist/strategy/types.d.mts +77 -0
- package/dist/strategy/types.d.mts.map +1 -0
- package/dist/strategy/types.mjs +10 -0
- package/dist/strategy/types.mjs.map +1 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +41 -6
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +41 -6
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/bridge.cjs +5 -1
- package/dist/utils/bridge.cjs.map +1 -1
- package/dist/utils/bridge.d.cts +2 -2
- package/dist/utils/bridge.d.cts.map +1 -1
- package/dist/utils/bridge.d.mts +2 -2
- package/dist/utils/bridge.d.mts.map +1 -1
- package/dist/utils/bridge.mjs +3 -0
- package/dist/utils/bridge.mjs.map +1 -1
- package/dist/utils/history.cjs +72 -20
- package/dist/utils/history.cjs.map +1 -1
- package/dist/utils/history.d.cts +19 -5
- package/dist/utils/history.d.cts.map +1 -1
- package/dist/utils/history.d.mts +19 -5
- package/dist/utils/history.d.mts.map +1 -1
- package/dist/utils/history.mjs +69 -19
- package/dist/utils/history.mjs.map +1 -1
- package/dist/utils/metrics.cjs +10 -7
- package/dist/utils/metrics.cjs.map +1 -1
- package/dist/utils/metrics.d.cts +7 -6
- package/dist/utils/metrics.d.cts.map +1 -1
- package/dist/utils/metrics.d.mts +7 -6
- package/dist/utils/metrics.d.mts.map +1 -1
- package/dist/utils/metrics.mjs +10 -7
- package/dist/utils/metrics.mjs.map +1 -1
- package/dist/utils/trace.cjs +4 -4
- package/dist/utils/trace.cjs.map +1 -1
- package/dist/utils/trace.d.cts +2 -2
- package/dist/utils/trace.d.cts.map +1 -1
- package/dist/utils/trace.d.mts +2 -2
- package/dist/utils/trace.d.mts.map +1 -1
- package/dist/utils/trace.mjs +4 -4
- package/dist/utils/trace.mjs.map +1 -1
- package/dist/utils/transaction.cjs +223 -252
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +68 -147
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +68 -147
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +214 -247
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -9,26 +9,25 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_intentManager, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionBatchFn, _BridgeStatusController_trace, _BridgeStatusController_onTransactionFailed, _BridgeStatusController_onTransactionConfirmed, _BridgeStatusController_restartPollingForIncompleteHistoryItems, _BridgeStatusController_addTxToHistory, _BridgeStatusController_rekeyHistoryItem, _BridgeStatusController_startPollingForTxId, _BridgeStatusController_handleFetchFailure, _BridgeStatusController_handleOldHistoryItem, _BridgeStatusController_fetchBridgeTxStatus, _BridgeStatusController_setAndGetSrcTxHash, _BridgeStatusController_updateHistoryItem, _BridgeStatusController_deleteHistoryItem, _BridgeStatusController_wipeBridgeStatusByChainId,
|
|
13
|
-
import {
|
|
12
|
+
var _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_intentManager, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionBatchFn, _BridgeStatusController_trace, _BridgeStatusController_onTransactionFailed, _BridgeStatusController_onTransactionConfirmed, _BridgeStatusController_restartPollingForIncompleteHistoryItems, _BridgeStatusController_addTxToHistory, _BridgeStatusController_rekeyHistoryItem, _BridgeStatusController_startPollingForTxId, _BridgeStatusController_handleFetchFailure, _BridgeStatusController_handleOldHistoryItem, _BridgeStatusController_fetchBridgeTxStatus, _BridgeStatusController_setAndGetSrcTxHash, _BridgeStatusController_updateHistoryItem, _BridgeStatusController_deleteHistoryItem, _BridgeStatusController_wipeBridgeStatusByChainId, _BridgeStatusController_executeSubmitStrategy, _BridgeStatusController_trackPollingStatusUpdatedEvent, _BridgeStatusController_trackUnifiedSwapBridgeEvent;
|
|
13
|
+
import { isNonEvmChainId, StatusTypes, getAccountHardwareType, UnifiedSwapBridgeEventName, isCrossChain, MetricsActionType, MetaMetricsSwapsEventSource, PollingStatus, formatChainIdToHex } from "@metamask/bridge-controller";
|
|
14
14
|
import { StaticIntervalPollingController } from "@metamask/polling-controller";
|
|
15
15
|
import { TransactionStatus, TransactionType, TransactionController } from "@metamask/transaction-controller";
|
|
16
16
|
import { numberToHex } from "@metamask/utils";
|
|
17
17
|
import { IntentManager } from "./bridge-status-controller.intent.mjs";
|
|
18
18
|
import { BRIDGE_PROD_API_BASE_URL, BRIDGE_STATUS_CONTROLLER_NAME, DEFAULT_BRIDGE_STATUS_CONTROLLER_STATE, MAX_ATTEMPTS, REFRESH_INTERVAL_MS } from "./constants.mjs";
|
|
19
|
+
import executeSubmitStrategy from "./strategy/index.mjs";
|
|
20
|
+
import { SubmitStep } from "./strategy/types.mjs";
|
|
19
21
|
import { BridgeClientId } from "./types.mjs";
|
|
20
22
|
import { getAccountByAddress } from "./utils/accounts.mjs";
|
|
21
23
|
import { getJwt } from "./utils/authentication.mjs";
|
|
22
|
-
import { stopPollingForQuotes, trackMetricsEvent } from "./utils/bridge.mjs";
|
|
24
|
+
import { getBatchSellTrades, stopPollingForQuotes, trackMetricsEvent } from "./utils/bridge.mjs";
|
|
23
25
|
import { fetchBridgeTxStatus, getStatusRequestWithSrcTxHash, shouldSkipFetchDueToFetchFailures, shouldWaitForFinalBridgeStatus } from "./utils/bridge-status.mjs";
|
|
24
26
|
import { getInitialHistoryItem, getMatchingHistoryEntryForTxMeta, rekeyHistoryItemInState, shouldPollHistoryItem, getMatchingHistoryEntryForApprovalTxMeta } from "./utils/history.mjs";
|
|
25
|
-
import { getIntentFromQuote, mapIntentOrderStatusToTransactionStatus, postSubmitOrder } from "./utils/intent-api.mjs";
|
|
26
|
-
import { signTypedMessage } from "./utils/keyring.mjs";
|
|
27
27
|
import { getFinalizedTxProperties, getPriceImpactFromQuote, getRequestMetadataFromHistory, getRequestParamFromHistory, getTradeDataFromHistory, getEVMTxPropertiesFromTransactionMeta, getTxStatusesFromHistory, getPreConfirmationPropertiesFromQuote, getPollingStatusUpdatedProperties } from "./utils/metrics.mjs";
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import { getAddTransactionBatchParams, handleApprovalDelay, handleMobileHardwareWalletDelay, generateActionId, waitForTxConfirmation, getTransactionMetaById, addTransactionBatch, addSyntheticTransaction, getTransactions, submitEvmTransaction, checkIsDelegatedAccount, isCrossChainTx } from "./utils/transaction.mjs";
|
|
28
|
+
import { getSelectedChainId } from "./utils/network.mjs";
|
|
29
|
+
import { getTraceParams } from "./utils/trace.mjs";
|
|
30
|
+
import { getTransactionMetaById, getTransactions, checkIsDelegatedAccount, isCrossChainTx, updateTransactionsInBatch, hasNestedSwapTransactions } from "./utils/transaction.mjs";
|
|
32
31
|
const metadata = {
|
|
33
32
|
// We want to persist the bridge status state so that we can show the proper data for the Activity list
|
|
34
33
|
// basically match the behavior of TransactionController
|
|
@@ -45,6 +44,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
45
44
|
'resetState',
|
|
46
45
|
'submitTx',
|
|
47
46
|
'submitIntent',
|
|
47
|
+
'submitBatchSell',
|
|
48
48
|
'restartPollingForFailedAttempts',
|
|
49
49
|
'getBridgeHistoryItemByTxMetaId',
|
|
50
50
|
];
|
|
@@ -76,14 +76,11 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
76
76
|
historyKey,
|
|
77
77
|
status: StatusTypes.FAILED,
|
|
78
78
|
txHash: isApprovalTxMeta ? undefined : txMeta.hash,
|
|
79
|
+
completionTime: Date.now(),
|
|
79
80
|
});
|
|
80
81
|
if (txMeta.status === TransactionStatus.rejected) {
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
|
-
// Skip account lookup and tracking when featureId is set (e.g. PERPS)
|
|
84
|
-
if (historyKey && this.state.txHistory[historyKey]?.featureId) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
84
|
// Skip tracking if this is a duplicate failed event for the same history item
|
|
88
85
|
// This can happen if the transaction includes an approval tx that fails
|
|
89
86
|
if (isHistoryItemAlreadyFailed) {
|
|
@@ -102,11 +99,13 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
102
99
|
historyKey,
|
|
103
100
|
txHash: txMeta.hash,
|
|
104
101
|
});
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
const isSwap = txMeta.type === TransactionType.swap || hasNestedSwapTransactions(txMeta);
|
|
103
|
+
switch (isSwap) {
|
|
104
|
+
case true:
|
|
107
105
|
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
108
106
|
historyKey,
|
|
109
107
|
status: StatusTypes.COMPLETE,
|
|
108
|
+
completionTime: Date.now(),
|
|
110
109
|
});
|
|
111
110
|
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
112
111
|
break;
|
|
@@ -243,10 +242,9 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
243
242
|
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
244
243
|
});
|
|
245
244
|
});
|
|
246
|
-
_BridgeStatusController_addTxToHistory.set(this, (...args) => {
|
|
247
|
-
const
|
|
245
|
+
_BridgeStatusController_addTxToHistory.set(this, (historyKey, ...args) => {
|
|
246
|
+
const txHistoryItem = getInitialHistoryItem(...args);
|
|
248
247
|
this.update((state) => {
|
|
249
|
-
// Use actionId as key for pre-submission, or txMeta.id for post-submission
|
|
250
248
|
state.txHistory[historyKey] = txHistoryItem;
|
|
251
249
|
});
|
|
252
250
|
return historyKey;
|
|
@@ -255,14 +253,15 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
255
253
|
* Rekeys a history item from actionId to txMeta.id after successful submission.
|
|
256
254
|
* Also updates txMetaId and srcTxHash which weren't available pre-submission.
|
|
257
255
|
*
|
|
258
|
-
* @param
|
|
256
|
+
* @param oldKey - The temporary key to use for the history item, usually the actionId
|
|
257
|
+
* @param newKey - The new key to use, typcally the txmeta.id
|
|
259
258
|
* @param txMeta - The transaction meta from the successful submission
|
|
260
259
|
* @param txMeta.id - The transaction meta id to use as the new key
|
|
261
260
|
* @param txMeta.hash - The transaction hash to set on the history item
|
|
262
261
|
*/
|
|
263
|
-
_BridgeStatusController_rekeyHistoryItem.set(this, (
|
|
262
|
+
_BridgeStatusController_rekeyHistoryItem.set(this, (oldKey, newKey, txMeta) => {
|
|
264
263
|
this.update((state) => {
|
|
265
|
-
rekeyHistoryItemInState(state,
|
|
264
|
+
rekeyHistoryItemInState(state, oldKey, newKey, txMeta);
|
|
266
265
|
});
|
|
267
266
|
});
|
|
268
267
|
_BridgeStatusController_startPollingForTxId.set(this, (txId) => {
|
|
@@ -293,7 +292,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
293
292
|
if (!bridgeTxMeta?.id) {
|
|
294
293
|
throw new Error('Cannot start polling: bridgeTxMeta.id is required for polling');
|
|
295
294
|
}
|
|
296
|
-
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
|
|
295
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, bridgeTxMeta.id, txHistoryMeta);
|
|
297
296
|
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
298
297
|
};
|
|
299
298
|
// This will be called after you call this.startPolling()
|
|
@@ -488,7 +487,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
488
487
|
});
|
|
489
488
|
return localTxHash;
|
|
490
489
|
});
|
|
491
|
-
_BridgeStatusController_updateHistoryItem.set(this, ({ historyKey, status, txHash, attempts, }) => {
|
|
490
|
+
_BridgeStatusController_updateHistoryItem.set(this, ({ historyKey, status, txHash, attempts, completionTime, }) => {
|
|
492
491
|
if (!historyKey) {
|
|
493
492
|
return;
|
|
494
493
|
}
|
|
@@ -502,6 +501,9 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
502
501
|
if (attempts) {
|
|
503
502
|
currentState.txHistory[historyKey].attempts = attempts;
|
|
504
503
|
}
|
|
504
|
+
if (completionTime) {
|
|
505
|
+
currentState.txHistory[historyKey].completionTime = completionTime;
|
|
506
|
+
}
|
|
505
507
|
});
|
|
506
508
|
});
|
|
507
509
|
_BridgeStatusController_deleteHistoryItem.set(this, (historyKey) => {
|
|
@@ -537,237 +539,134 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
537
539
|
* TX SUBMISSION HANDLING
|
|
538
540
|
*******************************************************
|
|
539
541
|
*/
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
542
|
+
_BridgeStatusController_executeSubmitStrategy.set(this, async (params, sharedHistoryItemProperties) => {
|
|
543
|
+
let tradeTxMeta;
|
|
544
|
+
const steps = executeSubmitStrategy(params);
|
|
545
|
+
// Each submission strategy determines when to execute step, which means these actions can happen in any order
|
|
546
|
+
for await (const { type, payload } of steps) {
|
|
547
|
+
try {
|
|
548
|
+
switch (type) {
|
|
549
|
+
case SubmitStep.RekeyHistoryItem:
|
|
550
|
+
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this, payload.oldHistoryKey, payload.newHistoryKey, payload.tradeMeta);
|
|
551
|
+
break;
|
|
552
|
+
case SubmitStep.UpdateBatchTransactions:
|
|
553
|
+
updateTransactionsInBatch({
|
|
554
|
+
messenger: this.messenger,
|
|
555
|
+
allTradesWithMetadata: payload.quoteAndTxMetas,
|
|
556
|
+
});
|
|
557
|
+
break;
|
|
558
|
+
case SubmitStep.SetTradeMeta:
|
|
559
|
+
tradeTxMeta = payload.tradeMeta;
|
|
560
|
+
break;
|
|
561
|
+
case SubmitStep.AddHistoryItem:
|
|
562
|
+
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, payload.historyKey, {
|
|
563
|
+
...payload,
|
|
564
|
+
...sharedHistoryItemProperties,
|
|
565
|
+
quoteResponse: payload.quoteResponse,
|
|
566
|
+
accountAddress: params.selectedAccount.address,
|
|
567
|
+
isStxEnabled: params.isStxEnabled,
|
|
568
|
+
slippagePercentage: 0, // TODO include slippage provided by quote if using dynamic slippage, or slippage from quote request
|
|
569
|
+
});
|
|
570
|
+
break;
|
|
571
|
+
case SubmitStep.StartPolling:
|
|
572
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, payload.historyKey);
|
|
573
|
+
break;
|
|
574
|
+
case SubmitStep.PublishCompletedEvent:
|
|
575
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, payload.historyKey);
|
|
576
|
+
break;
|
|
577
|
+
/* c8 ignore start */
|
|
578
|
+
default:
|
|
579
|
+
throw new Error(`Unknown submit step type: ${String(type)}`);
|
|
580
|
+
/* c8 ignore end */
|
|
549
581
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
: TransactionType.swapApproval,
|
|
555
|
-
trade: approval,
|
|
556
|
-
requireApproval,
|
|
557
|
-
});
|
|
558
|
-
await handleApprovalDelay(srcChainId);
|
|
559
|
-
return approvalTxMeta;
|
|
560
|
-
};
|
|
561
|
-
return await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getApprovalTraceParams(quoteResponse, false), approveTx);
|
|
582
|
+
}
|
|
583
|
+
catch (error) {
|
|
584
|
+
console.error('Failed to add to bridge history and start polling.', error);
|
|
585
|
+
}
|
|
562
586
|
}
|
|
563
|
-
return
|
|
564
|
-
});
|
|
565
|
-
// TODO simplify and make more readable
|
|
566
|
-
/**
|
|
567
|
-
* Submits batched EVM transactions to the TransactionController
|
|
568
|
-
*
|
|
569
|
-
* @param args - The parameters for the transaction
|
|
570
|
-
* @param args.isBridgeTx - Whether the transaction is a bridge transaction
|
|
571
|
-
* @param args.trade - The trade data to confirm
|
|
572
|
-
* @param args.approval - The approval data to confirm
|
|
573
|
-
* @param args.resetApproval - The ethereum:USDT reset approval data to confirm
|
|
574
|
-
* @param args.quoteResponse - The quote response
|
|
575
|
-
* @param args.requireApproval - Whether to require approval for the transaction
|
|
576
|
-
* @returns The approvalMeta and tradeMeta for the batched transaction
|
|
577
|
-
*/
|
|
578
|
-
_BridgeStatusController_handleEvmTransactionBatch.set(this, async (args) => {
|
|
579
|
-
const transactionParams = await getAddTransactionBatchParams({
|
|
580
|
-
messenger: this.messenger,
|
|
581
|
-
...args,
|
|
582
|
-
});
|
|
583
|
-
return await addTransactionBatch(this.messenger, __classPrivateFieldGet(this, _BridgeStatusController_addTransactionBatchFn, "f"), transactionParams);
|
|
587
|
+
return tradeTxMeta;
|
|
584
588
|
});
|
|
585
589
|
/**
|
|
586
590
|
* Submits a cross-chain swap transaction
|
|
587
591
|
*
|
|
588
592
|
* @param accountAddress - The address of the account to submit the transaction for
|
|
589
|
-
* @param
|
|
590
|
-
* @param
|
|
593
|
+
* @param maybeQuoteResponses - A single quote response or an array of quote responses
|
|
594
|
+
* @param isStxEnabled - Whether smart transactions are enabled on the client, for example the getSmartTransactionsEnabled selector value from the extension
|
|
591
595
|
* @param quotesReceivedContext - The context for the QuotesReceived event
|
|
592
596
|
* @param location - The entry point from which the user initiated the swap or bridge (e.g. Main View, Token View, Trending Explore)
|
|
593
597
|
* @param abTests - Legacy A/B test context for `ab_tests` (backward compatibility)
|
|
594
598
|
* @param activeAbTests - New A/B test context for `active_ab_tests` (migration target). Attributes events to specific experiments.
|
|
595
599
|
* @param tokenSecurityTypeDestination - The security classification of the destination token, supplied by the client (e.g. from token security/scanning data). Pass `null` when no security data is available.
|
|
600
|
+
* @param batchSellTrades - Contains transaction data for the quotes, provided by the obtainGaslessBatch API
|
|
596
601
|
* @returns The transaction meta
|
|
602
|
+
* @throws An error if transaction submission fails before it gets published
|
|
597
603
|
*/
|
|
598
|
-
this.submitTx = async (accountAddress,
|
|
599
|
-
|
|
604
|
+
this.submitTx = async (accountAddress, maybeQuoteResponses, isStxEnabled, quotesReceivedContext, location = MetaMetricsSwapsEventSource.MainView, abTests, activeAbTests, tokenSecurityTypeDestination, batchSellTrades) => {
|
|
605
|
+
/**
|
|
606
|
+
* If there are multiple quote responses, we assume that they all originate from the same src chain
|
|
607
|
+
* and the same account. In this case its safe to use the first quote response's properties for
|
|
608
|
+
* metrics and other pre-submission logic
|
|
609
|
+
*/
|
|
610
|
+
const quoteResponses = Array.isArray(maybeQuoteResponses)
|
|
611
|
+
? maybeQuoteResponses
|
|
612
|
+
: [maybeQuoteResponses];
|
|
613
|
+
const quoteResponse = quoteResponses[0];
|
|
614
|
+
const { featureId, quote } = quoteResponse;
|
|
615
|
+
const startTime = Date.now();
|
|
616
|
+
stopPollingForQuotes(this.messenger, featureId, quotesReceivedContext);
|
|
600
617
|
const selectedAccount = getAccountByAddress(this.messenger, accountAddress);
|
|
601
618
|
if (!selectedAccount) {
|
|
602
619
|
throw new Error('Failed to submit cross-chain swap transaction: undefined multichain account');
|
|
603
620
|
}
|
|
604
621
|
const accountHardwareType = getAccountHardwareType(selectedAccount);
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
const
|
|
610
|
-
const isBridgeTx = isCrossChain(
|
|
611
|
-
const
|
|
622
|
+
/**
|
|
623
|
+
* For hardware wallets on Mobile, this is fixes an issue where the Ledger does not get prompted for the 2nd approval.
|
|
624
|
+
* Extension does not have this issue
|
|
625
|
+
*/
|
|
626
|
+
const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE && accountHardwareType !== null;
|
|
627
|
+
const isBridgeTx = isCrossChain(quote.srcChainId, quote.destChainId);
|
|
628
|
+
const preConfirmationProperties = getPreConfirmationPropertiesFromQuote(quoteResponse, isStxEnabled, accountHardwareType, location, abTests, activeAbTests, tokenSecurityTypeDestination, batchSellTrades);
|
|
612
629
|
try {
|
|
613
630
|
// Emit Submitted event after submit button is clicked
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE &&
|
|
646
|
-
accountHardwareType !== null;
|
|
647
|
-
// Handle smart transactions if enabled
|
|
648
|
-
txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getTraceParams(quoteResponse, isStxEnabledOnClient), async () => {
|
|
649
|
-
if (!isEvmTxData(quoteResponse.trade)) {
|
|
650
|
-
throw new Error('Failed to submit cross-chain swap transaction: trade is not an EVM transaction');
|
|
651
|
-
}
|
|
652
|
-
// Check if the account is an EIP-7702 delegated account
|
|
653
|
-
// Delegated accounts only allow 1 in-flight tx, so approve + swap
|
|
654
|
-
// must be batched into a single transaction
|
|
655
|
-
const hexChainId = formatChainIdToHex(quoteResponse.quote.srcChainId);
|
|
656
|
-
isDelegatedAccount = await checkIsDelegatedAccount(this.messenger, quoteResponse.trade.from, [hexChainId]);
|
|
657
|
-
if (isStxEnabledOnClient ||
|
|
658
|
-
quoteResponse.quote.gasIncluded7702 ||
|
|
659
|
-
isDelegatedAccount) {
|
|
660
|
-
const { tradeMeta, approvalMeta } = await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransactionBatch, "f").call(this, {
|
|
661
|
-
isBridgeTx,
|
|
662
|
-
resetApproval: quoteResponse.resetApproval,
|
|
663
|
-
approval: quoteResponse.approval &&
|
|
664
|
-
isEvmTxData(quoteResponse.approval)
|
|
665
|
-
? quoteResponse.approval
|
|
666
|
-
: undefined,
|
|
667
|
-
trade: quoteResponse.trade,
|
|
668
|
-
quoteResponse,
|
|
669
|
-
requireApproval,
|
|
670
|
-
isDelegatedAccount,
|
|
671
|
-
});
|
|
672
|
-
approvalTxId = approvalMeta?.id;
|
|
673
|
-
return tradeMeta;
|
|
674
|
-
}
|
|
675
|
-
// Set approval time and id if an approval tx is needed
|
|
676
|
-
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, quoteResponse, isBridgeTx, quoteResponse.quote.srcChainId, quoteResponse.approval && isEvmTxData(quoteResponse.approval)
|
|
677
|
-
? quoteResponse.approval
|
|
678
|
-
: undefined, quoteResponse.resetApproval, requireApproval);
|
|
679
|
-
approvalTxId = approvalTxMeta?.id;
|
|
680
|
-
// Hardware-wallet delay first (Ledger second-prompt spacing), then wait for
|
|
681
|
-
// on-chain approval confirmation so swap gas estimation runs after allowance is set.
|
|
682
|
-
if (requireApproval && approvalTxMeta) {
|
|
683
|
-
await handleMobileHardwareWalletDelay(requireApproval);
|
|
684
|
-
await waitForTxConfirmation(this.messenger, approvalTxMeta.id);
|
|
685
|
-
}
|
|
686
|
-
else {
|
|
687
|
-
await handleMobileHardwareWalletDelay(requireApproval);
|
|
688
|
-
}
|
|
689
|
-
// Generate actionId for pre-submission history (non-batch EVM only)
|
|
690
|
-
const actionId = generateActionId().toString();
|
|
691
|
-
// Add pre-submission history keyed by actionId
|
|
692
|
-
// This ensures we have quote data available if transaction fails during submission
|
|
693
|
-
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
694
|
-
accountAddress: selectedAccount.address,
|
|
695
|
-
quoteResponse,
|
|
696
|
-
slippagePercentage: 0,
|
|
697
|
-
isStxEnabled: isStxEnabledOnClient,
|
|
698
|
-
startTime,
|
|
699
|
-
approvalTxId,
|
|
700
|
-
location,
|
|
701
|
-
abTests,
|
|
702
|
-
activeAbTests,
|
|
703
|
-
actionId,
|
|
704
|
-
tokenSecurityTypeDestination,
|
|
705
|
-
});
|
|
706
|
-
// Pass txFee when gasIncluded is true to use the quote's gas fees
|
|
707
|
-
// instead of re-estimating (which would fail for max native token swaps)
|
|
708
|
-
const tradeTxMeta = await submitEvmTransaction({
|
|
709
|
-
messenger: this.messenger,
|
|
710
|
-
transactionType: isBridgeTx
|
|
711
|
-
? TransactionType.bridge
|
|
712
|
-
: TransactionType.swap,
|
|
713
|
-
trade: quoteResponse.trade,
|
|
714
|
-
requireApproval,
|
|
715
|
-
txFee: quoteResponse.quote.gasIncluded
|
|
716
|
-
? quoteResponse.quote.feeData.txFee
|
|
717
|
-
: undefined,
|
|
718
|
-
actionId,
|
|
719
|
-
});
|
|
720
|
-
// On success, rekey from actionId to txMeta.id and update srcTxHash
|
|
721
|
-
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this, historyKey, tradeTxMeta);
|
|
722
|
-
return tradeTxMeta;
|
|
723
|
-
});
|
|
724
|
-
}
|
|
631
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Submitted, undefined, preConfirmationProperties, featureId);
|
|
632
|
+
/**
|
|
633
|
+
* Check if the account is an EIP-7702 delegated account.
|
|
634
|
+
* Delegated accounts only allow 1 in-flight tx, so approve + swap
|
|
635
|
+
* must be batched into a single transaction
|
|
636
|
+
*/
|
|
637
|
+
const isDelegatedAccount = isNonEvmChainId(quote.srcChainId)
|
|
638
|
+
? false
|
|
639
|
+
: await checkIsDelegatedAccount(this.messenger, selectedAccount.address, [formatChainIdToHex(quote.srcChainId)]);
|
|
640
|
+
const strategyParams = {
|
|
641
|
+
messenger: this.messenger,
|
|
642
|
+
quoteResponses,
|
|
643
|
+
batchSellTrades,
|
|
644
|
+
isStxEnabled,
|
|
645
|
+
isBridgeTx,
|
|
646
|
+
isDelegatedAccount,
|
|
647
|
+
selectedAccount,
|
|
648
|
+
requireApproval,
|
|
649
|
+
clientId: __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"),
|
|
650
|
+
bridgeApiBaseUrl: __classPrivateFieldGet(this, _BridgeStatusController_config, "f").customBridgeApiBaseUrl,
|
|
651
|
+
addTransactionBatchFn: __classPrivateFieldGet(this, _BridgeStatusController_addTransactionBatchFn, "f"),
|
|
652
|
+
fetchFn: __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"),
|
|
653
|
+
traceFn: __classPrivateFieldGet(this, _BridgeStatusController_trace, "f"),
|
|
654
|
+
};
|
|
655
|
+
return await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getTraceParams(quoteResponse, isStxEnabled), async () => await __classPrivateFieldGet(this, _BridgeStatusController_executeSubmitStrategy, "f").call(this, strategyParams, {
|
|
656
|
+
startTime,
|
|
657
|
+
location,
|
|
658
|
+
abTests,
|
|
659
|
+
activeAbTests,
|
|
660
|
+
tokenSecurityTypeDestination,
|
|
661
|
+
}));
|
|
725
662
|
}
|
|
726
663
|
catch (error) {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
});
|
|
664
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed, undefined, {
|
|
665
|
+
error_message: error?.message,
|
|
666
|
+
...preConfirmationProperties,
|
|
667
|
+
}, featureId);
|
|
732
668
|
throw error;
|
|
733
669
|
}
|
|
734
|
-
try {
|
|
735
|
-
// For non-batch EVM transactions, history was already added/rekeyed above
|
|
736
|
-
// Only add history here for non-EVM and batch EVM transactions
|
|
737
|
-
const isNonBatchEvm = !isNonEvmChainId(quoteResponse.quote.srcChainId) &&
|
|
738
|
-
!isStxEnabledOnClient &&
|
|
739
|
-
!quoteResponse.quote.gasIncluded7702 &&
|
|
740
|
-
!isDelegatedAccount;
|
|
741
|
-
let historyKey = txMeta.id;
|
|
742
|
-
if (!isNonBatchEvm) {
|
|
743
|
-
// Add swap or bridge tx to history
|
|
744
|
-
historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
745
|
-
accountAddress: selectedAccount.address,
|
|
746
|
-
bridgeTxMeta: txMeta, // Only the id and hash fields are used by the BridgeStatusController
|
|
747
|
-
quoteResponse,
|
|
748
|
-
slippagePercentage: 0, // TODO include slippage provided by quote if using dynamic slippage, or slippage from quote request
|
|
749
|
-
isStxEnabled: isStxEnabledOnClient,
|
|
750
|
-
startTime,
|
|
751
|
-
approvalTxId,
|
|
752
|
-
location,
|
|
753
|
-
abTests,
|
|
754
|
-
activeAbTests,
|
|
755
|
-
tokenSecurityTypeDestination,
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
if (isNonEvmChainId(quoteResponse.quote.srcChainId)) {
|
|
759
|
-
// Start polling for bridge tx status
|
|
760
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
761
|
-
// Track non-EVM Swap completed event
|
|
762
|
-
if (!(isBridgeTx || isTronTx)) {
|
|
763
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
catch {
|
|
768
|
-
// Ignore errors here, we don't want to crash the app if this fails and tx submission succeeds
|
|
769
|
-
}
|
|
770
|
-
return txMeta;
|
|
771
670
|
};
|
|
772
671
|
/**
|
|
773
672
|
* Submits an intent order and creates a synthetic history entry for UX.
|
|
@@ -780,135 +679,28 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
780
679
|
* @param params.abTests - Legacy A/B test context for `ab_tests` (backward compatibility)
|
|
781
680
|
* @param params.activeAbTests - New A/B test context for `active_ab_tests` (migration target). Attributes events to specific experiments.
|
|
782
681
|
* @param params.tokenSecurityTypeDestination - The security classification of the destination token, supplied by the client (e.g. from token security/scanning data). Pass `null` when no security data is available.
|
|
682
|
+
* @param params.isStxEnabled - Whether smart transactions are enabled on the client, for example the getSmartTransactionsEnabled selector value from the extension
|
|
683
|
+
* @param params.quotesReceivedContext - The context for the QuotesReceived event
|
|
783
684
|
* @returns A lightweight TransactionMeta-like object for history linking
|
|
685
|
+
* @throws An error if intent or transaction submission fails before they get published
|
|
784
686
|
*/
|
|
785
687
|
this.submitIntent = async (params) => {
|
|
786
|
-
const { quoteResponse, accountAddress, location, abTests, activeAbTests, tokenSecurityTypeDestination, } = params;
|
|
688
|
+
const { quoteResponse, accountAddress, location, abTests, activeAbTests, tokenSecurityTypeDestination, isStxEnabled = false, quotesReceivedContext, } = params;
|
|
787
689
|
// TODO add metrics context
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
// then proceed with off-chain intent submission.
|
|
798
|
-
const isBridgeTx = isCrossChain(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
799
|
-
const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE &&
|
|
800
|
-
accountHardwareType !== null;
|
|
801
|
-
// Handle approval silently for better UX in intent flows
|
|
802
|
-
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, quoteResponse, isBridgeTx, quoteResponse.quote.srcChainId, quoteResponse.approval, quoteResponse.resetApproval, requireApproval);
|
|
803
|
-
const approvalTxId = approvalTxMeta?.id;
|
|
804
|
-
if (approvalTxId) {
|
|
805
|
-
await waitForTxConfirmation(this.messenger, approvalTxId);
|
|
806
|
-
}
|
|
807
|
-
const { srcChainId, requestId } = quoteResponse.quote;
|
|
808
|
-
const signature = await signTypedMessage({
|
|
809
|
-
messenger: this.messenger,
|
|
810
|
-
accountAddress,
|
|
811
|
-
typedData: intent.typedData,
|
|
812
|
-
});
|
|
813
|
-
const submissionParams = {
|
|
814
|
-
srcChainId,
|
|
815
|
-
quoteId: requestId,
|
|
816
|
-
signature,
|
|
817
|
-
order: intent.order,
|
|
818
|
-
userAddress: accountAddress,
|
|
819
|
-
aggregatorId: intent.protocol,
|
|
820
|
-
};
|
|
821
|
-
const { id: orderUid, status } = await postSubmitOrder({
|
|
822
|
-
params: submissionParams,
|
|
823
|
-
clientId: __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"),
|
|
824
|
-
jwt: await getJwt(this.messenger),
|
|
825
|
-
fetchFn: __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"),
|
|
826
|
-
bridgeApiBaseUrl: __classPrivateFieldGet(this, _BridgeStatusController_config, "f").customBridgeApiBaseUrl,
|
|
827
|
-
});
|
|
828
|
-
// Determine transaction type: swap for same-chain, bridge for cross-chain
|
|
829
|
-
const transactionType = isBridgeTx
|
|
830
|
-
? /* c8 ignore start */
|
|
831
|
-
TransactionType.bridge
|
|
832
|
-
: /* c8 ignore end */
|
|
833
|
-
TransactionType.swap;
|
|
834
|
-
// Create actual transaction in Transaction Controller first
|
|
835
|
-
const networkClientId = getNetworkClientIdByChainId(this.messenger, srcChainId);
|
|
836
|
-
// This is a synthetic transaction whose purpose is to be able
|
|
837
|
-
// to track the order status via the history
|
|
838
|
-
const intentTransactionParams = {
|
|
839
|
-
chainId: formatChainIdToHex(srcChainId),
|
|
840
|
-
from: accountAddress,
|
|
841
|
-
to: intent.settlementContract ??
|
|
842
|
-
'0x9008D19f58AAbd9eD0D60971565AA8510560ab41', // Default settlement contract
|
|
843
|
-
data: `0x${orderUid.slice(-8)}`, // Use last 8 chars of orderUid to make each transaction unique
|
|
844
|
-
value: '0x0',
|
|
845
|
-
gas: '0x5208', // Minimal gas for display purposes
|
|
846
|
-
gasPrice: '0x3b9aca00', // 1 Gwei - will be converted to EIP-1559 fees if network supports it
|
|
847
|
-
};
|
|
848
|
-
const initialTxMeta = await addSyntheticTransaction(this.messenger, intentTransactionParams, {
|
|
849
|
-
requireApproval: false,
|
|
850
|
-
networkClientId,
|
|
851
|
-
type: transactionType,
|
|
852
|
-
});
|
|
853
|
-
// Update txHistory with actual transaction metadata
|
|
854
|
-
const syntheticMeta = {
|
|
855
|
-
...initialTxMeta,
|
|
856
|
-
// Map intent order status to TransactionController status
|
|
857
|
-
status: mapIntentOrderStatusToTransactionStatus(status),
|
|
858
|
-
isIntentTx: true,
|
|
859
|
-
orderUid,
|
|
860
|
-
};
|
|
861
|
-
// Record in bridge history with actual transaction metadata
|
|
862
|
-
try {
|
|
863
|
-
// Create a bridge transaction metadata keyed by orderUid for intent polling
|
|
864
|
-
const bridgeTxMetaForHistory = {
|
|
865
|
-
...syntheticMeta,
|
|
866
|
-
id: orderUid,
|
|
867
|
-
};
|
|
868
|
-
// Use orderId as the history key for intent transactions
|
|
869
|
-
// IMPORTANT: pass originalTransactionId as a top-level argument so
|
|
870
|
-
// `getInitialHistoryItem` reads it. Setting it on `bridgeTxMeta` is a no-op
|
|
871
|
-
// because `getInitialHistoryItem` destructures `originalTransactionId` from
|
|
872
|
-
// the top-level args, not from `bridgeTxMeta`. Without this, the field
|
|
873
|
-
// falls back to `bridgeTxMeta.id` (the orderUid), severing the link between
|
|
874
|
-
// the bridge history record and the synthetic TransactionController entry.
|
|
875
|
-
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
876
|
-
accountAddress,
|
|
877
|
-
bridgeTxMeta: bridgeTxMetaForHistory,
|
|
878
|
-
originalTransactionId: syntheticMeta.id,
|
|
879
|
-
quoteResponse,
|
|
880
|
-
slippagePercentage: 0,
|
|
881
|
-
isStxEnabled: false,
|
|
882
|
-
approvalTxId,
|
|
883
|
-
startTime,
|
|
884
|
-
location,
|
|
885
|
-
abTests,
|
|
886
|
-
activeAbTests,
|
|
887
|
-
tokenSecurityTypeDestination,
|
|
888
|
-
});
|
|
889
|
-
// Start polling using the orderId key to route to intent manager
|
|
890
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
891
|
-
}
|
|
892
|
-
catch (error) {
|
|
893
|
-
console.error('📝 [submitIntent] Failed to add to bridge history', error);
|
|
894
|
-
// non-fatal but log the error
|
|
895
|
-
}
|
|
896
|
-
return syntheticMeta;
|
|
897
|
-
}
|
|
898
|
-
catch (error) {
|
|
899
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed, undefined, {
|
|
900
|
-
error_message: error?.message,
|
|
901
|
-
...preConfirmationProperties,
|
|
902
|
-
});
|
|
903
|
-
throw error;
|
|
904
|
-
}
|
|
690
|
+
return await this.submitTx(accountAddress, quoteResponse, isStxEnabled, quotesReceivedContext, location, abTests, activeAbTests, tokenSecurityTypeDestination);
|
|
691
|
+
};
|
|
692
|
+
this.submitBatchSell = async (params) => {
|
|
693
|
+
/**
|
|
694
|
+
* Retrieve the batch sell trades from the BridgeController's state to ensure we submit
|
|
695
|
+
* the original response data from the bridge-api
|
|
696
|
+
*/
|
|
697
|
+
const batchSellTrades = getBatchSellTrades(this.messenger);
|
|
698
|
+
return await this.submitTx(params.accountAddress, params.quoteResponses.filter((quoteResponse) => quoteResponse !== null), params.isStxEnabled ?? false, params.quotesReceivedContext, params.location, params.abTests, params.activeAbTests, params.tokenSecurityTypeDestination, batchSellTrades);
|
|
905
699
|
};
|
|
906
700
|
_BridgeStatusController_trackPollingStatusUpdatedEvent.set(this, (historyKey, pollingStatus) => {
|
|
907
701
|
// Track polling status updated event
|
|
908
702
|
const historyItem = this.state.txHistory[historyKey];
|
|
909
|
-
|
|
910
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.PollingStatusUpdated, historyKey, getPollingStatusUpdatedProperties(this.messenger, pollingStatus, historyItem));
|
|
911
|
-
}
|
|
703
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.PollingStatusUpdated, historyKey, getPollingStatusUpdatedProperties(this.messenger, pollingStatus, historyItem));
|
|
912
704
|
});
|
|
913
705
|
/**
|
|
914
706
|
* Tracks post-submission events for a cross-chain swap based on the history item
|
|
@@ -916,8 +708,22 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
916
708
|
* @param eventName - The name of the event to track
|
|
917
709
|
* @param txMetaId - The txMetaId of the history item to track the event for
|
|
918
710
|
* @param eventProperties - The properties for the event
|
|
711
|
+
* @param featureIdOverride - The featureId to use when the history item is not available. Should
|
|
712
|
+
* only be provided for events that are not associated with a history item yet, such as Submitted or Failed
|
|
919
713
|
*/
|
|
920
|
-
_BridgeStatusController_trackUnifiedSwapBridgeEvent.set(this, (eventName, txMetaId, eventProperties) => {
|
|
714
|
+
_BridgeStatusController_trackUnifiedSwapBridgeEvent.set(this, (eventName, txMetaId, eventProperties, featureIdOverride) => {
|
|
715
|
+
const historyItem = txMetaId
|
|
716
|
+
? this.state.txHistory[txMetaId]
|
|
717
|
+
: undefined;
|
|
718
|
+
const featureId = featureIdOverride ?? historyItem?.featureId;
|
|
719
|
+
const shouldSkipMetrics =
|
|
720
|
+
// Skip tracking all other events when featureId is set (i.e. PERPS)
|
|
721
|
+
featureId &&
|
|
722
|
+
// Always publish StatusValidationFailed event, regardless of featureId
|
|
723
|
+
eventName !== UnifiedSwapBridgeEventName.StatusValidationFailed;
|
|
724
|
+
if (shouldSkipMetrics) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
921
727
|
// Legacy/new metrics fields are intentionally kept independent during migration.
|
|
922
728
|
const historyAbTests = txMetaId
|
|
923
729
|
? this.state.txHistory?.[txMetaId]?.abTests
|
|
@@ -927,12 +733,12 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
927
733
|
: undefined;
|
|
928
734
|
const resolvedAbTests = eventProperties?.ab_tests ?? historyAbTests;
|
|
929
735
|
const resolvedActiveAbTests = eventProperties?.active_ab_tests ?? historyActiveAbTests;
|
|
736
|
+
const location = (txMetaId ? this.state.txHistory?.[txMetaId]?.location : undefined) ??
|
|
737
|
+
MetaMetricsSwapsEventSource.MainView;
|
|
930
738
|
const baseProperties = {
|
|
931
739
|
action_type: MetricsActionType.SWAPBRIDGE_V1,
|
|
932
|
-
location: eventProperties?.location ??
|
|
933
|
-
(txMetaId ? this.state.txHistory?.[txMetaId]?.location : undefined) ??
|
|
934
|
-
MetaMetricsSwapsEventSource.MainView,
|
|
935
740
|
...(eventProperties ?? {}),
|
|
741
|
+
location,
|
|
936
742
|
...(resolvedAbTests &&
|
|
937
743
|
Object.keys(resolvedAbTests).length > 0 && {
|
|
938
744
|
ab_tests: resolvedAbTests,
|
|
@@ -943,15 +749,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
943
749
|
}),
|
|
944
750
|
};
|
|
945
751
|
// This will publish events for PERPS dropped tx failures as well
|
|
946
|
-
if (!txMetaId) {
|
|
947
|
-
trackMetricsEvent({
|
|
948
|
-
messenger: this.messenger,
|
|
949
|
-
eventName,
|
|
950
|
-
properties: baseProperties,
|
|
951
|
-
});
|
|
952
|
-
return;
|
|
953
|
-
}
|
|
954
|
-
const historyItem = this.state.txHistory[txMetaId];
|
|
955
752
|
if (!historyItem) {
|
|
956
753
|
trackMetricsEvent({
|
|
957
754
|
messenger: this.messenger,
|
|
@@ -960,9 +757,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
960
757
|
});
|
|
961
758
|
return;
|
|
962
759
|
}
|
|
963
|
-
const {
|
|
760
|
+
const { approvalTxId, quote } = historyItem;
|
|
964
761
|
const requestParamProperties = getRequestParamFromHistory(historyItem);
|
|
965
|
-
// Always publish StatusValidationFailed event, regardless of featureId
|
|
966
762
|
if (eventName === UnifiedSwapBridgeEventName.StatusValidationFailed) {
|
|
967
763
|
trackMetricsEvent({
|
|
968
764
|
messenger: this.messenger,
|
|
@@ -979,10 +775,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
979
775
|
});
|
|
980
776
|
return;
|
|
981
777
|
}
|
|
982
|
-
// Skip tracking all other events when featureId is set (i.e. PERPS)
|
|
983
|
-
if (featureId) {
|
|
984
|
-
return;
|
|
985
|
-
}
|
|
986
778
|
const selectedAccount = getAccountByAddress(this.messenger, historyItem.account);
|
|
987
779
|
const transactions = getTransactions(this.messenger);
|
|
988
780
|
const txMeta = transactions.find((tx) => tx.id === txMetaId);
|
|
@@ -1062,5 +854,5 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
1062
854
|
__classPrivateFieldGet(this, _BridgeStatusController_restartPollingForIncompleteHistoryItems, "f").call(this);
|
|
1063
855
|
}
|
|
1064
856
|
}
|
|
1065
|
-
_BridgeStatusController_pollingTokensByTxMetaId = new WeakMap(), _BridgeStatusController_intentManager = new WeakMap(), _BridgeStatusController_clientId = new WeakMap(), _BridgeStatusController_fetchFn = new WeakMap(), _BridgeStatusController_config = new WeakMap(), _BridgeStatusController_addTransactionBatchFn = new WeakMap(), _BridgeStatusController_trace = new WeakMap(), _BridgeStatusController_onTransactionFailed = new WeakMap(), _BridgeStatusController_onTransactionConfirmed = new WeakMap(), _BridgeStatusController_restartPollingForIncompleteHistoryItems = new WeakMap(), _BridgeStatusController_addTxToHistory = new WeakMap(), _BridgeStatusController_rekeyHistoryItem = new WeakMap(), _BridgeStatusController_startPollingForTxId = new WeakMap(), _BridgeStatusController_handleFetchFailure = new WeakMap(), _BridgeStatusController_handleOldHistoryItem = new WeakMap(), _BridgeStatusController_fetchBridgeTxStatus = new WeakMap(), _BridgeStatusController_setAndGetSrcTxHash = new WeakMap(), _BridgeStatusController_updateHistoryItem = new WeakMap(), _BridgeStatusController_deleteHistoryItem = new WeakMap(), _BridgeStatusController_wipeBridgeStatusByChainId = new WeakMap(),
|
|
857
|
+
_BridgeStatusController_pollingTokensByTxMetaId = new WeakMap(), _BridgeStatusController_intentManager = new WeakMap(), _BridgeStatusController_clientId = new WeakMap(), _BridgeStatusController_fetchFn = new WeakMap(), _BridgeStatusController_config = new WeakMap(), _BridgeStatusController_addTransactionBatchFn = new WeakMap(), _BridgeStatusController_trace = new WeakMap(), _BridgeStatusController_onTransactionFailed = new WeakMap(), _BridgeStatusController_onTransactionConfirmed = new WeakMap(), _BridgeStatusController_restartPollingForIncompleteHistoryItems = new WeakMap(), _BridgeStatusController_addTxToHistory = new WeakMap(), _BridgeStatusController_rekeyHistoryItem = new WeakMap(), _BridgeStatusController_startPollingForTxId = new WeakMap(), _BridgeStatusController_handleFetchFailure = new WeakMap(), _BridgeStatusController_handleOldHistoryItem = new WeakMap(), _BridgeStatusController_fetchBridgeTxStatus = new WeakMap(), _BridgeStatusController_setAndGetSrcTxHash = new WeakMap(), _BridgeStatusController_updateHistoryItem = new WeakMap(), _BridgeStatusController_deleteHistoryItem = new WeakMap(), _BridgeStatusController_wipeBridgeStatusByChainId = new WeakMap(), _BridgeStatusController_executeSubmitStrategy = new WeakMap(), _BridgeStatusController_trackPollingStatusUpdatedEvent = new WeakMap(), _BridgeStatusController_trackUnifiedSwapBridgeEvent = new WeakMap();
|
|
1066
858
|
//# sourceMappingURL=bridge-status-controller.mjs.map
|