@metamask/bridge-status-controller 70.0.5 → 71.1.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 +58 -8
- package/dist/bridge-status-controller-method-action-types.cjs +7 -0
- package/dist/bridge-status-controller-method-action-types.cjs.map +1 -0
- package/dist/bridge-status-controller-method-action-types.d.cts +38 -0
- package/dist/bridge-status-controller-method-action-types.d.cts.map +1 -0
- package/dist/bridge-status-controller-method-action-types.d.mts +38 -0
- package/dist/bridge-status-controller-method-action-types.d.mts.map +1 -0
- package/dist/bridge-status-controller-method-action-types.mjs +6 -0
- package/dist/bridge-status-controller-method-action-types.mjs.map +1 -0
- package/dist/bridge-status-controller.cjs +217 -123
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts +4 -1
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts +4 -1
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.mjs +222 -128
- package/dist/bridge-status-controller.mjs.map +1 -1
- package/dist/constants.cjs +2 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +21 -18
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +21 -18
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +4 -0
- package/dist/types.mjs.map +1 -1
- package/dist/utils/accounts.d.cts +1 -1
- package/dist/utils/accounts.d.mts +1 -1
- package/dist/utils/bridge-status.cjs +49 -2
- package/dist/utils/bridge-status.cjs.map +1 -1
- package/dist/utils/bridge-status.d.cts +2 -1
- package/dist/utils/bridge-status.d.cts.map +1 -1
- package/dist/utils/bridge-status.d.mts +2 -1
- package/dist/utils/bridge-status.d.mts.map +1 -1
- package/dist/utils/bridge-status.mjs +48 -2
- package/dist/utils/bridge-status.mjs.map +1 -1
- package/dist/utils/feature-flags.cjs +12 -0
- package/dist/utils/feature-flags.cjs.map +1 -0
- package/dist/utils/feature-flags.d.cts +3 -0
- package/dist/utils/feature-flags.d.cts.map +1 -0
- package/dist/utils/feature-flags.d.mts +3 -0
- package/dist/utils/feature-flags.d.mts.map +1 -0
- package/dist/utils/feature-flags.mjs +8 -0
- package/dist/utils/feature-flags.mjs.map +1 -0
- package/dist/utils/history.cjs +48 -3
- package/dist/utils/history.cjs.map +1 -1
- package/dist/utils/history.d.cts +19 -1
- package/dist/utils/history.d.cts.map +1 -1
- package/dist/utils/history.d.mts +19 -1
- package/dist/utils/history.d.mts.map +1 -1
- package/dist/utils/history.mjs +45 -3
- package/dist/utils/history.mjs.map +1 -1
- package/dist/utils/intent-api.cjs.map +1 -1
- package/dist/utils/intent-api.d.cts +1 -1
- package/dist/utils/intent-api.d.cts.map +1 -1
- package/dist/utils/intent-api.d.mts +1 -1
- package/dist/utils/intent-api.d.mts.map +1 -1
- package/dist/utils/intent-api.mjs.map +1 -1
- package/dist/utils/metrics.cjs +45 -8
- package/dist/utils/metrics.cjs.map +1 -1
- package/dist/utils/metrics.d.cts +37 -6
- package/dist/utils/metrics.d.cts.map +1 -1
- package/dist/utils/metrics.d.mts +37 -6
- package/dist/utils/metrics.d.mts.map +1 -1
- package/dist/utils/metrics.mjs +44 -8
- package/dist/utils/metrics.mjs.map +1 -1
- package/dist/utils/network.cjs +7 -1
- package/dist/utils/network.cjs.map +1 -1
- package/dist/utils/network.d.cts +4 -2
- package/dist/utils/network.d.cts.map +1 -1
- package/dist/utils/network.d.mts +4 -2
- package/dist/utils/network.d.mts.map +1 -1
- package/dist/utils/network.mjs +5 -0
- package/dist/utils/network.mjs.map +1 -1
- package/dist/utils/transaction.cjs +10 -9
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +3 -0
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +3 -0
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +8 -8
- package/dist/utils/transaction.mjs.map +1 -1
- package/dist/utils/validators.d.cts +2 -2
- package/dist/utils/validators.d.mts +2 -2
- package/package.json +22 -20
|
@@ -9,8 +9,8 @@ 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,
|
|
13
|
-
import { formatChainIdToHex, isNonEvmChainId, StatusTypes, UnifiedSwapBridgeEventName, isCrossChain, isTronChainId, isEvmTxData,
|
|
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_handleApprovalTx, _BridgeStatusController_handleEvmTransactionBatch, _BridgeStatusController_trackPollingStatusUpdatedEvent, _BridgeStatusController_trackUnifiedSwapBridgeEvent;
|
|
13
|
+
import { formatChainIdToHex, isNonEvmChainId, StatusTypes, getAccountHardwareType, UnifiedSwapBridgeEventName, isCrossChain, isTronChainId, isEvmTxData, MetricsActionType, MetaMetricsSwapsEventSource, isBitcoinTrade, isTronTrade, PollingStatus } 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";
|
|
@@ -20,15 +20,15 @@ import { BridgeClientId } from "./types.mjs";
|
|
|
20
20
|
import { getAccountByAddress } from "./utils/accounts.mjs";
|
|
21
21
|
import { getJwt } from "./utils/authentication.mjs";
|
|
22
22
|
import { stopPollingForQuotes, trackMetricsEvent } from "./utils/bridge.mjs";
|
|
23
|
-
import { fetchBridgeTxStatus, getStatusRequestWithSrcTxHash, shouldSkipFetchDueToFetchFailures } from "./utils/bridge-status.mjs";
|
|
24
|
-
import { getInitialHistoryItem, rekeyHistoryItemInState, shouldPollHistoryItem } from "./utils/history.mjs";
|
|
23
|
+
import { fetchBridgeTxStatus, getStatusRequestWithSrcTxHash, shouldSkipFetchDueToFetchFailures, shouldWaitForFinalBridgeStatus } from "./utils/bridge-status.mjs";
|
|
24
|
+
import { getInitialHistoryItem, getMatchingHistoryEntryForTxMeta, rekeyHistoryItemInState, shouldPollHistoryItem, getMatchingHistoryEntryForApprovalTxMeta } from "./utils/history.mjs";
|
|
25
25
|
import { getIntentFromQuote, mapIntentOrderStatusToTransactionStatus, postSubmitOrder } from "./utils/intent-api.mjs";
|
|
26
26
|
import { signTypedMessage } from "./utils/keyring.mjs";
|
|
27
|
-
import { getFinalizedTxProperties, getPriceImpactFromQuote, getRequestMetadataFromHistory, getRequestParamFromHistory, getTradeDataFromHistory, getEVMTxPropertiesFromTransactionMeta, getTxStatusesFromHistory, getPreConfirmationPropertiesFromQuote } from "./utils/metrics.mjs";
|
|
27
|
+
import { getFinalizedTxProperties, getPriceImpactFromQuote, getRequestMetadataFromHistory, getRequestParamFromHistory, getTradeDataFromHistory, getEVMTxPropertiesFromTransactionMeta, getTxStatusesFromHistory, getPreConfirmationPropertiesFromQuote, getPollingStatusUpdatedProperties } from "./utils/metrics.mjs";
|
|
28
28
|
import { getNetworkClientIdByChainId, getSelectedChainId } from "./utils/network.mjs";
|
|
29
29
|
import { handleNonEvmTx } from "./utils/snaps.mjs";
|
|
30
30
|
import { getApprovalTraceParams, getTraceParams } from "./utils/trace.mjs";
|
|
31
|
-
import { getAddTransactionBatchParams, handleApprovalDelay, handleMobileHardwareWalletDelay, generateActionId, waitForTxConfirmation, getTransactionMetaById, addTransactionBatch, addSyntheticTransaction, getTransactions, submitEvmTransaction, checkIsDelegatedAccount } from "./utils/transaction.mjs";
|
|
31
|
+
import { getAddTransactionBatchParams, handleApprovalDelay, handleMobileHardwareWalletDelay, generateActionId, waitForTxConfirmation, getTransactionMetaById, addTransactionBatch, addSyntheticTransaction, getTransactions, submitEvmTransaction, checkIsDelegatedAccount, isCrossChainTx } from "./utils/transaction.mjs";
|
|
32
32
|
const metadata = {
|
|
33
33
|
// We want to persist the bridge status state so that we can show the proper data for the Activity list
|
|
34
34
|
// basically match the behavior of TransactionController
|
|
@@ -39,6 +39,15 @@ const metadata = {
|
|
|
39
39
|
usedInUi: true,
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
|
+
const MESSENGER_EXPOSED_METHODS = [
|
|
43
|
+
'startPollingForBridgeTxStatus',
|
|
44
|
+
'wipeBridgeStatus',
|
|
45
|
+
'resetState',
|
|
46
|
+
'submitTx',
|
|
47
|
+
'submitIntent',
|
|
48
|
+
'restartPollingForFailedAttempts',
|
|
49
|
+
'getBridgeHistoryItemByTxMetaId',
|
|
50
|
+
];
|
|
42
51
|
export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
43
52
|
constructor({ messenger, state, clientId, fetchFn, addTransactionBatchFn, config, traceFn, }) {
|
|
44
53
|
super({
|
|
@@ -58,25 +67,55 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
58
67
|
_BridgeStatusController_config.set(this, void 0);
|
|
59
68
|
_BridgeStatusController_addTransactionBatchFn.set(this, void 0);
|
|
60
69
|
_BridgeStatusController_trace.set(this, void 0);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
_BridgeStatusController_onTransactionFailed.set(this, ({ txMeta, historyKey, isApprovalTxMeta, }) => {
|
|
71
|
+
// Check if the history item is already marked as a failure
|
|
72
|
+
const isHistoryItemAlreadyFailed = historyKey
|
|
73
|
+
? this.state.txHistory[historyKey]?.status.status === StatusTypes.FAILED
|
|
74
|
+
: false;
|
|
75
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
76
|
+
historyKey,
|
|
77
|
+
status: StatusTypes.FAILED,
|
|
78
|
+
txHash: isApprovalTxMeta ? undefined : txMeta.hash,
|
|
79
|
+
});
|
|
80
|
+
if (txMeta.status === TransactionStatus.rejected) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
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
|
+
// Skip tracking if this is a duplicate failed event for the same history item
|
|
88
|
+
// This can happen if the transaction includes an approval tx that fails
|
|
89
|
+
if (isHistoryItemAlreadyFailed) {
|
|
90
|
+
return;
|
|
70
91
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
92
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed, historyKey, getEVMTxPropertiesFromTransactionMeta(txMeta));
|
|
93
|
+
});
|
|
94
|
+
// Only EVM txs
|
|
95
|
+
_BridgeStatusController_onTransactionConfirmed.set(this, ({ txMeta, historyKey, isApprovalTxMeta, }) => {
|
|
96
|
+
// Return early if the confirmed txMeta is for an approval since we
|
|
97
|
+
// still need to wait for the trade to be confirmed
|
|
98
|
+
if (isApprovalTxMeta) {
|
|
74
99
|
return;
|
|
75
100
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
101
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
102
|
+
historyKey,
|
|
103
|
+
txHash: txMeta.hash,
|
|
79
104
|
});
|
|
105
|
+
switch (txMeta.type) {
|
|
106
|
+
case TransactionType.swap:
|
|
107
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
108
|
+
historyKey,
|
|
109
|
+
status: StatusTypes.COMPLETE,
|
|
110
|
+
});
|
|
111
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
112
|
+
break;
|
|
113
|
+
default:
|
|
114
|
+
if (historyKey) {
|
|
115
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
80
119
|
});
|
|
81
120
|
this.resetState = () => {
|
|
82
121
|
this.update((state) => {
|
|
@@ -177,30 +216,31 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
177
216
|
_BridgeStatusController_restartPollingForIncompleteHistoryItems.set(this, () => {
|
|
178
217
|
// Check for historyItems that do not have a status of complete and restart polling
|
|
179
218
|
const { txHistory } = this.state;
|
|
180
|
-
const historyItems = Object.
|
|
219
|
+
const historyItems = Object.entries(txHistory);
|
|
181
220
|
const incompleteHistoryItems = historyItems
|
|
182
|
-
.filter((historyItem) => historyItem.status.status === StatusTypes.PENDING ||
|
|
221
|
+
.filter(([_, historyItem]) => historyItem.status.status === StatusTypes.PENDING ||
|
|
183
222
|
historyItem.status.status === StatusTypes.UNKNOWN)
|
|
184
223
|
// Only poll items with txMetaId (post-submission items)
|
|
185
|
-
.filter((historyItem) =>
|
|
186
|
-
|
|
224
|
+
.filter(([_, historyItem]) => {
|
|
225
|
+
if (!historyItem.txMetaId) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
187
228
|
// Check if we are already polling this tx, if so, skip restarting polling for that
|
|
188
229
|
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[historyItem.txMetaId];
|
|
189
230
|
return !pollingToken;
|
|
190
231
|
})
|
|
191
232
|
// Only restart polling for items that still require status updates
|
|
192
|
-
.filter((historyItem) => {
|
|
233
|
+
.filter(([_, historyItem]) => {
|
|
193
234
|
return shouldPollHistoryItem(historyItem);
|
|
194
235
|
});
|
|
195
|
-
incompleteHistoryItems.forEach((historyItem) => {
|
|
196
|
-
const bridgeTxMetaId = historyItem.txMetaId;
|
|
236
|
+
incompleteHistoryItems.forEach(([historyKey, historyItem]) => {
|
|
197
237
|
const shouldSkipFetch = shouldSkipFetchDueToFetchFailures(historyItem.attempts);
|
|
198
238
|
if (shouldSkipFetch) {
|
|
199
239
|
return;
|
|
200
240
|
}
|
|
201
241
|
// We manually call startPolling() here rather than go through startPollingForBridgeTxStatus()
|
|
202
242
|
// because we don't want to overwrite the existing historyItem in state
|
|
203
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
243
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
204
244
|
});
|
|
205
245
|
});
|
|
206
246
|
_BridgeStatusController_addTxToHistory.set(this, (...args) => {
|
|
@@ -209,6 +249,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
209
249
|
// Use actionId as key for pre-submission, or txMeta.id for post-submission
|
|
210
250
|
state.txHistory[historyKey] = txHistoryItem;
|
|
211
251
|
});
|
|
252
|
+
return historyKey;
|
|
212
253
|
});
|
|
213
254
|
/**
|
|
214
255
|
* Rekeys a history item from actionId to txMeta.id after successful submission.
|
|
@@ -231,10 +272,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
231
272
|
this.stopPollingByPollingToken(existingPollingToken);
|
|
232
273
|
}
|
|
233
274
|
const txHistoryItem = this.state.txHistory[txId];
|
|
234
|
-
if (
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
if (shouldPollHistoryItem(txHistoryItem)) {
|
|
275
|
+
if (txHistoryItem && shouldPollHistoryItem(txHistoryItem)) {
|
|
238
276
|
__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId] = this.startPolling({
|
|
239
277
|
bridgeTxMetaId: txId,
|
|
240
278
|
});
|
|
@@ -255,8 +293,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
255
293
|
if (!bridgeTxMeta?.id) {
|
|
256
294
|
throw new Error('Cannot start polling: bridgeTxMeta.id is required for polling');
|
|
257
295
|
}
|
|
258
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
|
|
259
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
296
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
|
|
297
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
260
298
|
};
|
|
261
299
|
// This will be called after you call this.startPolling()
|
|
262
300
|
// The args passed in are the args you passed in to startPolling()
|
|
@@ -291,29 +329,38 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
291
329
|
// Track max polling reached event
|
|
292
330
|
const historyItem = this.state.txHistory[bridgeTxMetaId];
|
|
293
331
|
if (historyItem && !historyItem.featureId) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
const requestMetadata = getRequestMetadataFromHistory(historyItem, selectedAccount);
|
|
297
|
-
const { security_warnings: _, ...metadataWithoutWarnings } = requestMetadata;
|
|
298
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.PollingStatusUpdated, bridgeTxMetaId, {
|
|
299
|
-
...getTradeDataFromHistory(historyItem),
|
|
300
|
-
...getPriceImpactFromQuote(historyItem.quote),
|
|
301
|
-
...metadataWithoutWarnings,
|
|
302
|
-
chain_id_source: requestParams.chain_id_source,
|
|
303
|
-
chain_id_destination: requestParams.chain_id_destination,
|
|
304
|
-
token_symbol_source: requestParams.token_symbol_source,
|
|
305
|
-
token_symbol_destination: requestParams.token_symbol_destination,
|
|
306
|
-
action_type: MetricsActionType.SWAPBRIDGE_V1,
|
|
307
|
-
polling_status: PollingStatus.MaxPollingReached,
|
|
308
|
-
retry_attempts: newAttempts.counter,
|
|
309
|
-
});
|
|
332
|
+
// Track polling status updated event
|
|
333
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackPollingStatusUpdatedEvent, "f").call(this, bridgeTxMetaId, PollingStatus.MaxPollingReached);
|
|
310
334
|
}
|
|
311
335
|
}
|
|
312
336
|
// Update the attempts counter
|
|
313
|
-
this.
|
|
314
|
-
|
|
337
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
338
|
+
historyKey: bridgeTxMetaId,
|
|
339
|
+
attempts: newAttempts,
|
|
315
340
|
});
|
|
316
341
|
});
|
|
342
|
+
/**
|
|
343
|
+
* Checks if the history item should be preserved so its status can be fetched.
|
|
344
|
+
*
|
|
345
|
+
* @param bridgeTxMetaId - The txMetaId of the bridge tx
|
|
346
|
+
*/
|
|
347
|
+
_BridgeStatusController_handleOldHistoryItem.set(this, async (bridgeTxMetaId) => {
|
|
348
|
+
// Continue polling on next restart if the history item is valid
|
|
349
|
+
if (this.state.txHistory[bridgeTxMetaId] &&
|
|
350
|
+
(await shouldWaitForFinalBridgeStatus(this.messenger, this.state.txHistory[bridgeTxMetaId]))) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
354
|
+
// Track polling status updated event
|
|
355
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackPollingStatusUpdatedEvent, "f").call(this, bridgeTxMetaId, PollingStatus.InvalidTransactionHash);
|
|
356
|
+
// If we've failed too many times, stop polling for the tx
|
|
357
|
+
if (pollingToken) {
|
|
358
|
+
this.stopPollingByPollingToken(pollingToken);
|
|
359
|
+
delete __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
360
|
+
}
|
|
361
|
+
// Delete the history item so polling doesn't start over on the next restart
|
|
362
|
+
__classPrivateFieldGet(this, _BridgeStatusController_deleteHistoryItem, "f").call(this, bridgeTxMetaId);
|
|
363
|
+
});
|
|
317
364
|
_BridgeStatusController_fetchBridgeTxStatus.set(this, async ({ bridgeTxMetaId, }) => {
|
|
318
365
|
// 1. Check for history item
|
|
319
366
|
const { txHistory } = this.state;
|
|
@@ -325,7 +372,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
325
372
|
if (shouldSkipFetchDueToFetchFailures(historyItem.attempts)) {
|
|
326
373
|
return;
|
|
327
374
|
}
|
|
328
|
-
// 3. Fetch
|
|
375
|
+
// 3. Fetch transaction status
|
|
329
376
|
try {
|
|
330
377
|
let status;
|
|
331
378
|
let validationFailures = [];
|
|
@@ -341,11 +388,10 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
341
388
|
// We try here because we receive 500 errors from Bridge API if we try to fetch immediately after submitting the source tx
|
|
342
389
|
// Oddly mostly happens on Optimism, never on Arbitrum. By the 2nd fetch, the Bridge API responds properly.
|
|
343
390
|
// Also srcTxHash may not be available immediately for STX, so we don't want to fetch in those cases
|
|
344
|
-
const srcTxHash = __classPrivateFieldGet(this,
|
|
391
|
+
const srcTxHash = __classPrivateFieldGet(this, _BridgeStatusController_setAndGetSrcTxHash, "f").call(this, bridgeTxMetaId);
|
|
345
392
|
if (!srcTxHash) {
|
|
346
393
|
return;
|
|
347
394
|
}
|
|
348
|
-
__classPrivateFieldGet(this, _BridgeStatusController_updateSrcTxHash, "f").call(this, bridgeTxMetaId, srcTxHash);
|
|
349
395
|
const statusRequest = getStatusRequestWithSrcTxHash(historyItem.quote, srcTxHash);
|
|
350
396
|
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);
|
|
351
397
|
status = response.status;
|
|
@@ -402,26 +448,65 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
402
448
|
console.warn('Failed to fetch bridge tx status', error);
|
|
403
449
|
__classPrivateFieldGet(this, _BridgeStatusController_handleFetchFailure, "f").call(this, bridgeTxMetaId);
|
|
404
450
|
}
|
|
451
|
+
finally {
|
|
452
|
+
await __classPrivateFieldGet(this, _BridgeStatusController_handleOldHistoryItem, "f").call(this, bridgeTxMetaId);
|
|
453
|
+
}
|
|
405
454
|
});
|
|
406
|
-
|
|
455
|
+
/**
|
|
456
|
+
* Returns the srcTxHash for a non-STX EVM tx, the hash from the bridge status api,
|
|
457
|
+
* or the local hash from the TransactionController if the tx is in a finalized state
|
|
458
|
+
*
|
|
459
|
+
* @param bridgeTxMetaId - The bridge tx meta id
|
|
460
|
+
* @returns The srcTxHash
|
|
461
|
+
*/
|
|
462
|
+
_BridgeStatusController_setAndGetSrcTxHash.set(this, (bridgeTxMetaId) => {
|
|
407
463
|
const { txHistory } = this.state;
|
|
408
|
-
// Prefer the srcTxHash from bridgeStatusState so we don't have to
|
|
464
|
+
// Prefer the srcTxHash from bridgeStatusState so we don't have to look up in TransactionController
|
|
409
465
|
// But it is possible to have bridgeHistoryItem in state without the srcTxHash yet when it is an STX
|
|
410
466
|
const srcTxHash = txHistory[bridgeTxMetaId].status.srcChain.txHash;
|
|
411
|
-
if (srcTxHash
|
|
467
|
+
if (srcTxHash ||
|
|
468
|
+
isNonEvmChainId(txHistory[bridgeTxMetaId].quote.srcChainId)) {
|
|
412
469
|
return srcTxHash;
|
|
413
470
|
}
|
|
414
|
-
//
|
|
471
|
+
// Update history with TransactionController's hash if it has been updated
|
|
415
472
|
const txMeta = getTransactionMetaById(this.messenger, bridgeTxMetaId);
|
|
416
|
-
|
|
473
|
+
if (!txMeta) {
|
|
474
|
+
return undefined;
|
|
475
|
+
}
|
|
476
|
+
// Wait for finalized status before updating the history item
|
|
477
|
+
const localTxHash = [
|
|
478
|
+
TransactionStatus.confirmed,
|
|
479
|
+
TransactionStatus.dropped,
|
|
480
|
+
TransactionStatus.rejected,
|
|
481
|
+
TransactionStatus.failed,
|
|
482
|
+
].includes(txMeta.status)
|
|
483
|
+
? txMeta.hash
|
|
484
|
+
: undefined;
|
|
485
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
486
|
+
historyKey: bridgeTxMetaId,
|
|
487
|
+
txHash: localTxHash,
|
|
488
|
+
});
|
|
489
|
+
return localTxHash;
|
|
417
490
|
});
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (txHistory[bridgeTxMetaId].status.srcChain.txHash) {
|
|
491
|
+
_BridgeStatusController_updateHistoryItem.set(this, ({ historyKey, status, txHash, attempts, }) => {
|
|
492
|
+
if (!historyKey) {
|
|
421
493
|
return;
|
|
422
494
|
}
|
|
423
|
-
this.update((
|
|
424
|
-
|
|
495
|
+
this.update((currentState) => {
|
|
496
|
+
if (status) {
|
|
497
|
+
currentState.txHistory[historyKey].status.status = status;
|
|
498
|
+
}
|
|
499
|
+
if (txHash) {
|
|
500
|
+
currentState.txHistory[historyKey].status.srcChain.txHash = txHash;
|
|
501
|
+
}
|
|
502
|
+
if (attempts) {
|
|
503
|
+
currentState.txHistory[historyKey].attempts = attempts;
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
_BridgeStatusController_deleteHistoryItem.set(this, (historyKey) => {
|
|
508
|
+
this.update((currentState) => {
|
|
509
|
+
delete currentState.txHistory[historyKey];
|
|
425
510
|
});
|
|
426
511
|
});
|
|
427
512
|
// Wipes the bridge status for the given address and chainId
|
|
@@ -437,6 +522,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
437
522
|
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId];
|
|
438
523
|
if (pollingToken) {
|
|
439
524
|
this.stopPollingByPollingToken(__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId]);
|
|
525
|
+
delete __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId];
|
|
440
526
|
}
|
|
441
527
|
});
|
|
442
528
|
this.update((state) => {
|
|
@@ -506,16 +592,17 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
506
592
|
* @param location - The entry point from which the user initiated the swap or bridge (e.g. Main View, Token View, Trending Explore)
|
|
507
593
|
* @param abTests - Legacy A/B test context for `ab_tests` (backward compatibility)
|
|
508
594
|
* @param activeAbTests - New A/B test context for `active_ab_tests` (migration target). Attributes events to specific experiments.
|
|
595
|
+
* @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.
|
|
509
596
|
* @returns The transaction meta
|
|
510
597
|
*/
|
|
511
|
-
this.submitTx = async (accountAddress, quoteResponse, isStxEnabledOnClient, quotesReceivedContext, location = MetaMetricsSwapsEventSource.MainView, abTests, activeAbTests) => {
|
|
598
|
+
this.submitTx = async (accountAddress, quoteResponse, isStxEnabledOnClient, quotesReceivedContext, location = MetaMetricsSwapsEventSource.MainView, abTests, activeAbTests, tokenSecurityTypeDestination) => {
|
|
512
599
|
stopPollingForQuotes(this.messenger, quoteResponse.featureId, quotesReceivedContext);
|
|
513
600
|
const selectedAccount = getAccountByAddress(this.messenger, accountAddress);
|
|
514
601
|
if (!selectedAccount) {
|
|
515
602
|
throw new Error('Failed to submit cross-chain swap transaction: undefined multichain account');
|
|
516
603
|
}
|
|
517
|
-
const
|
|
518
|
-
const preConfirmationProperties = getPreConfirmationPropertiesFromQuote(quoteResponse, isStxEnabledOnClient,
|
|
604
|
+
const accountHardwareType = getAccountHardwareType(selectedAccount);
|
|
605
|
+
const preConfirmationProperties = getPreConfirmationPropertiesFromQuote(quoteResponse, isStxEnabledOnClient, accountHardwareType, location, abTests, activeAbTests, tokenSecurityTypeDestination);
|
|
519
606
|
let txMeta;
|
|
520
607
|
let approvalTxId;
|
|
521
608
|
let isDelegatedAccount = false;
|
|
@@ -555,7 +642,8 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
555
642
|
// Submit EVM tx
|
|
556
643
|
// For hardware wallets on Mobile, this is fixes an issue where the Ledger does not get prompted for the 2nd approval
|
|
557
644
|
// Extension does not have this issue
|
|
558
|
-
const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE &&
|
|
645
|
+
const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE &&
|
|
646
|
+
accountHardwareType !== null;
|
|
559
647
|
// Handle smart transactions if enabled
|
|
560
648
|
txMeta = await __classPrivateFieldGet(this, _BridgeStatusController_trace, "f").call(this, getTraceParams(quoteResponse, isStxEnabledOnClient), async () => {
|
|
561
649
|
if (!isEvmTxData(quoteResponse.trade)) {
|
|
@@ -602,7 +690,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
602
690
|
const actionId = generateActionId().toString();
|
|
603
691
|
// Add pre-submission history keyed by actionId
|
|
604
692
|
// This ensures we have quote data available if transaction fails during submission
|
|
605
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
693
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
606
694
|
accountAddress: selectedAccount.address,
|
|
607
695
|
quoteResponse,
|
|
608
696
|
slippagePercentage: 0,
|
|
@@ -613,6 +701,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
613
701
|
abTests,
|
|
614
702
|
activeAbTests,
|
|
615
703
|
actionId,
|
|
704
|
+
tokenSecurityTypeDestination,
|
|
616
705
|
});
|
|
617
706
|
// Pass txFee when gasIncluded is true to use the quote's gas fees
|
|
618
707
|
// instead of re-estimating (which would fail for max native token swaps)
|
|
@@ -629,7 +718,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
629
718
|
actionId,
|
|
630
719
|
});
|
|
631
720
|
// On success, rekey from actionId to txMeta.id and update srcTxHash
|
|
632
|
-
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this,
|
|
721
|
+
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this, historyKey, tradeTxMeta);
|
|
633
722
|
return tradeTxMeta;
|
|
634
723
|
});
|
|
635
724
|
}
|
|
@@ -649,11 +738,12 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
649
738
|
!isStxEnabledOnClient &&
|
|
650
739
|
!quoteResponse.quote.gasIncluded7702 &&
|
|
651
740
|
!isDelegatedAccount;
|
|
741
|
+
let historyKey = txMeta.id;
|
|
652
742
|
if (!isNonBatchEvm) {
|
|
653
743
|
// Add swap or bridge tx to history
|
|
654
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
744
|
+
historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
655
745
|
accountAddress: selectedAccount.address,
|
|
656
|
-
bridgeTxMeta: txMeta, // Only the id
|
|
746
|
+
bridgeTxMeta: txMeta, // Only the id and hash fields are used by the BridgeStatusController
|
|
657
747
|
quoteResponse,
|
|
658
748
|
slippagePercentage: 0, // TODO include slippage provided by quote if using dynamic slippage, or slippage from quote request
|
|
659
749
|
isStxEnabled: isStxEnabledOnClient,
|
|
@@ -662,14 +752,15 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
662
752
|
location,
|
|
663
753
|
abTests,
|
|
664
754
|
activeAbTests,
|
|
755
|
+
tokenSecurityTypeDestination,
|
|
665
756
|
});
|
|
666
757
|
}
|
|
667
758
|
if (isNonEvmChainId(quoteResponse.quote.srcChainId)) {
|
|
668
759
|
// Start polling for bridge tx status
|
|
669
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
760
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
670
761
|
// Track non-EVM Swap completed event
|
|
671
762
|
if (!(isBridgeTx || isTronTx)) {
|
|
672
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed,
|
|
763
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
673
764
|
}
|
|
674
765
|
}
|
|
675
766
|
}
|
|
@@ -688,23 +779,25 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
688
779
|
* @param params.location - The entry point from which the user initiated the swap or bridge
|
|
689
780
|
* @param params.abTests - Legacy A/B test context for `ab_tests` (backward compatibility)
|
|
690
781
|
* @param params.activeAbTests - New A/B test context for `active_ab_tests` (migration target). Attributes events to specific experiments.
|
|
782
|
+
* @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.
|
|
691
783
|
* @returns A lightweight TransactionMeta-like object for history linking
|
|
692
784
|
*/
|
|
693
785
|
this.submitIntent = async (params) => {
|
|
694
|
-
const { quoteResponse, accountAddress, location, abTests, activeAbTests } = params;
|
|
786
|
+
const { quoteResponse, accountAddress, location, abTests, activeAbTests, tokenSecurityTypeDestination, } = params;
|
|
695
787
|
// TODO add metrics context
|
|
696
788
|
stopPollingForQuotes(this.messenger);
|
|
697
789
|
const startTime = Date.now();
|
|
698
790
|
// Build pre-confirmation properties for error tracking parity with submitTx
|
|
699
791
|
const account = getAccountByAddress(this.messenger, accountAddress);
|
|
700
|
-
const
|
|
701
|
-
const preConfirmationProperties = getPreConfirmationPropertiesFromQuote(quoteResponse, false,
|
|
792
|
+
const accountHardwareType = getAccountHardwareType(account);
|
|
793
|
+
const preConfirmationProperties = getPreConfirmationPropertiesFromQuote(quoteResponse, false, accountHardwareType, location, abTests, activeAbTests, tokenSecurityTypeDestination);
|
|
702
794
|
try {
|
|
703
795
|
const intent = getIntentFromQuote(quoteResponse);
|
|
704
796
|
// If backend provided an approval tx for this intent quote, submit it first (on-chain),
|
|
705
797
|
// then proceed with off-chain intent submission.
|
|
706
798
|
const isBridgeTx = isCrossChain(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
707
|
-
const requireApproval =
|
|
799
|
+
const requireApproval = __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f") === BridgeClientId.MOBILE &&
|
|
800
|
+
accountHardwareType !== null;
|
|
708
801
|
// Handle approval silently for better UX in intent flows
|
|
709
802
|
const approvalTxMeta = await __classPrivateFieldGet(this, _BridgeStatusController_handleApprovalTx, "f").call(this, quoteResponse, isBridgeTx, quoteResponse.quote.srcChainId, quoteResponse.approval, quoteResponse.resetApproval, requireApproval);
|
|
710
803
|
const approvalTxId = approvalTxMeta?.id;
|
|
@@ -767,15 +860,14 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
767
860
|
};
|
|
768
861
|
// Record in bridge history with actual transaction metadata
|
|
769
862
|
try {
|
|
770
|
-
// Use orderId as the history key for intent transactions
|
|
771
|
-
const bridgeHistoryKey = orderUid;
|
|
772
863
|
// Create a bridge transaction metadata that includes the original txId
|
|
773
864
|
const bridgeTxMetaForHistory = {
|
|
774
865
|
...syntheticMeta,
|
|
775
|
-
id:
|
|
866
|
+
id: orderUid,
|
|
776
867
|
originalTransactionId: syntheticMeta.id, // Keep original txId for TransactionController updates
|
|
777
868
|
};
|
|
778
|
-
|
|
869
|
+
// Use orderId as the history key for intent transactions
|
|
870
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
779
871
|
accountAddress,
|
|
780
872
|
bridgeTxMeta: bridgeTxMetaForHistory,
|
|
781
873
|
quoteResponse,
|
|
@@ -786,9 +878,10 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
786
878
|
location,
|
|
787
879
|
abTests,
|
|
788
880
|
activeAbTests,
|
|
881
|
+
tokenSecurityTypeDestination,
|
|
789
882
|
});
|
|
790
883
|
// Start polling using the orderId key to route to intent manager
|
|
791
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
884
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
792
885
|
}
|
|
793
886
|
catch (error) {
|
|
794
887
|
console.error('📝 [submitIntent] Failed to add to bridge history', error);
|
|
@@ -804,6 +897,13 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
804
897
|
throw error;
|
|
805
898
|
}
|
|
806
899
|
};
|
|
900
|
+
_BridgeStatusController_trackPollingStatusUpdatedEvent.set(this, (historyKey, pollingStatus) => {
|
|
901
|
+
// Track polling status updated event
|
|
902
|
+
const historyItem = this.state.txHistory[historyKey];
|
|
903
|
+
if (historyItem && !historyItem.featureId) {
|
|
904
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.PollingStatusUpdated, historyKey, getPollingStatusUpdatedProperties(this.messenger, pollingStatus, historyItem));
|
|
905
|
+
}
|
|
906
|
+
});
|
|
807
907
|
/**
|
|
808
908
|
* Tracks post-submission events for a cross-chain swap based on the history item
|
|
809
909
|
*
|
|
@@ -867,6 +967,7 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
867
967
|
chain_id_destination: requestParamProperties.chain_id_destination,
|
|
868
968
|
token_address_source: requestParamProperties.token_address_source,
|
|
869
969
|
token_address_destination: requestParamProperties.token_address_destination,
|
|
970
|
+
token_security_type_destination: requestParamProperties.token_security_type_destination,
|
|
870
971
|
refresh_count: historyItem.attempts?.counter ?? 0,
|
|
871
972
|
},
|
|
872
973
|
});
|
|
@@ -908,53 +1009,46 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
908
1009
|
fetchFn: __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"),
|
|
909
1010
|
}), "f");
|
|
910
1011
|
// Register action handlers
|
|
911
|
-
this.messenger.
|
|
912
|
-
this.messenger.registerActionHandler(`${BRIDGE_STATUS_CONTROLLER_NAME}:wipeBridgeStatus`, this.wipeBridgeStatus.bind(this));
|
|
913
|
-
this.messenger.registerActionHandler(`${BRIDGE_STATUS_CONTROLLER_NAME}:resetState`, this.resetState.bind(this));
|
|
914
|
-
this.messenger.registerActionHandler(`${BRIDGE_STATUS_CONTROLLER_NAME}:submitTx`, this.submitTx.bind(this));
|
|
915
|
-
this.messenger.registerActionHandler(`${BRIDGE_STATUS_CONTROLLER_NAME}:submitIntent`, this.submitIntent.bind(this));
|
|
916
|
-
this.messenger.registerActionHandler(`${BRIDGE_STATUS_CONTROLLER_NAME}:restartPollingForFailedAttempts`, this.restartPollingForFailedAttempts.bind(this));
|
|
917
|
-
this.messenger.registerActionHandler(`${BRIDGE_STATUS_CONTROLLER_NAME}:getBridgeHistoryItemByTxMetaId`, this.getBridgeHistoryItemByTxMetaId.bind(this));
|
|
1012
|
+
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
918
1013
|
// Set interval
|
|
919
1014
|
this.setIntervalLength(REFRESH_INTERVAL_MS);
|
|
920
|
-
this.messenger.subscribe('TransactionController:
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
[
|
|
924
|
-
TransactionType.bridge,
|
|
925
|
-
TransactionType.swap,
|
|
926
|
-
TransactionType.bridgeApproval,
|
|
927
|
-
TransactionType.swapApproval,
|
|
928
|
-
].includes(type) &&
|
|
929
|
-
[
|
|
930
|
-
TransactionStatus.failed,
|
|
931
|
-
TransactionStatus.dropped,
|
|
932
|
-
TransactionStatus.rejected,
|
|
933
|
-
].includes(status)) {
|
|
934
|
-
// Mark tx as failed in txHistory
|
|
935
|
-
__classPrivateFieldGet(this, _BridgeStatusController_markTxAsFailed, "f").call(this, transactionMeta);
|
|
936
|
-
// Track failed event
|
|
937
|
-
if (status !== TransactionStatus.rejected) {
|
|
938
|
-
// Look up history by txMetaId first, then by actionId (for pre-submission failures)
|
|
939
|
-
let historyKey;
|
|
940
|
-
if (this.state.txHistory[txMetaId]) {
|
|
941
|
-
historyKey = txMetaId;
|
|
942
|
-
}
|
|
943
|
-
else if (actionId && this.state.txHistory[actionId]) {
|
|
944
|
-
historyKey = actionId;
|
|
945
|
-
}
|
|
946
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, UnifiedSwapBridgeEventName.Failed, historyKey ?? txMetaId, getEVMTxPropertiesFromTransactionMeta(transactionMeta));
|
|
947
|
-
}
|
|
1015
|
+
this.messenger.subscribe('TransactionController:transactionStatusUpdated', ({ txMeta, historyKey, historyItem, isApprovalTxMeta }) => {
|
|
1016
|
+
if (!txMeta) {
|
|
1017
|
+
return;
|
|
948
1018
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1019
|
+
const { type, status } = txMeta;
|
|
1020
|
+
// Allow event publishing if the txMeta is a swap/bridge OR if the
|
|
1021
|
+
// corresponding history item exists
|
|
1022
|
+
const isSwapOrBridgeTransaction = type && isCrossChainTx(type);
|
|
1023
|
+
if (!isSwapOrBridgeTransaction && !historyKey && !historyItem) {
|
|
1024
|
+
return;
|
|
954
1025
|
}
|
|
955
|
-
|
|
956
|
-
|
|
1026
|
+
switch (status) {
|
|
1027
|
+
case TransactionStatus.confirmed:
|
|
1028
|
+
__classPrivateFieldGet(this, _BridgeStatusController_onTransactionConfirmed, "f").call(this, {
|
|
1029
|
+
txMeta,
|
|
1030
|
+
historyKey,
|
|
1031
|
+
isApprovalTxMeta,
|
|
1032
|
+
});
|
|
1033
|
+
break;
|
|
1034
|
+
case TransactionStatus.failed:
|
|
1035
|
+
case TransactionStatus.dropped:
|
|
1036
|
+
case TransactionStatus.rejected:
|
|
1037
|
+
__classPrivateFieldGet(this, _BridgeStatusController_onTransactionFailed, "f").call(this, { txMeta, historyKey, isApprovalTxMeta });
|
|
1038
|
+
break;
|
|
1039
|
+
default:
|
|
1040
|
+
break;
|
|
957
1041
|
}
|
|
1042
|
+
}, ({ transactionMeta }) => {
|
|
1043
|
+
const entry = getMatchingHistoryEntryForTxMeta(this.state.txHistory, transactionMeta);
|
|
1044
|
+
const approvalEntry = getMatchingHistoryEntryForApprovalTxMeta(this.state.txHistory, transactionMeta);
|
|
1045
|
+
const entryToUse = entry ?? approvalEntry;
|
|
1046
|
+
return {
|
|
1047
|
+
historyKey: entryToUse?.[0],
|
|
1048
|
+
historyItem: entryToUse?.[1],
|
|
1049
|
+
txMeta: transactionMeta,
|
|
1050
|
+
isApprovalTxMeta: entryToUse?.[1]?.approvalTxId === transactionMeta.id,
|
|
1051
|
+
};
|
|
958
1052
|
});
|
|
959
1053
|
// If you close the extension, but keep the browser open, the polling continues
|
|
960
1054
|
// If you close the browser, the polling stops
|
|
@@ -962,5 +1056,5 @@ export class BridgeStatusController extends StaticIntervalPollingController() {
|
|
|
962
1056
|
__classPrivateFieldGet(this, _BridgeStatusController_restartPollingForIncompleteHistoryItems, "f").call(this);
|
|
963
1057
|
}
|
|
964
1058
|
}
|
|
965
|
-
_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(),
|
|
1059
|
+
_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_handleApprovalTx = new WeakMap(), _BridgeStatusController_handleEvmTransactionBatch = new WeakMap(), _BridgeStatusController_trackPollingStatusUpdatedEvent = new WeakMap(), _BridgeStatusController_trackUnifiedSwapBridgeEvent = new WeakMap();
|
|
966
1060
|
//# sourceMappingURL=bridge-status-controller.mjs.map
|