@metamask-previews/bridge-status-controller 70.0.5-preview-42c8fd288 → 70.0.5-preview-8e9c439
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 -135
- 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 +200 -138
- 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 +4 -3
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +4 -3
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/bridge-status.cjs +39 -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 +38 -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 +49 -2
- package/dist/utils/history.cjs.map +1 -1
- package/dist/utils/history.d.cts +12 -1
- package/dist/utils/history.d.cts.map +1 -1
- package/dist/utils/history.d.mts +12 -1
- package/dist/utils/history.d.mts.map +1 -1
- package/dist/utils/history.mjs +46 -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 +1 -1
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.mjs +1 -1
- 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, polling backs off exponentially and also checks for the src tx hash's receipt. If there is no receipt, the history item's hash is presumed to be invalid and 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_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,45 @@ 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
|
-
transaction_controller_1.TransactionType.swap
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
transaction_controller_1.TransactionStatus.dropped,
|
|
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
|
-
}
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
// Mark tx as failed in txHistory if either the approval or trade fails
|
|
109
|
-
_BridgeStatusController_markTxAsFailed.set(this, ({ id: txMetaId, actionId, }) => {
|
|
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;
|
|
73
|
+
_BridgeStatusController_onTransactionFailed.set(this, ({ txMeta, historyKey, }) => {
|
|
74
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
75
|
+
historyKey,
|
|
76
|
+
status: bridge_controller_1.StatusTypes.FAILED,
|
|
77
|
+
txHash: txMeta.type &&
|
|
78
|
+
[transaction_controller_1.TransactionType.bridge, transaction_controller_1.TransactionType.swap].includes(txMeta.type)
|
|
79
|
+
? txMeta.hash
|
|
80
|
+
: undefined,
|
|
81
|
+
});
|
|
82
|
+
if (txMeta.status === transaction_controller_1.TransactionStatus.rejected) {
|
|
83
|
+
return;
|
|
117
84
|
}
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
if (!txHistoryKey) {
|
|
85
|
+
// Skip account lookup and tracking when featureId is set (e.g. PERPS)
|
|
86
|
+
if (historyKey && this.state.txHistory[historyKey]?.featureId) {
|
|
121
87
|
return;
|
|
122
88
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
89
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, historyKey, (0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(txMeta));
|
|
90
|
+
});
|
|
91
|
+
// Only EVM txs
|
|
92
|
+
_BridgeStatusController_onTransactionConfirmed.set(this, ({ txMeta, historyKey, }) => {
|
|
93
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
94
|
+
historyKey,
|
|
95
|
+
txHash: txMeta.hash,
|
|
126
96
|
});
|
|
97
|
+
console.log('======TransactionController:transactionConfirmed', txMeta);
|
|
98
|
+
switch (txMeta.type) {
|
|
99
|
+
case transaction_controller_1.TransactionType.swap:
|
|
100
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
101
|
+
historyKey,
|
|
102
|
+
status: bridge_controller_1.StatusTypes.COMPLETE,
|
|
103
|
+
});
|
|
104
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
105
|
+
break;
|
|
106
|
+
default:
|
|
107
|
+
if (historyKey) {
|
|
108
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
127
112
|
});
|
|
128
113
|
this.resetState = () => {
|
|
129
114
|
this.update((state) => {
|
|
@@ -224,30 +209,31 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
224
209
|
_BridgeStatusController_restartPollingForIncompleteHistoryItems.set(this, () => {
|
|
225
210
|
// Check for historyItems that do not have a status of complete and restart polling
|
|
226
211
|
const { txHistory } = this.state;
|
|
227
|
-
const historyItems = Object.
|
|
212
|
+
const historyItems = Object.entries(txHistory);
|
|
228
213
|
const incompleteHistoryItems = historyItems
|
|
229
|
-
.filter((historyItem) => historyItem.status.status === bridge_controller_1.StatusTypes.PENDING ||
|
|
214
|
+
.filter(([_, historyItem]) => historyItem.status.status === bridge_controller_1.StatusTypes.PENDING ||
|
|
230
215
|
historyItem.status.status === bridge_controller_1.StatusTypes.UNKNOWN)
|
|
231
216
|
// Only poll items with txMetaId (post-submission items)
|
|
232
|
-
.filter((historyItem) =>
|
|
233
|
-
|
|
217
|
+
.filter(([_, historyItem]) => {
|
|
218
|
+
if (!historyItem.txMetaId) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
234
221
|
// Check if we are already polling this tx, if so, skip restarting polling for that
|
|
235
222
|
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[historyItem.txMetaId];
|
|
236
223
|
return !pollingToken;
|
|
237
224
|
})
|
|
238
225
|
// Only restart polling for items that still require status updates
|
|
239
|
-
.filter((historyItem) => {
|
|
226
|
+
.filter(([_, historyItem]) => {
|
|
240
227
|
return (0, history_1.shouldPollHistoryItem)(historyItem);
|
|
241
228
|
});
|
|
242
|
-
incompleteHistoryItems.forEach((historyItem) => {
|
|
243
|
-
const bridgeTxMetaId = historyItem.txMetaId;
|
|
229
|
+
incompleteHistoryItems.forEach(([historyKey, historyItem]) => {
|
|
244
230
|
const shouldSkipFetch = (0, bridge_status_1.shouldSkipFetchDueToFetchFailures)(historyItem.attempts);
|
|
245
231
|
if (shouldSkipFetch) {
|
|
246
232
|
return;
|
|
247
233
|
}
|
|
248
234
|
// We manually call startPolling() here rather than go through startPollingForBridgeTxStatus()
|
|
249
235
|
// because we don't want to overwrite the existing historyItem in state
|
|
250
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
236
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
251
237
|
});
|
|
252
238
|
});
|
|
253
239
|
_BridgeStatusController_addTxToHistory.set(this, (...args) => {
|
|
@@ -256,6 +242,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
256
242
|
// Use actionId as key for pre-submission, or txMeta.id for post-submission
|
|
257
243
|
state.txHistory[historyKey] = txHistoryItem;
|
|
258
244
|
});
|
|
245
|
+
return historyKey;
|
|
259
246
|
});
|
|
260
247
|
/**
|
|
261
248
|
* Rekeys a history item from actionId to txMeta.id after successful submission.
|
|
@@ -278,9 +265,6 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
278
265
|
this.stopPollingByPollingToken(existingPollingToken);
|
|
279
266
|
}
|
|
280
267
|
const txHistoryItem = this.state.txHistory[txId];
|
|
281
|
-
if (!txHistoryItem) {
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
268
|
if ((0, history_1.shouldPollHistoryItem)(txHistoryItem)) {
|
|
285
269
|
__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[txId] = this.startPolling({
|
|
286
270
|
bridgeTxMetaId: txId,
|
|
@@ -302,8 +286,8 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
302
286
|
if (!bridgeTxMeta?.id) {
|
|
303
287
|
throw new Error('Cannot start polling: bridgeTxMeta.id is required for polling');
|
|
304
288
|
}
|
|
305
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
|
|
306
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
289
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, txHistoryMeta);
|
|
290
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
307
291
|
};
|
|
308
292
|
// This will be called after you call this.startPolling()
|
|
309
293
|
// The args passed in are the args you passed in to startPolling()
|
|
@@ -311,55 +295,45 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
311
295
|
await __classPrivateFieldGet(this, _BridgeStatusController_fetchBridgeTxStatus, "f").call(this, pollingInput);
|
|
312
296
|
};
|
|
313
297
|
/**
|
|
314
|
-
* Handles the failure to fetch the bridge tx status
|
|
315
|
-
* We eventually stop polling for the tx if we fail too many times
|
|
298
|
+
* Handles the failure to fetch the bridge tx status or recognize the transaction hash
|
|
299
|
+
* We eventually stop polling for the tx if we fail too many times or if the transaction is stale
|
|
316
300
|
* Failures (500 errors) can be due to:
|
|
317
301
|
* - The srcTxHash not being available immediately for STX
|
|
318
302
|
* - The srcTxHash being invalid for the chain. This case will never resolve so we stop polling for it to avoid hammering the Bridge API forever.
|
|
319
303
|
*
|
|
320
304
|
* @param bridgeTxMetaId - The txMetaId of the bridge tx
|
|
321
305
|
*/
|
|
322
|
-
_BridgeStatusController_handleFetchFailure.set(this, (bridgeTxMetaId) => {
|
|
323
|
-
|
|
324
|
-
const newAttempts =
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
// If we've failed too many times, stop polling for the tx
|
|
306
|
+
_BridgeStatusController_handleFetchFailure.set(this, async (bridgeTxMetaId) => {
|
|
307
|
+
// Increment the polling attempts counter
|
|
308
|
+
const newAttempts = (0, history_1.incrementPollingAttempts)(this.state.txHistory[bridgeTxMetaId]);
|
|
309
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
310
|
+
historyKey: bridgeTxMetaId,
|
|
311
|
+
attempts: newAttempts,
|
|
312
|
+
});
|
|
313
|
+
// Continue polling every 10s until the max attempts is reached
|
|
314
|
+
if (newAttempts.counter < constants_1.MAX_ATTEMPTS) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
334
317
|
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
335
|
-
|
|
318
|
+
// After the attempts exceed the max, keep polling with exponential backoff
|
|
319
|
+
// If the historyItem age is less than the configured maxPendingHistoryItemAgeMs flag, wait for a valid srcTxHash
|
|
320
|
+
if (await (0, bridge_status_1.shouldWaitForFinalBridgeStatus)(this.messenger, this.state.txHistory[bridgeTxMetaId])) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// If we've failed too many times and the srcTxHash is invalid, stop polling for the tx
|
|
324
|
+
if (pollingToken) {
|
|
336
325
|
this.stopPollingByPollingToken(pollingToken);
|
|
337
326
|
delete __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[bridgeTxMetaId];
|
|
338
|
-
// Track max polling reached event
|
|
339
|
-
const historyItem = this.state.txHistory[bridgeTxMetaId];
|
|
340
|
-
if (historyItem && !historyItem.featureId) {
|
|
341
|
-
const selectedAccount = (0, accounts_1.getAccountByAddress)(this.messenger, historyItem.account);
|
|
342
|
-
const requestParams = (0, metrics_1.getRequestParamFromHistory)(historyItem);
|
|
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
|
-
});
|
|
357
|
-
}
|
|
358
327
|
}
|
|
359
|
-
//
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
}
|
|
328
|
+
// Track polling status updated event
|
|
329
|
+
if (newAttempts.counter === constants_1.MAX_ATTEMPTS) {
|
|
330
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackPollingStatusUpdatedEvent, "f").call(this, bridgeTxMetaId, bridge_controller_1.PollingStatus.MaxPollingReached);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackPollingStatusUpdatedEvent, "f").call(this, bridgeTxMetaId, bridge_controller_1.PollingStatus.StaleTransactionHash);
|
|
334
|
+
// Delete the history item so polling doesn't start over on the next restart
|
|
335
|
+
__classPrivateFieldGet(this, _BridgeStatusController_deleteHistoryItem, "f").call(this, bridgeTxMetaId);
|
|
336
|
+
}
|
|
363
337
|
});
|
|
364
338
|
_BridgeStatusController_fetchBridgeTxStatus.set(this, async ({ bridgeTxMetaId, }) => {
|
|
365
339
|
// 1. Check for history item
|
|
@@ -388,11 +362,14 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
388
362
|
// We try here because we receive 500 errors from Bridge API if we try to fetch immediately after submitting the source tx
|
|
389
363
|
// Oddly mostly happens on Optimism, never on Arbitrum. By the 2nd fetch, the Bridge API responds properly.
|
|
390
364
|
// Also srcTxHash may not be available immediately for STX, so we don't want to fetch in those cases
|
|
391
|
-
const srcTxHash = __classPrivateFieldGet(this,
|
|
365
|
+
const srcTxHash = __classPrivateFieldGet(this, _BridgeStatusController_setAndGetSrcTxHash, "f").call(this, bridgeTxMetaId);
|
|
366
|
+
// Throw errors to increase polling attempts counter
|
|
367
|
+
if ((0, history_1.isHistoryItemTooOld)(this.messenger, historyItem)) {
|
|
368
|
+
throw new Error(`History item is too old: ${bridgeTxMetaId}}`);
|
|
369
|
+
}
|
|
392
370
|
if (!srcTxHash) {
|
|
393
371
|
return;
|
|
394
372
|
}
|
|
395
|
-
__classPrivateFieldGet(this, _BridgeStatusController_updateSrcTxHash, "f").call(this, bridgeTxMetaId, srcTxHash);
|
|
396
373
|
const statusRequest = (0, bridge_status_1.getStatusRequestWithSrcTxHash)(historyItem.quote, srcTxHash);
|
|
397
374
|
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
375
|
status = response.status;
|
|
@@ -447,28 +424,65 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
447
424
|
}
|
|
448
425
|
catch (error) {
|
|
449
426
|
console.warn('Failed to fetch bridge tx status', error);
|
|
450
|
-
__classPrivateFieldGet(this, _BridgeStatusController_handleFetchFailure, "f").call(this, bridgeTxMetaId);
|
|
427
|
+
await __classPrivateFieldGet(this, _BridgeStatusController_handleFetchFailure, "f").call(this, bridgeTxMetaId);
|
|
451
428
|
}
|
|
452
429
|
});
|
|
453
|
-
|
|
430
|
+
/**
|
|
431
|
+
* Returns the srcTxHash for a non-STX EVM tx, the hash from the bridge status api,
|
|
432
|
+
* or the local hash from the TransactionController if the tx is in a finalized state
|
|
433
|
+
*
|
|
434
|
+
* @param bridgeTxMetaId - The bridge tx meta id
|
|
435
|
+
* @returns The srcTxHash
|
|
436
|
+
*/
|
|
437
|
+
_BridgeStatusController_setAndGetSrcTxHash.set(this, (bridgeTxMetaId) => {
|
|
454
438
|
const { txHistory } = this.state;
|
|
455
|
-
// Prefer the srcTxHash from bridgeStatusState so we don't have to
|
|
439
|
+
// Prefer the srcTxHash from bridgeStatusState so we don't have to look up in TransactionController
|
|
456
440
|
// But it is possible to have bridgeHistoryItem in state without the srcTxHash yet when it is an STX
|
|
457
441
|
const srcTxHash = txHistory[bridgeTxMetaId].status.srcChain.txHash;
|
|
458
|
-
if (srcTxHash
|
|
442
|
+
if (srcTxHash ||
|
|
443
|
+
(0, bridge_controller_1.isNonEvmChainId)(txHistory[bridgeTxMetaId].quote.srcChainId)) {
|
|
444
|
+
// throw new Error(`Src tx hash not found for non-EVM chain: ${srcTxHash}`);
|
|
459
445
|
return srcTxHash;
|
|
460
446
|
}
|
|
461
|
-
//
|
|
447
|
+
// Update history with TransactionController's hash if it has been updated
|
|
462
448
|
const txMeta = (0, transaction_1.getTransactionMetaById)(this.messenger, bridgeTxMetaId);
|
|
463
|
-
|
|
449
|
+
if (!txMeta) {
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
452
|
+
// Wait for finalized status before updating the history item
|
|
453
|
+
const localTxHash = [
|
|
454
|
+
transaction_controller_1.TransactionStatus.confirmed,
|
|
455
|
+
transaction_controller_1.TransactionStatus.dropped,
|
|
456
|
+
transaction_controller_1.TransactionStatus.rejected,
|
|
457
|
+
transaction_controller_1.TransactionStatus.failed,
|
|
458
|
+
].includes(txMeta.status)
|
|
459
|
+
? txMeta.hash
|
|
460
|
+
: undefined;
|
|
461
|
+
__classPrivateFieldGet(this, _BridgeStatusController_updateHistoryItem, "f").call(this, {
|
|
462
|
+
historyKey: bridgeTxMetaId,
|
|
463
|
+
txHash: localTxHash,
|
|
464
|
+
});
|
|
465
|
+
return localTxHash;
|
|
464
466
|
});
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if (txHistory[bridgeTxMetaId].status.srcChain.txHash) {
|
|
467
|
+
_BridgeStatusController_updateHistoryItem.set(this, ({ historyKey, status, txHash, attempts, }) => {
|
|
468
|
+
if (!historyKey) {
|
|
468
469
|
return;
|
|
469
470
|
}
|
|
470
|
-
this.update((
|
|
471
|
-
|
|
471
|
+
this.update((currentState) => {
|
|
472
|
+
if (status) {
|
|
473
|
+
currentState.txHistory[historyKey].status.status = status;
|
|
474
|
+
}
|
|
475
|
+
if (txHash) {
|
|
476
|
+
currentState.txHistory[historyKey].status.srcChain.txHash = txHash;
|
|
477
|
+
}
|
|
478
|
+
if (attempts) {
|
|
479
|
+
currentState.txHistory[historyKey].attempts = attempts;
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
_BridgeStatusController_deleteHistoryItem.set(this, (historyKey) => {
|
|
484
|
+
this.update((currentState) => {
|
|
485
|
+
delete currentState.txHistory[historyKey];
|
|
472
486
|
});
|
|
473
487
|
});
|
|
474
488
|
// Wipes the bridge status for the given address and chainId
|
|
@@ -484,6 +498,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
484
498
|
const pollingToken = __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId];
|
|
485
499
|
if (pollingToken) {
|
|
486
500
|
this.stopPollingByPollingToken(__classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId]);
|
|
501
|
+
delete __classPrivateFieldGet(this, _BridgeStatusController_pollingTokensByTxMetaId, "f")[sourceTxMetaId];
|
|
487
502
|
}
|
|
488
503
|
});
|
|
489
504
|
this.update((state) => {
|
|
@@ -650,7 +665,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
650
665
|
const actionId = (0, transaction_1.generateActionId)().toString();
|
|
651
666
|
// Add pre-submission history keyed by actionId
|
|
652
667
|
// This ensures we have quote data available if transaction fails during submission
|
|
653
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
668
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
654
669
|
accountAddress: selectedAccount.address,
|
|
655
670
|
quoteResponse,
|
|
656
671
|
slippagePercentage: 0,
|
|
@@ -677,7 +692,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
677
692
|
actionId,
|
|
678
693
|
});
|
|
679
694
|
// On success, rekey from actionId to txMeta.id and update srcTxHash
|
|
680
|
-
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this,
|
|
695
|
+
__classPrivateFieldGet(this, _BridgeStatusController_rekeyHistoryItem, "f").call(this, historyKey, tradeTxMeta);
|
|
681
696
|
return tradeTxMeta;
|
|
682
697
|
});
|
|
683
698
|
}
|
|
@@ -697,11 +712,12 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
697
712
|
!isStxEnabledOnClient &&
|
|
698
713
|
!quoteResponse.quote.gasIncluded7702 &&
|
|
699
714
|
!isDelegatedAccount;
|
|
715
|
+
let historyKey = txMeta.id;
|
|
700
716
|
if (!isNonBatchEvm) {
|
|
701
717
|
// Add swap or bridge tx to history
|
|
702
|
-
__classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
718
|
+
historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
703
719
|
accountAddress: selectedAccount.address,
|
|
704
|
-
bridgeTxMeta: txMeta, // Only the id
|
|
720
|
+
bridgeTxMeta: txMeta, // Only the id and hash fields are used by the BridgeStatusController
|
|
705
721
|
quoteResponse,
|
|
706
722
|
slippagePercentage: 0, // TODO include slippage provided by quote if using dynamic slippage, or slippage from quote request
|
|
707
723
|
isStxEnabled: isStxEnabledOnClient,
|
|
@@ -714,10 +730,10 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
714
730
|
}
|
|
715
731
|
if ((0, bridge_controller_1.isNonEvmChainId)(quoteResponse.quote.srcChainId)) {
|
|
716
732
|
// Start polling for bridge tx status
|
|
717
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
733
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
718
734
|
// Track non-EVM Swap completed event
|
|
719
735
|
if (!(isBridgeTx || isTronTx)) {
|
|
720
|
-
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed,
|
|
736
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Completed, historyKey);
|
|
721
737
|
}
|
|
722
738
|
}
|
|
723
739
|
}
|
|
@@ -816,15 +832,14 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
816
832
|
};
|
|
817
833
|
// Record in bridge history with actual transaction metadata
|
|
818
834
|
try {
|
|
819
|
-
// Use orderId as the history key for intent transactions
|
|
820
|
-
const bridgeHistoryKey = orderUid;
|
|
821
835
|
// Create a bridge transaction metadata that includes the original txId
|
|
822
836
|
const bridgeTxMetaForHistory = {
|
|
823
837
|
...syntheticMeta,
|
|
824
|
-
id:
|
|
838
|
+
id: orderUid,
|
|
825
839
|
originalTransactionId: syntheticMeta.id, // Keep original txId for TransactionController updates
|
|
826
840
|
};
|
|
827
|
-
|
|
841
|
+
// Use orderId as the history key for intent transactions
|
|
842
|
+
const historyKey = __classPrivateFieldGet(this, _BridgeStatusController_addTxToHistory, "f").call(this, {
|
|
828
843
|
accountAddress,
|
|
829
844
|
bridgeTxMeta: bridgeTxMetaForHistory,
|
|
830
845
|
quoteResponse,
|
|
@@ -837,7 +852,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
837
852
|
activeAbTests,
|
|
838
853
|
});
|
|
839
854
|
// Start polling using the orderId key to route to intent manager
|
|
840
|
-
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this,
|
|
855
|
+
__classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, historyKey);
|
|
841
856
|
}
|
|
842
857
|
catch (error) {
|
|
843
858
|
console.error('📝 [submitIntent] Failed to add to bridge history', error);
|
|
@@ -853,6 +868,13 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
853
868
|
throw error;
|
|
854
869
|
}
|
|
855
870
|
};
|
|
871
|
+
_BridgeStatusController_trackPollingStatusUpdatedEvent.set(this, (historyKey, pollingStatus) => {
|
|
872
|
+
// Track polling status updated event
|
|
873
|
+
const historyItem = this.state.txHistory[historyKey];
|
|
874
|
+
if (historyItem && !historyItem.featureId) {
|
|
875
|
+
__classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.PollingStatusUpdated, historyKey, (0, metrics_1.getPollingStatusUpdatedProperties)(this.messenger, pollingStatus, historyItem));
|
|
876
|
+
}
|
|
877
|
+
});
|
|
856
878
|
/**
|
|
857
879
|
* Tracks post-submission events for a cross-chain swap based on the history item
|
|
858
880
|
*
|
|
@@ -960,15 +982,55 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
960
982
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
961
983
|
// Set interval
|
|
962
984
|
this.setIntervalLength(constants_1.REFRESH_INTERVAL_MS);
|
|
963
|
-
this.messenger.subscribe('TransactionController:
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
985
|
+
this.messenger.subscribe('TransactionController:transactionStatusUpdated', ({ txMeta, historyKey, historyItem }) => {
|
|
986
|
+
if (!txMeta) {
|
|
987
|
+
console.error('======TransactionController:transactionStatusUpdated NOT FOUND');
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
const { type, hash, status, id, actionId, batchId } = txMeta;
|
|
991
|
+
console.error('======TransactionController:transactionStatusUpdated', {
|
|
992
|
+
type,
|
|
993
|
+
hash,
|
|
994
|
+
status,
|
|
995
|
+
id,
|
|
996
|
+
actionId,
|
|
997
|
+
batchId,
|
|
998
|
+
});
|
|
999
|
+
// Allow event publishing if the txMeta is a swap/bridge OR if the
|
|
1000
|
+
// corresponding history item exists
|
|
1001
|
+
const isSwapOrBridgeTransaction = type &&
|
|
1002
|
+
[
|
|
1003
|
+
transaction_controller_1.TransactionType.swap,
|
|
1004
|
+
transaction_controller_1.TransactionType.bridge,
|
|
1005
|
+
transaction_controller_1.TransactionType.swapApproval,
|
|
1006
|
+
transaction_controller_1.TransactionType.bridgeApproval,
|
|
1007
|
+
].includes(type);
|
|
1008
|
+
const isApprovalConfirmation = txMeta.id === historyItem?.approvalTxId &&
|
|
1009
|
+
status === transaction_controller_1.TransactionStatus.confirmed;
|
|
1010
|
+
if ((!isSwapOrBridgeTransaction && !historyKey && !historyItem) ||
|
|
1011
|
+
isApprovalConfirmation) {
|
|
1012
|
+
console.error('======approval tx confirmed');
|
|
1013
|
+
return;
|
|
968
1014
|
}
|
|
969
|
-
|
|
970
|
-
|
|
1015
|
+
switch (status) {
|
|
1016
|
+
case transaction_controller_1.TransactionStatus.confirmed:
|
|
1017
|
+
__classPrivateFieldGet(this, _BridgeStatusController_onTransactionConfirmed, "f").call(this, { txMeta, historyKey });
|
|
1018
|
+
break;
|
|
1019
|
+
case transaction_controller_1.TransactionStatus.failed:
|
|
1020
|
+
case transaction_controller_1.TransactionStatus.dropped:
|
|
1021
|
+
case transaction_controller_1.TransactionStatus.rejected:
|
|
1022
|
+
__classPrivateFieldGet(this, _BridgeStatusController_onTransactionFailed, "f").call(this, { txMeta, historyKey });
|
|
1023
|
+
break;
|
|
1024
|
+
default:
|
|
1025
|
+
break;
|
|
971
1026
|
}
|
|
1027
|
+
}, ({ transactionMeta }) => {
|
|
1028
|
+
const entry = (0, history_1.getMatchingHistoryEntryForTxMeta)(this.state.txHistory, transactionMeta);
|
|
1029
|
+
return {
|
|
1030
|
+
historyKey: entry?.[0],
|
|
1031
|
+
historyItem: entry?.[1],
|
|
1032
|
+
txMeta: transactionMeta,
|
|
1033
|
+
};
|
|
972
1034
|
});
|
|
973
1035
|
// If you close the extension, but keep the browser open, the polling continues
|
|
974
1036
|
// If you close the browser, the polling stops
|
|
@@ -977,5 +1039,5 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
|
|
|
977
1039
|
}
|
|
978
1040
|
}
|
|
979
1041
|
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(),
|
|
1042
|
+
_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_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
1043
|
//# sourceMappingURL=bridge-status-controller.cjs.map
|