Skip to content

Commit

Permalink
Implement rpc-eth-client for Ethereum compatible JSON-RPC endpoint (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
nikugogoi authored Aug 8, 2023
1 parent 47d4b66 commit c06330d
Show file tree
Hide file tree
Showing 22 changed files with 889 additions and 53 deletions.
3 changes: 2 additions & 1 deletion packages/cli/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { JsonRpcProvider } from '@ethersproject/providers';
import {
Config,
getConfig,
initClients,
JobQueue,
DatabaseInterface,
IndexerInterface,
Expand All @@ -21,6 +20,8 @@ import {
GraphWatcherInterface
} from '@cerc-io/util';

import { initClients } from './utils/index';

export class BaseCmd {
_config?: Config;
_clients?: Clients;
Expand Down
46 changes: 46 additions & 0 deletions packages/cli/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
};
};
3 changes: 0 additions & 3 deletions packages/ipld-eth-client/src/eth-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@ interface Vars {
}

export class EthClient {
_config: Config;
_graphqlClient: GraphQLClient;
_cache: Cache | undefined;

constructor (config: Config) {
this._config = config;

const { gqlEndpoint, gqlSubscriptionEndpoint, cache } = config;

assert(gqlEndpoint, 'Missing gql endpoint');
Expand Down
2 changes: 1 addition & 1 deletion packages/ipld-eth-client/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const getMappingSlot = (mappingSlot: string, key: string): string => {

export const getStorageLeafKey = (slot: string): string => ethers.utils.keccak256(slot);

export const topictoAddress = (topic: string): string => {
export const topicToAddress = (topic: string): string => {
return ethers.utils.getAddress(
ethers.utils.hexZeroPad(
ethers.utils.hexStripZeros(topic), 20
Expand Down
5 changes: 5 additions & 0 deletions packages/rpc-eth-client/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Don't lint node_modules.
node_modules

# Don't lint build output.
dist
32 changes: 32 additions & 0 deletions packages/rpc-eth-client/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"semistandard",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"indent": ["error", 2, { "SwitchCase": 1 }],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": [
"warn",
{
"allowArgumentsExplicitlyTypedAsAny": true
}
],
"@typescript-eslint/no-unused-vars": [
"error",
{ "ignoreRestSiblings": true }
]
}
}
5 changes: 5 additions & 0 deletions packages/rpc-eth-client/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/src/
index.ts
tsconfig.json
.eslintrc.json
.eslintignore
5 changes: 5 additions & 0 deletions packages/rpc-eth-client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//
// Copyright 2021 Vulcanize, Inc.
//

export * from './src/eth-client';
44 changes: 44 additions & 0 deletions packages/rpc-eth-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@cerc-io/rpc-eth-client",
"version": "0.2.50",
"description": "RPC ETH Client",
"main": "dist/index.js",
"scripts": {
"lint": "eslint .",
"test:rpc": "mocha -r ts-node/register src/**/*.test.ts",
"build": "tsc"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cerc-io/watcher-ts.git"
},
"author": "",
"license": "AGPL-3.0",
"bugs": {
"url": "https://github.com/cerc-io/watcher-ts/issues"
},
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
"dependencies": {
"@cerc-io/cache": "^0.2.50",
"@cerc-io/util": "^0.2.50",
"@cerc-io/ipld-eth-client": "^0.2.50",
"cross-fetch": "^3.1.4",
"debug": "^4.3.1",
"ethers": "^5.4.4",
"left-pad": "^1.3.0",
"ws": "^8.11.0",
"zen-observable-ts": "^1.1.0"
},
"devDependencies": {
"@types/ws": "^8.5.3",
"@typescript-eslint/eslint-plugin": "^5.47.1",
"@typescript-eslint/parser": "^5.47.1",
"eslint": "^8.35.0",
"eslint-config-semistandard": "^15.0.1",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-standard": "^5.0.0"
}
}
Loading

0 comments on commit c06330d

Please sign in to comment.