diff --git a/packages/bridge-ui/src/components/Transactions/Status/Status.svelte b/packages/bridge-ui/src/components/Transactions/Status/Status.svelte index 6862c04317..120af7dc4a 100644 --- a/packages/bridge-ui/src/components/Transactions/Status/Status.svelte +++ b/packages/bridge-ui/src/components/Transactions/Status/Status.svelte @@ -8,6 +8,7 @@ import { isTransactionProcessable } from '$libs/bridge/isTransactionProcessable'; import { BridgePausedError } from '$libs/error'; import { PollingEvent, startPolling } from '$libs/polling/messageStatusPoller'; + import { bridgeTxService } from '$libs/storage'; import { isBridgePaused } from '$libs/util/checkForPausedContracts'; import { account } from '$stores/account'; import { connectedSourceChain } from '$stores/network'; @@ -15,14 +16,13 @@ const dispatch = createEventDispatcher(); export let bridgeTx: BridgeTransaction; - - let polling: ReturnType; + export let bridgeTxStatus: Maybe; // UI state let isProcessable = false; // bridge tx state to be processed: claimed/retried/released - export let bridgeTxStatus: Maybe; - + let polling: ReturnType; let loading = false; + let hasError = false; function onProcessable(isTxProcessable: boolean) { isProcessable = isTxProcessable; @@ -69,6 +69,16 @@ // TODO: implement release handling } + $: if (hasError && $account.address) { + if (bridgeTxService.transactionIsStoredLocally($account.address, bridgeTx)) { + // If we can't start polling, it maybe an old/outdated transaction in the local storage, so we remove it + bridgeTxService.removeTransactions($account.address, [bridgeTx]); + if (!bridgeTxService.transactionIsStoredLocally($account.address, bridgeTx)) { + dispatch('transactionRemoved', bridgeTx); + } + } + } + onMount(async () => { if (bridgeTx && $account?.address) { bridgeTxStatus = bridgeTx.msgStatus; @@ -87,8 +97,8 @@ polling.emitter.on(PollingEvent.STATUS, onStatusChange); } } catch (err) { - console.error(err); - // TODO: handle error + console.warn('Cannot start polling', err); + hasError = true; } } }); diff --git a/packages/bridge-ui/src/components/Transactions/Transaction.svelte b/packages/bridge-ui/src/components/Transactions/Transaction.svelte index 586e95bb92..03b07fcf9b 100644 --- a/packages/bridge-ui/src/components/Transactions/Transaction.svelte +++ b/packages/bridge-ui/src/components/Transactions/Transaction.svelte @@ -24,6 +24,7 @@ export let item: BridgeTransaction; export let loading = false; + export let handleTransactionRemoved: (event: CustomEvent) => void; let token: NFT; let insufficientModal = false; @@ -188,6 +189,7 @@ @@ -247,6 +249,7 @@
diff --git a/packages/bridge-ui/src/components/Transactions/Transactions.svelte b/packages/bridge-ui/src/components/Transactions/Transactions.svelte index 88ea55e210..974d57f0fb 100644 --- a/packages/bridge-ui/src/components/Transactions/Transactions.svelte +++ b/packages/bridge-ui/src/components/Transactions/Transactions.svelte @@ -85,6 +85,10 @@ } }; + const handleTransactionRemoved = () => { + refresh(); + }; + const updateTransactions = async (address: Address) => { if (loadingTxs) return; loadingTxs = true; @@ -245,7 +249,7 @@ class="flex flex-col items-center" style={isBlurred ? `filter: blur(5px); transition: filter ${transitionTime / 1000}s ease-in-out` : ''}> {#each transactionsToShow as item (item.srcTxHash)} - +
{/each}
diff --git a/packages/bridge-ui/src/libs/storage/BridgeTxService.ts b/packages/bridge-ui/src/libs/storage/BridgeTxService.ts index 2653e768af..c46ef355d2 100644 --- a/packages/bridge-ui/src/libs/storage/BridgeTxService.ts +++ b/packages/bridge-ui/src/libs/storage/BridgeTxService.ts @@ -8,7 +8,6 @@ import { type BridgeTransaction, MessageStatus } from '$libs/bridge'; import { getMessageStatusForMsgHash } from '$libs/bridge/getMessageStatusForMsgHash'; import { isSupportedChain } from '$libs/chain'; import { FilterLogsError } from '$libs/error'; -import { fetchTransactionReceipt } from '$libs/util/fetchTransactionReceipt'; import { jsonParseWithDefault } from '$libs/util/jsonParseWithDefault'; import { getLogger } from '$libs/util/logger'; import { config } from '$libs/wagmi'; @@ -21,7 +20,11 @@ export class BridgeTxService { //Todo: duplicate code in RelayerAPIService private static async _getTransactionReceipt(chainId: number, hash: Hash) { try { - return await fetchTransactionReceipt(hash, chainId); + return await waitForTransactionReceipt(config, { + hash, + chainId: Number(chainId), + timeout: pendingTransaction.waitTimeout, + }); } catch (error) { log(`Error getting transaction receipt for ${hash}: ${error}`); return null; @@ -94,7 +97,7 @@ export class BridgeTxService { private async _enhanceTx(tx: BridgeTransaction, address: Address, waitForTx: boolean) { // Filters out the transactions that are not from the current address - if (tx.from.toLowerCase() !== address.toLowerCase()) return; + // if (tx.from.toLowerCase() !== address.toLowerCase()) return; const bridgeTx: BridgeTransaction = { ...tx }; // prevent mutation @@ -107,15 +110,11 @@ export class BridgeTxService { if (waitForTx) { // We might want to wait for the transaction to be mined - receipt = await waitForTransactionReceipt(config, { - hash: srcTxHash, - chainId: Number(srcChainId), - timeout: pendingTransaction.waitTimeout, - }); - } else { - // Returns the transaction receipt for hash or null - // if the transaction has not been mined. - receipt = await BridgeTxService._getTransactionReceipt(Number(srcChainId), srcTxHash); + try { + receipt = await BridgeTxService._getTransactionReceipt(Number(srcChainId), srcTxHash); + } catch (error) { + console.error('Error waiting for transaction receipt', error); + } } if (!receipt) { @@ -249,4 +248,9 @@ export class BridgeTxService { const key = `${storageService.bridgeTxPrefix}-${address}`; this.storage.removeItem(key); } + + transactionIsStoredLocally(address: Address, tx: BridgeTransaction) { + const txs = this._getTxFromStorage(address); + return txs.some((t) => t.srcTxHash === tx.srcTxHash); + } }