Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Allow optional chainId or short network name into getNetwork #122

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions src/providers/BaseProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { buildRPCPostBody, post } from '../classes/utils/fetchers';
import { hexToDecimal } from '../classes/utils/hex-to-decimal';
import { TinyBig, tinyBig } from '../shared/tiny-big/tiny-big';
import { BlockResponse, BlockTag, RPCBlock } from '../types/Block.types';
import { Network } from '../types/Network.types';
import { Network, Networkish } from '../types/Network.types';
import {
RPCTransaction,
RPCTransactionReceipt,
Expand Down Expand Up @@ -39,15 +39,34 @@ export abstract class BaseProvider {
}

/**
* Returns the network this provider is connected to
* Returns the network this provider is connected to, or information about the network provided
*
* * Similar to [`ethers.provider.getNetwork`](https://docs.ethers.io/v5/api/providers/provider/#Provider-getNetwork), accepts short names of networks instead of long names
*
* @param network the network, either chainId or short name, to get information about
*
* @returns information about the network either specified, or the network the user is currently connected to
*/
public async getNetwork(): Promise<Network> {
const hexChainId = (await this.post(
buildRPCPostBody('eth_chainId', []),
)) as string;
public async getNetwork(network?: Networkish): Promise<Network> {
let chainId, info;
if (network) {
if (typeof network === 'number') {
chainId = network;
info = (chainsInfo as any)[network];
} else if (typeof network === 'string') {
chainId = Object.keys(chainsInfo).find(
(key) => (chainsInfo as any)[key][0] === network,
);
info = (chainsInfo as any)[Number(chainId)];
}
} else {
const hexChainId = (await this.post(
buildRPCPostBody('eth_chainId', []),
)) as string;

const chainId = hexToDecimal(hexChainId);
const info = (chainsInfo as any)[chainId];
chainId = hexToDecimal(hexChainId);
info = (chainsInfo as any)[chainId];
}
return {
chainId: Number(chainId),
name: info[0] || 'unknown',
Expand Down
30 changes: 25 additions & 5 deletions src/providers/test/json-rpc-provider/get-network.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { ethers } from 'ethers';
import { JsonRpcProvider } from '../../../index';
import { fakeUrls, rpcUrls } from '../rpc-urls';
import { Networkish } from './../../../types/Network.types';

const xdaiRPCUrl = rpcUrls.gno;
const bscRPCUrl = rpcUrls.bnb;

describe('provider.getNetwork happy path', () => {
async function testNetwork(rpcUrl: string) {
async function testNetwork(rpcUrl: string, network?: Networkish) {
const essentialEth = new JsonRpcProvider(rpcUrl);
const ethersProvider = new ethers.providers.StaticJsonRpcProvider(rpcUrl);
const [eeNetwork, ethersNetwork] = await Promise.all([
essentialEth.getNetwork(),
ethersProvider.getNetwork(),
]);
let eeNetwork, ethersNetwork;
if (network) {
[eeNetwork, ethersNetwork] = await Promise.all([
essentialEth.getNetwork(network),
ethers.providers.getNetwork(network),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dawsbot you'll notice on here, comparing to the test below, that ethers actually has two separate getNetwork functions: one called on a provider to get the network that provider is using, and another more util-like function to get the information about a specified network. Given this, I'm thinking that it'd be better for us to split them up as well. If that plan makes sense, it seems like the easiest approach is to add this as a new util fn, instead of how ethers exports their providers package

Thoughts?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, yes yes, this is a great point.

Soon this package too should split into utils and provider. I will do this with #105, and then this PR can continue. Let's put this task to a "blocked" column for now on the task board (I've just made a new column for that)

]);
} else {
[eeNetwork, ethersNetwork] = await Promise.all([
essentialEth.getNetwork(),
ethersProvider.getNetwork(),
]);
}

expect(eeNetwork.chainId).toBe(ethersNetwork.chainId);
expect(eeNetwork.ensAddress).toBe(ethersNetwork.ensAddress);
Expand All @@ -27,6 +36,17 @@ describe('provider.getNetwork happy path', () => {
it('bsc should match ethers', async () => {
await testNetwork(bscRPCUrl);
});
it('should match ethers for a specified chain ID number', () => {
const chainIds = [1, 6, 137];
chainIds.forEach((id) => {
})
});
it('should match ethers for a specified chain name', () => {
const chainNames = [];
});
it('should match ethers for a specified network', () => {
const networkObjects = [];
});
});

describe('provider.getNetwork error handling', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/types/Network.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export interface Network {
ensAddress: string | null; // ensAddress: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
name: string;
}

export type Networkish = Network | string | number;