[SNIP] Wallet Multi Chain Support

Simple Summary

An interface for wallet to manage multiple chains.

Inspired by EIP-3085 and EIP-3326.

Abstract

JavaScript wallet providers may implements wallet_addStarknetChain and wallet_switchStarknetChain RPC methods. This allow dapps to add a new chain and switch to another known chain.

Motivation

Dapps can require to interact to a specific Starknet chain in order to work. wallet_switchStarknetChain enables dapps to request that the wallet switches its active chain to whichever one is required by the dapp.

Wallets having a limited list of pre-defined chains, dapps may require to use another chain. wallet_addStarknetChain enables dapps to request that the wallet add a new chain.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”,
and “OPTIONAL” in this document are to be interpreted as described in RFC-2119.

RPC methods

wallet_addStarknetChain

The method accepts a single object parameter, with a chainId and some chain metadata. The method returns null if the chain was added to the wallet, and an error otherwise.

The wallet MAY reject the request for any reason.

Adding a new chain does not necessarily mean that the wallet will automatically switch to it.

Parameters

wallet_addStarknetChain accepts a single object parameter, specified by the following TypeScript interface:

interface AddStarknetChainParameters {
  id: string // What the purpose
  chainId: string // A 0x-prefixed hexadecimal string
  chainName: string
  rpcUrl: string
  accountImplementation?: string

  nativeCurrency?: {
    name: string
    symbol: string // 2-6 characters long
    decimals: 18
  }
}

wallet_switchStarknetChain

The method accepts a single object parameter with a chainId field. The method returns null if the wallet switched its active chain, and an error otherwise.

The method presupposes that the wallet has a concept of a single “active chain”. The active chain is defined as the chain that the wallet is forwarding RPC requests to.

Parameters

wallet_switchStarknetChain accepts a single object parameter, specified by the following TypeScript interface:

interface SwitchStarknetChainParameters {
  chainId: string;
}

If a field does not meet the requirements of this specification, the wallet MUST reject the request.

  • chainId
    • MUST specify the integer ID of the chain as a hexadecimal string.
    • The chain ID MUST be known to the wallet.
    • The wallet MUST be able to switch to the specified chain and service RPC requests to it.
  • The method MUST return null if the request was successful, and an error otherwise.
  • If the wallet does not have a concept of an active chain, the wallet MUST reject the request.

Events

chainChanged

Based on EIP-1193

The Provider emits chainChanged when connecting to a new chain.

Provider.on('chainChanged', listener: (chainId: string) => void): Provider;
  • chainId MUST be presented as a hexadecimal string.
23 Likes

Some comments regarding this proposal:

  • I saw ArgentX using baseUrl instead of rpcUrl, I think it’s better to match already existing API (on Ethereum wallets)
  • rpcUrl is a single url, not a list of url like what is defined by EIP-3085
    I looked at Metamask source code and it simply select the first valid url of the list and do nothing from the others, that’s why I don’t see any value to allow a list, we should directly send a valid url
  • to stay consistent with existing EIP, chainChanged event return the chainId, but we could choose to return an object containing the id, the chainId and the chainName (or even more if needed)
11 Likes

Agree.

rpcUrls was added to support multiple protocols (here), so I think we should keep it and allow wallets to choose a protocol based on their preferences/capabilities (let it be https, wss, etc.)


One question -
I see both iconUrls & blockExplorerUrls are missing from wallet_addStarknetChain params, could you pls elaborate on that?

12 Likes

You’re right, we should definitely keep it as a list.

I removed them because in my mind it is not mandatory to be able to add a new chain.
That being said, we could add them as optional params to ensure providers use the same properties in case they want to handle those parameters.

7 Likes

sure, as they are also optional on L1, see EIP-3085’s params -

...
blockExplorerUrls?: string[];
...
iconUrls?: string[];
...
9 Likes

An other comment on multiple rpcUrls. There might be region blocks such as Infura blocking parts of Ukraine, then a backup would be nice. Ethereum's Infura cuts off users to separatist areas in Ukraine, accidentally blocks Venezuela, Sarah Wolter

8 Likes

Hey @ltoussaint
Thanks for the proposal

I want to mention that baseUrl != rpcUrl
The baseUrl needs to point to a sequencer directly, while the rpcUrl expects an roc node like pathfinder.

Currently only baseUrl is supported by Argent X, as rpc nodes are still experimental.

So I think we should expose both, where either the one or the other needs to be set.

10 Likes

Ok thanks for the explanation.
So maybe we could rename baseUrl by sequencerUrl to clarify what we are dealing with?

7 Likes

I think it’s coming from starknet.js terminology, see here.

7 Likes

With many dApps going mainnet, I think it’s more important now than ever to decide on the interface that we plan to use for this SIMP

5 Likes