CAIP-294: Browser Wallet Messaging for Extensions
Simple Summary
CAIP-294 defines a standardized messaging transport for browser extension wallets.
Abstract
To interface with a Decentralized Application (dapp), users install browser wallets to manage their blockchain accounts, which are required to sign messages and transactions. Leveraging existing browser messaging APIs, these are used to initiate a dapp-wallet connection in a browser environment.
Motivation
Currently, in order for Decentralized Applications to be able to support all users they need support different messaging standards for each namespace such as Ethereum's EIP-6963, Solana Wallet Protocol, etc., they do not cover all wallets and are not chain-angostic.
Developers must support different SDKs for different blockchain namespaces which work very differently despite following the same patterns of discovery, handshake and signing.
This proposal is motivated by the fragmentation on the events across different ecosystems and aims to bring cohesion to reduce the unnecessary logic to support multiple chains in different namespaces.
Additionally this aligns the messaging for browser wallets to leverage existing standards for handshake (CAIP-25) and signing (CAIP-27). Thus introducing a solution focused on optimizing interoperability for multiple Wallet Providers, fostering fairer competition by reducing the barriers to entry for new Wallet Providers, and enhancing user experience across all blockchain networks.
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].
Definitions
Wallet Provider: A user agent that manages accounts and facilitates transactions with a blockchain.
Decentralized Application (dapp): A web page that relies upon one or many Web3 platform APIs which are exposed to the web page via the Wallet.
Blockchain Library: A library or piece of software that assists a dapp to interact with a blockchain and interface with the Wallet.
Messaging APIs
Browser Extensions make use of events with window.dispatchEvent
and window.addEventListener
which will be necessary for publishing and listening messages, respectively, between the Blockchain Library used by the Decentralized Application to communicate with the Wallet Provider.
This provides the foundation for any Wallet Provider to interface with a Decentralized Application using a Blockchain Library which implements this standard.
Different loading times can be affected by multiple factors, which makes it non-deterministic to publish and listen to messages from different sources within the browser.
Discovery
Both Wallet Providers and blockchain libraries must listen to incoming messages that might be published after their initialization. Additionally both Wallet Providers and blockchain libraries must publish a message to both announce themselves and their intent to connect, respectively.
Here is the expected logic from the Blockchain Library:
Here is the expected logic from the Wallet Provider:
Wallet Data
The walletData
object MUST include the following properties:
uuid
: A unique identifier for the wallet instance.name
: The name of the wallet.icon
: An icon representing the wallet.rdns
: The reverse domain name of the wallet provider.
Additionally, the walletData
object MAY include the following optional properties:
targets
: An array of objects, with an object containingtype: "caip341"
andvalue: <extension_id>
used to connect to wallets usingexternally_connectable
. Important to note here that other CAIPs can extend this, and CAIP-341 is an example of a valid target type for this use case.scopes
: An object defining the authorization scopes supported by the wallet, as specified in CAIP-217.
Example of a walletData
object with optional properties:
This walletData
type is a superset of WalletAnnounceRequestParams
type described in the CAIP-282 standard, adding the optional targets
property with the object defining extensionId
, as it is only relevant for browser extension based wallets.
Targets
When a targets
property with the array containing an object with type: 'caip341'
is included in the walletData
object, it indicates that the wallet expects communication via the browser's externally_connectable
API. In this case:
- The dapp MUST use the
targets.find(({ type }) => type === "caip314").value
(anextensionId
) to establish a connection with the wallet using theexternally_connectable
browser API. - All subsequent communication with the wallet (the "session") SHOULD be conducted over the
externally_connectable
API usingruntime.connect()
andruntime.sendMessage()
. - The dapp MUST NOT use the injected provider for communication when
targets
with CAIP-341 type is present.
Example of establishing a connection and sending a message:
If the targets
object with CAIP-341 type is not present in the walletData
object, the dapp SHOULD assume that communication will occur through the traditional injected provider method.
Handshake
After the wallet has been selected by the user then the Blockchain Library MUST publish a message to share its intent to establish a connection. This can be either done as a CAIP-25 request.
The communication will use the uuid
shared by the initial Wallet Provider announcement payload as described by the CAIP-372 wallet info, which the Wallet Provider will listen to for any incoming requests, and consequently, the Blockchain Library will also be used for publishing messages. The same will happen again the other way around but vice-versa, where the Wallet Provider will be the Blockchain Library that will be listening to any incoming responses, and consequently, the Wallet Provider will also use it for publishing messages.
Signing
This same channel uuid
can then be used for a connected session using CAIP-27 which then would use the sessionId
from the established connection to identify incoming payloads that need to be respond to, and also which chainId
is being targetted.
UUIDs
The generation of UUIDs is crucial for this messaging interface to work seamlessly for the users.
A Wallet Provider MUST always generate UUIDs distinctly for each web page loaded, and they must not be re-used without a session being established between the application and the wallet with the user's consent.
A UUID can be re-used as a sessionId
if and only if the CAIP-25 procedure has been prompted to the user and the user has approved its permissions to allow the application to make future signing requests.
Once established, the UUID is used as sessionId
for the CAIP-27 payloads, which can verify that incoming messages are being routed through the appropriate channels.
Rationale
Browser wallets differentiate themselves because they can be installed by users without the application developer requiring any further integration. Therefore, we optimize for a messaging interface that leverages the two-way communication available to browser wallets to make themselves discoverable, and negotiate a set of parameters that enable not only easy human readability with a clear name and icon but also machine-readability using strong identifiers with uuids and rdns.
The choice for using window.postMessage
is motivated by expanding the range of Wallet Providers it can support, including browser extensions that can alternatively use window.dispatchEvent
but instead it would also cover Inline Frames, Service Workers, Shared Workers, and more.
The use of UUID for message routing is important because while RDNS is useful for identifying the Wallet Provider, it causes issues when it comes to the session management of different webpages connected to the same Wallet Provider or even managing stale sessions, which can be out-of-sync. Since UUID generation is derived dynamically on page load, Wallet Providers can track these sessions more granularly rather than making assumptions around the webpage URL and RDNS relationship.
The existing standards around wallet session creation (CAIP-25) are fundamental to this experience because they create clear intents for a wallet to "connect" with a webpage url after it's been discovered. This standard does not enforce either one but strongly recommends these standards as the preferred interface for connecting or authenticating a wallet.
Finally the use of CAIP-27 leverages the work above to properly target signing requests that are intended to be prompt to wallet users which will include a sessionId
and chainId
in parallel with the pre-established sessions using either CAIP-25.
Test Cases
Here is a test case where we demonstrate a scenario with logic from both a Blockchain Library and a Wallet Provider.
Logic from the Blockchain Library:
Logic from the Wallet Provider:
Security Considerations
TODO
Privacy Considerations
TODO
Backwards Compatibility
TODO
Links
- EIP-6963 - Multi Injected Provider Discovery
- CAIP-27 - Blockchain ID Specification
- CAIP-25 - Blockchain ID Specification
- CAIP-282 - Browser Wallet Discovery Interface
- CAIP-341 - Extension ID Target Type Specification
- CAIP-372 - Wallet Information Metadata Standard
- externally_connectable - Chrome's
externally_connectable
browser API documentation
Copyright
Copyright and related rights waived via CC0.