Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ensure network #220

Merged
merged 1 commit into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/core/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions src/core/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ export function delay(ms: number) {
export function getRandom(list: Array<any>) {
return list[Math.floor(Math.random() * list.length)]
}

export async function sleep(ms: number): Promise<any> {
return await new Promise((resolve) => setTimeout(resolve, ms))
}
52 changes: 44 additions & 8 deletions src/core/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down Expand Up @@ -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<void> {
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<Chain | undefined>
): Promise<void> {
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,
Expand All @@ -124,17 +155,22 @@ export async function enforceNetwork(
): Promise<bigint> {
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
Expand Down
Loading