[SNIP] Connect accounts to dapps

Simple Summary

A RPC method to request accounts and to let the user to choose which account he agree to expose to the dapps.

Inspired by EIP-1102.

Adapted to match with Starknet account.

Abstract

Dapps may require a user to connect an account from his wallet.

This RPC method allow dapps to request accounts and let the user choose which account to expose.

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.

wallet_requestAccounts

This RPC method allows a user to connect one or several accounts from his wallet.

Calling this method SHOULD display to the user the list of available accounts to let him choose which accounts to expose to the dapp.

In case the user reject the connection, the method SHOULD return an error.

Here is the type of this method:

Provider.request('wallet_requestAccounts'): Promise<AccountInterface[]>

Where AccountInterface comes from starknetjs

  • The method MUST return a Promise with the selected Account instance.

  • If the user reject the connection, the method MUST reject the Promise.

  • The method MUST always return one account.

  • If the user didn’t select any accounts, he SHOULD NOT be able to validate the connection.

  • In any case, if the user didn’t select any accounts, the method MUST reject the Promise instead.

  • If no accounts are available, the method MUST reject the Promise.

Account usage

The account instance (AccountInterface) returned by this method can directly be used to execute transactions.

If several accounts are returned, using one or the other account SHOULD end by the wallet to automatically select the good account when displaying confirmation interface.

This way a dapps could manage several accounts and let the user choose which one to use directly from dapps.

Here is an example with 2 accounts selected :

const accounts = await Provider.request('wallet_requestAccounts');
const nbAccounts = accounts.length;
const selectedAccount = accounts[nbAccounts - 1];

selectedAccount.execute(...)
8 Likes

Some comments regarding this proposal

  • it matches what exists on Ethereum ecosystem:
    • no enable method (which is deprecated on Ethereum)
    • RPC method wallet_requestAccounts to retrieve a list of account
  • we could remove the reference of starknetjs by replacing the usage of its AccountInterface by a specific interface which match the AccountInterface of starknetjs.
  • I kept the possibility to retrieve a list of accounts, even if some wallets provider could choose to only select one. This way we don’t close the door to let dapps manage different accounts.
2 Likes

at least*

I think it’s better to manage it over get-starknet since it’s used by dapps to discover & connect with wallets, so it just make sense to have the associated types managed/exposed over there

1 Like

I have an issue with returning an AccountInterface since it contains functions this makes it incompatible with JSON-RPC. I think the beauty of Ethereum RPC API is that it is JSON-RPC making it easy for wallet developers to implement the functionality wherever they see fit.

A way to address this would be to make it return the address as a string just like EIP-1102. However I’m not sure if the goal of the [SIMPS] is to define a interface towards users or to define a RPC protocol for talking to the wallet. If the protocol facing the user contains high level types like AccountInterface, it would still be nice to define a low level JSON-RPC protocol for interaction between the Provider and a wallet. I’m quite fond of the MetaMask api-spec and would like to see something similar for StarkNet.

1 Like

You are right, I think we should separate 2 concerns:

  • how providers interact with wallet (using RPC methods)
  • how users can interact with the provider (where we could define the usage of AccountInterface)

@owodunni, should we create 2 specific proposals or define both of them in the this one?
@avimak, I think we should define a repository like MetaMask api-spec in the Github orga “starknet-community-libs” (so ultimately we could have 2 repository, one for all the JSON-RPC definition, and the other one to define typescript interface to be exported by providers to the users)

1 Like

I’m not sure that we need to define the user facing API. If we look at ethers.js and web3.js they have different user facing APIs. The common denominator is that both know how to communicate with nodes over JSON-RPC. Different libraries could implement whatever AccountInterface they like giving users a choise over what they want to use.

1 Like

@owodunni The goal here is to define an easy way to handle different wallet like Braavos and ArgentX which inject their own JavaScript object.
To do so we need them to define the same API so that dapps developers don’t have to adapt their code depending on which wallet is chosen by a user.

Then you can have third party libraries which could develop their own implementation on top of that.
One of the reason is also the keep compatibility with what is already developed

1 Like

Right, ArgentX or Braavos will both provide the Provider that you defined in your other post. [SIMP] Starknet Provider JavaScript API - #8 by ltoussaint

My thinking is that as long as that proposal gets implemented then both wallets can communicate over the same JSON-RPC API then it should be possible for the DAPP developers to just do:

const provider = new starknet.Provider(window.starknet);
const accounts: AccountInterface[] = await provider.getAccounts();

Of course, this could be up to starknet.js to facilitate, not necessarily the API. Translation from the JSON-RPC API to AccountInterface which the users use could be handled internally by starknet.js.

Or atleast thats one way in which I think we could have an API that more wallets could implement without breaking the things that already work :slight_smile:

1 Like

not going to work when both Braavos & Argent are installed - this way the user have no choice but forced to work with Argent.

the get-starknet lib - which is now adopted by all major dapps & libs in the StarkNet ecosystem - introduced multi-wallets support and encapsulates this process for dapps.
reverting back to new starknet.Provider(window.starknet) will force every dapp to re-implement multi-wallets support (and discovery) over and over (and over) again.

2 Likes

That is neat. Haven’t gotten all that far in the ecosystem yet…

1 Like

sure, pls take a look, PRs are welcome :wink:
also - the lib was covered during the prev starknet community call, you can recap it here.

1 Like

Really like this proposal, but I think we should keep types inside of starknet.js
Especially AccountInterface

It’s easy to just import the type from starknet.js, which does not change the bundle size.
starknet.js could just be a devDependency.

I think we should split between RPC messages and get-starknet return value.
While RPC messages should always be JSON, get-starknet could decide to build an Account out of the provided informations.

The Account is injected in the browser window by the wallet to be able to send signed transactions.

If we build the Account in get-starknet, it also means we need to define new RPC methods to communicate to the wallet to execute signed transactions (starknet_sendTransaction) and to sign messages (starknet_sign) … and maybe more I forgot