Endless Wallet Standard
Last updated
Last updated
The wallet standard provides guidelines for interoperability between wallet types. This ensures dapp developers do not need to change their applications to handle different wallets. This standard offers a single interface for all dapp developers, allowing easy additions of new wallets and more users to each application. This interoperability allows users to choose which wallet they want without worrying about whether apps support their use cases.
In order to ensure interoperability across Endless wallets, the following is required:
Mnemonics - a set of words that can be used to derive account private keys
dapp API - entry points into the wallet to support access to identity managed by the wallet
A mnemonic phrase is a multiple word phrase that can be used to generate account addresses. However, some wallets may want to support one mnemonic to many accounts coming from other chains. To support both of these use cases, the Endless wallet standard uses a to derive path for mnemonics to accounts.
Endless account creation can be supported across wallets in the following manner:
Generate a mnemonic phrase, for example with BIP39.
Get the master seed from that mnemonic phrase.
Use the BIP44-derived path to retrieve an account address (m/44'/637'/0'/0'/0'
)
See the
For example, Endless Wallet always uses the path m/44'/637'/0'/0'/0'
since there is one mnemonic per one account.
Many wallets from other ecosystems use this paradigm, and take these steps to generate accounts
Generate a mnemonic phrase, for example with BIP39.
Get the master seed from that mnemonic phrase.
Use the BIP44-derived path to retrieve private keys (e.g. m/44'/637'/i'/0'/0'
) where i
is the account index.
Increase i
until all the accounts the user wants to import are found.
Note: The iteration should be limited, if an account doesn't exist during iteration, keep iterating for a constant address_gap_limit
(10 for now) to see if there are any other accounts. If an account is found we will continue to iterate as normal.
ie.
More important than account creation, is how wallets connect to dapps. Additionally, following these APIs will allow for the wallet developer to integrate with the Endless Wallet Adapter Standard. The APIs are as follows:
connect()
, disconnect()
getAccount()
changeNetwork()
getNetwork()
signAndSubmitTransaction(data: EndlessSignAndSubmitTransactionInput)
signMessage(data: EndlessSignMessageInput)
Event listening (EndLessSDKEvent.ACCOUNT_CHANGE
, EndLessSDKEvent.SWITCH_NETWORK
)
The connection APIs ensure that wallets don't accept requests until the user acknowledges that they want to see the requests. This keeps the user state clean and prevents the user from unknowingly having prompts.
connect()
will prompt the user for a connection
return Promise<UserResponse<AccountInfo>>
disconnect()
allows the user to stop giving access to a dapp and also helps the dapp with state management
return Promise<void>
Get Account
Connection required
Allows a dapp to query for the current connected account address and authkey
getAccount()
no prompt to the user
returns Promise<UserResponse<AccountInfo>>
Get Network
Connection required
Allows a dapp to query for the current connected network name, chain ID, and URL
getNetwork()
no prompt to the user
returns Promise<UserResponse<NetworkInfo>>
Sign and submit transaction
Connection required
signAndSubmitTransaction(data: EndlessSignAndSubmitTransactionInput)
will prompt the user with the transaction they are signing
returns Promise<UserResponse<{ hash: string }>>
Sign message
Connection required
Allows a dapp to sign a message with their private key. The most common use case is to verify identity, but there are a few other possible use cases. The user should be prompted for approval. You may notice some wallets from other chains just provide an interface to sign arbitrary strings. This can be susceptible to man-in-the-middle attacks, signing string transactions, etc.
Types:
signMessage(data: EndlessSignMessageInput)
prompts the user with the payload.message
to be signed
returns Promise<SignMessageResponse>
An example: signMessage({message: "Welcome to dapp!"})
This would generate the fullMessage
to be signed and returned as the signature
:
Event listening
See the for the derive path
Allows a dapp to send a simple JSON payload using the for signing and submission to the current network. The user should be prompted for approval.