TBD54566975 / janky-wallet

Identity Wallet Web Extension
Apache License 2.0
18 stars 4 forks source link

Web5 Provider API: Allow for multiple providers #4

Open sondreb opened 1 year ago

sondreb commented 1 year ago

Have you considered allowing for multiple providers to be registered on the global "web5" object created by the extension?

Having web5.providers where different wallets can inject their own providers would be a great feature for the ecosystem, allowing co-existence of multiple implementations for Web5 wallets to exists on the users' devices at the same time.

sondreb commented 1 year ago

Here is a reference to some ideas around this topic for Web3: https://github.com/brave/brave-browser/issues/7503

sondreb commented 1 year ago

I made a library that could be a starting point for a "web5-injector" library: https://github.com/block-core/web5-injector

The idea is as follows:

Wallets implement a very generic "request provider" which is based off the EIP1193Provider request method primarily and can be extended in the future.

The web5-injector library can either be copied or referenced in wallets and used to register an implementation of Web5RequestProvider which is part of the web5-injector library.

export interface Web5RequestProvider {
    name: string;
    request(args: RequestArguments): Promise<unknown>;
}

export interface RequestArguments {
    readonly method: string;
    readonly params?: unknown[] | object;
}

The wallet would then call Injector.register(provider); which will register the globally web5 object, which has this definition:

export class Web5 {
    /** Get the current active provider. */
    currentProvider?: Web5RequestProvider;

    /** Get all registered providers. */
    get providers() { }

    /** Adds an request provider, multiple with same name can be added. */
    addProvider(provider: Web5RequestProvider) { }

    /** Get a provider based upon the name. */
    getProvider(name: string) { }
}

The wallets would need to provide some UI to list all providers and allow users to pick what they want as currentProvider. The library doesn't set this automatically at the moment.

This is how we currently use this new web5-injector library in our wallet extension:

import { Injector, RequestArguments, Web5RequestProvider } from '@blockcore/web5-injector';

const provider = new BlockcoreRequestProvider();
Injector.register(provider);

// Also make our provider available on "blockcore".
globalThis.blockcore = provider;

The final part of the solution is the "Web5 Provider", this will be one or multiple implementations that provides developer-friendly APIs that wraps the generic Web5RequestProvider.

This is a potential example of an Web5 Provider library that a regular app developer could use:

const web5 = new Web5Provider(globalThis.web5.currentProvider);
const methods = await web5.did.supportedMethods();

This developer friendly library would map this function to a request that might look like this:

const args: RequestArguments = {
    method: 'did.supportedMethods',
    params: [],
};

return await this.provider.request(args);

In summary:

web5-injector creates a basic object on globalThis.web5 that holds an array of all Web5RequestProviders that individual wallet extensions register on web page load.

App developers can use request directly if they want to or use a third party "Web5 Provider" library that simplifies the request messages for them.

Wallets need to provide some UI for users to pick their preferred provider, until a future where Web Browsers allow this (Brave allow selection of default Solana and Ethereum wallets).

mistermoe commented 1 year ago

@sondreb sorry for the delay here! just getting settled into work again. Generally speaking, i think allowing for multiple providers is a great idea and honestly necessary. Users should definitely be able to have more than 1 wallet installed and be able to choose which wallet is in the "driver's seat" per se.

It looks like Brave achieved optionality for Web3 by baking the ability to choose directly into the browser. I think your suggestion is a step in the right direction and may be the most we can do without native browser support. The downside of course is that all wallets have to provide some UI to list all providers and allow users to pick what they want as currentProvider (as you mentioned). Any wallet could come along and decide not to play nice by either not providing that UI or just outright hijacking window.web5

michaelneale commented 1 year ago

yeah this is quite interesting, and agree with it largely. If there is a web5 api being injected, would be nice if there weren't competing things trying to do the same thing, but a provider model.