This is a module consisting (almost) only of types. These types are the types
of the messages exchanged between apps using @substrate/connect
and the
browser extension. This package is shared between @substrate/connect
and the
extension in order for the TypeScript compiler to enforce the contract between
them.
This module contains the types and explanations of the communication protocol between the JavaScript code embedded in a web page and the substrate-connect extension.
Overview
If a web page wants to use the features of the substrate-connect extension, it must first check whether the extension is available by checking whether there exists an element on the DOM whose
id
is equal to DOM_ELEMENT_ID. This DOM element is automatically inserted by the extension when the page loads.If so, the web page can make use of the extension by sending messages on its
window
by usingWindow.postMessage
. These messages must conform to the ToExtension interface defined below.The substrate-connect extension (more precisely, its content-script) listens for "message" events (using
window.addEventListener("message", ...)
) and replies by sending back messages usingWindow.postMessage
as well. The messages sent by the extension conform to the ToApplication interface defined below.Detailed usage
In order to ask the substrate-connect extension to connect to a certain chain, the web page must:
chainId
, a string that will be used to identify this specific chain connection during its lifetime. At least 48 bits of entropy are recommended in order to avoid accidentally generating the same string multiple times.Window.postMessage
, as explained in the previous section) containing thischainid
and the specification of the chain to connect to.Instead of a ToExtensionAddChain message, the web page can alternatively send a ToExtensionAddWellKnownChain message and pass a chain name recognized by the extension such as "polkadot" or "ksmcc3", in which case the extension will use the chain specification stored internally. Doing so provides multiple advantages such as less bandwidth usage (as the web page doesn't have to download the chain specification), and a faster initialization as the extension is most likely already connected to that chain.
After a ToExtensionAddChain or a ToExtensionAddWellKnownChain message has been sent, the extension starts connecting to the chain, and later replies by sending back a ToApplicationChainReady message in case of success, or a ToApplicationError message in case of failure. This reply might only be sent back after a few seconds or more, and the web page is encouraged to display some kind of loading screen in the meanwhile.
Note that the extension reserves the rights to stop supporting a chain that used to be recognized by ToExtensionAddWellKnownChain. If the web page has sent a ToExtensionAddWellKnownChain and receives back a ToApplicationError, it should automatically fall back to downloading the chain specification and sending a ToExtensionAddChain instead.
After a chain has been successfully initialized (i.e. a ToApplicationChainReady message has been sent to the web page), the web page can submit JSON-RPC requests and notifications to the chain client by sending ToExtensionRpc messages. The chain client sends back JSON-RPC responses and notifications using ToApplicationRpc messages.
Once a web page no longer wants to interface with a certain chain, it should send a ToExtensionRemoveChain message to the extension in order for resources to be de-allocated. This can also be done before a ToApplicationChainReady message has been sent back.
At any point in time after the chain has been initialized, the extension can send a ToApplicationError message to indicate a critical problem with the chain or the extension that prevents execution from continuing. This can include for example the extension being disabled by the user, the underlying client crashing, an internal error, etc. Contrary to ToApplicationError messages before a chain has been initialized, ToApplicationError messages that happen after a chain has been initialized are rare and serious. If that happens, the web page is encouraged to remove all of its existing chains and stop using the extension altogether.
Note that if the extension sends a ToApplicationError message, either before of after the chain is ready, the corresponding
chainId
is immediately considered dead/removed, and the web page doesn't need to send a ToExtensionRemoveChain message.Other extensions implementing this protocol
While the documentation above refers to the substrate-connect extension in particular, any other browser extension is free to implement this protocol in order to pretend to be the substrate-connect extension.
In order to avoid conflicts when multiple different extensions implement this protocol, extensions must check whether there already exists an element on the DOM whose
id
is equal to DOM_ELEMENT_ID before creating one and listening for events.