@metamask-previews/bridge-status-controller 70.0.5-preview-a3274bb30 → 70.0.5-preview-92fa59a42
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 +10 -0
- package/dist/bridge-status-controller.cjs +197 -114
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.mjs +201 -118
- 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/types.cjs.map +1 -1
- package/dist/types.d.cts +6 -5
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +6 -5
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/bridge-status.cjs +42 -1
- 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 +41 -1
- 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 +43 -2
- 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 +40 -2
- package/dist/utils/history.mjs.map +1 -1
- package/dist/utils/metrics.cjs +27 -2
- package/dist/utils/metrics.cjs.map +1 -1
- package/dist/utils/metrics.d.cts +25 -2
- package/dist/utils/metrics.d.cts.map +1 -1
- package/dist/utils/metrics.d.mts +25 -2
- package/dist/utils/metrics.d.mts.map +1 -1
- package/dist/utils/metrics.mjs +25 -1
- 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 +9 -8
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +1 -0
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +1 -0
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +7 -7
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
+
- Remove stale bridge transactions from `txHistory` to prevent excessive polling. Once a history item exceeds the configured maximum age, the status is fetched once, then the src tx hash's receipt is retrieved. If there is no receipt, the history item's hash is presumed to be invalid and the entry is deleted from state. ([#8479](https://github.com/MetaMask/core/pull/8479))
|
|
12
13
|
- Add missing action types for public `BridgeStatusController` methods ([#8367](https://github.com/MetaMask/core/pull/8367))
|
|
13
14
|
- The following types are now available:
|
|
14
15
|
- `BridgeStatusControllerSubmitTxAction`
|
|
@@ -17,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
18
|
|
|
18
19
|
### Changed
|
|
19
20
|
|
|
21
|
+
- **BREAKING:** Replace `transactionFailed` and `transactionConfirmed` event subscriptions with `TransactionController:transactionStatusUpdated` ([#8479](https://github.com/MetaMask/core/pull/8479))
|
|
22
|
+
- **BREAKING:** Add `RemoteFeatureFlags:getState` to allowed actions to retrieve max history item age config ([#8479](https://github.com/MetaMask/core/pull/8479))
|
|
20
23
|
- Add `account_hardware_type` field to all cross-chain swap analytics events ([#8503](https://github.com/MetaMask/core/pull/8503))
|
|
21
24
|
- `account_hardware_type` carries the specific hardware wallet brand (e.g. `'Ledger'`, `'QR Hardware'`) or `null` for software wallets
|
|
22
25
|
- `is_hardware_wallet` is now derived from `account_hardware_type !== null`, keeping both fields in sync
|
|
@@ -28,6 +31,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
28
31
|
- Bump `@metamask/base-controller` from `^9.0.1` to `^9.1.0` ([#8457](https://github.com/MetaMask/core/pull/8457))
|
|
29
32
|
- Bump `@metamask/bridge-controller` from `^70.0.1` to `^70.1.1` ([#8466](https://github.com/MetaMask/core/pull/8466), [#8474](https://github.com/MetaMask/core/pull/8474))
|
|
30
33
|
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Prevent invalid src hashes from being persisted in `txHistory` ([#8479](https://github.com/MetaMask/core/pull/8479))
|
|
37
|
+
- Make transaction status subscribers generic so that `txHistory` items get updated if there are any transaction updates matching by actionId, txMetaId, hash or type
|
|
38
|
+
- Skip saving smart transaction hashes on transaction submission. This used to make it possible for invalid src hashes to be stored in state and polled indefinitely. Instead, the txHistory item will now be updated with the confirmed tx hash when the `transactionStatusUpdated` event is published
|
|
39
|
+
- If there is no srcTxHash in state, attempt to set it based on the local TransactionController state
|
|
40
|
+
|
|
31
41
|
## [70.0.5]
|
|
32
42
|
|
|
33
43
|
### Changed
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _BridgeStatusController_pollingTokensByTxMetaId, _BridgeStatusController_intentManager, _BridgeStatusController_clientId, _BridgeStatusController_fetchFn, _BridgeStatusController_config, _BridgeStatusController_addTransactionBatchFn, _BridgeStatusController_trace, _BridgeStatusController_onTransactionFailed,
|
|
13
|
+
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;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.BridgeStatusController = void 0;
|
|
16
16
|
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
@@ -70,60 +70,55 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
70
70
|
_BridgeStatusController_config.set(this, void 0);
|
|
71
71
|
_BridgeStatusController_addTransactionBatchFn.set(this, void 0);
|
|
72
72
|
_BridgeStatusController_trace.set(this, void 0);
|
|
73
|
-
_BridgeStatusController_onTransactionFailed.set(this, ({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
[
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
transaction_controller_1.TransactionStatus.rejected,
|
|
86
|
-
].includes(status)) {
|
|
87
|
-
__classPrivateFieldGet(this, _BridgeStatusController_markTxAsFailed, "f").call(this, transactionMeta);
|
|
88
|
-
if (status !== transaction_controller_1.TransactionStatus.rejected) {
|
|
89
|
-
let historyKey;
|
|
90
|
-
if (this.state.txHistory[txMetaId]) {
|
|
91
|
-
historyKey = txMetaId;
|
|
92
|
-
}
|
|
93
|
-
else if (actionId && this.state.txHistory[actionId]) {
|
|
94
|
-
historyKey = actionId;
|
|
95
|
-
}
|
|
96
|
-
const activeHistoryKey = historyKey ?? txMetaId;
|
|
97
|
-
// Skip account lookup and tracking when featureId is set (e.g. PERPS)
|
|
98
|
-
if (this.state.txHistory[activeHistoryKey]?.featureId) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const from = transactionMeta.txParams?.from;
|
|
102
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, activeHistoryKey, (0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(transactionMeta, from
|
|
103
|
-
? this.messenger.call('AccountsController:getAccountByAddress', from)
|
|
104
|
-
: undefined));
|
|
105
|
-
}
|
|
73
|
+
_BridgeStatusController_onTransactionFailed.set(this, ({ txMeta, historyKey, isApprovalTxMeta, }) => {
|
|
74
|
+
// Check if the history item is already marked as a failure
|
|
75
|
+
const isHistoryItemAlreadyFailed = historyKey
|
|
76
|
+
? this.state.txHistory[historyKey]?.status.status === bridge_controller_1.StatusTypes.FAILED
|
|
77
|
+
: false;
|
|
78
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
79
|
+
historyKey,
|
|
80
|
+
status: bridge_controller_1.StatusTypes.FAILED,
|
|
81
|
+
txHash: isApprovalTxMeta ? undefined : txMeta.hash,
|
|
82
|
+
});
|
|
83
|
+
if (txMeta.status === transaction_controller_1.TransactionStatus.rejected) {
|
|
84
|
+
return;
|
|
106
85
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// Look up by txMetaId first
|
|
111
|
-
let txHistoryKey = this.state.txHistory[txMetaId]
|
|
112
|
-
? txMetaId
|
|
113
|
-
: undefined;
|
|
114
|
-
// If not found by txMetaId, try looking up by actionId (for pre-submission failures)
|
|
115
|
-
if (!txHistoryKey && actionId && this.state.txHistory[actionId]) {
|
|
116
|
-
txHistoryKey = actionId;
|
|
86
|
+
// Skip account lookup and tracking when featureId is set (e.g. PERPS)
|
|
87
|
+
if (historyKey && this.state.txHistory[historyKey]?.featureId) {
|
|
88
|
+
return;
|
|
117
89
|
}
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
if (
|
|
90
|
+
// Skip tracking if this is a duplicate failed event for the same history item
|
|
91
|
+
// This can happen if the transaction includes an approval tx that fails
|
|
92
|
+
if (isHistoryItemAlreadyFailed) {
|
|
121
93
|
return;
|
|
122
94
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
95
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, historyKey, (0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(txMeta));
|
|
96
|
+
});
|
|
97
|
+
// Only EVM txs
|
|
98
|
+
_BridgeStatusController_onTransactionConfirmed.set(this, ({ txMeta, historyKey, isApprovalTxMeta, }) => {
|
|
99
|
+
// Return early if the confirmed txMeta is for an approval since we
|
|
100
|
+
// still need to wait for the trade to be confirmed
|
|
101
|
+
if (isApprovalTxMeta) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
105
|
+
historyKey,
|
|
106
|
+
txHash: txMeta.hash,
|
|
126
107
|
});
|
|
108
|
+
switch (txMeta.type) {
|
|
109
|
+
case transaction_controller_1.TransactionType.swap:
|
|
110
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
111
|
+
historyKey,
|
|
112
|
+
status: bridge_controller_1.StatusTypes.COMPLETE,
|
|
113
|
+
});
|
|
114
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
115
|
+
break;
|
|
116
|
+
default:
|
|
117
|
+
if (historyKey) {
|
|
118
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
127
122
|
});
|
|
128
123
|
this.resetState = () => {
|
|
129
124
|
this.update((state) => {
|
|
@@ -224,30 +219,31 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
224
219
|
_BridgeStatusController_restartPollingForIncompleteHistoryItems.set(this, () => {
|
|
225
220
|
// Check for historyItems that do not have a status of complete and restart polling
|
|
226
221
|
const { txHistory } = this.state;
|
|
227
|
-
const historyItems = Object.
|
|
222
|
+
const historyItems = Object.entries(txHistory);
|
|
228
223
|
const incompleteHistoryItems = historyItems
|
|
229
|
-
.filter((historyItem) => historyItem.status.status === bridge_controller_1.StatusTypes.PENDING ||
|
|
224
|
+
.filter(([_, historyItem]) => historyItem.status.status === bridge_controller_1.StatusTypes.PENDING ||
|
|
230
225
|
historyItem.status.status === bridge_controller_1.StatusTypes.UNKNOWN)
|
|
231
226
|
// Only poll items with txMetaId (post-submission items)
|
|
232
|
-
.filter((historyItem) =>
|
|
233
|
-
|
|
227
|
+
.filter(([_, historyItem]) => {
|
|
228
|
+
if (!historyItem.txMetaId) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
234
231
|
// Check if we are already polling this tx, if so, skip restarting polling for that
|
|
235
232
|
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[historyItem.txMetaId];
|
|
236
233
|
return !pollingToken;
|
|
237
234
|
})
|
|
238
235
|
// Only restart polling for items that still require status updates
|
|
239
|
-
.filter((historyItem) => {
|
|
236
|
+
.filter(([_, historyItem]) => {
|
|
240
237
|
return (0, history_1.shouldPollHistoryItem)(historyItem);
|
|
241
238
|
});
|
|
242
|
-
incompleteHistoryItems.forEach((historyItem) => {
|
|
243
|
-
const bridgeTxMetaId = historyItem.txMetaId;
|
|
239
|
+
incompleteHistoryItems.forEach(([historyKey, historyItem]) => {
|
|
244
240
|
const shouldSkipFetch = (0, bridge_status_1.shouldSkipFetchDueToFetchFailures)(historyItem.attempts);
|
|
245
241
|
if (shouldSkipFetch) {
|
|
246
242
|
return;
|
|
247
243
|
}
|
|
248
244
|
// We manually call startPolling() here rather than go through startPollingForBridgeTxStatus()
|
|
249
245
|
// because we don't want to overwrite the existing historyItem in state
|
|
250
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
246
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
251
247
|
});
|
|
252
248
|
});
|
|
253
249
|
_BridgeStatusController_addTxToHistory.set(this, (...args) => {
|
|
@@ -256,6 +252,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
256
252
|
// Use actionId as key for pre-submission, or txMeta.id for post-submission
|
|
257
253
|
state.txHistory[historyKey] = txHistoryItem;
|
|
258
254
|
});
|
|
255
|
+
return historyKey;
|
|
259
256
|
});
|
|
260
257
|
/**
|
|
261
258
|
* Rekeys a history item from actionId to txMeta.id after successful submission.
|
|
@@ -278,10 +275,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
278
275
|
this.stopPollingByPollingToken(existingPollingToken);
|
|
279
276
|
}
|
|
280
277
|
const txHistoryItem = this.state.txHistory[txId];
|
|
281
|
-
if (
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
if ((0, history_1.shouldPollHistoryItem)(txHistoryItem)) {
|
|
278
|
+
if (txHistoryItem && (0, history_1.shouldPollHistoryItem)(txHistoryItem)) {
|
|
285
279
|
__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId] = this.startPolling({
|
|
286
280
|
bridgeTxMetaId: txId,
|
|
287
281
|
});
|
|
@@ -302,8 +296,8 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
302
296
|
if (!bridgeTxMeta?.id) {
|
|
303
297
|
throw new Error('Cannot start polling: bridgeTxMeta.id is required for polling');
|
|
304
298
|
}
|
|
305
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
|
|
306
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
299
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
|
|
300
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
307
301
|
};
|
|
308
302
|
// This will be called after you call this.startPolling()
|
|
309
303
|
// The args passed in are the args you passed in to startPolling()
|
|
@@ -338,29 +332,44 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
338
332
|
// Track max polling reached event
|
|
339
333
|
const historyItem = this.state.txHistory[bridgeTxMetaId];
|
|
340
334
|
if (historyItem && !historyItem.featureId) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const requestMetadata = (0, metrics_1.getRequestMetadataFromHistory)(historyItem, selectedAccount);
|
|
344
|
-
const { security_warnings: _, ...metadataWithoutWarnings } = requestMetadata;
|
|
345
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.PollingStatusUpdated, bridgeTxMetaId, {
|
|
346
|
-
...(0, metrics_1.getTradeDataFromHistory)(historyItem),
|
|
347
|
-
...(0, metrics_1.getPriceImpactFromQuote)(historyItem.quote),
|
|
348
|
-
...metadataWithoutWarnings,
|
|
349
|
-
chain_id_source: requestParams.chain_id_source,
|
|
350
|
-
chain_id_destination: requestParams.chain_id_destination,
|
|
351
|
-
token_symbol_source: requestParams.token_symbol_source,
|
|
352
|
-
token_symbol_destination: requestParams.token_symbol_destination,
|
|
353
|
-
action_type: bridge_controller_1.MetricsActionType.SWAPBRIDGE_V1,
|
|
354
|
-
polling_status: bridge_controller_1.PollingStatus.MaxPollingReached,
|
|
355
|
-
retry_attempts: newAttempts.counter,
|
|
356
|
-
});
|
|
335
|
+
// Track polling status updated event
|
|
336
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackPollingStatusUpdatedEvent, "f").call(this, bridgeTxMetaId, bridge_controller_1.PollingStatus.MaxPollingReached);
|
|
357
337
|
}
|
|
358
338
|
}
|
|
359
339
|
// Update the attempts counter
|
|
360
|
-
this.
|
|
361
|
-
|
|
340
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
341
|
+
historyKey: bridgeTxMetaId,
|
|
342
|
+
attempts: newAttempts,
|
|
362
343
|
});
|
|
363
344
|
});
|
|
345
|
+
/**
|
|
346
|
+
* Checks if the history item should be preserved so its status can be fetched.
|
|
347
|
+
*
|
|
348
|
+
* @param bridgeTxMetaId - The txMetaId of the bridge tx
|
|
349
|
+
*/
|
|
350
|
+
_BridgeStatusController_handleOldHistoryItem.set(this, async (bridgeTxMetaId) => {
|
|
351
|
+
if (
|
|
352
|
+
// Skip if the history item is finalized or not old
|
|
353
|
+
!(this.state.txHistory[bridgeTxMetaId] &&
|
|
354
|
+
(0, history_1.isHistoryItemTooOld)(this.messenger, this.state.txHistory[bridgeTxMetaId]) &&
|
|
355
|
+
[bridge_controller_1.StatusTypes.PENDING, bridge_controller_1.StatusTypes.UNKNOWN].includes(this.state.txHistory[bridgeTxMetaId].status.status))) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
// Continue polling on next restart if the history item is valid
|
|
359
|
+
if (await (0, bridge_status_1.shouldWaitForFinalBridgeStatus)(this.messenger, this.state.txHistory[bridgeTxMetaId])) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
363
|
+
// Track polling status updated event
|
|
364
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackPollingStatusUpdatedEvent, "f").call(this, bridgeTxMetaId, bridge_controller_1.PollingStatus.InvalidTransactionHash);
|
|
365
|
+
// If we've failed too many times, stop polling for the tx
|
|
366
|
+
if (pollingToken) {
|
|
367
|
+
this.stopPollingByPollingToken(pollingToken);
|
|
368
|
+
delete __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
369
|
+
}
|
|
370
|
+
// Delete the history item so polling doesn't start over on the next restart
|
|
371
|
+
__classPrivateFieldGet(this, _BridgeStatusController_deleteHistoryItem, "f").call(this, bridgeTxMetaId);
|
|
372
|
+
});
|
|
364
373
|
_BridgeStatusController_fetchBridgeTxStatus.set(this, async ({ bridgeTxMetaId, }) => {
|
|
365
374
|
// 1. Check for history item
|
|
366
375
|
const { txHistory } = this.state;
|
|
@@ -372,7 +381,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
372
381
|
if ((0, bridge_status_1.shouldSkipFetchDueToFetchFailures)(historyItem.attempts)) {
|
|
373
382
|
return;
|
|
374
383
|
}
|
|
375
|
-
// 3. Fetch
|
|
384
|
+
// 3. Fetch transaction status
|
|
376
385
|
try {
|
|
377
386
|
let status;
|
|
378
387
|
let validationFailures = [];
|
|
@@ -388,11 +397,10 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
388
397
|
// We try here because we receive 500 errors from Bridge API if we try to fetch immediately after submitting the source tx
|
|
389
398
|
// Oddly mostly happens on Optimism, never on Arbitrum. By the 2nd fetch, the Bridge API responds properly.
|
|
390
399
|
// Also srcTxHash may not be available immediately for STX, so we don't want to fetch in those cases
|
|
391
|
-
const srcTxHash = __classPrivateFieldGet(this,
|
|
400
|
+
const srcTxHash = __classPrivateFieldGet(this, _BridgeStatusController_setAndGetSrcTxHash, "f").call(this, bridgeTxMetaId);
|
|
392
401
|
if (!srcTxHash) {
|
|
393
402
|
return;
|
|
394
403
|
}
|
|
395
|
-
__classPrivateFieldGet(this, _BridgeStatusController_updateSrcTxHash, "f").call(this, bridgeTxMetaId, srcTxHash);
|
|
396
404
|
const statusRequest = (0, bridge_status_1.getStatusRequestWithSrcTxHash)(historyItem.quote, srcTxHash);
|
|
397
405
|
const response = await (0, bridge_status_1.fetchBridgeTxStatus)(statusRequest, __classPrivateFieldGet(this, _BridgeStatusController_clientId, "f"), await (0, authentication_1.getJwt)(this.messenger), __classPrivateFieldGet(this, _BridgeStatusController_fetchFn, "f"), __classPrivateFieldGet(this, _BridgeStatusController_config, "f").customBridgeApiBaseUrl);
|
|
398
406
|
status = response.status;
|
|
@@ -449,26 +457,65 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
449
457
|
console.warn('Failed to fetch bridge tx status', error);
|
|
450
458
|
__classPrivateFieldGet(this, _BridgeStatusController_handleFetchFailure, "f").call(this, bridgeTxMetaId);
|
|
451
459
|
}
|
|
460
|
+
finally {
|
|
461
|
+
await __classPrivateFieldGet(this, _BridgeStatusController_handleOldHistoryItem, "f").call(this, bridgeTxMetaId);
|
|
462
|
+
}
|
|
452
463
|
});
|
|
453
|
-
|
|
464
|
+
/**
|
|
465
|
+
* Returns the srcTxHash for a non-STX EVM tx, the hash from the bridge status api,
|
|
466
|
+
* or the local hash from the TransactionController if the tx is in a finalized state
|
|
467
|
+
*
|
|
468
|
+
* @param bridgeTxMetaId - The bridge tx meta id
|
|
469
|
+
* @returns The srcTxHash
|
|
470
|
+
*/
|
|
471
|
+
_BridgeStatusController_setAndGetSrcTxHash.set(this, (bridgeTxMetaId) => {
|
|
454
472
|
const { txHistory } = this.state;
|
|
455
|
-
// Prefer the srcTxHash from bridgeStatusState so we don't have to
|
|
473
|
+
// Prefer the srcTxHash from bridgeStatusState so we don't have to look up in TransactionController
|
|
456
474
|
// But it is possible to have bridgeHistoryItem in state without the srcTxHash yet when it is an STX
|
|
457
475
|
const srcTxHash = txHistory[bridgeTxMetaId].status.srcChain.txHash;
|
|
458
|
-
if (srcTxHash
|
|
476
|
+
if (srcTxHash ||
|
|
477
|
+
(0, bridge_controller_1.isNonEvmChainId)(txHistory[bridgeTxMetaId].quote.srcChainId)) {
|
|
459
478
|
return srcTxHash;
|
|
460
479
|
}
|
|
461
|
-
//
|
|
480
|
+
// Update history with TransactionController's hash if it has been updated
|
|
462
481
|
const txMeta = (0, transaction_1.getTransactionMetaById)(this.messenger, bridgeTxMetaId);
|
|
463
|
-
|
|
482
|
+
if (!txMeta) {
|
|
483
|
+
return undefined;
|
|
484
|
+
}
|
|
485
|
+
// Wait for finalized status before updating the history item
|
|
486
|
+
const localTxHash = [
|
|
487
|
+
transaction_controller_1.TransactionStatus.confirmed,
|
|
488
|
+
transaction_controller_1.TransactionStatus.dropped,
|
|
489
|
+
transaction_controller_1.TransactionStatus.rejected,
|
|
490
|
+
transaction_controller_1.TransactionStatus.failed,
|
|
491
|
+
].includes(txMeta.status)
|
|
492
|
+
? txMeta.hash
|
|
493
|
+
: undefined;
|
|
494
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
495
|
+
historyKey: bridgeTxMetaId,
|
|
496
|
+
txHash: localTxHash,
|
|
497
|
+
});
|
|
498
|
+
return localTxHash;
|
|
464
499
|
});
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if (txHistory[bridgeTxMetaId].status.srcChain.txHash) {
|
|
500
|
+
_BridgeStatusController_updateHistoryItem.set(this, ({ historyKey, status, txHash, attempts, }) => {
|
|
501
|
+
if (!historyKey) {
|
|
468
502
|
return;
|
|
469
503
|
}
|
|
470
|
-
this.update((
|
|
471
|
-
|
|
504
|
+
this.update((currentState) => {
|
|
505
|
+
if (status) {
|
|
506
|
+
currentState.txHistory[historyKey].status.status = status;
|
|
507
|
+
}
|
|
508
|
+
if (txHash) {
|
|
509
|
+
currentState.txHistory[historyKey].status.srcChain.txHash = txHash;
|
|
510
|
+
}
|
|
511
|
+
if (attempts) {
|
|
512
|
+
currentState.txHistory[historyKey].attempts = attempts;
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
_BridgeStatusController_deleteHistoryItem.set(this, (historyKey) => {
|
|
517
|
+
this.update((currentState) => {
|
|
518
|
+
delete currentState.txHistory[historyKey];
|
|
472
519
|
});
|
|
473
520
|
});
|
|
474
521
|
// Wipes the bridge status for the given address and chainId
|
|
@@ -484,6 +531,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
484
531
|
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId];
|
|
485
532
|
if (pollingToken) {
|
|
486
533
|
this.stopPollingByPollingToken(__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId]);
|
|
534
|
+
delete __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId];
|
|
487
535
|
}
|
|
488
536
|
});
|
|
489
537
|
this.update((state) => {
|
|
@@ -650,7 +698,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
650
698
|
const actionId = (0, transaction_1.generateActionId)().toString();
|
|
651
699
|
// Add pre-submission history keyed by actionId
|
|
652
700
|
// This ensures we have quote data available if transaction fails during submission
|
|
653
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
701
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
654
702
|
accountAddress: selectedAccount.address,
|
|
655
703
|
quoteResponse,
|
|
656
704
|
slippagePercentage: 0,
|
|
@@ -677,7 +725,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
677
725
|
actionId,
|
|
678
726
|
});
|
|
679
727
|
// On success, rekey from actionId to txMeta.id and update srcTxHash
|
|
680
|
-
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this,
|
|
728
|
+
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this, historyKey, tradeTxMeta);
|
|
681
729
|
return tradeTxMeta;
|
|
682
730
|
});
|
|
683
731
|
}
|
|
@@ -697,11 +745,12 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
697
745
|
!isStxEnabledOnClient &&
|
|
698
746
|
!quoteResponse.quote.gasIncluded7702 &&
|
|
699
747
|
!isDelegatedAccount;
|
|
748
|
+
let historyKey = txMeta.id;
|
|
700
749
|
if (!isNonBatchEvm) {
|
|
701
750
|
// Add swap or bridge tx to history
|
|
702
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
751
|
+
historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
703
752
|
accountAddress: selectedAccount.address,
|
|
704
|
-
bridgeTxMeta: txMeta, // Only the id
|
|
753
|
+
bridgeTxMeta: txMeta, // Only the id and hash fields are used by the BridgeStatusController
|
|
705
754
|
quoteResponse,
|
|
706
755
|
slippagePercentage: 0, // TODO include slippage provided by quote if using dynamic slippage, or slippage from quote request
|
|
707
756
|
isStxEnabled: isStxEnabledOnClient,
|
|
@@ -714,10 +763,10 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
714
763
|
}
|
|
715
764
|
if ((0, bridge_controller_1.isNonEvmChainId)(quoteResponse.quote.srcChainId)) {
|
|
716
765
|
// Start polling for bridge tx status
|
|
717
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
766
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
718
767
|
// Track non-EVM Swap completed event
|
|
719
768
|
if (!(isBridgeTx || isTronTx)) {
|
|
720
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed,
|
|
769
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
721
770
|
}
|
|
722
771
|
}
|
|
723
772
|
}
|
|
@@ -816,15 +865,14 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
816
865
|
};
|
|
817
866
|
// Record in bridge history with actual transaction metadata
|
|
818
867
|
try {
|
|
819
|
-
// Use orderId as the history key for intent transactions
|
|
820
|
-
const bridgeHistoryKey = orderUid;
|
|
821
868
|
// Create a bridge transaction metadata that includes the original txId
|
|
822
869
|
const bridgeTxMetaForHistory = {
|
|
823
870
|
...syntheticMeta,
|
|
824
|
-
id:
|
|
871
|
+
id: orderUid,
|
|
825
872
|
originalTransactionId: syntheticMeta.id, // Keep original txId for TransactionController updates
|
|
826
873
|
};
|
|
827
|
-
|
|
874
|
+
// Use orderId as the history key for intent transactions
|
|
875
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
828
876
|
accountAddress,
|
|
829
877
|
bridgeTxMeta: bridgeTxMetaForHistory,
|
|
830
878
|
quoteResponse,
|
|
@@ -837,7 +885,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
837
885
|
activeAbTests,
|
|
838
886
|
});
|
|
839
887
|
// Start polling using the orderId key to route to intent manager
|
|
840
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
888
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
841
889
|
}
|
|
842
890
|
catch (error) {
|
|
843
891
|
console.error('📝 [submitIntent] Failed to add to bridge history', error);
|
|
@@ -853,6 +901,13 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
853
901
|
throw error;
|
|
854
902
|
}
|
|
855
903
|
};
|
|
904
|
+
_BridgeStatusController_trackPollingStatusUpdatedEvent.set(this, (historyKey, pollingStatus) => {
|
|
905
|
+
// Track polling status updated event
|
|
906
|
+
const historyItem = this.state.txHistory[historyKey];
|
|
907
|
+
if (historyItem && !historyItem.featureId) {
|
|
908
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.PollingStatusUpdated, historyKey, (0, metrics_1.getPollingStatusUpdatedProperties)(this.messenger, pollingStatus, historyItem));
|
|
909
|
+
}
|
|
910
|
+
});
|
|
856
911
|
/**
|
|
857
912
|
* Tracks post-submission events for a cross-chain swap based on the history item
|
|
858
913
|
*
|
|
@@ -960,15 +1015,43 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
960
1015
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
961
1016
|
// Set interval
|
|
962
1017
|
this.setIntervalLength(constants_1.REFRESH_INTERVAL_MS);
|
|
963
|
-
this.messenger.subscribe('TransactionController:
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
if (type === transaction_controller_1.TransactionType.swap) {
|
|
967
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, txMetaId);
|
|
1018
|
+
this.messenger.subscribe('TransactionController:transactionStatusUpdated', ({ txMeta, historyKey, historyItem, isApprovalTxMeta }) => {
|
|
1019
|
+
if (!txMeta) {
|
|
1020
|
+
return;
|
|
968
1021
|
}
|
|
969
|
-
|
|
970
|
-
|
|
1022
|
+
const { type, status } = txMeta;
|
|
1023
|
+
// Allow event publishing if the txMeta is a swap/bridge OR if the
|
|
1024
|
+
// corresponding history item exists
|
|
1025
|
+
const isSwapOrBridgeTransaction = type && (0, transaction_1.isCrossChainTx)(type);
|
|
1026
|
+
if (!isSwapOrBridgeTransaction && !historyKey && !historyItem) {
|
|
1027
|
+
return;
|
|
971
1028
|
}
|
|
1029
|
+
switch (status) {
|
|
1030
|
+
case transaction_controller_1.TransactionStatus.confirmed:
|
|
1031
|
+
__classPrivateFieldGet(this, _BridgeStatusController_onTransactionConfirmed, "f").call(this, {
|
|
1032
|
+
txMeta,
|
|
1033
|
+
historyKey,
|
|
1034
|
+
isApprovalTxMeta,
|
|
1035
|
+
});
|
|
1036
|
+
break;
|
|
1037
|
+
case transaction_controller_1.TransactionStatus.failed:
|
|
1038
|
+
case transaction_controller_1.TransactionStatus.dropped:
|
|
1039
|
+
case transaction_controller_1.TransactionStatus.rejected:
|
|
1040
|
+
__classPrivateFieldGet(this, _BridgeStatusController_onTransactionFailed, "f").call(this, { txMeta, historyKey, isApprovalTxMeta });
|
|
1041
|
+
break;
|
|
1042
|
+
default:
|
|
1043
|
+
break;
|
|
1044
|
+
}
|
|
1045
|
+
}, ({ transactionMeta }) => {
|
|
1046
|
+
const entry = (0, history_1.getMatchingHistoryEntryForTxMeta)(this.state.txHistory, transactionMeta);
|
|
1047
|
+
const approvalEntry = (0, history_1.getMatchingHistoryEntryForApprovalTxMeta)(this.state.txHistory, transactionMeta);
|
|
1048
|
+
const entryToUse = entry ?? approvalEntry;
|
|
1049
|
+
return {
|
|
1050
|
+
historyKey: entryToUse?.[0],
|
|
1051
|
+
historyItem: entryToUse?.[1],
|
|
1052
|
+
txMeta: transactionMeta,
|
|
1053
|
+
isApprovalTxMeta: entryToUse?.[1]?.approvalTxId === transactionMeta.id,
|
|
1054
|
+
};
|
|
972
1055
|
});
|
|
973
1056
|
// If you close the extension, but keep the browser open, the polling continues
|
|
974
1057
|
// If you close the browser, the polling stops
|
|
@@ -977,5 +1060,5 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
977
1060
|
}
|
|
978
1061
|
}
|
|
979
1062
|
exports.BridgeStatusController = BridgeStatusController;
|
|
980
|
-
_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(),
|
|
1063
|
+
_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();
|
|
981
1064
|
//# sourceMappingURL=bridge-status-controller.cjs.map
|