Implement rpc-eth-client for Ethereum compatible JSON-RPC endpoint (#398)

* Implement rpc-eth-client with getStorageAt method

* Add test for comparing RPC and GQL eth-client getStorageAt method

* Add getBlockWithTransactions and getBlocks method

* Implement getFullBlocks with RLP encoded data

* Implement getFullTransaction method with raw tx

* Implement getBlockByHash and getLogs methods

* Add flag and interface to switch between RPC and GQL eth clients

* Fix getBlocks to return empty array when block not present

* Return empty array in getBlocks for missing block and use blockNumber in getLogs

* Fix getRawTransaction method for zero signature.v value

* Remove duplicate util from rpc-eth-client
This commit is contained in:
2023-08-08 18:48:55 +05:30
committed by GitHub
parent 47d4b667f4
commit c06330dd06
22 changed files with 889 additions and 53 deletions
+2 -1
View File
@@ -11,7 +11,6 @@ import { JsonRpcProvider } from '@ethersproject/providers';
import {
Config,
getConfig,
initClients,
JobQueue,
DatabaseInterface,
IndexerInterface,
@@ -21,6 +20,8 @@ import {
GraphWatcherInterface
} from '@cerc-io/util';
import { initClients } from './utils/index';
export class BaseCmd {
_config?: Config;
_clients?: Clients;
+46
View File
@@ -4,9 +4,15 @@
import fs from 'fs';
import path from 'path';
import assert from 'assert';
import { providers } from 'ethers';
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
import { PeerIdObj } from '@cerc-io/peer';
import { Config, EthClient, getCustomProvider } from '@cerc-io/util';
import { getCache } from '@cerc-io/cache';
import { EthClient as GqlEthClient } from '@cerc-io/ipld-eth-client';
import { EthClient as RpcEthClient } from '@cerc-io/rpc-eth-client';
export function readPeerId (filePath: string): PeerIdObj {
const peerIdFilePath = path.resolve(filePath);
@@ -15,3 +21,43 @@ export function readPeerId (filePath: string): PeerIdObj {
const peerIdJson = fs.readFileSync(peerIdFilePath, 'utf-8');
return JSON.parse(peerIdJson);
}
export const initClients = async (config: Config): Promise<{
ethClient: EthClient,
ethProvider: providers.JsonRpcProvider
}> => {
const { database: dbConfig, upstream: upstreamConfig, server: serverConfig } = config;
assert(serverConfig, 'Missing server config');
assert(dbConfig, 'Missing database config');
assert(upstreamConfig, 'Missing upstream config');
const { ethServer: { gqlApiEndpoint, rpcProviderEndpoint, rpcClient = false }, cache: cacheConfig } = upstreamConfig;
assert(rpcProviderEndpoint, 'Missing upstream ethServer.rpcProviderEndpoint');
const cache = await getCache(cacheConfig);
let ethClient: EthClient;
if (rpcClient) {
ethClient = new RpcEthClient({
rpcEndpoint: rpcProviderEndpoint,
cache
});
} else {
assert(gqlApiEndpoint, 'Missing upstream ethServer.gqlApiEndpoint');
ethClient = new GqlEthClient({
gqlEndpoint: gqlApiEndpoint,
cache
});
}
const ethProvider = getCustomProvider(rpcProviderEndpoint);
return {
ethClient,
ethProvider
};
};