Skip to content

Commit

Permalink
fix: verify provider endpoint if not browserprovider (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastiendan committed Jan 19, 2024
1 parent 0884437 commit c3db516
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 60 deletions.
1 change: 1 addition & 0 deletions packages/frontend/cypress/e2e/full/step1.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('Multistep form step-1 with Topos', () => {
cy.get('#sendingSubnet').click()
cy.get('.ant-select-item-option-content').contains('Topos').click()
cy.get('#nextButton').click()
cy.wait(500)
})

it('should have token field enabled and others disabled', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/steps/Step0.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const Step0 = ({ onFinish }: StepProps) => {

const { status } = useEthers({
subnet: sendingSubnet,
viaMetaMask: sendingSubnet !== undefined,
viaMetaMask: true,
})

const nextStep = useCallback(() => {
Expand Down
39 changes: 32 additions & 7 deletions packages/frontend/src/hooks/useEthers.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { BrowserProvider, getDefaultProvider } from 'ethers'
import { useEffect, useMemo } from 'react'
import { useContext, useEffect, useMemo } from 'react'
import { useMetaMask } from 'metamask-react'

import { Subnet } from '../types'
import { ErrorsContext } from '../contexts/errors'

interface Args {
subnet?: Subnet
viaMetaMask?: boolean
}

export default function useEthers({ subnet, viaMetaMask }: Args = {}) {
const { setErrors } = useContext(ErrorsContext)
const { account, addChain, connect, ethereum, status, switchChain } =
useMetaMask()

Expand All @@ -18,16 +20,39 @@ export default function useEthers({ subnet, viaMetaMask }: Args = {}) {
return new BrowserProvider(ethereum)
}

if (!subnet) {
const toposSubnetEndpointWs = import.meta.env
.VITE_TOPOS_SUBNET_ENDPOINT_WS
return getDefaultProvider(toposSubnetEndpointWs)
}
const endpoint = subnet
? subnet.endpointWs || subnet.endpointHttp
: import.meta.env.VITE_TOPOS_SUBNET_ENDPOINT_WS

const endpoint = subnet.endpointWs || subnet.endpointHttp
return getDefaultProvider(endpoint)
}, [subnet, viaMetaMask, ethereum])

useEffect(
function verifyProviderReadiness() {
const timeoutId = window.setTimeout(() => {
if (!viaMetaMask && !(provider as any).ready) {
setErrors((e) => [
...e,
{
message: `Could not reach provider's endpoint${
' (' +
(subnet
? subnet.endpointWs || subnet.endpointHttp
: import.meta.env.VITE_TOPOS_SUBNET_ENDPOINT_WS) +
')'
}`,
},
])
}
}, 3000)

return function clearTimeout() {
window.clearTimeout(timeoutId)
}
},
[provider]
)

useEffect(
function switchNetworkAndConnect() {
const _ = async () => {
Expand Down
109 changes: 57 additions & 52 deletions packages/frontend/src/hooks/useRegisteredSubnets.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { SubnetRegistrator__factory } from '@topos-protocol/topos-smart-contracts/typechain-types'
import {} from 'ethers'
import { useCallback, useContext, useEffect, useState } from 'react'
import { useContext, useEffect, useState } from 'react'

import { ErrorsContext } from '../contexts/errors'
import { Subnet, SubnetWithId } from '../types'
import { SubnetWithId } from '../types'
import useEthers from './useEthers'

export default function useRegisteredSubnets() {
Expand All @@ -12,78 +12,83 @@ export default function useRegisteredSubnets() {
const [loading, setLoading] = useState(false)
const [registeredSubnets, setRegisteredSubnets] = useState<SubnetWithId[]>()

const contract = SubnetRegistrator__factory.connect(
import.meta.env.VITE_SUBNET_REGISTRATOR_CONTRACT_ADDRESS,
provider
)

const getRegisteredSubnets = useCallback(async () => {
setLoading(true)
useEffect(
function getRegisteredSubnets() {
async function _() {
setLoading(true)

const registeredSubnetsCount = await contract
.getSubnetCount()
.then((count) => Number(count))
.catch((error: any) => {
console.error(error)
setErrors((e) => [
...e,
{ message: `Error when fetching the count of registered subnets.` },
])
})
const subnetRegistrator = SubnetRegistrator__factory.connect(
import.meta.env.VITE_SUBNET_REGISTRATOR_CONTRACT_ADDRESS,
provider
)

if (registeredSubnetsCount !== undefined) {
const promises = []
let i = 0
while (i < registeredSubnetsCount) {
const subnetId = await contract
.getSubnetIdAtIndex(i)
const registeredSubnetsCount = await subnetRegistrator
.getSubnetCount()
.then((count) => Number(count))
.catch((error: any) => {
console.error(error)
setErrors((e) => [
...e,
{
message: `Error fetching the id of the registered subnet at index ${i}.`,
message: `Error when fetching the count of registered subnets.`,
},
])
})

if (subnetId !== undefined) {
promises.push(
contract
.subnets(subnetId)
.then((subnet) => ({
...(subnet as any).toObject(), // toObject method of ES6 Proxy
id: subnetId,
}))
.catch((error: Error) => {
if (registeredSubnetsCount !== undefined) {
const promises = []
let i = 0
while (i < registeredSubnetsCount) {
const subnetId = await subnetRegistrator
.getSubnetIdAtIndex(i)
.catch((error: any) => {
console.error(error)
setErrors((e) => [
...e,
{
message: `Error fetching registered subnet with id ${subnetId}.`,
message: `Error fetching the id of the registered subnet at index ${i}.`,
},
])
})

if (subnetId !== undefined) {
promises.push(
subnetRegistrator
.subnets(subnetId)
.then((subnet) => ({
...(subnet as any).toObject(), // toObject method of ES6 Proxy
id: subnetId,
}))
.catch((error: Error) => {
console.error(error)
setErrors((e) => [
...e,
{
message: `Error fetching registered subnet with id ${subnetId}.`,
},
])
})
)
}
i++
}

const subnets = await Promise.allSettled(promises).then((values) =>
values
.filter((v) => v.status === 'fulfilled')
.map((v) => (v.status === 'fulfilled' ? v.value : undefined))
.filter((v) => v && v.name === 'Incal')
)
setRegisteredSubnets(subnets as SubnetWithId[])
}
i++
}

const subnets = await Promise.allSettled(promises).then((values) =>
values
.filter((v) => v.status === 'fulfilled')
.map((v) => (v.status === 'fulfilled' ? v.value : undefined))
.filter((v) => v && v.name === 'Incal')
)
setRegisteredSubnets(subnets as SubnetWithId[])
}

setLoading(false)
}, [])
setLoading(false)
}

useEffect(function init() {
getRegisteredSubnets()
}, [])
_()
},
[provider]
)

return { loading, registeredSubnets }
}

0 comments on commit c3db516

Please sign in to comment.