Cross-browser extension interface (#21)
* Cross-browser extension interface * Allow eventTarget * Use extension.* in State
This commit is contained in:
parent
f241e7191d
commit
ebe20c3e23
@ -11,6 +11,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chrome": "^0.0.86",
|
||||
"@types/firefox-webext-browser": "^67.0.1",
|
||||
"extensionizer": "^1.0.1",
|
||||
"extract-loader": "^3.1.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"html-loader": "^0.5.5"
|
||||
|
||||
@ -1,20 +1,22 @@
|
||||
// Copyright 2019 @polkadot/extension-bg authors & contributors
|
||||
// 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 { KeyringStore } from '@polkadot/ui-keyring/types';
|
||||
|
||||
import extension from 'extensionizer';
|
||||
|
||||
const lastError = (type: string): void => {
|
||||
const error = chrome.runtime.lastError;
|
||||
const error = extension.runtime.lastError;
|
||||
|
||||
if (error) {
|
||||
console.error(`ChromeStore.${type}:: chrome.runtime.lastError:`, error);
|
||||
console.error(`ChromeStore.${type}:: runtime.lastError:`, error);
|
||||
}
|
||||
};
|
||||
|
||||
export default class ChromeStore implements KeyringStore {
|
||||
all (cb: (key: string, value: any) => void): void {
|
||||
chrome.storage.local.get(null, (result: { [index: string]: any }) => {
|
||||
extension.storage.local.get(null, (result: { [index: string]: any }) => {
|
||||
lastError('all');
|
||||
|
||||
Object.entries(result).forEach(([key, value]) =>
|
||||
@ -24,7 +26,7 @@ export default class ChromeStore implements KeyringStore {
|
||||
}
|
||||
|
||||
get (key: string, cb: (value: any) => void): void {
|
||||
chrome.storage.local.get([key], (result: { [index: string]: any }) => {
|
||||
extension.storage.local.get([key], (result: { [index: string]: any }) => {
|
||||
lastError('get');
|
||||
|
||||
cb(result[key]);
|
||||
@ -32,7 +34,7 @@ export default class ChromeStore implements KeyringStore {
|
||||
}
|
||||
|
||||
remove (key: string, cb?: () => void): void {
|
||||
chrome.storage.local.remove(key, () => {
|
||||
extension.storage.local.remove(key, () => {
|
||||
lastError('remove');
|
||||
|
||||
cb && cb();
|
||||
@ -47,7 +49,7 @@ export default class ChromeStore implements KeyringStore {
|
||||
return;
|
||||
}
|
||||
|
||||
chrome.storage.local.set({ [key]: value }, () => {
|
||||
extension.storage.local.set({ [key]: value }, () => {
|
||||
lastError('set');
|
||||
|
||||
cb && cb();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-bg authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import { AuthorizeRequest, MessageAuthorize, MessageExtrinsicSign, MessageExtrinsicSign$Response, SigningRequest } from '../types';
|
||||
|
||||
import extension from 'extensionizer';
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
type AuthRequest = {
|
||||
@ -115,7 +116,7 @@ export default class State {
|
||||
: (signCount ? `${signCount}` : '')
|
||||
);
|
||||
|
||||
chrome.browserAction.setBadgeText({ text });
|
||||
extension.browserAction.setBadgeText({ text });
|
||||
}
|
||||
|
||||
async authorizeUrl (url: string, request: MessageAuthorize): Promise<boolean> {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-bg authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-bg authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
// Copyright 2019 @polkadot/extension-bg authors & contributors
|
||||
// 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 extension from 'extensionizer';
|
||||
|
||||
// Runs in the extension background, handling all keyring access
|
||||
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
@ -10,8 +12,8 @@ import { cryptoWaitReady } from '@polkadot/util-crypto';
|
||||
import ChromeStore from './ChromeStore';
|
||||
import handlers from './handlers';
|
||||
|
||||
chrome.browserAction.setBadgeBackgroundColor({ color: '#ff0000' });
|
||||
chrome.runtime.onMessage.addListener(handlers);
|
||||
extension.browserAction.setBadgeBackgroundColor({ color: '#ff0000' });
|
||||
extension.runtime.onMessage.addListener(handlers);
|
||||
|
||||
cryptoWaitReady()
|
||||
.then(() => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-bg authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -1,10 +1,19 @@
|
||||
// Copyright 2019 @polkadot/extension-bg authors & contributors
|
||||
// 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.
|
||||
|
||||
// for FireFox, we need to listent here to allow origin restrictions to not
|
||||
// be an issue (otherwise we cannot read the properties on the created events)
|
||||
// const contentDocument = typeof gBrowser !== 'undefined'
|
||||
// ? gBrowser.selectedBrowser.contentDocument
|
||||
// : document;
|
||||
const eventTarget = document;
|
||||
|
||||
const events = {
|
||||
request: 'PolkadotJsWebRequest',
|
||||
response: 'PolkadotJsWebResponse'
|
||||
};
|
||||
|
||||
export { eventTarget };
|
||||
|
||||
export default events;
|
||||
|
||||
15
packages/extension/src/extensionizer.d.ts
vendored
Normal file
15
packages/extension/src/extensionizer.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// 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.
|
||||
|
||||
declare var gBrowser: undefined | {
|
||||
selectedBrowser: {
|
||||
contentDocument: Document
|
||||
}
|
||||
};
|
||||
|
||||
declare module 'extensionizer' {
|
||||
const extensionizer: typeof chrome;
|
||||
|
||||
export default extensionizer;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-inject authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-inject authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-inject authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { MessageTypes } from '../background/types';
|
||||
import { WindowInjected } from './types';
|
||||
|
||||
import events from '../events';
|
||||
import events, { eventTarget } from '../events';
|
||||
import Injected from './Injected';
|
||||
|
||||
// when sending a message from the injector to the expension, we
|
||||
@ -40,7 +40,7 @@ function sendMessage (message: MessageTypes, request: any = null): Promise<any>
|
||||
}
|
||||
|
||||
// setup a response listener (events created by the loader for extension responses)
|
||||
document.addEventListener(events.response, (event) => {
|
||||
eventTarget.addEventListener(events.response, (event) => {
|
||||
const response = (event as CustomEvent).detail;
|
||||
const promise = callbacks[response.id];
|
||||
|
||||
@ -58,11 +58,14 @@ document.addEventListener(events.response, (event) => {
|
||||
}
|
||||
});
|
||||
|
||||
// small helper with the typescript types, just cast window
|
||||
const windowInject = window as WindowInjected;
|
||||
|
||||
// don't clobber the existing object, we will add it it (or create as needed)
|
||||
(window as WindowInjected).injectedWeb3 = (window as WindowInjected).injectedWeb3 || {};
|
||||
windowInject.injectedWeb3 = windowInject.injectedWeb3 || {};
|
||||
|
||||
// add our enable function
|
||||
(window as WindowInjected).injectedWeb3['polkadot-js'] = {
|
||||
windowInject.injectedWeb3['polkadot-js'] = {
|
||||
name: 'polkadot-js', // process.env.PKG_NAME as string,
|
||||
version: process.env.PKG_VERSION as string,
|
||||
enable: (origin: string): Promise<Injected> =>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 @polkadot/extension-inject authors & contributors
|
||||
// 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.
|
||||
|
||||
|
||||
@ -2,19 +2,22 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import events from './events';
|
||||
import extension from 'extensionizer';
|
||||
|
||||
import events, { eventTarget } from './events';
|
||||
|
||||
function sendResponse (detail: any): void {
|
||||
document.dispatchEvent(new CustomEvent(events.response, { detail }));
|
||||
// create the custom event, this will be handled on the injection script
|
||||
eventTarget.dispatchEvent(new CustomEvent(events.response, { detail }));
|
||||
}
|
||||
|
||||
// Handle all custom events, passing messages to the extension
|
||||
document.addEventListener(events.request, (event) => {
|
||||
eventTarget.addEventListener(events.request, (event) => {
|
||||
// get the request as part of the the event detailt
|
||||
const request = (event as CustomEvent).detail;
|
||||
|
||||
// pass the detail as-is as a message to the extension
|
||||
chrome.runtime.sendMessage(request, (response) => {
|
||||
extension.runtime.sendMessage(request, (response) => {
|
||||
if (!response) {
|
||||
// no data, send diconnected/unknown error
|
||||
sendResponse({ id: request.id, error: 'Unknown response' });
|
||||
@ -28,7 +31,7 @@ document.addEventListener(events.request, (event) => {
|
||||
// inject our data injector
|
||||
const script = document.createElement('script');
|
||||
|
||||
script.src = chrome.extension.getURL('inject.js');
|
||||
script.src = extension.extension.getURL('inject.js');
|
||||
script.onload = (): void => {
|
||||
// remove the injecting tag when loaded
|
||||
if (script.parentNode) {
|
||||
|
||||
10
yarn.lock
10
yarn.lock
@ -2121,6 +2121,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.28.tgz#c054e8af4d9dd75db4e63abc76f885168714d4b3"
|
||||
integrity sha1-wFTor02d11205jq8dviFFocU1LM=
|
||||
|
||||
"@types/firefox-webext-browser@^67.0.1":
|
||||
version "67.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/firefox-webext-browser/-/firefox-webext-browser-67.0.1.tgz#92e3eb4440b56ab43eb93891ea4a3f33516fa7d7"
|
||||
integrity sha512-+RE7MDu8EQ5EcQe7i0378oCvu1Sf9fEtRdPakYfdcEr79v7wTpO/meQXv9JLqvy7FwM2/9D8cwV7GyclXgRtxA==
|
||||
|
||||
"@types/fs-extra@^5.0.3":
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1"
|
||||
@ -5666,6 +5671,11 @@ extend@~3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
extensionizer@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extensionizer/-/extensionizer-1.0.1.tgz#504544239a7610ba8404b15c1832091a37768d09"
|
||||
integrity sha512-UES5CSOYqshNsWFrpORcQR47+ph6UvQK25mguD44IyeMemt40CG+LTZrH1PgpGUHX3w7ACtNQnmM0J+qEe8G0Q==
|
||||
|
||||
external-editor@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user