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

Support Flask and Beta in the external extension provider #252

Merged
merged 4 commits into from
Apr 20, 2023
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
6 changes: 3 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ module.exports = {
coveragePathIgnorePatterns: ['/node_modules/', '/mocks/', '/test/'],
coverageThreshold: {
global: {
branches: 58.12,
branches: 59.24,
functions: 54.95,
lines: 60.61,
statements: 60.84,
lines: 60.91,
statements: 61.14,
},
},
projects: [
Expand Down
35 changes: 35 additions & 0 deletions src/extension-provider/createExternalExtensionProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { StreamProvider } from '../StreamProvider';
import { MockPort } from '../../test/mocks/MockPort';
import messages from '../messages';
import { createExternalExtensionProvider } from './createExternalExtensionProvider';
import config from './external-extension-config.json';

/**
* A fully initialized extension provider, and additional mocks to help
Expand Down Expand Up @@ -126,6 +127,40 @@ describe('createExternalExtensionProvider', () => {
expect(results).toBeInstanceOf(StreamProvider);
});

it('supports Flask', () => {
// `global.chrome.runtime` mock setup by `jest-chrome` in `jest.setup.js`
(global.chrome.runtime.connect as any).mockImplementation(() => {
Mrtenz marked this conversation as resolved.
Show resolved Hide resolved
return new MockPort();
});
const results = createExternalExtensionProvider('flask');
expect(results).toBeInstanceOf(StreamProvider);
expect(global.chrome.runtime.connect).toHaveBeenCalledWith(
config.chromeIds.flask,
);
});

it('supports Beta', () => {
// `global.chrome.runtime` mock setup by `jest-chrome` in `jest.setup.js`
(global.chrome.runtime.connect as any).mockImplementation(() => {
return new MockPort();
});
const results = createExternalExtensionProvider('beta');
expect(results).toBeInstanceOf(StreamProvider);
expect(global.chrome.runtime.connect).toHaveBeenCalledWith(
config.chromeIds.beta,
);
});

it('supports custom extension ID', () => {
// `global.chrome.runtime` mock setup by `jest-chrome` in `jest.setup.js`
(global.chrome.runtime.connect as any).mockImplementation(() => {
return new MockPort();
});
const results = createExternalExtensionProvider('foobar');
expect(results).toBeInstanceOf(StreamProvider);
expect(global.chrome.runtime.connect).toHaveBeenCalledWith('foobar');
});

describe('RPC warnings', () => {
const warnings = [
{
Expand Down
25 changes: 11 additions & 14 deletions src/extension-provider/createExternalExtensionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import config from './external-extension-config.json';

const browser = detect();

export function createExternalExtensionProvider() {
export type ExtensionType = 'stable' | 'flask' | 'beta' | string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually provide autocomplete, since ExtensionType is inferred as just string?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not. Do you have an idea of how to make that happen?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not possible unless the ID is not a string.

export type ExtensionType = 'stable' | 'flask' | 'beta' | `id:${string}`;

This works for example, but not sure if that's what we want.


export function createExternalExtensionProvider(
typeOrId: ExtensionType = 'stable',
) {
let provider;

try {
const currentMetaMaskId = getMetaMaskId();
const metamaskPort = chrome.runtime.connect(
currentMetaMaskId,
) as Runtime.Port;
const extensionId = getExtensionId(typeOrId);
const metamaskPort = chrome.runtime.connect(extensionId) as Runtime.Port;

const pluginStream = new PortStream(metamaskPort);
provider = new StreamProvider(pluginStream, {
Expand All @@ -35,13 +37,8 @@ export function createExternalExtensionProvider() {
return provider;
}

function getMetaMaskId() {
switch (browser?.name) {
case 'chrome':
return config.CHROME_ID;
case 'firefox':
return config.FIREFOX_ID;
default:
return config.CHROME_ID;
}
function getExtensionId(typeOrId: ExtensionType) {
const ids =
browser?.name === 'firefox' ? config.firefoxIds : config.chromeIds;
return ids[typeOrId as keyof typeof ids] ?? typeOrId;
}
12 changes: 10 additions & 2 deletions src/extension-provider/external-extension-config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
{
"CHROME_ID": "nkbihfbeogaeaoehlefnkodbefgpgknn",
"FIREFOX_ID": "webextension@metamask.io"
"chromeIds": {
"stable": "nkbihfbeogaeaoehlefnkodbefgpgknn",
"beta": "pbbkamfgmaedccnfkmjcofcecjhfgldn",
"flask": "ljfoeinjpaedjfecbmggjgodbgkmjkjk"
},
"firefoxIds": {
"stable": "webextension@metamask.io",
"beta": "webextension-beta@metamask.io",
"flask": "webextension-flask@metamask.io"
}
}