Compat with other extensions (#36)

This commit is contained in:
Jaco Greeff 2019-05-30 09:21:56 +02:00 committed by GitHub
parent 0359b7a601
commit bb99f8a27b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 15 deletions

View File

@ -0,0 +1,11 @@
// Copyright 2019 @polkadot/extension-dapp authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import singleSource from './singleSource';
export default function initCompat (): Promise<boolean> {
return Promise.all([
singleSource()
]).then(() => true);
}

View File

@ -0,0 +1,69 @@
// Copyright 2019 @polkadot/extension-dapp authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Signer } from '@polkadot/api/types';
import { InjectedAccount, InjectedWindow } from '../types';
// RxJs interface, only what we need here
type Subscriber<T> = {
subscribe: (cb: (value: Array<T>) => void) => void
};
type SingleSourceAccount = {
address: string,
assets: Array<{ assetId: number }>,
name: string
};
type SingleSource = {
accounts$: Subscriber<SingleSourceAccount>,
environment$: Subscriber<string>,
signer: Signer
};
type SingleWindow = Window & InjectedWindow & {
SingleSource: SingleSource
};
// add a compat interface of SingleSource to window.injectedWeb3
function injectSingleSource (win: SingleWindow): void {
let accounts: Array<InjectedAccount> = [];
// we don't yet have an accounts subscribe on the interface, simply get the
// accounts and store them, any get will resolve the last found values
win.SingleSource.accounts$.subscribe((_accounts) => {
accounts = _accounts.map(({ address, name }) => ({
address,
name
}));
});
// decorate the compat interface
win.injectedWeb3['SingleSource'] = {
enable: async (origin: string) => ({
accounts: {
get: async () => accounts
},
signer: win.SingleSource.signer
}),
version: '0.0.0'
};
}
// returns the SingleSource instance, as per
// https://github.com/cennznet/singlesource-extension/blob/f7cb35b54e820bf46339f6b88ffede1b8e140de0/react-example/src/App.js#L19
export default function initSingleSource (): Promise<boolean> {
return new Promise((resolve) => {
window.addEventListener('load', () => {
const win = window as SingleWindow;
if (win.SingleSource) {
injectSingleSource(win);
resolve(true);
} else {
resolve(false);
}
});
});
}

View File

@ -4,11 +4,22 @@
import { InjectedAccountWithMeta, InjectedExtension, InjectedExtensionInfo, InjectedWindow } from './types';
// our extension adaptor for other kinds of extensions
import compatInjector from './compat';
// just a helper (otherwise we cast all-over, so shorter and more readable)
const injectedWeb3 = (window as InjectedWindow).injectedWeb3 || {};
const win = window as InjectedWindow;
// don't clobber the existing object, but ensure non-undefined
win.injectedWeb3 = win.injectedWeb3 || {};
// true when anything has been injected and is available
function web3IsInjected (): boolean {
return Object.keys(win.injectedWeb3).length !== 0;
}
// have we found a properly constructed window.injectedWeb3
const isWeb3Injected = Object.keys(injectedWeb3).length !== 0;
let isWeb3Injected = web3IsInjected();
// we keep the last promise created around (for queries)
let web3EnablePromise: Promise<Array<InjectedExtension>> | null = null;
@ -17,29 +28,27 @@ export { isWeb3Injected, web3EnablePromise };
// enables all the providers found on the injected window interface
export function web3Enable (originName: string): Promise<Array<InjectedExtension>> {
web3EnablePromise = Promise
.all(
Object
.entries(injectedWeb3)
.map(([name, { enable, version }]) =>
Promise
.all([Promise.resolve({ name, version }), enable(originName)])
.catch(() => [{ name, version }, null] as [InjectedExtensionInfo, null])
)
web3EnablePromise = compatInjector().then(() =>
Promise.all(
Object.entries(win.injectedWeb3).map(([name, { enable, version }]) =>
Promise
.all([Promise.resolve({ name, version }), enable(originName)])
.catch(() => [{ name, version }, null] as [InjectedExtensionInfo, null])
)
)
.then((values) =>
values
.filter(([, ext]) => ext !== null)
.map(([info, ext]) => ({ ...info, ...ext } as InjectedExtension))
values.filter(([, ext]) => ext).map(([info, ext]) => ({ ...info, ...ext } as InjectedExtension))
)
.catch(() => [] as Array<InjectedExtension>)
.then((values) => {
const names = values.map(({ name, version }) => `${name}/${version}`);
isWeb3Injected = web3IsInjected();
console.log(`web3Enable: Enabled ${values.length} extensions ${names.join(', ')}`);
return values;
});
})
);
return web3EnablePromise;
}