From 434f8511438eecd066f211cf934db7655cd78640 Mon Sep 17 00:00:00 2001 From: impelcrypto Date: Mon, 19 Feb 2024 21:27:11 +0800 Subject: [PATCH 1/3] fix: disable sending bridge transactions when Gelato API is down --- src/components/bridge/ethereum/L1.vue | 4 +++- src/hooks/bridge/useL1History.ts | 21 +++++++++++++++++++++ src/hooks/useGasPrice.ts | 8 +++++++- src/i18n/en-US/index.ts | 1 + 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/components/bridge/ethereum/L1.vue b/src/components/bridge/ethereum/L1.vue index 52ee5a488..75d4704a9 100644 --- a/src/components/bridge/ethereum/L1.vue +++ b/src/components/bridge/ethereum/L1.vue @@ -15,7 +15,7 @@ :set-right-ui="setRightUi" :bridge-amt="String(bridgeAmt)" :err-msg="errMsg" - :is-disabled-bridge="isDisabledBridge" + :is-disabled-bridge="isDisabledBridge || !isGelatoApiConnected" :from-bridge-balance="fromBridgeBalance" :to-bridge-balance="toBridgeBalance" :from-chain-name="fromChainName" @@ -111,6 +111,7 @@ export default defineComponent({ l1Network, l2Network, isActionRequired, + isGelatoApiConnected, fetchUserHistory, handleClaim, } = useL1History(); @@ -224,6 +225,7 @@ export default defineComponent({ isApproved, isApproving, isApproveMaxAmount, + isGelatoApiConnected, inputImportTokenHandler, cancelHighlight, handleSetToken, diff --git a/src/hooks/bridge/useL1History.ts b/src/hooks/bridge/useL1History.ts index e80e3b808..75dc50673 100644 --- a/src/hooks/bridge/useL1History.ts +++ b/src/hooks/bridge/useL1History.ts @@ -19,8 +19,14 @@ import { useEthProvider } from '../custom-signature/useEthProvider'; import { astarNativeTokenErcAddr } from 'src/modules/xcm'; import { AbiItem } from 'web3-utils'; import ERC20_ABI from 'src/config/abi/ERC20.json'; +import { useStore } from 'src/store'; +import { useI18n } from 'vue-i18n'; export const useL1History = () => { + const { t } = useI18n(); + const store = useStore(); + const isGelatoApiConnected = ref(true); + const l1Network = computed(() => { const networkIdxStore = String(localStorage.getItem(LOCAL_STORAGE.NETWORK_IDX)); return networkIdxStore === String(endpointKey.ASTAR_ZKEVM) @@ -71,6 +77,8 @@ export const useL1History = () => { try { isLoadingHistories.value = true; const data = await fetchAccountHistory(currentAccount.value); + isGelatoApiConnected.value = true; + const l1Web3 = buildWeb3Instance(EthBridgeChainId[l1Network.value as EthBridgeNetworkName]); const l2Web3 = buildWeb3Instance(EthBridgeChainId[l2Network.value as EthBridgeNetworkName]); @@ -121,6 +129,18 @@ export const useL1History = () => { isFetchAutomatically.value = numberInProgress > 0; histories.value = formattedResult.sort((a, b) => Number(b.timestamp) - Number(a.timestamp)); } catch (error) { + // Memo: disable sending bridge transactions from UI + if (isGelatoApiConnected.value) { + store.dispatch( + 'general/showAlertMsg', + { + msg: t('bridge.gelatoApiError'), + alertType: 'error', + }, + { root: true } + ); + isGelatoApiConnected.value = false; + } console.error(error); isFetchAutomatically.value = false; } finally { @@ -146,6 +166,7 @@ export const useL1History = () => { histories, isLoadingHistories, isActionRequired, + isGelatoApiConnected, handleClaim, fetchUserHistory, }; diff --git a/src/hooks/useGasPrice.ts b/src/hooks/useGasPrice.ts index f171f805e..1155c3762 100644 --- a/src/hooks/useGasPrice.ts +++ b/src/hooks/useGasPrice.ts @@ -74,7 +74,13 @@ export const useGasPrice = (isFetch = false) => { watch( [network], async () => { - if (isFetch && network.value && !gas.value && isEnableSpeedConfiguration.value) { + if ( + isFetch && + network.value && + !gas.value && + isEnableSpeedConfiguration.value && + !isZkEvm.value + ) { // console.info('gas price', network.value, gas.value); await dispatchGasPrice(network.value); } diff --git a/src/i18n/en-US/index.ts b/src/i18n/en-US/index.ts index 2fe1d4a65..21a5d3792 100644 --- a/src/i18n/en-US/index.ts +++ b/src/i18n/en-US/index.ts @@ -986,6 +986,7 @@ export default { warning32blocks: 'It could take around 10~20mins or more to finalize', warning2steps: 'Bridging to L1 (Ethereum) involves 2 steps, and it requires users to make a claim on the L1 network (available in Recent History)', + gelatoApiError: 'Bridge UI is not available, please try again later', tokenInfo: { invalidTokenAddress: 'Invalid token address', tokenAddress: '{network} token address', From 62f210588103baadbcda559e03dcef7fa170013c Mon Sep 17 00:00:00 2001 From: impelcrypto Date: Mon, 19 Feb 2024 21:36:22 +0800 Subject: [PATCH 2/3] fix: refactor --- src/hooks/bridge/useL1History.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/hooks/bridge/useL1History.ts b/src/hooks/bridge/useL1History.ts index 75dc50673..012ce4bd9 100644 --- a/src/hooks/bridge/useL1History.ts +++ b/src/hooks/bridge/useL1History.ts @@ -25,7 +25,7 @@ import { useI18n } from 'vue-i18n'; export const useL1History = () => { const { t } = useI18n(); const store = useStore(); - const isGelatoApiConnected = ref(true); + const isGelatoApiConnected = ref(false); const l1Network = computed(() => { const networkIdxStore = String(localStorage.getItem(LOCAL_STORAGE.NETWORK_IDX)); @@ -74,6 +74,7 @@ export const useL1History = () => { }; const fetchUserHistory = async (): Promise => { + if (!currentAccount.value) return; try { isLoadingHistories.value = true; const data = await fetchAccountHistory(currentAccount.value); @@ -130,17 +131,15 @@ export const useL1History = () => { histories.value = formattedResult.sort((a, b) => Number(b.timestamp) - Number(a.timestamp)); } catch (error) { // Memo: disable sending bridge transactions from UI - if (isGelatoApiConnected.value) { - store.dispatch( - 'general/showAlertMsg', - { - msg: t('bridge.gelatoApiError'), - alertType: 'error', - }, - { root: true } - ); - isGelatoApiConnected.value = false; - } + store.dispatch( + 'general/showAlertMsg', + { + msg: t('bridge.gelatoApiError'), + alertType: 'error', + }, + { root: true } + ); + isGelatoApiConnected.value = false; console.error(error); isFetchAutomatically.value = false; } finally { From c175817f9d564ffa89899bf9c9ab15af6b5a4292 Mon Sep 17 00:00:00 2001 From: impelcrypto Date: Tue, 27 Feb 2024 21:33:08 +0800 Subject: [PATCH 3/3] fix: added fetchIsGelatoApiHealth function --- src/hooks/bridge/useL1History.ts | 5 +++++ src/modules/zk-evm-bridge/l1-bridge/utils.ts | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/hooks/bridge/useL1History.ts b/src/hooks/bridge/useL1History.ts index 012ce4bd9..5c742d517 100644 --- a/src/hooks/bridge/useL1History.ts +++ b/src/hooks/bridge/useL1History.ts @@ -9,6 +9,7 @@ import { ZkChainId, checkIsL1, fetchAccountHistory, + fetchIsGelatoApiHealth, getChainIdFromNetId, } from 'src/modules/zk-evm-bridge'; import { container } from 'src/v2/common'; @@ -78,6 +79,10 @@ export const useL1History = () => { try { isLoadingHistories.value = true; const data = await fetchAccountHistory(currentAccount.value); + const isHealth = await fetchIsGelatoApiHealth(); + if (!isHealth) { + throw Error('The API is currently in maintenance mode.'); + } isGelatoApiConnected.value = true; const l1Web3 = buildWeb3Instance(EthBridgeChainId[l1Network.value as EthBridgeNetworkName]); diff --git a/src/modules/zk-evm-bridge/l1-bridge/utils.ts b/src/modules/zk-evm-bridge/l1-bridge/utils.ts index da9f05ca9..dace6a84f 100644 --- a/src/modules/zk-evm-bridge/l1-bridge/utils.ts +++ b/src/modules/zk-evm-bridge/l1-bridge/utils.ts @@ -65,6 +65,13 @@ const getApiUrl = (): string => { return zkEvmApi[network]; }; +export const fetchIsGelatoApiHealth = async (): Promise => { + const base = getApiUrl(); + const url = `${base}/healthz`; + const result = await axios.get<{ status: string }>(url); + return result && result.data.status === 'SERVING'; +}; + export const fetchAccountHistory = async (address: string): Promise => { const base = getApiUrl(); const limit = 15;