This post introduces the latest additions and updates to Substrate Connect. For those who are not familiar, Substrate Connect is a web extension that uses smoldot, a light-client provider that synchronizes Substrate-based chains in the background for the user. This ensures that when you visit a dApp, the time to connect to the chain is almost instantaneous.
During the first half of 2024, we’ve added wallet capabilities to Substrate Connect. This means you can securely create accounts and sign transactions with them, but instead of using centralized RPCs to submit the transaction, you are using a light client. Substrate Connect is the first of its kind to do so.
In addition, we created a new protocol called @substrate/discovery
that serves as a common interface for dApps to communicate with light client extensions.
What You Need To Know:
-
The Wallet Template: There is now a new wallet template under the projects directory in the Substrate Connect repository. You can use this template to get a light client wallet up and running quickly. We have extensive documentation here on how you can get it running.
-
The Discovery Protocol: The new
@substrate/discovery protocol
; a common interface for dApps to communicate with light client extensions, has been created here. There are currently two implementations of this protocol: @substrate/smoldot-discovery and @substrate/connect-discovery. The former is useful for wallets that just want to expose the smoldot API to dApps, while the latter is internal to Substrate Connect. -
Getting Started: The wallet template contains a Step By Step Guide on how you can add light client functionality to your extension.
Why do we need a Discovery Protocol?
Prior to the introduction of the discovery protocol, we had the Connect Extension Protocol, which dictates how dApps can connect to Substrate Connect and use it to interface with a smoldot light client.
However, when it comes to real-world usage, you’re going to want to connect your dApp to a wallet provider and not just Substrate Connect. That wallet provider will also be running its own light client instance, so it is paramount that your dApp shares the same light client state as the wallet you are connected to.
Since it’s not possible for multiple browser extensions to implement the Connect Extension Protocol, we decided to come up with the Discovery Protocol. This protocol dictates the interface Wallet Providers need to provide in their content script, such that they can be discovered by dApps. It takes inspiration from EIP-6963: Multi Injected Provider Discovery, which is the protocol Ethereum uses for wallet provider discovery.
How it works
When a dApp is loaded, the extension’s first priority is to inject an inpage
script from the content script that is attached to the DOM of the dApp. Inside this inpage script, it adds a window event listener under the namespace "substrateDiscovery:requestProvider"
. When the listener is invoked, it receives a callback: onProvider
that accepts a provider instance. The inpage script will execute this callback with all the providers it supports and this will be passed to the caller of the event that triggered the listener.
In this case, the caller is the dApp. All the dApp needs to do upon initialization is invoke the getProviders
method from the @substrate/discovery
package. This initiates a window.dispatchEvent with a CustomEvent that has the same namespace: "substrateDiscovery:requestProvider"
.
By using this protocol, dApps are able to get a list of wallet providers in a synchronous manner. To filter for specific providers, dApps can install provider-specific implementations of the discovery protocol such as @substrate/smoldot-discovery and @substrate/connect-discovery. These packages invoke getProviders
under the hood, but filter the provider-specific variant for you.
Workflow Comparison: Old vs. New
To better understand the improvements, lets compare the old and new workflows.
Old Workflow
Previously, dapps had to rely on @polkadot/extension-dapp
to inject a global named window.injectedWeb3
to connect to a wallet. This had its limitations because it mandated a single interface wallets could expose that was dictated by Polkadot JS.
New Workflow
+-----------+ +---------------+ +---------------+
| Dapp |<------------- | Inpage Script |<-------------| Extension |
| | add listeners | | add script | Content Script|
| | | | | |
| |-------------->| | | |
| | getProviders | | | |
| | | | | |
| |<--------------| | | |
| | onProvider | | | |
| | | | | |
+-----------+ +---------------+ +---------------+
In the new workflow, we allow dapps to request providers that confirm to an agreed upon interface (that is arbitrary based on an agreed upon specificiation). The steps are as follows:
- Extension content script: injects inpage script, it adds a window event listener for provider requests.
- Dapp: invokes the
getProviders
method to synchronously get a list of all available providers. - Inpage Script: responds to the
getProviders
event and passes the providers back to the dApp in theonProvider
callback.
For in-depth code examples, read the docs.
What’s Next
Substrate Connect is now considered stable and ready for general use. We encoursage wallet providers to try the template so we can solicit feedback on how we can make the template better for integration.
We also plan to present the Substrate Connect Wallet Template at the Sub0 Reset in Bangkok and; I will personally be running a 90 minute workshop where I will light client wallet live using the libraries we’ve have built.