diff --git a/src/hooks/useRWA.ts b/src/hooks/useRWA.ts index d09c8c3..076d710 100644 --- a/src/hooks/useRWA.ts +++ b/src/hooks/useRWA.ts @@ -3,10 +3,7 @@ import { useSelector } from 'react-redux' import { ethers } from 'ethers' -import { - EthereumRpcProvider, - GnosisRpcProvider, -} from 'src/repositories/RpcProvider' +import { initializeProviders } from 'src/repositories/RpcProvider' import { selectUserCurrency } from 'src/store/features/currencies/currenciesSelector' import { selectUserAddressList, @@ -22,6 +19,7 @@ const getRWA = async ( includeETH: boolean = false, ): Promise => { let totalAmount = 0 + const { GnosisRpcProvider, EthereumRpcProvider } = await initializeProviders() let providers = [GnosisRpcProvider] diff --git a/src/repositories/RpcProvider.ts b/src/repositories/RpcProvider.ts index 03d3f10..726ba81 100644 --- a/src/repositories/RpcProvider.ts +++ b/src/repositories/RpcProvider.ts @@ -9,10 +9,40 @@ declare module 'ethers' { } } -const GNOSIS_RPC_URL = 'https://rpc.ankr.com/gnosis' -const ETHEREUM_RPC_URL = 'https://rpc.ankr.com/eth' -export const GnosisRpcProvider = new ethers.JsonRpcProvider(GNOSIS_RPC_URL) -export const EthereumRpcProvider = new ethers.JsonRpcProvider(ETHEREUM_RPC_URL) +const GNOSIS_RPC_URLS = [ + 'https://gnosis-rpc.publicnode.com', + 'https://rpc.ankr.com/gnosis', + 'https://gnosis.drpc.org', +] +const ETHEREUM_RPC_URLS = [ + 'https://rpc.ankr.com/eth', + 'https://eth.llamarpc.com', + 'https://eth-pokt.nodies.app', +] + +async function getWorkingRpcUrl(urls: string[]): Promise { + for (const url of urls) { + const provider = new ethers.JsonRpcProvider(url) + try { + await provider.getBlockNumber() + return url + } catch (error) { + console.error(`Failed to connect to ${url}, trying next one...`) + } + } + + throw new Error('All RPC URLs failed') +} + +export const initializeProviders = async () => { + const gnosisRpcUrl = await getWorkingRpcUrl(GNOSIS_RPC_URLS) + const ethereumRpcUrl = await getWorkingRpcUrl(ETHEREUM_RPC_URLS) + + const GnosisRpcProvider = new ethers.JsonRpcProvider(gnosisRpcUrl) + const EthereumRpcProvider = new ethers.JsonRpcProvider(ethereumRpcUrl) + + return { GnosisRpcProvider, EthereumRpcProvider } +} /** * Get transaction receipt @@ -27,6 +57,8 @@ export async function getTransactionReceipt( let attempt = 0 let receipt: ethers.TransactionReceipt | null = null + const { GnosisRpcProvider, EthereumRpcProvider } = await initializeProviders() + const RpcProvider = chainId === 1 ? EthereumRpcProvider : GnosisRpcProvider do { diff --git a/src/repositories/currencies.repository.ts b/src/repositories/currencies.repository.ts index 084c59d..1a3d2ed 100644 --- a/src/repositories/currencies.repository.ts +++ b/src/repositories/currencies.repository.ts @@ -2,7 +2,7 @@ import { ethers } from 'ethers' import { useCacheWithLocalStorage } from 'src/utils/useCache' -import { GnosisRpcProvider } from './RpcProvider' +import { initializeProviders } from './RpcProvider' export interface CurrencyRates { XdaiUsd: number @@ -16,15 +16,17 @@ function getChainlinkHandler(options: { }) { const { priceFeedContract, decimals } = options const ABI = ['function latestAnswer() view returns (int256)'] - const contract = new ethers.Contract( - priceFeedContract, - ABI, - GnosisRpcProvider, - ) return useCacheWithLocalStorage( - async () => - Number(ethers.formatUnits(await contract.latestAnswer(), decimals)), + async () => { + const { GnosisRpcProvider } = await initializeProviders() + const contract = new ethers.Contract( + priceFeedContract, + ABI, + GnosisRpcProvider, + ) + return Number(ethers.formatUnits(await contract.latestAnswer(), decimals)) + }, { duration: 1000 * 60 * 60 * 24, // 24 hours key: `getChainlinkHandler-${priceFeedContract}`, @@ -32,7 +34,6 @@ function getChainlinkHandler(options: { }, ) } - const getXdaiUsd = getChainlinkHandler({ priceFeedContract: '0x678df3415fc31947dA4324eC63212874be5a82f8', decimals: 8, diff --git a/src/repositories/rmm.repository.ts b/src/repositories/rmm.repository.ts index 2c1a8e9..0a869e0 100644 --- a/src/repositories/rmm.repository.ts +++ b/src/repositories/rmm.repository.ts @@ -4,7 +4,7 @@ import _sumBy from 'lodash/sumBy' import { UsdcAddress, WxdaiAddress } from 'src/utils/blockchain/Stablecoin' import { useCacheWithLocalStorage } from 'src/utils/useCache' -import { GnosisRpcProvider } from './RpcProvider' +import { initializeProviders } from './RpcProvider' import { RmmPosition, getRmmPositions } from './subgraphs/queries/rmm.queries' export const RmmRepository = { @@ -65,13 +65,30 @@ const aUSDCAddress = '0xed56f76e9cbc6a64b821e9c016eafbd3db5436d1' const vUSDCAddress = '0x69c731ae5f5356a779f44c355abb685d84e5e9e6' const aXDAIAddress = '0x0ca4f5554dd9da6217d62d8df2816c82bba4157b' const vXDAIAddress = '0x9908801df7902675c3fedd6fea0294d18d5d5d34' -const aUSDCContract = new ethers.Contract(aUSDCAddress, ABI, GnosisRpcProvider) -const vUSDCContract = new ethers.Contract(vUSDCAddress, ABI, GnosisRpcProvider) -const aXDAIContract = new ethers.Contract(aXDAIAddress, ABI, GnosisRpcProvider) -const vXDAIContract = new ethers.Contract(vXDAIAddress, ABI, GnosisRpcProvider) const getBalanceOfStableRMM3 = useCacheWithLocalStorage( async (userAddress: string) => { + const { GnosisRpcProvider } = await initializeProviders() + const aUSDCContract = new ethers.Contract( + aUSDCAddress, + ABI, + GnosisRpcProvider, + ) + const vUSDCContract = new ethers.Contract( + vUSDCAddress, + ABI, + GnosisRpcProvider, + ) + const aXDAIContract = new ethers.Contract( + aXDAIAddress, + ABI, + GnosisRpcProvider, + ) + const vXDAIContract = new ethers.Contract( + vXDAIAddress, + ABI, + GnosisRpcProvider, + ) const [aUSDC, vUSDC, aXDAI, vXDAI] = await Promise.all([ aUSDCContract.balanceOf(userAddress), vUSDCContract.balanceOf(userAddress),