ghost-keychain/packages/extension/src/page/index.ts
Jaco Greeff c70d9a0e63
Swap to eslint (#72)
* 626 problems (430 errors, 196 warnings)

* A start.

* < 200

* 80

* 0
2019-07-12 20:09:44 +02:00

87 lines
2.8 KiB
TypeScript

// Copyright 2019 @polkadot/extension 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 { InjectedWindow } from '@polkadot/extension-dapp/types';
import { MessageTypes } from '../background/types';
import Injected from './Injected';
// when sending a message from the injector to the extension, we
// - create an event - this we send to the loader
// - the loader takes this event and uses port.postMessage to background
// - on response, the loader creates a reponse event
// - this injector, listens on the events, maps it to the original
// - resolves/rejects the promise with the result (or sub data)
interface Handler {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
resolve: (data: any) => void;
reject: (error: Error) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
subscriber?: (data: any) => void;
}
type Handlers = Record<string, Handler>;
// small helper with the typescript types, just cast window
const windowInject = window as InjectedWindow;
const handlers: Handlers = {};
let idCounter = 0;
// a generic message sender that creates an event, returning a promise that will
// resolve once the event is resolved (by the response listener just below this)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function sendMessage (message: MessageTypes, request: any = null, subscriber?: (data: any) => void): Promise<any> {
return new Promise((resolve, reject): void => {
const id = `${Date.now()}.${++idCounter}`;
handlers[id] = { resolve, reject, subscriber };
window.postMessage({ id, message, origin: 'page', request }, '*');
});
}
// the enable function, called by the dapp to allow access
async function enable (origin: string): Promise<Injected> {
await sendMessage('authorize.tab', { origin });
return new Injected(sendMessage);
}
// setup a response listener (events created by the loader for extension responses)
window.addEventListener('message', ({ data, source }): void => {
// only allow messages from our window, by the loader
if (source !== window || data.origin !== 'content') {
return;
}
const handler = handlers[data.id];
if (!handler) {
console.error(`Uknown response: ${JSON.stringify(data)}`);
return;
}
if (!handler.subscriber) {
delete handlers[data.id];
}
if (data.subscription) {
(handler.subscriber as Function)(data.subscription);
} else if (data.error) {
handler.reject(new Error(data.error));
} else {
handler.resolve(data.response);
}
});
// don't clobber the existing object, we will add it it (or create as needed)
windowInject.injectedWeb3 = windowInject.injectedWeb3 || {};
// add our enable function
windowInject.injectedWeb3['polkadot-js'] = {
enable,
version: process.env.PKG_VERSION as string
};