Skip to content

Commit

Permalink
perf(network connector): use an inline network connector until improv…
Browse files Browse the repository at this point in the history
…ed connector is pushed upstream
  • Loading branch information
moodysalem committed May 30, 2020
1 parent 83554f4 commit 73d3df0
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 3,097 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"@web3-react/core": "^6.0.9",
"@web3-react/fortmatic-connector": "^6.0.9",
"@web3-react/injected-connector": "^6.0.7",
"@web3-react/network-connector": "^6.0.9",
"@web3-react/portis-connector": "^6.0.9",
"@web3-react/walletconnect-connector": "^6.0.9",
"@web3-react/walletlink-connector": "^6.0.9",
Expand All @@ -50,7 +49,6 @@
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^4.0.0",
"history": "^4.9.0",
"i18next": "^15.0.9",
"i18next-browser-languagedetector": "^3.0.1",
"i18next-xhr-backend": "^2.0.1",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Popups/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function PopupItem({ content, popKey }: { content: PopupContent; popKey: string
}
}

export default function App() {
export default function Popups() {
const theme = useContext(ThemeContext)
// get all popups
const activePopups = useActivePopups()
Expand Down
14 changes: 0 additions & 14 deletions src/components/Web3ReactManager/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,6 @@ export default function Web3ReactManager({ children }) {
}
}, [triedEager, networkActive, networkError, activateNetwork, active])

// 'pause' the network connector if we're ever connected to an account and it's active
useEffect(() => {
if (active && networkActive) {
network.pause()
}
}, [active, networkActive])

// 'resume' the network connector if we're ever not connected to an account and it's active
useEffect(() => {
if (!active && networkActive) {
network.resume()
}
}, [active, networkActive])

// when there's no account connected, react to logins (broadly speaking) on the injected provider, if it exists
useInactiveListener(!triedEager)

Expand Down
15 changes: 0 additions & 15 deletions src/connectors/Network.ts

This file was deleted.

105 changes: 105 additions & 0 deletions src/connectors/NetworkConnector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { ConnectorUpdate } from '@web3-react/types'
import { AbstractConnector } from '@web3-react/abstract-connector'
import invariant from 'tiny-invariant'

interface NetworkConnectorArguments {
urls: { [chainId: number]: string }
defaultChainId?: number
}

// taken from ethers.js, compatible interface with web3 provider
type AsyncSendable = {
isMetaMask?: boolean
host?: string
path?: string
sendAsync?: (request: any, callback: (error: any, response: any) => void) => void
send?: (request: any, callback: (error: any, response: any) => void) => void
}

class RequestError extends Error {
constructor(message: string, public code: number, public data?: unknown) {
super(message)
}
}

class MiniRpcProvider implements AsyncSendable {
public readonly isMetaMask: false = false
public readonly chainId: number
public readonly url: string
public readonly host: string
public readonly path: string

constructor(chainId: number, url: string) {
this.chainId = chainId
this.url = url
const parsed = new URL(url)
this.host = parsed.host
this.path = parsed.pathname
}

public readonly sendAsync = (
request: { jsonrpc: '2.0'; id: number | string | null; method: string; params?: unknown[] | object },
callback: (error: any, response: any) => void
): void => {
this.request(request.method, request.params)
.then(result => callback(null, { jsonrpc: '2.0', id: request.id, result }))
.catch(error => callback(error, null))
}

public readonly request = async (method: string, params?: unknown[] | object): Promise<unknown> => {
const response = await fetch(this.url, {
method: 'POST',
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method,
params
})
})
if (!response.ok) throw new RequestError(`${response.status}: ${response.statusText}`, -32000)
const body = await response.json()
if ('error' in body) {
throw new RequestError(body?.error?.message, body?.error?.code, body?.error?.data)
} else if ('result' in body) {
return body.result
} else {
throw new RequestError(`Received unexpected JSON-RPC response to ${method} request.`, -32000, body)
}
}
}

export class NetworkConnector extends AbstractConnector {
private readonly providers: { [chainId: number]: MiniRpcProvider }
private currentChainId: number

constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })

this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
return accumulator
}, {})
}

public async activate(): Promise<ConnectorUpdate> {
return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
}

public async getProvider(): Promise<MiniRpcProvider> {
return this.providers[this.currentChainId]
}

public async getChainId(): Promise<number> {
return this.currentChainId
}

public async getAccount(): Promise<null> {
return null
}

public deactivate() {
return
}
}
5 changes: 2 additions & 3 deletions src/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { WalletLinkConnector } from '@web3-react/walletlink-connector'
import { PortisConnector } from '@web3-react/portis-connector'

import { NetworkConnector } from './Network'
import { FortmaticConnector } from './Fortmatic'
import { NetworkConnector } from './NetworkConnector'

const POLLING_INTERVAL = 10000
const NETWORK_URL = process.env.REACT_APP_NETWORK_URL
Expand All @@ -16,8 +16,7 @@ if (typeof NETWORK_URL === 'undefined') {
}

export const network = new NetworkConnector({
urls: { [Number(process.env.REACT_APP_CHAIN_ID)]: NETWORK_URL },
pollingInterval: POLLING_INTERVAL * 3
urls: { [Number(process.env.REACT_APP_CHAIN_ID)]: NETWORK_URL }
})

export const injected = new InjectedConnector({
Expand Down
Loading

0 comments on commit 73d3df0

Please sign in to comment.