Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add createExternalExtensionProvider #152

Merged
merged 4 commits into from
May 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 0 additions & 150 deletions index.d.ts

This file was deleted.

1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = {
// statements: 100,
// },
// },
setupFilesAfterEnv: ['./jest.setup.js'],
moduleFileExtensions: ['js'],
silent: true,
testEnvironment: 'jsdom',
Expand Down
1 change: 1 addition & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Object.assign(global, require('jest-chrome'));
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,16 @@
"dependencies": {
"@metamask/object-multiplex": "^1.1.0",
"@metamask/safe-event-emitter": "^2.0.0",
"@types/chrome": "^0.0.136",
"detect-browser": "^5.2.0",
"eth-rpc-errors": "^4.0.2",
"extension-port-stream": "^2.0.1",
"fast-deep-equal": "^2.0.1",
"is-stream": "^2.0.0",
"json-rpc-engine": "^6.1.0",
"json-rpc-middleware-stream": "^3.0.0",
"pump": "^3.0.0"
"pump": "^3.0.0",
"webextension-polyfill-ts": "^0.25.0"
},
"devDependencies": {
"@metamask/eslint-config": "^6.0.0",
Expand All @@ -58,13 +62,14 @@
"@typescript-eslint/eslint-plugin": "^4.10.0",
"@typescript-eslint/parser": "^4.10.0",
"eslint": "^7.15.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^23.18.0",
"eslint-plugin-json": "^2.0.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-config-prettier": "^8.1.0",
"jest": "^26.6.3",
"jest-chrome": "^0.7.1",
"prettier": "^2.2.1",
"typescript": "^4.1.3"
}
Expand Down
4 changes: 2 additions & 2 deletions src/BaseProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export interface BaseProviderState {
export interface JsonRpcConnection {
events: SafeEventEmitter;
middleware: JsonRpcMiddleware<unknown, unknown>;
stream: _Readable.Duplex;
stream: Duplex;
}

export default class BaseProvider extends SafeEventEmitter {
Expand Down Expand Up @@ -112,7 +112,7 @@ export default class BaseProvider extends SafeEventEmitter {
* listeners. Default: 100
*/
constructor(
connectionStream: typeof Duplex,
connectionStream: Duplex,
{
jsonRpcStreamName = 'metamask-provider',
logger = console,
Expand Down
2 changes: 1 addition & 1 deletion src/MetaMaskInpageProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default class MetaMaskInpageProvider extends BaseProvider {
* send page metadata. Default: true
*/
constructor(
connectionStream: typeof Duplex,
connectionStream: Duplex,
{
jsonRpcStreamName = 'metamask-provider',
logger = console,
Expand Down
34 changes: 34 additions & 0 deletions src/extension-provider/createExternalExtensionProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import PortStream from 'extension-port-stream';
import { detect } from 'detect-browser';
import { Runtime } from 'webextension-polyfill-ts';
import BaseProvider from '../BaseProvider';
import config from './external-extension-config.json';

const browser = detect();

export default function createMetaMaskExternalExtensionProvider() {
let provider;
try {
const currentMetaMaskId = getMetaMaskId();
const metamaskPort = chrome.runtime.connect(
currentMetaMaskId,
) as Runtime.Port;
const pluginStream = new PortStream(metamaskPort);
provider = new BaseProvider(pluginStream);
} catch (e) {
console.dir(`Metamask connect error `, e);
throw e;
}
return provider;
}

function getMetaMaskId() {
switch (browser?.name) {
case 'chrome':
return config.CHROME_ID;
case 'firefox':
return config.FIREFOX_ID;
default:
return config.CHROME_ID;
}
}
4 changes: 4 additions & 0 deletions src/extension-provider/external-extension-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"CHROME_ID": "nkbihfbeogaeaoehlefnkodbefgpgknn",
"FIREFOX_ID": "webextension@metamask.io"
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import MetaMaskInpageProvider from './MetaMaskInpageProvider';
import createExternalExtensionProvider from './extension-provider/createExternalExtensionProvider';
import BaseProvider from './BaseProvider';
import {
initializeProvider,
Expand All @@ -12,4 +13,5 @@ export {
BaseProvider,
setGlobalProvider,
shimWeb3,
createExternalExtensionProvider,
};
2 changes: 1 addition & 1 deletion src/initializeInpageProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface InitializeProviderOptions extends MetaMaskInpageProviderOptions {
/**
* The stream used to connect to the wallet.
*/
connectionStream: typeof Duplex;
connectionStream: Duplex;

/**
* Whether the provider should be set as window.ethereum.
Expand Down
31 changes: 31 additions & 0 deletions test/createExternalExtensionProvider.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { createExternalExtensionProvider, BaseProvider } = require('../dist');

describe('createExternalExtensionProvider', () => {
beforeAll(() => {
global.chrome.runtime.connect.mockImplementation(() => {
return {
onMessage: {
addListener: jest.fn(),
},
onDisconnect: {
addListener: jest.fn(),
},
postMessage: jest.fn(),
};
});
});
afterAll(() => {
jest.restoreAllMocks();
});
it('can be called and not throw', () => {
expect(() => createExternalExtensionProvider()).not.toThrow();
});
it('calls connect', () => {
createExternalExtensionProvider();
expect(global.chrome.runtime.connect).toHaveBeenCalled();
});
it('returns a MetaMaskInpageProvider', () => {
const results = createExternalExtensionProvider();
expect(results).toBeInstanceOf(BaseProvider);
});
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"esModuleInterop": true,
"module": "CommonJS",
"moduleResolution": "node",
"resolveJsonModule": true,
"outDir": "dist",
"sourceMap": true,
"strict": true,
Expand Down
Loading