2022-09-14 20:05:29 +03:00
|
|
|
import { deepCopy } from '@ethersproject/properties'
|
2022-09-13 19:07:47 +03:00
|
|
|
// This is the only file which should instantiate new Providers.
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
|
|
|
import { StaticJsonRpcProvider } from '@ethersproject/providers'
|
2022-09-14 20:05:29 +03:00
|
|
|
import { isPlain } from '@reduxjs/toolkit'
|
2022-09-13 19:07:47 +03:00
|
|
|
|
|
|
|
import { SupportedChainId } from './chains'
|
|
|
|
import { RPC_URLS } from './networks'
|
|
|
|
|
|
|
|
class AppJsonRpcProvider extends StaticJsonRpcProvider {
|
2022-09-14 20:05:29 +03:00
|
|
|
private _blockCache = new Map<string, Promise<any>>()
|
|
|
|
get blockCache() {
|
|
|
|
// If the blockCache has not yet been initialized this block, do so by
|
|
|
|
// setting a listener to clear it on the next block.
|
|
|
|
if (!this._blockCache.size) {
|
|
|
|
this.once('block', () => this._blockCache.clear())
|
|
|
|
}
|
|
|
|
return this._blockCache
|
|
|
|
}
|
|
|
|
|
2022-09-13 19:07:47 +03:00
|
|
|
constructor(urls: string[]) {
|
|
|
|
super(urls[0])
|
|
|
|
}
|
2022-09-14 20:05:29 +03:00
|
|
|
|
|
|
|
send(method: string, params: Array<any>): Promise<any> {
|
|
|
|
// Only cache eth_call's.
|
|
|
|
if (method !== 'eth_call') return super.send(method, params)
|
|
|
|
|
|
|
|
// Only cache if params are serializable.
|
|
|
|
if (!isPlain(params)) return super.send(method, params)
|
|
|
|
|
|
|
|
const key = `call:${JSON.stringify(params)}`
|
|
|
|
const cached = this.blockCache.get(key)
|
|
|
|
if (cached) {
|
|
|
|
this.emit('debug', {
|
|
|
|
action: 'request',
|
|
|
|
request: deepCopy({ method, params, id: 'cache' }),
|
|
|
|
provider: this,
|
|
|
|
})
|
|
|
|
return cached
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = super.send(method, params)
|
|
|
|
this.blockCache.set(key, result)
|
|
|
|
return result
|
|
|
|
}
|
2022-09-13 19:07:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* These are the only JsonRpcProviders used directly by the interface.
|
|
|
|
*/
|
|
|
|
export const RPC_PROVIDERS: { [key in SupportedChainId]: StaticJsonRpcProvider } = {
|
|
|
|
[SupportedChainId.MAINNET]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.MAINNET]),
|
|
|
|
[SupportedChainId.RINKEBY]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.RINKEBY]),
|
|
|
|
[SupportedChainId.ROPSTEN]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.ROPSTEN]),
|
|
|
|
[SupportedChainId.GOERLI]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.GOERLI]),
|
|
|
|
[SupportedChainId.KOVAN]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.KOVAN]),
|
|
|
|
[SupportedChainId.OPTIMISM]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.OPTIMISM]),
|
2022-09-26 21:42:47 +03:00
|
|
|
[SupportedChainId.OPTIMISM_GOERLI]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.OPTIMISM_GOERLI]),
|
2022-09-13 19:07:47 +03:00
|
|
|
[SupportedChainId.ARBITRUM_ONE]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.ARBITRUM_ONE]),
|
|
|
|
[SupportedChainId.ARBITRUM_RINKEBY]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.ARBITRUM_RINKEBY]),
|
|
|
|
[SupportedChainId.POLYGON]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.POLYGON]),
|
|
|
|
[SupportedChainId.POLYGON_MUMBAI]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.POLYGON_MUMBAI]),
|
|
|
|
[SupportedChainId.CELO]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.CELO]),
|
|
|
|
[SupportedChainId.CELO_ALFAJORES]: new AppJsonRpcProvider(RPC_URLS[SupportedChainId.CELO_ALFAJORES]),
|
|
|
|
}
|