-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf(network connector): use an inline network connector until improv…
…ed connector is pushed upstream
- Loading branch information
1 parent
83554f4
commit 73d3df0
Showing
7 changed files
with
221 additions
and
3,097 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.