@metamask/bridge-status-controller 68.1.0 → 70.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 +30 -1
- package/dist/bridge-status-controller.cjs +123 -221
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts +1 -4
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts +1 -4
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.intent.cjs +9 -13
- package/dist/bridge-status-controller.intent.cjs.map +1 -1
- package/dist/bridge-status-controller.intent.d.cts +6 -8
- package/dist/bridge-status-controller.intent.d.cts.map +1 -1
- package/dist/bridge-status-controller.intent.d.mts +6 -8
- package/dist/bridge-status-controller.intent.d.mts.map +1 -1
- package/dist/bridge-status-controller.intent.mjs +10 -14
- package/dist/bridge-status-controller.intent.mjs.map +1 -1
- package/dist/bridge-status-controller.mjs +125 -223
- package/dist/bridge-status-controller.mjs.map +1 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +0 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/accounts.cjs +8 -0
- package/dist/utils/accounts.cjs.map +1 -0
- package/dist/utils/accounts.d.cts +36 -0
- package/dist/utils/accounts.d.cts.map +1 -0
- package/dist/utils/accounts.d.mts +36 -0
- package/dist/utils/accounts.d.mts.map +1 -0
- package/dist/utils/accounts.mjs +4 -0
- package/dist/utils/accounts.mjs.map +1 -0
- package/dist/utils/authentication.cjs +15 -0
- package/dist/utils/authentication.cjs.map +1 -0
- package/dist/utils/authentication.d.cts +3 -0
- package/dist/utils/authentication.d.cts.map +1 -0
- package/dist/utils/authentication.d.mts +3 -0
- package/dist/utils/authentication.d.mts.map +1 -0
- package/dist/utils/authentication.mjs +11 -0
- package/dist/utils/authentication.mjs.map +1 -0
- package/dist/utils/bridge-status.cjs +2 -4
- package/dist/utils/bridge-status.cjs.map +1 -1
- package/dist/utils/bridge-status.d.cts.map +1 -1
- package/dist/utils/bridge-status.d.mts.map +1 -1
- package/dist/utils/bridge-status.mjs +2 -4
- package/dist/utils/bridge-status.mjs.map +1 -1
- package/dist/utils/bridge.cjs +16 -0
- package/dist/utils/bridge.cjs.map +1 -0
- package/dist/utils/bridge.d.cts +10 -0
- package/dist/utils/bridge.d.cts.map +1 -0
- package/dist/utils/bridge.d.mts +10 -0
- package/dist/utils/bridge.d.mts.map +1 -0
- package/dist/utils/bridge.mjs +11 -0
- package/dist/utils/bridge.mjs.map +1 -0
- package/dist/utils/gas.cjs +4 -7
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts +1 -1
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts +1 -1
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +4 -7
- package/dist/utils/gas.mjs.map +1 -1
- package/dist/utils/history.cjs +97 -0
- package/dist/utils/history.cjs.map +1 -0
- package/dist/utils/history.d.cts +21 -0
- package/dist/utils/history.d.cts.map +1 -0
- package/dist/utils/history.d.mts +21 -0
- package/dist/utils/history.d.mts.map +1 -0
- package/dist/utils/history.mjs +90 -0
- package/dist/utils/history.mjs.map +1 -0
- package/dist/utils/intent-api.cjs +18 -3
- package/dist/utils/intent-api.cjs.map +1 -1
- package/dist/utils/intent-api.d.cts +16 -7
- package/dist/utils/intent-api.d.cts.map +1 -1
- package/dist/utils/intent-api.d.mts +16 -7
- package/dist/utils/intent-api.d.mts.map +1 -1
- package/dist/utils/intent-api.mjs +18 -4
- package/dist/utils/intent-api.mjs.map +1 -1
- package/dist/utils/keyring.cjs +12 -0
- package/dist/utils/keyring.cjs.map +1 -0
- package/dist/utils/keyring.d.cts +8 -0
- package/dist/utils/keyring.d.cts.map +1 -0
- package/dist/utils/keyring.d.mts +8 -0
- package/dist/utils/keyring.d.mts.map +1 -0
- package/dist/utils/keyring.mjs +8 -0
- package/dist/utils/keyring.mjs.map +1 -0
- package/dist/utils/network.cjs +17 -0
- package/dist/utils/network.cjs.map +1 -0
- package/dist/utils/network.d.cts +5 -0
- package/dist/utils/network.d.cts.map +1 -0
- package/dist/utils/network.d.mts +5 -0
- package/dist/utils/network.d.mts.map +1 -0
- package/dist/utils/network.mjs +12 -0
- package/dist/utils/network.mjs.map +1 -0
- package/dist/utils/snaps.cjs +146 -1
- package/dist/utils/snaps.cjs.map +1 -1
- package/dist/utils/snaps.d.cts +62 -0
- package/dist/utils/snaps.d.cts.map +1 -1
- package/dist/utils/snaps.d.mts +62 -0
- package/dist/utils/snaps.d.mts.map +1 -1
- package/dist/utils/snaps.mjs +141 -0
- package/dist/utils/snaps.mjs.map +1 -1
- package/dist/utils/trace.cjs +31 -0
- package/dist/utils/trace.cjs.map +1 -0
- package/dist/utils/trace.d.cts +17 -0
- package/dist/utils/trace.d.cts.map +1 -0
- package/dist/utils/trace.d.mts +17 -0
- package/dist/utils/trace.d.mts.map +1 -0
- package/dist/utils/trace.mjs +26 -0
- package/dist/utils/trace.mjs.map +1 -0
- package/dist/utils/transaction.cjs +31 -193
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +8 -79
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +8 -79
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +31 -187
- package/dist/utils/transaction.mjs.map +1 -1
- package/dist/utils/validators.cjs +5 -5
- package/dist/utils/validators.cjs.map +1 -1
- package/dist/utils/validators.d.cts +6 -11
- package/dist/utils/validators.d.cts.map +1 -1
- package/dist/utils/validators.d.mts +6 -11
- package/dist/utils/validators.d.mts.map +1 -1
- package/dist/utils/validators.mjs +3 -3
- package/dist/utils/validators.mjs.map +1 -1
- package/package.json +4 -4
|
@@ -9,21 +9,28 @@ 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
|
|
13
|
-
import { formatChainIdToHex, isNonEvmChainId, StatusTypes, UnifiedSwapBridgeEventName,
|
|
12
|
+
var _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_intentManager, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionBatchFn, _BridgeStatusController_trace, _BridgeStatusController_markTxAsFailed, _BridgeStatusController_restartPollingForIncompleteHistoryItems, _BridgeStatusController_addTxToHistory, _BridgeStatusController_rekeyHistoryItem, _BridgeStatusController_startPollingForTxId, _BridgeStatusController_handleFetchFailure, _BridgeStatusController_fetchBridgeTxStatus, _BridgeStatusController_getSrcTxHash, _BridgeStatusController_updateSrcTxHash, _BridgeStatusController_wipeBridgeStatusByChainId, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, _BridgeStatusController_waitForTxConfirmation, _BridgeStatusController_handleApprovalTx, _BridgeStatusController_handleEvmTransaction, _BridgeStatusController_handleUSDTAllowanceReset, _BridgeStatusController_calculateGasFees, _BridgeStatusController_handleEvmTransactionBatch, _BridgeStatusController_trackUnifiedSwapBridgeEvent;
|
|
13
|
+
import { formatChainIdToHex, isNonEvmChainId, StatusTypes, UnifiedSwapBridgeEventName, isCrossChain, isTronChainId, isEvmTxData, isHardwareWallet, MetricsActionType, MetaMetricsSwapsEventSource, isBitcoinTrade, isTronTrade, PollingStatus } from "@metamask/bridge-controller";
|
|
14
14
|
import { toHex } from "@metamask/controller-utils";
|
|
15
|
-
import { SignTypedDataVersion } from "@metamask/keyring-controller";
|
|
16
15
|
import { StaticIntervalPollingController } from "@metamask/polling-controller";
|
|
17
16
|
import { TransactionStatus, TransactionType } from "@metamask/transaction-controller";
|
|
18
17
|
import { numberToHex } from "@metamask/utils";
|
|
19
18
|
import { IntentManager } from "./bridge-status-controller.intent.mjs";
|
|
20
|
-
import { BRIDGE_PROD_API_BASE_URL, BRIDGE_STATUS_CONTROLLER_NAME, DEFAULT_BRIDGE_STATUS_CONTROLLER_STATE, MAX_ATTEMPTS, REFRESH_INTERVAL_MS
|
|
19
|
+
import { BRIDGE_PROD_API_BASE_URL, BRIDGE_STATUS_CONTROLLER_NAME, DEFAULT_BRIDGE_STATUS_CONTROLLER_STATE, MAX_ATTEMPTS, REFRESH_INTERVAL_MS } from "./constants.mjs";
|
|
21
20
|
import { BridgeClientId } from "./types.mjs";
|
|
21
|
+
import { getAccountByAddress } from "./utils/accounts.mjs";
|
|
22
|
+
import { getJwt } from "./utils/authentication.mjs";
|
|
23
|
+
import { stopPollingForQuotes, trackMetricsEvent } from "./utils/bridge.mjs";
|
|
22
24
|
import { fetchBridgeTxStatus, getStatusRequestWithSrcTxHash, shouldSkipFetchDueToFetchFailures } from "./utils/bridge-status.mjs";
|
|
23
25
|
import { getTxGasEstimates } from "./utils/gas.mjs";
|
|
24
|
-
import {
|
|
26
|
+
import { getInitialHistoryItem, rekeyHistoryItemInState, shouldPollHistoryItem } from "./utils/history.mjs";
|
|
27
|
+
import { getIntentFromQuote, mapIntentOrderStatusToTransactionStatus } from "./utils/intent-api.mjs";
|
|
28
|
+
import { signTypedMessage } from "./utils/keyring.mjs";
|
|
25
29
|
import { getFinalizedTxProperties, getPriceImpactFromQuote, getRequestMetadataFromHistory, getRequestParamFromHistory, getTradeDataFromHistory, getEVMTxPropertiesFromTransactionMeta, getTxStatusesFromHistory, getPreConfirmationPropertiesFromQuote } from "./utils/metrics.mjs";
|
|
26
|
-
import {
|
|
30
|
+
import { getNetworkClientIdByChainId, getSelectedChainId } from "./utils/network.mjs";
|
|
31
|
+
import { handleNonEvmTx } from "./utils/snaps.mjs";
|
|
32
|
+
import { getApprovalTraceParams, getTraceParams } from "./utils/trace.mjs";
|
|
33
|
+
import { findAndUpdateTransactionsInBatch, getAddTransactionBatchParams, getStatusRequestParams, handleApprovalDelay, handleMobileHardwareWalletDelay, generateActionId, waitForTxConfirmation } from "./utils/transaction.mjs";
|
|
27
34
|
const metadata = {
|
|
28
35
|
// We want to persist the bridge status state so that we can show the proper data for the Activity list
|
|
29
36
|
// basically match the behavior of TransactionController
|
|
@@ -35,7 +42,7 @@ const metadata = {
|
|
|
35
42
|
},
|
|
36
43
|
};
|
|
37
44
|
export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
38
|
-
constructor({ messenger, state, clientId, fetchFn,
|
|
45
|
+
constructor({ messenger, state, clientId, fetchFn, addTransactionBatchFn, config, traceFn, }) {
|
|
39
46
|
super({
|
|
40
47
|
name: BRIDGE_STATUS_CONTROLLER_NAME,
|
|
41
48
|
metadata,
|
|
@@ -46,16 +53,12 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
46
53
|
...state,
|
|
47
54
|
},
|
|
48
55
|
});
|
|
49
|
-
_BridgeStatusController_instances.add(this);
|
|
50
56
|
_BridgeStatusController_pollingTokensByTxMetaId.set(this, {});
|
|
51
57
|
_BridgeStatusController_intentManager.set(this, void 0);
|
|
52
58
|
_BridgeStatusController_clientId.set(this, void 0);
|
|
53
59
|
_BridgeStatusController_fetchFn.set(this, void 0);
|
|
54
60
|
_BridgeStatusController_config.set(this, void 0);
|
|
55
|
-
_BridgeStatusController_addTransactionFn.set(this, void 0);
|
|
56
61
|
_BridgeStatusController_addTransactionBatchFn.set(this, void 0);
|
|
57
|
-
_BridgeStatusController_updateTransactionFn.set(this, void 0);
|
|
58
|
-
_BridgeStatusController_estimateGasFeeFn.set(this, void 0);
|
|
59
62
|
_BridgeStatusController_trace.set(this, void 0);
|
|
60
63
|
// Mark tx as failed in txHistory if either the approval or trade fails
|
|
61
64
|
_BridgeStatusController_markTxAsFailed.set(this, ({ id: txMetaId, actionId, }) => {
|
|
@@ -90,9 +93,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
90
93
|
});
|
|
91
94
|
}
|
|
92
95
|
else {
|
|
93
|
-
const
|
|
94
|
-
const selectedNetworkClient = this.messenger.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
|
95
|
-
const selectedChainId = selectedNetworkClient.configuration.chainId;
|
|
96
|
+
const selectedChainId = getSelectedChainId(this.messenger);
|
|
96
97
|
__classPrivateFieldGet(this, _BridgeStatusController_wipeBridgeStatusByChainId, "f").call(this, address, selectedChainId);
|
|
97
98
|
}
|
|
98
99
|
};
|
|
@@ -134,7 +135,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
134
135
|
}
|
|
135
136
|
});
|
|
136
137
|
// Restart polling if it was stopped and this tx still needs status updates
|
|
137
|
-
if (
|
|
138
|
+
if (shouldPollHistoryItem(historyItem)) {
|
|
138
139
|
// Check if polling was stopped (no active polling token)
|
|
139
140
|
const existingPollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[targetTxMetaId];
|
|
140
141
|
if (!existingPollingToken) {
|
|
@@ -142,7 +143,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
142
143
|
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, targetTxMetaId);
|
|
143
144
|
// Track polling manually restarted event
|
|
144
145
|
if (!historyItem.featureId) {
|
|
145
|
-
const selectedAccount = this.messenger
|
|
146
|
+
const selectedAccount = getAccountByAddress(this.messenger, historyItem.account);
|
|
146
147
|
const requestParams = getRequestParamFromHistory(historyItem);
|
|
147
148
|
const requestMetadata = getRequestMetadataFromHistory(historyItem, selectedAccount);
|
|
148
149
|
const { security_warnings: _, ...metadataWithoutWarnings } = requestMetadata;
|
|
@@ -191,7 +192,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
191
192
|
})
|
|
192
193
|
// Only restart polling for items that still require status updates
|
|
193
194
|
.filter((historyItem) => {
|
|
194
|
-
return
|
|
195
|
+
return shouldPollHistoryItem(historyItem);
|
|
195
196
|
});
|
|
196
197
|
incompleteHistoryItems.forEach((historyItem) => {
|
|
197
198
|
const bridgeTxMetaId = historyItem.txMetaId;
|
|
@@ -204,51 +205,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
204
205
|
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeTxMetaId);
|
|
205
206
|
});
|
|
206
207
|
});
|
|
207
|
-
_BridgeStatusController_addTxToHistory.set(this, (
|
|
208
|
-
const {
|
|
209
|
-
// Determine the key for this history item:
|
|
210
|
-
// - For pre-submission (non-batch EVM): use actionId
|
|
211
|
-
// - For post-submission or other cases: use bridgeTxMeta.id
|
|
212
|
-
const historyKey = getHistoryKey(actionId, bridgeTxMeta?.id);
|
|
213
|
-
// Write all non-status fields to state so we can reference the quote in Activity list without the Bridge API
|
|
214
|
-
// We know it's in progress but not the exact status yet
|
|
215
|
-
const txHistoryItem = {
|
|
216
|
-
txMetaId: bridgeTxMeta?.id,
|
|
217
|
-
actionId,
|
|
218
|
-
originalTransactionId: bridgeTxMeta
|
|
219
|
-
?.originalTransactionId || bridgeTxMeta?.id, // Keep original for intent transactions
|
|
220
|
-
batchId: bridgeTxMeta?.batchId,
|
|
221
|
-
quote: quoteResponse.quote,
|
|
222
|
-
startTime,
|
|
223
|
-
estimatedProcessingTimeInSeconds: quoteResponse.estimatedProcessingTimeInSeconds,
|
|
224
|
-
slippagePercentage,
|
|
225
|
-
pricingData: {
|
|
226
|
-
amountSent: quoteResponse.sentAmount?.amount ?? '0',
|
|
227
|
-
amountSentInUsd: quoteResponse.sentAmount?.usd ?? undefined,
|
|
228
|
-
quotedGasInUsd: quoteResponse.gasFee?.effective?.usd ?? undefined,
|
|
229
|
-
quotedReturnInUsd: quoteResponse.toTokenAmount?.usd ?? undefined,
|
|
230
|
-
quotedGasAmount: quoteResponse.gasFee?.effective?.amount ?? undefined,
|
|
231
|
-
},
|
|
232
|
-
initialDestAssetBalance,
|
|
233
|
-
targetContractAddress,
|
|
234
|
-
account: selectedAddress,
|
|
235
|
-
status: {
|
|
236
|
-
// We always have a PENDING status when we start polling for a tx, don't need the Bridge API for that
|
|
237
|
-
// Also we know the bare minimum fields for status at this point in time
|
|
238
|
-
status: StatusTypes.PENDING,
|
|
239
|
-
srcChain: {
|
|
240
|
-
chainId: statusRequest.srcChainId,
|
|
241
|
-
txHash: statusRequest.srcTxHash,
|
|
242
|
-
},
|
|
243
|
-
},
|
|
244
|
-
hasApprovalTx: Boolean(quoteResponse.approval),
|
|
245
|
-
approvalTxId,
|
|
246
|
-
isStxEnabled: isStxEnabled ?? false,
|
|
247
|
-
featureId: quoteResponse.featureId,
|
|
248
|
-
location,
|
|
249
|
-
...(abTests && { abTests }),
|
|
250
|
-
...(activeAbTests && { activeAbTests }),
|
|
251
|
-
};
|
|
208
|
+
_BridgeStatusController_addTxToHistory.set(this, (...args) => {
|
|
209
|
+
const { historyKey, txHistoryItem } = getInitialHistoryItem(...args);
|
|
252
210
|
this.update((state) => {
|
|
253
211
|
// Use actionId as key for pre-submission, or txMeta.id for post-submission
|
|
254
212
|
state.txHistory[historyKey] = txHistoryItem;
|
|
@@ -278,18 +236,12 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
278
236
|
if (!txHistoryItem) {
|
|
279
237
|
return;
|
|
280
238
|
}
|
|
281
|
-
if (
|
|
239
|
+
if (shouldPollHistoryItem(txHistoryItem)) {
|
|
282
240
|
__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId] = this.startPolling({
|
|
283
241
|
bridgeTxMetaId: txId,
|
|
284
242
|
});
|
|
285
243
|
}
|
|
286
244
|
});
|
|
287
|
-
_BridgeStatusController_shouldPollHistoryItem.set(this, (historyItem) => {
|
|
288
|
-
const isIntent = Boolean(historyItem?.quote?.intent);
|
|
289
|
-
const isBridgeTx = isCrossChain(historyItem.quote.srcChainId, historyItem.quote.destChainId);
|
|
290
|
-
const isTronTx = isTronChainId(historyItem.quote.srcChainId);
|
|
291
|
-
return [isBridgeTx, isIntent, isTronTx].some(Boolean);
|
|
292
|
-
});
|
|
293
245
|
/**
|
|
294
246
|
* @deprecated For EVM/Solana swap/bridge txs we add tx to history in submitTx()
|
|
295
247
|
* For Solana swap/bridge we start polling in submitTx()
|
|
@@ -341,7 +293,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
341
293
|
// Track max polling reached event
|
|
342
294
|
const historyItem = this.state.txHistory[bridgeTxMetaId];
|
|
343
295
|
if (historyItem && !historyItem.featureId) {
|
|
344
|
-
const selectedAccount = this.messenger
|
|
296
|
+
const selectedAccount = getAccountByAddress(this.messenger, historyItem.account);
|
|
345
297
|
const requestParams = getRequestParamFromHistory(historyItem);
|
|
346
298
|
const requestMetadata = getRequestMetadataFromHistory(historyItem, selectedAccount);
|
|
347
299
|
const { security_warnings: _, ...metadataWithoutWarnings } = requestMetadata;
|
|
@@ -379,9 +331,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
379
331
|
try {
|
|
380
332
|
let status;
|
|
381
333
|
let validationFailures = [];
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const intentTxStatus = await __classPrivateFieldGet(this, _BridgeStatusController_intentManager, "f").getIntentTransactionStatus(bridgeTxMetaId, historyItem, __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"));
|
|
334
|
+
if (historyItem.quote.intent) {
|
|
335
|
+
const intentTxStatus = await __classPrivateFieldGet(this, _BridgeStatusController_intentManager, "f").getIntentTransactionStatus(bridgeTxMetaId, historyItem.quote.srcChainId, historyItem.quote.intent.protocol, __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"), historyItem.status.srcChain.txHash);
|
|
385
336
|
if (intentTxStatus?.bridgeStatus === null ||
|
|
386
337
|
intentTxStatus?.bridgeStatus === undefined) {
|
|
387
338
|
return;
|
|
@@ -398,7 +349,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
398
349
|
}
|
|
399
350
|
__classPrivateFieldGet(this, _BridgeStatusController_updateSrcTxHash, "f").call(this, bridgeTxMetaId, srcTxHash);
|
|
400
351
|
const statusRequest = getStatusRequestWithSrcTxHash(historyItem.quote, srcTxHash);
|
|
401
|
-
const response = await fetchBridgeTxStatus(statusRequest, __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"), await
|
|
352
|
+
const response = await fetchBridgeTxStatus(statusRequest, __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"), await getJwt(this.messenger), __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"), __classPrivateFieldGet(this, _BridgeStatusController_config, "f").customBridgeApiBaseUrl);
|
|
402
353
|
status = response.status;
|
|
403
354
|
validationFailures = response.validationFailures;
|
|
404
355
|
}
|
|
@@ -426,7 +377,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
426
377
|
this.update((state) => {
|
|
427
378
|
state.txHistory[bridgeTxMetaId] = newBridgeHistoryItem;
|
|
428
379
|
});
|
|
429
|
-
if (
|
|
380
|
+
if (historyItem.quote.intent) {
|
|
430
381
|
__classPrivateFieldGet(this, _BridgeStatusController_intentManager, "f").syncTransactionFromIntentStatus(bridgeTxMetaId, historyItem);
|
|
431
382
|
}
|
|
432
383
|
// 5. After effects
|
|
@@ -454,16 +405,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
454
405
|
__classPrivateFieldGet(this, _BridgeStatusController_handleFetchFailure, "f").call(this, bridgeTxMetaId);
|
|
455
406
|
}
|
|
456
407
|
});
|
|
457
|
-
_BridgeStatusController_getJwt.set(this, async () => {
|
|
458
|
-
try {
|
|
459
|
-
const token = await this.messenger.call('AuthenticationController:getBearerToken');
|
|
460
|
-
return token;
|
|
461
|
-
}
|
|
462
|
-
catch (error) {
|
|
463
|
-
console.error('Error getting JWT token for bridge-api request', error);
|
|
464
|
-
return undefined;
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
408
|
_BridgeStatusController_getSrcTxHash.set(this, (bridgeTxMetaId) => {
|
|
468
409
|
const { txHistory } = this.state;
|
|
469
410
|
// Prefer the srcTxHash from bridgeStatusState so we don't have to l ook up in TransactionController
|
|
@@ -513,34 +454,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
513
454
|
* TX SUBMISSION HANDLING
|
|
514
455
|
*******************************************************
|
|
515
456
|
*/
|
|
516
|
-
/**
|
|
517
|
-
* Submits the transaction to the snap using the new unified ClientRequest interface
|
|
518
|
-
* Works for all non-EVM chains (Solana, BTC, Tron)
|
|
519
|
-
* This adds an approval tx to the ApprovalsController in the background
|
|
520
|
-
* The client needs to handle the approval tx by redirecting to the confirmation page with the approvalTxId in the URL
|
|
521
|
-
*
|
|
522
|
-
* @param trade - The trade data (can be approval or main trade)
|
|
523
|
-
* @param quoteResponse - The quote response containing metadata
|
|
524
|
-
* @param selectedAccount - The account to submit the transaction for
|
|
525
|
-
* @returns The transaction meta
|
|
526
|
-
*/
|
|
527
|
-
_BridgeStatusController_handleNonEvmTx.set(this, async (trade, quoteResponse, selectedAccount) => {
|
|
528
|
-
if (!selectedAccount.metadata?.snap?.id) {
|
|
529
|
-
throw new Error('Failed to submit cross-chain swap transaction: undefined snap id');
|
|
530
|
-
}
|
|
531
|
-
const request = getClientRequest(trade, quoteResponse.quote.srcChainId, selectedAccount);
|
|
532
|
-
const requestResponse = (await this.messenger.call('SnapController:handleRequest', request));
|
|
533
|
-
// Create quote response with the specified trade
|
|
534
|
-
// This allows the same method to handle both approvals and main trades
|
|
535
|
-
const txQuoteResponse = {
|
|
536
|
-
...quoteResponse,
|
|
537
|
-
trade,
|
|
538
|
-
};
|
|
539
|
-
const txMeta = handleNonEvmTxResponse(requestResponse, txQuoteResponse, selectedAccount);
|
|
540
|
-
// TODO remove this eventually, just returning it now to match extension behavior
|
|
541
|
-
// OR if the snap can propagate the snapRequestId or keyringReqId to the ApprovalsController, this can return the approvalTxId instead and clients won't need to subscribe to the ApprovalsController state to redirect
|
|
542
|
-
return txMeta;
|
|
543
|
-
});
|
|
544
457
|
_BridgeStatusController_waitForHashAndReturnFinalTxMeta.set(this, async (hashPromise) => {
|
|
545
458
|
const transactionHash = await hashPromise;
|
|
546
459
|
const finalTransactionMeta = this.messenger
|
|
@@ -559,8 +472,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
559
472
|
pollMs,
|
|
560
473
|
});
|
|
561
474
|
});
|
|
562
|
-
_BridgeStatusController_handleApprovalTx.set(this, async (isBridgeTx, srcChainId, approval, resetApproval, requireApproval) => {
|
|
563
|
-
if (approval) {
|
|
475
|
+
_BridgeStatusController_handleApprovalTx.set(this, async (quoteResponse, isBridgeTx, srcChainId, approval, resetApproval, requireApproval) => {
|
|
476
|
+
if (approval && isEvmTxData(approval)) {
|
|
564
477
|
const approveTx = async () => {
|
|
565
478
|
await __classPrivateFieldGet(this, _BridgeStatusController_handleUSDTAllowanceReset, "f").call(this, resetApproval);
|
|
566
479
|
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransaction, "f").call(this, {
|
|
@@ -573,15 +486,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
573
486
|
await handleApprovalDelay(srcChainId);
|
|
574
487
|
return approvalTxMeta;
|
|
575
488
|
};
|
|
576
|
-
return await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this,
|
|
577
|
-
name: isBridgeTx
|
|
578
|
-
? TraceName.BridgeTransactionApprovalCompleted
|
|
579
|
-
: TraceName.SwapTransactionApprovalCompleted,
|
|
580
|
-
data: {
|
|
581
|
-
srcChainId: formatChainIdToCaip(srcChainId),
|
|
582
|
-
stxEnabled: false,
|
|
583
|
-
},
|
|
584
|
-
}, approveTx);
|
|
489
|
+
return await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getApprovalTraceParams(quoteResponse, false), approveTx);
|
|
585
490
|
}
|
|
586
491
|
return undefined;
|
|
587
492
|
});
|
|
@@ -600,13 +505,13 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
600
505
|
*/
|
|
601
506
|
_BridgeStatusController_handleEvmTransaction.set(this, async ({ transactionType, trade, requireApproval = false, txFee, actionId: providedActionId, }) => {
|
|
602
507
|
// Use provided actionId (for pre-submission history) or generate one
|
|
603
|
-
const actionId = providedActionId ?? generateActionId()
|
|
604
|
-
const selectedAccount = this.messenger
|
|
508
|
+
const actionId = providedActionId ?? generateActionId();
|
|
509
|
+
const selectedAccount = getAccountByAddress(this.messenger, trade.from);
|
|
605
510
|
if (!selectedAccount) {
|
|
606
511
|
throw new Error('Failed to submit cross-chain swap transaction: unknown account in trade data');
|
|
607
512
|
}
|
|
608
513
|
const hexChainId = formatChainIdToHex(trade.chainId);
|
|
609
|
-
const networkClientId = this.messenger
|
|
514
|
+
const networkClientId = getNetworkClientIdByChainId(this.messenger, hexChainId);
|
|
610
515
|
const requestOptions = {
|
|
611
516
|
actionId,
|
|
612
517
|
networkClientId,
|
|
@@ -630,7 +535,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
630
535
|
...transactionParams,
|
|
631
536
|
...(await __classPrivateFieldGet(this, _BridgeStatusController_calculateGasFees, "f").call(this, transactionParams, networkClientId, hexChainId, txFee)),
|
|
632
537
|
};
|
|
633
|
-
const { result } = await
|
|
538
|
+
const { result } = await this.messenger.call('TransactionController:addTransaction', transactionParamsWithMaxGas, requestOptions);
|
|
634
539
|
return await __classPrivateFieldGet(this, _BridgeStatusController_waitForHashAndReturnFinalTxMeta, "f").call(this, result);
|
|
635
540
|
});
|
|
636
541
|
_BridgeStatusController_handleUSDTAllowanceReset.set(this, async (resetApproval) => {
|
|
@@ -647,17 +552,13 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
647
552
|
// Convert to hex since txFee values from the quote are decimal strings
|
|
648
553
|
if (txFee) {
|
|
649
554
|
return {
|
|
650
|
-
maxFeePerGas: toHex(txFee.maxFeePerGas
|
|
651
|
-
maxPriorityFeePerGas: toHex(txFee.maxPriorityFeePerGas
|
|
555
|
+
maxFeePerGas: toHex(txFee.maxFeePerGas),
|
|
556
|
+
maxPriorityFeePerGas: toHex(txFee.maxPriorityFeePerGas),
|
|
652
557
|
gas: gas ? toHex(gas) : undefined,
|
|
653
558
|
};
|
|
654
559
|
}
|
|
655
560
|
const { gasFeeEstimates } = this.messenger.call('GasFeeController:getState');
|
|
656
|
-
const { estimates: txGasFeeEstimates } = await
|
|
657
|
-
transactionParams,
|
|
658
|
-
chainId,
|
|
659
|
-
networkClientId,
|
|
660
|
-
});
|
|
561
|
+
const { estimates: txGasFeeEstimates } = await this.messenger.call('TransactionController:estimateGasFee', { transactionParams, chainId, networkClientId });
|
|
661
562
|
const { maxFeePerGas, maxPriorityFeePerGas } = getTxGasEstimates({
|
|
662
563
|
networkGasFeeEstimates: gasFeeEstimates,
|
|
663
564
|
txGasFeeEstimates,
|
|
@@ -683,7 +584,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
683
584
|
_BridgeStatusController_handleEvmTransactionBatch.set(this, async (args) => {
|
|
684
585
|
const transactionParams = await getAddTransactionBatchParams({
|
|
685
586
|
messenger: this.messenger,
|
|
686
|
-
estimateGasFeeFn: __classPrivateFieldGet(this, _BridgeStatusController_estimateGasFeeFn, "f"),
|
|
687
587
|
...args,
|
|
688
588
|
});
|
|
689
589
|
const txDataByType = {
|
|
@@ -695,7 +595,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
695
595
|
const { batchId } = await __classPrivateFieldGet(this, _BridgeStatusController_addTransactionBatchFn, "f").call(this, transactionParams);
|
|
696
596
|
const { approvalMeta, tradeMeta } = findAndUpdateTransactionsInBatch({
|
|
697
597
|
messenger: this.messenger,
|
|
698
|
-
updateTransactionFn: __classPrivateFieldGet(this, _BridgeStatusController_updateTransactionFn, "f"),
|
|
699
598
|
batchId,
|
|
700
599
|
txDataByType,
|
|
701
600
|
});
|
|
@@ -717,11 +616,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
717
616
|
* @returns The transaction meta
|
|
718
617
|
*/
|
|
719
618
|
this.submitTx = async (accountAddress, quoteResponse, isStxEnabledOnClient, quotesReceivedContext, location = MetaMetricsSwapsEventSource.MainView, abTests, activeAbTests) => {
|
|
720
|
-
this.messenger
|
|
721
|
-
|
|
722
|
-
// If the trade has a featureId, it means it was submitted outside of the Unified Swap and Bridge experience, so no QuotesReceived event is published
|
|
723
|
-
quoteResponse.featureId ? undefined : quotesReceivedContext);
|
|
724
|
-
const selectedAccount = __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_getMultichainSelectedAccount).call(this, accountAddress);
|
|
619
|
+
stopPollingForQuotes(this.messenger, quoteResponse.featureId, quotesReceivedContext);
|
|
620
|
+
const selectedAccount = getAccountByAddress(this.messenger, accountAddress);
|
|
725
621
|
if (!selectedAccount) {
|
|
726
622
|
throw new Error('Failed to submit cross-chain swap transaction: undefined multichain account');
|
|
727
623
|
}
|
|
@@ -732,6 +628,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
732
628
|
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Submitted, undefined, preConfirmationProperties);
|
|
733
629
|
let txMeta;
|
|
734
630
|
let approvalTxId;
|
|
631
|
+
let isDelegatedAccount = false;
|
|
735
632
|
const startTime = Date.now();
|
|
736
633
|
const isBridgeTx = isCrossChain(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
737
634
|
const isTronTx = isTronChainId(quoteResponse.quote.srcChainId);
|
|
@@ -739,20 +636,14 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
739
636
|
if (isNonEvmChainId(quoteResponse.quote.srcChainId)) {
|
|
740
637
|
// Handle non-EVM approval if present (e.g., Tron token approvals)
|
|
741
638
|
if (quoteResponse.approval && isTronTrade(quoteResponse.approval)) {
|
|
742
|
-
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, {
|
|
743
|
-
name: isBridgeTx
|
|
744
|
-
? TraceName.BridgeTransactionApprovalCompleted
|
|
745
|
-
: TraceName.SwapTransactionApprovalCompleted,
|
|
746
|
-
data: {
|
|
747
|
-
srcChainId: formatChainIdToCaip(quoteResponse.quote.srcChainId),
|
|
748
|
-
stxEnabled: false,
|
|
749
|
-
},
|
|
750
|
-
}, async () => {
|
|
639
|
+
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getApprovalTraceParams(quoteResponse, false), async () => {
|
|
751
640
|
try {
|
|
752
641
|
return quoteResponse.approval &&
|
|
753
642
|
isTronTrade(quoteResponse.approval)
|
|
754
|
-
? await
|
|
755
|
-
:
|
|
643
|
+
? await handleNonEvmTx(this.messenger, quoteResponse.approval, quoteResponse, selectedAccount)
|
|
644
|
+
: /* c8 ignore start */
|
|
645
|
+
undefined;
|
|
646
|
+
/* c8 ignore end */
|
|
756
647
|
}
|
|
757
648
|
catch (error) {
|
|
758
649
|
!quoteResponse.featureId &&
|
|
@@ -767,26 +658,18 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
767
658
|
// Add delay after approval similar to EVM flow
|
|
768
659
|
await handleApprovalDelay(quoteResponse.quote.srcChainId);
|
|
769
660
|
}
|
|
770
|
-
txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, {
|
|
771
|
-
name: isBridgeTx
|
|
772
|
-
? TraceName.BridgeTransactionCompleted
|
|
773
|
-
: TraceName.SwapTransactionCompleted,
|
|
774
|
-
data: {
|
|
775
|
-
srcChainId: formatChainIdToCaip(quoteResponse.quote.srcChainId),
|
|
776
|
-
stxEnabled: false,
|
|
777
|
-
},
|
|
778
|
-
}, async () => {
|
|
661
|
+
txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getTraceParams(quoteResponse, false), async () => {
|
|
779
662
|
try {
|
|
780
663
|
if (!(isTronTrade(quoteResponse.trade) ||
|
|
781
664
|
isBitcoinTrade(quoteResponse.trade) ||
|
|
782
665
|
typeof quoteResponse.trade === 'string')) {
|
|
783
666
|
throw new Error('Failed to submit cross-chain swap transaction: trade is not a non-EVM transaction');
|
|
784
667
|
}
|
|
785
|
-
return await
|
|
668
|
+
return await handleNonEvmTx(this.messenger, quoteResponse.trade, quoteResponse, selectedAccount);
|
|
786
669
|
}
|
|
787
670
|
catch (error) {
|
|
788
671
|
!quoteResponse.featureId &&
|
|
789
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed,
|
|
672
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed, undefined, {
|
|
790
673
|
error_message: error?.message,
|
|
791
674
|
...preConfirmationProperties,
|
|
792
675
|
});
|
|
@@ -800,19 +683,30 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
800
683
|
// Extension does not have this issue
|
|
801
684
|
const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE && isHardwareAccount;
|
|
802
685
|
// Handle smart transactions if enabled
|
|
803
|
-
txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, {
|
|
804
|
-
name: isBridgeTx
|
|
805
|
-
? TraceName.BridgeTransactionCompleted
|
|
806
|
-
: TraceName.SwapTransactionCompleted,
|
|
807
|
-
data: {
|
|
808
|
-
srcChainId: formatChainIdToCaip(quoteResponse.quote.srcChainId),
|
|
809
|
-
stxEnabled: isStxEnabledOnClient,
|
|
810
|
-
},
|
|
811
|
-
}, async () => {
|
|
686
|
+
txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getTraceParams(quoteResponse, isStxEnabledOnClient), async () => {
|
|
812
687
|
if (!isEvmTxData(quoteResponse.trade)) {
|
|
813
688
|
throw new Error('Failed to submit cross-chain swap transaction: trade is not an EVM transaction');
|
|
814
689
|
}
|
|
815
|
-
if
|
|
690
|
+
// Check if the account is an EIP-7702 delegated account
|
|
691
|
+
// Delegated accounts only allow 1 in-flight tx, so approve + swap
|
|
692
|
+
// must be batched into a single transaction
|
|
693
|
+
const hexChainId = formatChainIdToHex(quoteResponse.quote.srcChainId);
|
|
694
|
+
isDelegatedAccount = await (async () => {
|
|
695
|
+
try {
|
|
696
|
+
const atomicBatchSupport = await this.messenger.call('TransactionController:isAtomicBatchSupported', {
|
|
697
|
+
address: quoteResponse.trade
|
|
698
|
+
.from,
|
|
699
|
+
chainIds: [hexChainId],
|
|
700
|
+
});
|
|
701
|
+
return atomicBatchSupport.some((entry) => entry.isSupported && entry.delegationAddress);
|
|
702
|
+
}
|
|
703
|
+
catch {
|
|
704
|
+
return false;
|
|
705
|
+
}
|
|
706
|
+
})();
|
|
707
|
+
if (isStxEnabledOnClient ||
|
|
708
|
+
quoteResponse.quote.gasIncluded7702 ||
|
|
709
|
+
isDelegatedAccount) {
|
|
816
710
|
const { tradeMeta, approvalMeta } = await __classPrivateFieldGet(this, _BridgeStatusController_handleEvmTransactionBatch, "f").call(this, {
|
|
817
711
|
isBridgeTx,
|
|
818
712
|
resetApproval: quoteResponse.resetApproval,
|
|
@@ -822,12 +716,13 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
822
716
|
trade: quoteResponse.trade,
|
|
823
717
|
quoteResponse,
|
|
824
718
|
requireApproval,
|
|
719
|
+
isDelegatedAccount,
|
|
825
720
|
});
|
|
826
721
|
approvalTxId = approvalMeta?.id;
|
|
827
722
|
return tradeMeta;
|
|
828
723
|
}
|
|
829
724
|
// Set approval time and id if an approval tx is needed
|
|
830
|
-
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, isBridgeTx, quoteResponse.quote.srcChainId, quoteResponse.approval && isEvmTxData(quoteResponse.approval)
|
|
725
|
+
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, quoteResponse, isBridgeTx, quoteResponse.quote.srcChainId, quoteResponse.approval && isEvmTxData(quoteResponse.approval)
|
|
831
726
|
? quoteResponse.approval
|
|
832
727
|
: undefined, quoteResponse.resetApproval, requireApproval);
|
|
833
728
|
approvalTxId = approvalTxMeta?.id;
|
|
@@ -874,7 +769,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
874
769
|
// Only add history here for non-EVM and batch EVM transactions
|
|
875
770
|
const isNonBatchEvm = !isNonEvmChainId(quoteResponse.quote.srcChainId) &&
|
|
876
771
|
!isStxEnabledOnClient &&
|
|
877
|
-
!quoteResponse.quote.gasIncluded7702
|
|
772
|
+
!quoteResponse.quote.gasIncluded7702 &&
|
|
773
|
+
!isDelegatedAccount;
|
|
878
774
|
if (!isNonBatchEvm) {
|
|
879
775
|
// Add swap or bridge tx to history
|
|
880
776
|
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
@@ -922,35 +818,32 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
922
818
|
*/
|
|
923
819
|
this.submitIntent = async (params) => {
|
|
924
820
|
const { quoteResponse, accountAddress, location, abTests, activeAbTests } = params;
|
|
925
|
-
|
|
821
|
+
// TODO add metrics context
|
|
822
|
+
stopPollingForQuotes(this.messenger);
|
|
926
823
|
// Build pre-confirmation properties for error tracking parity with submitTx
|
|
927
|
-
const account =
|
|
824
|
+
const account = getAccountByAddress(this.messenger, accountAddress);
|
|
928
825
|
const isHardwareAccount = Boolean(account) && isHardwareWallet(account);
|
|
929
826
|
const preConfirmationProperties = getPreConfirmationPropertiesFromQuote(quoteResponse, false, isHardwareAccount, location, abTests, activeAbTests);
|
|
930
827
|
try {
|
|
931
828
|
const intent = getIntentFromQuote(quoteResponse);
|
|
932
829
|
// If backend provided an approval tx for this intent quote, submit it first (on-chain),
|
|
933
830
|
// then proceed with off-chain intent submission.
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
/* requireApproval */ false);
|
|
942
|
-
approvalTxId = approvalTxMeta?.id;
|
|
943
|
-
if (approvalTxId) {
|
|
944
|
-
await __classPrivateFieldGet(this, _BridgeStatusController_waitForTxConfirmation, "f").call(this, approvalTxId);
|
|
945
|
-
}
|
|
831
|
+
const isBridgeTx = isCrossChain(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
832
|
+
const requireApproval = isHardwareAccount && __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE;
|
|
833
|
+
// Handle approval silently for better UX in intent flows
|
|
834
|
+
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, quoteResponse, isBridgeTx, quoteResponse.quote.srcChainId, quoteResponse.approval, quoteResponse.resetApproval, requireApproval);
|
|
835
|
+
const approvalTxId = approvalTxMeta?.id;
|
|
836
|
+
if (approvalTxId) {
|
|
837
|
+
await __classPrivateFieldGet(this, _BridgeStatusController_waitForTxConfirmation, "f").call(this, approvalTxId);
|
|
946
838
|
}
|
|
947
|
-
const { srcChainId
|
|
948
|
-
const signature = await
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
839
|
+
const { srcChainId, requestId } = quoteResponse.quote;
|
|
840
|
+
const signature = await signTypedMessage({
|
|
841
|
+
messenger: this.messenger,
|
|
842
|
+
accountAddress,
|
|
843
|
+
typedData: intent.typedData,
|
|
844
|
+
});
|
|
952
845
|
const submissionParams = {
|
|
953
|
-
srcChainId
|
|
846
|
+
srcChainId,
|
|
954
847
|
quoteId: requestId,
|
|
955
848
|
signature,
|
|
956
849
|
order: intent.order,
|
|
@@ -960,16 +853,17 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
960
853
|
const intentOrder = await __classPrivateFieldGet(this, _BridgeStatusController_intentManager, "f").submitIntent(submissionParams, __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"));
|
|
961
854
|
const orderUid = intentOrder.id;
|
|
962
855
|
// Determine transaction type: swap for same-chain, bridge for cross-chain
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
:
|
|
856
|
+
const transactionType = isBridgeTx
|
|
857
|
+
? /* c8 ignore start */
|
|
858
|
+
TransactionType.bridge
|
|
859
|
+
: /* c8 ignore end */
|
|
860
|
+
TransactionType.swap;
|
|
967
861
|
// Create actual transaction in Transaction Controller first
|
|
968
|
-
const networkClientId = this.messenger
|
|
862
|
+
const networkClientId = getNetworkClientIdByChainId(this.messenger, srcChainId);
|
|
969
863
|
// This is a synthetic transaction whose purpose is to be able
|
|
970
864
|
// to track the order status via the history
|
|
971
865
|
const intentTransactionParams = {
|
|
972
|
-
chainId: formatChainIdToHex(
|
|
866
|
+
chainId: formatChainIdToHex(srcChainId),
|
|
973
867
|
from: accountAddress,
|
|
974
868
|
to: intent.settlementContract ??
|
|
975
869
|
'0x9008D19f58AAbd9eD0D60971565AA8510560ab41', // Default settlement contract
|
|
@@ -978,7 +872,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
978
872
|
gas: '0x5208', // Minimal gas for display purposes
|
|
979
873
|
gasPrice: '0x3b9aca00', // 1 Gwei - will be converted to EIP-1559 fees if network supports it
|
|
980
874
|
};
|
|
981
|
-
const { transactionMeta: txMetaPromise } = await
|
|
875
|
+
const { transactionMeta: txMetaPromise } = await this.messenger.call('TransactionController:addTransaction', intentTransactionParams, {
|
|
982
876
|
origin: 'metamask',
|
|
983
877
|
actionId: generateActionId(),
|
|
984
878
|
requireApproval: false,
|
|
@@ -999,7 +893,6 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
999
893
|
...statusUpdatedTxMeta,
|
|
1000
894
|
isIntentTx: true,
|
|
1001
895
|
orderUid,
|
|
1002
|
-
intentType: isCrossChainTx ? 'bridge' : 'swap',
|
|
1003
896
|
};
|
|
1004
897
|
// Record in bridge history with actual transaction metadata
|
|
1005
898
|
try {
|
|
@@ -1079,24 +972,36 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
1079
972
|
};
|
|
1080
973
|
// This will publish events for PERPS dropped tx failures as well
|
|
1081
974
|
if (!txMetaId) {
|
|
1082
|
-
|
|
975
|
+
trackMetricsEvent({
|
|
976
|
+
messenger: this.messenger,
|
|
977
|
+
eventName,
|
|
978
|
+
properties: baseProperties,
|
|
979
|
+
});
|
|
1083
980
|
return;
|
|
1084
981
|
}
|
|
1085
982
|
const historyItem = this.state.txHistory[txMetaId];
|
|
1086
983
|
if (!historyItem) {
|
|
1087
|
-
|
|
984
|
+
trackMetricsEvent({
|
|
985
|
+
messenger: this.messenger,
|
|
986
|
+
eventName,
|
|
987
|
+
properties: baseProperties,
|
|
988
|
+
});
|
|
1088
989
|
return;
|
|
1089
990
|
}
|
|
1090
991
|
const requestParamProperties = getRequestParamFromHistory(historyItem);
|
|
1091
992
|
// Always publish StatusValidationFailed event, regardless of featureId
|
|
1092
993
|
if (eventName === UnifiedSwapBridgeEventName.StatusValidationFailed) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
994
|
+
trackMetricsEvent({
|
|
995
|
+
messenger: this.messenger,
|
|
996
|
+
eventName,
|
|
997
|
+
properties: {
|
|
998
|
+
...baseProperties,
|
|
999
|
+
chain_id_source: requestParamProperties.chain_id_source,
|
|
1000
|
+
chain_id_destination: requestParamProperties.chain_id_destination,
|
|
1001
|
+
token_address_source: requestParamProperties.token_address_source,
|
|
1002
|
+
token_address_destination: requestParamProperties.token_address_destination,
|
|
1003
|
+
refresh_count: historyItem.attempts?.counter ?? 0,
|
|
1004
|
+
},
|
|
1100
1005
|
});
|
|
1101
1006
|
return;
|
|
1102
1007
|
}
|
|
@@ -1104,7 +1009,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
1104
1009
|
if (historyItem.featureId) {
|
|
1105
1010
|
return;
|
|
1106
1011
|
}
|
|
1107
|
-
const selectedAccount = this.messenger
|
|
1012
|
+
const selectedAccount = getAccountByAddress(this.messenger, historyItem.account);
|
|
1108
1013
|
const { transactions } = this.messenger.call('TransactionController:getState');
|
|
1109
1014
|
const txMeta = transactions?.find((tx) => tx.id === txMetaId);
|
|
1110
1015
|
const approvalTxMeta = transactions?.find((tx) => tx.id === historyItem.approvalTxId);
|
|
@@ -1117,24 +1022,23 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
1117
1022
|
...getFinalizedTxProperties(historyItem, txMeta, approvalTxMeta),
|
|
1118
1023
|
...getPriceImpactFromQuote(historyItem.quote),
|
|
1119
1024
|
};
|
|
1120
|
-
|
|
1025
|
+
trackMetricsEvent({
|
|
1026
|
+
messenger: this.messenger,
|
|
1027
|
+
eventName,
|
|
1028
|
+
properties: requiredEventProperties,
|
|
1029
|
+
});
|
|
1121
1030
|
});
|
|
1122
1031
|
__classPrivateFieldSet(this, _BridgeStatusController_clientId, clientId, "f");
|
|
1123
1032
|
__classPrivateFieldSet(this, _BridgeStatusController_fetchFn, fetchFn, "f");
|
|
1124
|
-
__classPrivateFieldSet(this, _BridgeStatusController_addTransactionFn, addTransactionFn, "f");
|
|
1125
1033
|
__classPrivateFieldSet(this, _BridgeStatusController_addTransactionBatchFn, addTransactionBatchFn, "f");
|
|
1126
|
-
__classPrivateFieldSet(this, _BridgeStatusController_updateTransactionFn, updateTransactionFn, "f");
|
|
1127
|
-
__classPrivateFieldSet(this, _BridgeStatusController_estimateGasFeeFn, estimateGasFeeFn, "f");
|
|
1128
1034
|
__classPrivateFieldSet(this, _BridgeStatusController_config, {
|
|
1129
1035
|
customBridgeApiBaseUrl: config?.customBridgeApiBaseUrl ?? BRIDGE_PROD_API_BASE_URL,
|
|
1130
1036
|
}, "f");
|
|
1131
1037
|
__classPrivateFieldSet(this, _BridgeStatusController_trace, traceFn ?? ((_request, fn) => fn?.()), "f");
|
|
1132
1038
|
__classPrivateFieldSet(this, _BridgeStatusController_intentManager, new IntentManager({
|
|
1133
1039
|
messenger: this.messenger,
|
|
1134
|
-
updateTransactionFn: __classPrivateFieldGet(this, _BridgeStatusController_updateTransactionFn, "f"),
|
|
1135
1040
|
customBridgeApiBaseUrl: __classPrivateFieldGet(this, _BridgeStatusController_config, "f").customBridgeApiBaseUrl,
|
|
1136
1041
|
fetchFn: __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"),
|
|
1137
|
-
getJwt: __classPrivateFieldGet(this, _BridgeStatusController_getJwt, "f"),
|
|
1138
1042
|
}), "f");
|
|
1139
1043
|
// Register action handlers
|
|
1140
1044
|
this.messenger.registerActionHandler(`${BRIDGE_STATUS_CONTROLLER_NAME}:startPollingForBridgeTxStatus`, this.startPollingForBridgeTxStatus.bind(this));
|
|
@@ -1191,7 +1095,5 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
1191
1095
|
__classPrivateFieldGet(this, _BridgeStatusController_restartPollingForIncompleteHistoryItems, "f").call(this);
|
|
1192
1096
|
}
|
|
1193
1097
|
}
|
|
1194
|
-
_BridgeStatusController_pollingTokensByTxMetaId = new WeakMap(), _BridgeStatusController_intentManager = new WeakMap(), _BridgeStatusController_clientId = new WeakMap(), _BridgeStatusController_fetchFn = new WeakMap(), _BridgeStatusController_config = new WeakMap(),
|
|
1195
|
-
return this.messenger.call('AccountsController:getAccountByAddress', accountAddress);
|
|
1196
|
-
};
|
|
1098
|
+
_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_markTxAsFailed = new WeakMap(), _BridgeStatusController_restartPollingForIncompleteHistoryItems = new WeakMap(), _BridgeStatusController_addTxToHistory = new WeakMap(), _BridgeStatusController_rekeyHistoryItem = 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_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();
|
|
1197
1099
|
//# sourceMappingURL=bridge-status-controller.mjs.map
|