diff --git a/components/transaction/TransferWithdrawalLineItem.vue b/components/transaction/TransferWithdrawalLineItem.vue index cde136a6e..10099d68c 100644 --- a/components/transaction/TransferWithdrawalLineItem.vue +++ b/components/transaction/TransferWithdrawalLineItem.vue @@ -122,7 +122,7 @@ const timeAgo = useTimeAgo(props.transfer.timestamp); } .withdrawal-line-top { - @apply flex w-full items-center gap-4; + @apply grid w-full grid-cols-[1fr_max-content] items-center sm:gap-4; .line-button-with-img-body { @apply w-full overflow-hidden; diff --git a/data/networks.ts b/data/networks.ts index b967a9cbf..5264b3ebf 100644 --- a/data/networks.ts +++ b/data/networks.ts @@ -31,7 +31,6 @@ export type ZkSyncNetwork = { l1Network?: L1Network; blockExplorerUrl?: string; blockExplorerApi?: string; - withdrawalFinalizerApi?: string; displaySettings?: { showPartnerLinks?: boolean; }; @@ -74,7 +73,6 @@ const publicChains: ZkSyncNetwork[] = [ rpcUrl: "https://mainnet.era.zksync.io", blockExplorerUrl: "https://era.zksync.network", blockExplorerApi: "https://block-explorer-api.mainnet.zksync.io", - withdrawalFinalizerApi: "https://withdrawal-finalizer-api.zksync.io", displaySettings: { showPartnerLinks: true, }, @@ -87,7 +85,6 @@ const publicChains: ZkSyncNetwork[] = [ rpcUrl: "https://sepolia.era.zksync.dev", blockExplorerUrl: "https://sepolia-era.zksync.network", blockExplorerApi: "https://block-explorer-api.sepolia.zksync.dev", - withdrawalFinalizerApi: "https://withdrawal-finalizer-api.sepolia.zksync.dev", displaySettings: { showPartnerLinks: true, }, @@ -100,7 +97,6 @@ const publicChains: ZkSyncNetwork[] = [ rpcUrl: "https://testnet.era.zksync.dev", blockExplorerUrl: "https://goerli.explorer.zksync.io", blockExplorerApi: "https://block-explorer-api.testnets.zksync.dev", - withdrawalFinalizerApi: "https://withdrawal-finalizer-api.testnets.zksync.dev", displaySettings: { showPartnerLinks: true, }, @@ -113,7 +109,6 @@ const publicChains: ZkSyncNetwork[] = [ rpcUrl: "https://z2-dev-api.zksync.dev", blockExplorerUrl: "https://goerli-beta.staging-scan-v2.zksync.dev", blockExplorerApi: "https://block-explorer-api.stage.zksync.dev", - withdrawalFinalizerApi: "https://withdrawal-finalizer-api.stage.zksync.dev", l1Network: l1Networks.sepolia, hidden: true, }, diff --git a/store/zksync/withdrawals.ts b/store/zksync/withdrawals.ts index 606400b72..e1dfaaafe 100644 --- a/store/zksync/withdrawals.ts +++ b/store/zksync/withdrawals.ts @@ -15,61 +15,60 @@ export const useZkSyncWithdrawalsStore = defineStore("zkSyncWithdrawals", () => const updateWithdrawals = async () => { if (!isConnected.value) throw new Error("Account is not available"); - if (!eraNetwork.value.withdrawalFinalizerApi) - throw new Error(`Withdrawal Finalizer API is not available on ${eraNetwork.value.name}`); if (!eraNetwork.value.blockExplorerApi) throw new Error(`Block Explorer API is not available on ${eraNetwork.value.name}`); - const withdrawals: Api.Response.Finalizer_Withdrawal[] = await $fetch( - `${eraNetwork.value.withdrawalFinalizerApi}/withdrawals/${account.value.address}?limit=100` - ); - for (const withdrawal of withdrawals) { - const transactionFromStorage = transactionStatusStore.getTransaction(withdrawal.tx_hash); - if (transactionFromStorage) { - if (withdrawal.status === "Finalized" && !transactionFromStorage.info.completed) { - transactionStatusStore.updateTransactionData(withdrawal.tx_hash, { - ...transactionFromStorage, - info: { - ...transactionFromStorage.info, - completed: true, - }, - }); - } - continue; - } - const transactionTransfers: Api.Response.Collection = await $fetch( - `${eraNetwork.value.blockExplorerApi}/transactions/${withdrawal.tx_hash}/transfers?limit=100&page=1` - ); - const transfers = transactionTransfers.items.map(mapApiTransfer); - const withdrawalTransfer = transfers.find((e) => e.type === "withdrawal" && e.token && e.amount); - if (!withdrawalTransfer) continue; - if (new Date(withdrawalTransfer.timestamp).getTime() < Date.now() - FETCH_TIME_LIMIT) break; + const responses: Api.Response.Collection[] = await Promise.all([ + $fetch(`${eraNetwork.value.blockExplorerApi}/address/${account.value.address}/transfers?limit=100&page=1`), + $fetch(`${eraNetwork.value.blockExplorerApi}/address/${account.value.address}/transfers?limit=100&page=2`), + $fetch(`${eraNetwork.value.blockExplorerApi}/address/${account.value.address}/transfers?limit=100&page=3`), + ]); + const withdrawalTransfers = responses + .map((response) => response.items.map(mapApiTransfer)) + .flat() + .filter((e) => e.type === "withdrawal"); + + for (const withdrawal of withdrawalTransfers) { + if (!withdrawal.transactionHash) continue; + + const transactionFromStorage = transactionStatusStore.getTransaction(withdrawal.transactionHash); + if (transactionFromStorage) continue; + + if (new Date(withdrawal.timestamp).getTime() < Date.now() - FETCH_TIME_LIMIT) break; const transactionDetails = await retry(() => - providerStore.requestProvider().getTransactionDetails(withdrawal.tx_hash) + providerStore.requestProvider().getTransactionDetails(withdrawal.transactionHash!) ); + const withdrawalFinalizationAvailable = transactionDetails.status === "verified"; + const isFinalized = withdrawalFinalizationAvailable + ? await useZkSyncWalletStore() + .getL1VoidSigner(true) + ?.isWithdrawalFinalized(withdrawal.transactionHash) + .catch(() => false) + : false; + transactionStatusStore.saveTransaction({ type: "withdrawal", - transactionHash: withdrawal.tx_hash, - timestamp: withdrawalTransfer.timestamp, + transactionHash: withdrawal.transactionHash, + timestamp: withdrawal.timestamp, token: { - ...withdrawalTransfer.token!, - amount: withdrawalTransfer.amount!, + ...withdrawal.token!, + amount: withdrawal.amount!, }, from: { - address: withdrawalTransfer.from, + address: withdrawal.from, destination: destinations.value.era, }, to: { - address: withdrawalTransfer.to, + address: withdrawal.to, destination: destinations.value.ethereum, }, info: { expectedCompleteTimestamp: new Date( - new Date(withdrawalTransfer.timestamp).getTime() + WITHDRAWAL_DELAY + new Date(withdrawal.timestamp).getTime() + WITHDRAWAL_DELAY ).toISOString(), - completed: withdrawal.status === "Finalized", - withdrawalFinalizationAvailable: transactionDetails.status === "verified", + completed: isFinalized, + withdrawalFinalizationAvailable, }, }); } @@ -82,7 +81,7 @@ export const useZkSyncWithdrawalsStore = defineStore("zkSyncWithdrawals", () => ); const updateWithdrawalsIfPossible = async () => { - if (!isConnected.value || !eraNetwork.value.blockExplorerApi || !eraNetwork.value.withdrawalFinalizerApi) { + if (!isConnected.value || !eraNetwork.value.blockExplorerApi) { return; } await updateWithdrawals();