question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow to add custom networks with any ChainId

See original GitHub issue

Continuation of #47 Related to #132

Currently it is impossible to use a new network without adding PR to useDApp. We would like to change it by adding list of all possible networks to config, that can be modified. To do so I propose to:

Add new variable to Config - networks, i.e.

export const DEFAULT_CONFIG: FullConfig = {
  ...
  supportedChains: DEFAULT_SUPPORTED_CHAINS.map((network) => network.chainId),
  networks: DEFAULT_SUPPORTED_CHAINS

so that

  • supportedChains are list of chains ids that useDApp will connect without throwing error
  • networks are Chain[] storing list of all known Chain and their configurations

User can dynamically edit config by using:

const config = useConfig()
const updateConfig = useUpdateConfig()
updateConfig({ networks: [...config, {...}])

Could be further develop into something with nicer syntax, i.e.

const {config, addNetwork, removeNetwork, ...} = useConfigReducer()
addNetwork({...})

Replace all usages of constants to use useConfig, i.e.

DEFAULT_SUPPORTED_CHAINS -> const {networks} = useConfig()

Replace all usage in functions like:

getChainById(chainId: ChainId)
getExplorerAddressLink(address: string, chainId: ChainId)
getExplorerTransactionLink(transactionHash: string, chainId: ChainId)
getChainName(chainId: ChainId)
isTestChain(chainId: ChainId)
isLocalChain(chainId: ChainId)
etc...

Change ChainId type, i.e.

export type ChainId = KnownChainId | number
export enum KnownChainId {
  ...
}

or simply to number

Add documentation

Last but not least we would like to have a guide on how to add support for a new network:

  • to your project
  • issue a PR

Notes

This will be breaking change and will require to advance version accordingly.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:18 (11 by maintainers)

github_iconTop GitHub Comments

2reactions
sz-piotrcommented, Nov 20, 2021

The type enum | number means that chain ids outside the built-in range feel like a second class citizen. Instead I propose to use nominal typing as described here: https://basarat.gitbook.io/typescript/main-1/nominaltyping#using-interfaces. As referenced by the linked article the approach was also used internally in the typescript compiler.

The idea is to create an “impossible” type:

interface ChainId extends Number {
    _chainIdBrand: number
}

Then have a “constructor” of the same name that casts numbers to this type:

function ChainId (value: number) {
    if (!Number.isInteger(value) || value < 0) {
        throw new TypeError('ChainId must be a non-negative integer')
    }
    // we cast to unknown first as a direct number -> ChainId cast results in an error
    return value as unknown as ChainId
}

Creating the basic chainId constants is now very simple and is the same for in-house and third-party code:

const MAINNET_CHAIN_ID = ChainId(1)
const ROPSTEN_CHAIN_ID = ChainId(42)

Having this new type means that we gain huge type safety benefits with clear error messages:

// Type 'ChainId' is not assignable to type 'number'. (2322)
const myNumber: number = ChainId(1)
// Type 'number' is not assignable to type 'ChainId'. (2322)
const myChainId: ChainId = 1
// Operator '+' cannot be applied to types 'ChainId' and 'ChainId'. (2365)
const sum = ChainId(1) + ChainId(2)

The only downside is that in internal code where numbers are actually required a simple cast is needed

const chainId = ChainId(1)
const justANumber: number = +chainId
2reactions
tt-marekcommented, Nov 20, 2021

@gasolin Good points

I agree that dynamically editing networks indeed is not a strong use case My thinking was that we use it on application load to set up networks - it does feel unnecessary complex

So if I am getting right your idea, configuration would be something like this:

const config: Config = {
    networks: [Mainnet]
    readOnlyUrls: {
      [Mainnet.chainId]: 'https://mainnet.infura.io/v3/62687d1a985d4508b2b7a24827551934',
    },
  }

Correct?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Allow to add custom networks with any ChainId #408 - GitHub
Currently it is impossible to use a new network without adding PR to useDApp. We would like to change it by adding list...
Read more >
Adding Custom Network as Ganache ChainID Issue
I am trying to add Ganache as Custom network in Metamask but getting error on chainID. I have use 1337 as chain id...
Read more >
How to add a custom network RPC - MetaMask Support
Adding networks manually. MetaMask can access many more networks than just Ethereum mainnet: you can add any EVM-compatible network. The ...
Read more >
Metamask — How to add custom network (Binance Smart ...
Go the “Networks” then click on “Add Network”. You will be asked to fill these fields : Network name; New RPC URL; Chain...
Read more >
How to Add Custom Networks To MetaMask
It allows users to store Ether and other ERC-20 tokens while also allowing them to send funds to any Ethereum address. Because many...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found