diff --git a/skale-network b/skale-network index 676c221..261d890 160000 --- a/skale-network +++ b/skale-network @@ -1 +1 @@ -Subproject commit 676c2213b917f48a759c61ebe34be3520ece239f +Subproject commit 261d890cb564312cc0d1fae4dc500bd7d2b2759d diff --git a/src/core/constants.ts b/src/core/constants.ts index cd1bf8d..ec1e8ac 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -114,3 +114,6 @@ export const SFUEL_RESERVE_AMOUNT = 0.02 export const SUCCESS_EMOJIS = ['🎉', '👌', '✅', '🙌', '🎊'] export const GRAY_BG = 'rgb(136 135 135 / 15%)' + +export const DEFAULT_SLEEP = 6000 +export const DEFAULT_ITERATIONS = 60 diff --git a/src/core/helper.ts b/src/core/helper.ts index eedd40b..6ace6f4 100644 --- a/src/core/helper.ts +++ b/src/core/helper.ts @@ -52,3 +52,7 @@ export function delay(ms: number) { export function getRandom(list: Array) { return list[Math.floor(Math.random() * list.length)] } + +export async function sleep(ms: number): Promise { + return await new Promise((resolve) => setTimeout(resolve, ms)) +} diff --git a/src/core/network.ts b/src/core/network.ts index 35382ee..2df301b 100644 --- a/src/core/network.ts +++ b/src/core/network.ts @@ -22,17 +22,18 @@ */ import debug from 'debug' -import { MainnetChain, SChain } from '@skalenetwork/ima-js' +import { MainnetChain, SChain, TimeoutException } from '@skalenetwork/ima-js' import { JsonRpcProvider, Provider } from 'ethers' import { WalletClient } from 'viem' import { Chain } from '@wagmi/core' import proxyEndpoints from '../metadata/proxy.json' -import { MAINNET_CHAIN_NAME } from './constants' +import { MAINNET_CHAIN_NAME, DEFAULT_ITERATIONS, DEFAULT_SLEEP } from './constants' import { IMA_ADDRESSES, IMA_ABIS } from './contracts' import { SkaleNetwork } from './interfaces' import { constructWagmiChain } from './wagmi_network' +import { sleep } from './helper' export { proxyEndpoints as PROXY_ENDPOINTS } @@ -115,6 +116,36 @@ export function initSChain(network: SkaleNetwork, chainName: string): SChain { return new SChain(provider, IMA_ABIS.schain) } +async function waitForNetworkChange( + walletClient: WalletClient, + initialChainId: number | bigint, + requiredChainId: number | bigint, + sleepInterval: number = DEFAULT_SLEEP, + iterations: number = DEFAULT_ITERATIONS +): Promise { + const logData = `${initialChainId} -> ${requiredChainId}, sleep ${sleepInterval}ms` + for (let i = 1; i <= iterations; i++) { + const chainId = await walletClient.getChainId() + if (BigInt(chainId) === BigInt(requiredChainId)) { + return + } + log(`🔎 ${i}/${iterations} Waiting for network change - ${logData}`) + await sleep(sleepInterval) + } + throw new TimeoutException('waitForNetworkChange timeout - ' + logData) +} + +async function _networkSwitch( + chainId: number | bigint, + currentChainId: number | bigint, + switchNetwork: (chainId: number | bigint) => Promise +): Promise { + const chain = await switchNetwork(Number(chainId)) + if (!chain) { + throw new Error(`Failed to switch from ${currentChainId} to ${chainId} `) + } +} + export async function enforceNetwork( provider: Provider, walletClient: WalletClient, @@ -124,17 +155,22 @@ export async function enforceNetwork( ): Promise { const currentChainId = walletClient.chain.id const { chainId } = await provider.getNetwork() - log(`Current chainId: ${currentChainId}, required chainId: ${chainId} `) + log( + `Current chainId: ${currentChainId}, required chainId: ${chainId}, required network: ${chainName} ` + ) if (currentChainId !== Number(chainId)) { log(`Switching network to ${chainId}...`) if (chainId !== 1n && chainId !== 5n) { await walletClient.addChain({ chain: constructWagmiChain(skaleNetwork, chainName) }) - } else { - const chain = await switchNetwork(Number(chainId)) - if (!chain) { - throw new Error(`Failed to switch from ${currentChainId} to ${chainId} `) - } } + try { + // tmp fix for coinbase wallet + _networkSwitch(chainId, currentChainId, switchNetwork) + } catch (e) { + await sleep(DEFAULT_SLEEP) + _networkSwitch(chainId, currentChainId, switchNetwork) + } + await waitForNetworkChange(walletClient, currentChainId, chainId) log(`Network switched to ${chainId}...`) } return chainId