@subwallet/extension-base 0.3.6-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +10 -0
- package/build/LICENSE +201 -0
- package/build/README.md +10 -0
- package/build/background/KoniTypes.d.ts +462 -0
- package/build/background/KoniTypes.js +57 -0
- package/build/background/RequestBytesSign.d.ts +12 -0
- package/build/background/RequestBytesSign.js +16 -0
- package/build/background/RequestExtrinsicSign.d.ts +12 -0
- package/build/background/RequestExtrinsicSign.js +14 -0
- package/build/background/handlers/Extension.d.ts +49 -0
- package/build/background/handlers/Extension.js +676 -0
- package/build/background/handlers/State.d.ts +87 -0
- package/build/background/handlers/State.js +434 -0
- package/build/background/handlers/Tabs.d.ts +24 -0
- package/build/background/handlers/Tabs.js +230 -0
- package/build/background/handlers/helpers.d.ts +1 -0
- package/build/background/handlers/helpers.js +13 -0
- package/build/background/handlers/index.d.ts +3 -0
- package/build/background/handlers/index.js +43 -0
- package/build/background/handlers/subscriptions.d.ts +4 -0
- package/build/background/handlers/subscriptions.js +24 -0
- package/build/background/types.d.ts +345 -0
- package/build/background/types.js +1 -0
- package/build/bundle.d.ts +1 -0
- package/build/bundle.js +3 -0
- package/build/cjs/background/KoniTypes.js +69 -0
- package/build/cjs/background/RequestBytesSign.js +27 -0
- package/build/cjs/background/RequestExtrinsicSign.js +23 -0
- package/build/cjs/background/handlers/Extension.js +764 -0
- package/build/cjs/background/handlers/State.js +472 -0
- package/build/cjs/background/handlers/Tabs.js +273 -0
- package/build/cjs/background/handlers/helpers.js +20 -0
- package/build/cjs/background/handlers/index.js +60 -0
- package/build/cjs/background/handlers/subscriptions.js +32 -0
- package/build/cjs/background/types.js +1 -0
- package/build/cjs/bundle.js +13 -0
- package/build/cjs/defaults.js +26 -0
- package/build/cjs/detectOther.js +17 -0
- package/build/cjs/detectPackage.js +14 -0
- package/build/cjs/index.js +18 -0
- package/build/cjs/package.json +3 -0
- package/build/cjs/packageInfo.js +16 -0
- package/build/cjs/page/Accounts.js +31 -0
- package/build/cjs/page/Injected.js +30 -0
- package/build/cjs/page/Metadata.js +27 -0
- package/build/cjs/page/PostMessageProvider.js +184 -0
- package/build/cjs/page/Signer.js +44 -0
- package/build/cjs/page/index.js +76 -0
- package/build/cjs/page/types.js +1 -0
- package/build/cjs/stores/Accounts.js +33 -0
- package/build/cjs/stores/Base.js +84 -0
- package/build/cjs/stores/Metadata.js +23 -0
- package/build/cjs/stores/index.js +23 -0
- package/build/cjs/types.js +1 -0
- package/build/cjs/utils/canDerive.js +12 -0
- package/build/cjs/utils/getId.js +16 -0
- package/build/cjs/utils/index.js +13 -0
- package/build/defaults.d.ts +10 -0
- package/build/defaults.js +12 -0
- package/build/detectOther.d.ts +7 -0
- package/build/detectOther.js +6 -0
- package/build/detectPackage.d.ts +1 -0
- package/build/detectPackage.js +7 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +5 -0
- package/build/package.json +210 -0
- package/build/packageInfo.d.ts +6 -0
- package/build/packageInfo.js +9 -0
- package/build/page/Accounts.d.ts +7 -0
- package/build/page/Accounts.js +22 -0
- package/build/page/Injected.d.ts +13 -0
- package/build/page/Injected.js +15 -0
- package/build/page/Metadata.d.ts +7 -0
- package/build/page/Metadata.js +18 -0
- package/build/page/PostMessageProvider.d.ts +62 -0
- package/build/page/PostMessageProvider.js +171 -0
- package/build/page/Signer.d.ts +8 -0
- package/build/page/Signer.js +35 -0
- package/build/page/index.d.ts +16 -0
- package/build/page/index.js +64 -0
- package/build/page/types.d.ts +6 -0
- package/build/page/types.js +1 -0
- package/build/stores/Accounts.d.ts +6 -0
- package/build/stores/Accounts.js +20 -0
- package/build/stores/Base.d.ts +10 -0
- package/build/stores/Base.js +74 -0
- package/build/stores/Metadata.d.ts +5 -0
- package/build/stores/Metadata.js +10 -0
- package/build/stores/index.d.ts +2 -0
- package/build/stores/index.js +4 -0
- package/build/types.d.ts +9 -0
- package/build/types.js +1 -0
- package/build/utils/canDerive.d.ts +2 -0
- package/build/utils/canDerive.js +5 -0
- package/build/utils/getId.d.ts +1 -0
- package/build/utils/getId.js +7 -0
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.js +3 -0
- package/build-cjs/background/KoniTypes.js +69 -0
- package/build-cjs/background/RequestBytesSign.js +27 -0
- package/build-cjs/background/RequestExtrinsicSign.js +23 -0
- package/build-cjs/background/handlers/Extension.js +764 -0
- package/build-cjs/background/handlers/State.js +472 -0
- package/build-cjs/background/handlers/Tabs.js +273 -0
- package/build-cjs/background/handlers/helpers.js +20 -0
- package/build-cjs/background/handlers/index.js +60 -0
- package/build-cjs/background/handlers/subscriptions.js +32 -0
- package/build-cjs/background/types.js +1 -0
- package/build-cjs/bundle.js +13 -0
- package/build-cjs/defaults.js +26 -0
- package/build-cjs/detectOther.js +17 -0
- package/build-cjs/detectPackage.js +14 -0
- package/build-cjs/index.js +18 -0
- package/build-cjs/packageInfo.js +16 -0
- package/build-cjs/page/Accounts.js +31 -0
- package/build-cjs/page/Injected.js +30 -0
- package/build-cjs/page/Metadata.js +27 -0
- package/build-cjs/page/PostMessageProvider.js +184 -0
- package/build-cjs/page/Signer.js +44 -0
- package/build-cjs/page/index.js +76 -0
- package/build-cjs/page/types.js +1 -0
- package/build-cjs/stores/Accounts.js +33 -0
- package/build-cjs/stores/Base.js +84 -0
- package/build-cjs/stores/Metadata.js +23 -0
- package/build-cjs/stores/index.js +23 -0
- package/build-cjs/types.js +1 -0
- package/build-cjs/utils/canDerive.js +12 -0
- package/build-cjs/utils/getId.js +16 -0
- package/build-cjs/utils/index.js +13 -0
- package/package.json +46 -0
- package/src/background/KoniTypes.ts +537 -0
- package/src/background/RequestBytesSign.ts +30 -0
- package/src/background/RequestExtrinsicSign.ts +23 -0
- package/src/background/handlers/Extension.spec.ts +456 -0
- package/src/background/handlers/Extension.ts +627 -0
- package/src/background/handlers/State.ts +513 -0
- package/src/background/handlers/Tabs.ts +223 -0
- package/src/background/handlers/helpers.ts +14 -0
- package/src/background/handlers/index.ts +49 -0
- package/src/background/handlers/subscriptions.ts +30 -0
- package/src/background/types.ts +437 -0
- package/src/bundle.ts +4 -0
- package/src/defaults.ts +24 -0
- package/src/detectOther.ts +8 -0
- package/src/detectPackage.ts +11 -0
- package/src/index.ts +7 -0
- package/src/packageInfo.ts +6 -0
- package/src/page/Accounts.ts +27 -0
- package/src/page/Injected.ts +27 -0
- package/src/page/Metadata.ts +22 -0
- package/src/page/PostMessageProvider.ts +178 -0
- package/src/page/Signer.ts +45 -0
- package/src/page/index.ts +87 -0
- package/src/page/types.ts +10 -0
- package/src/stores/Accounts.ts +24 -0
- package/src/stores/Base.ts +81 -0
- package/src/stores/Metadata.ts +13 -0
- package/src/stores/index.ts +5 -0
- package/src/types.ts +12 -0
- package/src/utils/canDerive.ts +8 -0
- package/src/utils/getId.ts +10 -0
- package/src/utils/index.ts +4 -0
- package/tsconfig.build.json +18 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/// <reference types="chrome" />
|
|
2
|
+
import type { MetadataDef, ProviderMeta } from '@subwallet/extension-inject/types';
|
|
3
|
+
import type { JsonRpcResponse, ProviderInterface, ProviderInterfaceCallback } from '@polkadot/rpc-provider/types';
|
|
4
|
+
import type { AccountJson, AuthorizeRequest, MetadataRequest, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe, RequestRpcUnsubscribe, RequestSign, ResponseRpcListProviders, ResponseSigning, SigningRequest } from '../types';
|
|
5
|
+
import { BehaviorSubject } from 'rxjs';
|
|
6
|
+
export interface Resolver<T> {
|
|
7
|
+
reject: (error: Error) => void;
|
|
8
|
+
resolve: (result: T) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface AuthRequest extends Resolver<boolean> {
|
|
11
|
+
id: string;
|
|
12
|
+
idStr: string;
|
|
13
|
+
request: RequestAuthorizeTab;
|
|
14
|
+
url: string;
|
|
15
|
+
}
|
|
16
|
+
export declare type AuthUrls = Record<string, AuthUrlInfo>;
|
|
17
|
+
export interface AuthUrlInfo {
|
|
18
|
+
count: number;
|
|
19
|
+
id: string;
|
|
20
|
+
isAllowed: boolean;
|
|
21
|
+
origin: string;
|
|
22
|
+
url: string;
|
|
23
|
+
isAllowedMap: Record<string, boolean>;
|
|
24
|
+
}
|
|
25
|
+
interface MetaRequest extends Resolver<boolean> {
|
|
26
|
+
id: string;
|
|
27
|
+
request: MetadataDef;
|
|
28
|
+
url: string;
|
|
29
|
+
}
|
|
30
|
+
declare type Providers = Record<string, {
|
|
31
|
+
meta: ProviderMeta;
|
|
32
|
+
start: () => ProviderInterface;
|
|
33
|
+
}>;
|
|
34
|
+
interface SignRequest extends Resolver<ResponseSigning> {
|
|
35
|
+
account: AccountJson;
|
|
36
|
+
id: string;
|
|
37
|
+
request: RequestSign;
|
|
38
|
+
url: string;
|
|
39
|
+
}
|
|
40
|
+
export declare enum NotificationOptions {
|
|
41
|
+
None = 0,
|
|
42
|
+
Normal = 1,
|
|
43
|
+
PopUp = 2
|
|
44
|
+
}
|
|
45
|
+
export default class State {
|
|
46
|
+
#private;
|
|
47
|
+
readonly authSubject: BehaviorSubject<AuthorizeRequest[]>;
|
|
48
|
+
readonly metaSubject: BehaviorSubject<MetadataRequest[]>;
|
|
49
|
+
readonly signSubject: BehaviorSubject<SigningRequest[]>;
|
|
50
|
+
constructor(providers?: Providers);
|
|
51
|
+
get knownMetadata(): MetadataDef[];
|
|
52
|
+
get numAuthRequests(): number;
|
|
53
|
+
get numMetaRequests(): number;
|
|
54
|
+
get numSignRequests(): number;
|
|
55
|
+
get allAuthRequests(): AuthorizeRequest[];
|
|
56
|
+
get allMetaRequests(): MetadataRequest[];
|
|
57
|
+
get allSignRequests(): SigningRequest[];
|
|
58
|
+
get authUrls(): AuthUrls;
|
|
59
|
+
protected popupClose(): void;
|
|
60
|
+
protected popupOpen(): void;
|
|
61
|
+
private authComplete;
|
|
62
|
+
private saveCurrentAuthList;
|
|
63
|
+
private metaComplete;
|
|
64
|
+
private signComplete;
|
|
65
|
+
stripUrl(url: string): string;
|
|
66
|
+
private updateIcon;
|
|
67
|
+
toggleAuthorization(url: string): AuthUrls;
|
|
68
|
+
private updateIconAuth;
|
|
69
|
+
private updateIconMeta;
|
|
70
|
+
private updateIconSign;
|
|
71
|
+
authorizeUrl(url: string, request: RequestAuthorizeTab): Promise<boolean>;
|
|
72
|
+
ensureUrlAuthorized(url: string): boolean;
|
|
73
|
+
injectMetadata(url: string, request: MetadataDef): Promise<boolean>;
|
|
74
|
+
getAuthRequest(id: string): AuthRequest;
|
|
75
|
+
getMetaRequest(id: string): MetaRequest;
|
|
76
|
+
getSignRequest(id: string): SignRequest;
|
|
77
|
+
rpcListProviders(): Promise<ResponseRpcListProviders>;
|
|
78
|
+
rpcSend(request: RequestRpcSend, port: chrome.runtime.Port): Promise<JsonRpcResponse>;
|
|
79
|
+
rpcStartProvider(key: string, port: chrome.runtime.Port): Promise<ProviderMeta>;
|
|
80
|
+
rpcSubscribe({ method, params, type }: RequestRpcSubscribe, cb: ProviderInterfaceCallback, port: chrome.runtime.Port): Promise<number | string>;
|
|
81
|
+
rpcSubscribeConnected(_request: null, cb: ProviderInterfaceCallback, port: chrome.runtime.Port): void;
|
|
82
|
+
rpcUnsubscribe(request: RequestRpcUnsubscribe, port: chrome.runtime.Port): Promise<boolean>;
|
|
83
|
+
saveMetadata(meta: MetadataDef): void;
|
|
84
|
+
setNotification(notification: string): boolean;
|
|
85
|
+
sign(url: string, request: RequestSign, account: AccountJson): Promise<ResponseSigning>;
|
|
86
|
+
}
|
|
87
|
+
export {};
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-bg authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
4
|
+
import { addMetadata, knownMetadata } from '@subwallet/extension-chains';
|
|
5
|
+
import { BehaviorSubject } from 'rxjs';
|
|
6
|
+
import { knownGenesis } from '@polkadot/networks/defaults';
|
|
7
|
+
import settings from '@polkadot/ui-settings';
|
|
8
|
+
import { assert } from '@polkadot/util';
|
|
9
|
+
import { MetadataStore } from "../../stores/index.js";
|
|
10
|
+
import { withErrorLog } from "./helpers.js";
|
|
11
|
+
const NOTIFICATION_URL = chrome.extension.getURL('notification.html');
|
|
12
|
+
const POPUP_WINDOW_OPTS = {
|
|
13
|
+
focused: true,
|
|
14
|
+
height: 621,
|
|
15
|
+
left: 150,
|
|
16
|
+
top: 150,
|
|
17
|
+
type: 'popup',
|
|
18
|
+
url: NOTIFICATION_URL,
|
|
19
|
+
width: 460
|
|
20
|
+
};
|
|
21
|
+
const NORMAL_WINDOW_OPTS = {
|
|
22
|
+
focused: true,
|
|
23
|
+
type: 'normal',
|
|
24
|
+
url: NOTIFICATION_URL
|
|
25
|
+
};
|
|
26
|
+
export let NotificationOptions;
|
|
27
|
+
|
|
28
|
+
(function (NotificationOptions) {
|
|
29
|
+
NotificationOptions[NotificationOptions["None"] = 0] = "None";
|
|
30
|
+
NotificationOptions[NotificationOptions["Normal"] = 1] = "Normal";
|
|
31
|
+
NotificationOptions[NotificationOptions["PopUp"] = 2] = "PopUp";
|
|
32
|
+
})(NotificationOptions || (NotificationOptions = {}));
|
|
33
|
+
|
|
34
|
+
const AUTH_URLS_KEY = 'authUrls';
|
|
35
|
+
|
|
36
|
+
function extractMetadata(store) {
|
|
37
|
+
store.allMap(map => {
|
|
38
|
+
const knownEntries = Object.entries(knownGenesis);
|
|
39
|
+
const defs = {};
|
|
40
|
+
const removals = [];
|
|
41
|
+
Object.entries(map).forEach(([key, def]) => {
|
|
42
|
+
const entry = knownEntries.find(([, hashes]) => hashes.includes(def.genesisHash));
|
|
43
|
+
|
|
44
|
+
if (entry) {
|
|
45
|
+
const [name, hashes] = entry;
|
|
46
|
+
const index = hashes.indexOf(def.genesisHash); // flatten the known metadata based on the genesis index
|
|
47
|
+
// (lower is better/newer)
|
|
48
|
+
|
|
49
|
+
if (!defs[name] || defs[name].index > index) {
|
|
50
|
+
if (defs[name]) {
|
|
51
|
+
// remove the old version of the metadata
|
|
52
|
+
removals.push(defs[name].key);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
defs[name] = {
|
|
56
|
+
def,
|
|
57
|
+
index,
|
|
58
|
+
key
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
// this is not a known entry, so we will just apply it
|
|
63
|
+
defs[key] = {
|
|
64
|
+
def,
|
|
65
|
+
index: 0,
|
|
66
|
+
key
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
removals.forEach(key => store.remove(key));
|
|
71
|
+
Object.values(defs).forEach(({
|
|
72
|
+
def
|
|
73
|
+
}) => addMetadata(def));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default class State {
|
|
78
|
+
#authUrls = {};
|
|
79
|
+
#authRequests = {};
|
|
80
|
+
#metaStore = new MetadataStore(); // Map of providers currently injected in tabs
|
|
81
|
+
|
|
82
|
+
#injectedProviders = new Map();
|
|
83
|
+
#metaRequests = {};
|
|
84
|
+
#notification = settings.notification; // Map of all providers exposed by the extension, they are retrievable by key
|
|
85
|
+
|
|
86
|
+
#providers;
|
|
87
|
+
#signRequests = {};
|
|
88
|
+
#windows = [];
|
|
89
|
+
authSubject = new BehaviorSubject([]);
|
|
90
|
+
metaSubject = new BehaviorSubject([]);
|
|
91
|
+
signSubject = new BehaviorSubject([]);
|
|
92
|
+
|
|
93
|
+
constructor(providers = {}) {
|
|
94
|
+
this.#providers = providers;
|
|
95
|
+
extractMetadata(this.#metaStore); // retrieve previously set authorizations
|
|
96
|
+
|
|
97
|
+
const authString = localStorage.getItem(AUTH_URLS_KEY) || '{}';
|
|
98
|
+
const previousAuth = JSON.parse(authString);
|
|
99
|
+
this.#authUrls = previousAuth;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get knownMetadata() {
|
|
103
|
+
return knownMetadata();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get numAuthRequests() {
|
|
107
|
+
return Object.keys(this.#authRequests).length;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get numMetaRequests() {
|
|
111
|
+
return Object.keys(this.#metaRequests).length;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get numSignRequests() {
|
|
115
|
+
return Object.keys(this.#signRequests).length;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get allAuthRequests() {
|
|
119
|
+
return Object.values(this.#authRequests).map(({
|
|
120
|
+
id,
|
|
121
|
+
request,
|
|
122
|
+
url
|
|
123
|
+
}) => ({
|
|
124
|
+
id,
|
|
125
|
+
request,
|
|
126
|
+
url
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get allMetaRequests() {
|
|
131
|
+
return Object.values(this.#metaRequests).map(({
|
|
132
|
+
id,
|
|
133
|
+
request,
|
|
134
|
+
url
|
|
135
|
+
}) => ({
|
|
136
|
+
id,
|
|
137
|
+
request,
|
|
138
|
+
url
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get allSignRequests() {
|
|
143
|
+
return Object.values(this.#signRequests).map(({
|
|
144
|
+
account,
|
|
145
|
+
id,
|
|
146
|
+
request,
|
|
147
|
+
url
|
|
148
|
+
}) => ({
|
|
149
|
+
account,
|
|
150
|
+
id,
|
|
151
|
+
request,
|
|
152
|
+
url
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get authUrls() {
|
|
157
|
+
return this.#authUrls;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
popupClose() {
|
|
161
|
+
this.#windows.forEach(id => withErrorLog(() => chrome.windows.remove(id)));
|
|
162
|
+
this.#windows = [];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
popupOpen() {
|
|
166
|
+
this.#notification !== 'extension' && chrome.windows.create(this.#notification === 'window' ? NORMAL_WINDOW_OPTS : POPUP_WINDOW_OPTS, window => {
|
|
167
|
+
if (window) {
|
|
168
|
+
this.#windows.push(window.id || 0);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
authComplete = (id, resolve, reject) => {
|
|
174
|
+
const complete = result => {
|
|
175
|
+
const isAllowed = result === true;
|
|
176
|
+
const {
|
|
177
|
+
idStr,
|
|
178
|
+
request: {
|
|
179
|
+
origin
|
|
180
|
+
},
|
|
181
|
+
url
|
|
182
|
+
} = this.#authRequests[id];
|
|
183
|
+
const isAllowedMap = {};
|
|
184
|
+
this.#authUrls[this.stripUrl(url)] = {
|
|
185
|
+
count: 0,
|
|
186
|
+
id: idStr,
|
|
187
|
+
isAllowed,
|
|
188
|
+
isAllowedMap,
|
|
189
|
+
origin,
|
|
190
|
+
url
|
|
191
|
+
};
|
|
192
|
+
this.saveCurrentAuthList();
|
|
193
|
+
delete this.#authRequests[id];
|
|
194
|
+
this.updateIconAuth(true);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
reject: error => {
|
|
199
|
+
complete(error);
|
|
200
|
+
reject(error);
|
|
201
|
+
},
|
|
202
|
+
resolve: result => {
|
|
203
|
+
complete(result);
|
|
204
|
+
resolve(result);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
saveCurrentAuthList() {
|
|
210
|
+
localStorage.setItem(AUTH_URLS_KEY, JSON.stringify(this.#authUrls));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
metaComplete = (id, resolve, reject) => {
|
|
214
|
+
const complete = () => {
|
|
215
|
+
delete this.#metaRequests[id];
|
|
216
|
+
this.updateIconMeta(true);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
reject: error => {
|
|
221
|
+
complete();
|
|
222
|
+
reject(error);
|
|
223
|
+
},
|
|
224
|
+
resolve: result => {
|
|
225
|
+
complete();
|
|
226
|
+
resolve(result);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
signComplete = (id, resolve, reject) => {
|
|
231
|
+
const complete = () => {
|
|
232
|
+
delete this.#signRequests[id];
|
|
233
|
+
this.updateIconSign(true);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
reject: error => {
|
|
238
|
+
complete();
|
|
239
|
+
reject(error);
|
|
240
|
+
},
|
|
241
|
+
resolve: result => {
|
|
242
|
+
complete();
|
|
243
|
+
resolve(result);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
stripUrl(url) {
|
|
249
|
+
assert(url && (url.startsWith('http:') || url.startsWith('https:') || url.startsWith('ipfs:') || url.startsWith('ipns:')), `Invalid url ${url}, expected to start with http: or https: or ipfs: or ipns:`);
|
|
250
|
+
const parts = url.split('/');
|
|
251
|
+
return parts[2];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
updateIcon(shouldClose) {
|
|
255
|
+
const authCount = this.numAuthRequests;
|
|
256
|
+
const metaCount = this.numMetaRequests;
|
|
257
|
+
const signCount = this.numSignRequests;
|
|
258
|
+
const text = authCount ? 'Auth' : metaCount ? 'Meta' : signCount ? `${signCount}` : '';
|
|
259
|
+
withErrorLog(() => chrome.browserAction.setBadgeText({
|
|
260
|
+
text
|
|
261
|
+
}));
|
|
262
|
+
|
|
263
|
+
if (shouldClose && text === '') {
|
|
264
|
+
this.popupClose();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
toggleAuthorization(url) {
|
|
269
|
+
const entry = this.#authUrls[url];
|
|
270
|
+
assert(entry, `The source ${url} is not known`);
|
|
271
|
+
this.#authUrls[url].isAllowed = !entry.isAllowed;
|
|
272
|
+
this.saveCurrentAuthList();
|
|
273
|
+
return this.#authUrls;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
updateIconAuth(shouldClose) {
|
|
277
|
+
this.authSubject.next(this.allAuthRequests);
|
|
278
|
+
this.updateIcon(shouldClose);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
updateIconMeta(shouldClose) {
|
|
282
|
+
this.metaSubject.next(this.allMetaRequests);
|
|
283
|
+
this.updateIcon(shouldClose);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
updateIconSign(shouldClose) {
|
|
287
|
+
this.signSubject.next(this.allSignRequests);
|
|
288
|
+
this.updateIcon(shouldClose);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async authorizeUrl(url, request) {
|
|
292
|
+
const idStr = this.stripUrl(url); // Do not enqueue duplicate authorization requests.
|
|
293
|
+
|
|
294
|
+
const isDuplicate = Object.values(this.#authRequests).some(request => request.idStr === idStr);
|
|
295
|
+
assert(!isDuplicate, `The source ${url} has a pending authorization request`);
|
|
296
|
+
|
|
297
|
+
if (this.#authUrls[idStr]) {
|
|
298
|
+
// this url was seen in the past
|
|
299
|
+
assert(this.#authUrls[idStr].isAllowed, `The source ${url} is not allowed to interact with this extension`);
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return new Promise((resolve, reject) => {
|
|
304
|
+
const id = getId();
|
|
305
|
+
this.#authRequests[id] = { ...this.authComplete(id, resolve, reject),
|
|
306
|
+
id,
|
|
307
|
+
idStr,
|
|
308
|
+
request,
|
|
309
|
+
url
|
|
310
|
+
};
|
|
311
|
+
this.updateIconAuth();
|
|
312
|
+
this.popupOpen();
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
ensureUrlAuthorized(url) {
|
|
317
|
+
const entry = this.#authUrls[this.stripUrl(url)];
|
|
318
|
+
assert(entry, `The source ${url} has not been enabled yet`);
|
|
319
|
+
assert(entry.isAllowed, `The source ${url} is not allowed to interact with this extension`);
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
injectMetadata(url, request) {
|
|
324
|
+
return new Promise((resolve, reject) => {
|
|
325
|
+
const id = getId();
|
|
326
|
+
this.#metaRequests[id] = { ...this.metaComplete(id, resolve, reject),
|
|
327
|
+
id,
|
|
328
|
+
request,
|
|
329
|
+
url
|
|
330
|
+
};
|
|
331
|
+
this.updateIconMeta();
|
|
332
|
+
this.popupOpen();
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
getAuthRequest(id) {
|
|
337
|
+
return this.#authRequests[id];
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
getMetaRequest(id) {
|
|
341
|
+
return this.#metaRequests[id];
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
getSignRequest(id) {
|
|
345
|
+
return this.#signRequests[id];
|
|
346
|
+
} // List all providers the extension is exposing
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
rpcListProviders() {
|
|
350
|
+
return Promise.resolve(Object.keys(this.#providers).reduce((acc, key) => {
|
|
351
|
+
acc[key] = this.#providers[key].meta;
|
|
352
|
+
return acc;
|
|
353
|
+
}, {}));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
rpcSend(request, port) {
|
|
357
|
+
const provider = this.#injectedProviders.get(port);
|
|
358
|
+
assert(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
|
|
359
|
+
return provider.send(request.method, request.params);
|
|
360
|
+
} // Start a provider, return its meta
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
rpcStartProvider(key, port) {
|
|
364
|
+
assert(Object.keys(this.#providers).includes(key), `Provider ${key} is not exposed by extension`);
|
|
365
|
+
|
|
366
|
+
if (this.#injectedProviders.get(port)) {
|
|
367
|
+
return Promise.resolve(this.#providers[key].meta);
|
|
368
|
+
} // Instantiate the provider
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
this.#injectedProviders.set(port, this.#providers[key].start()); // Close provider connection when page is closed
|
|
372
|
+
|
|
373
|
+
port.onDisconnect.addListener(() => {
|
|
374
|
+
const provider = this.#injectedProviders.get(port);
|
|
375
|
+
|
|
376
|
+
if (provider) {
|
|
377
|
+
withErrorLog(() => provider.disconnect());
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
this.#injectedProviders.delete(port);
|
|
381
|
+
});
|
|
382
|
+
return Promise.resolve(this.#providers[key].meta);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
rpcSubscribe({
|
|
386
|
+
method,
|
|
387
|
+
params,
|
|
388
|
+
type
|
|
389
|
+
}, cb, port) {
|
|
390
|
+
const provider = this.#injectedProviders.get(port);
|
|
391
|
+
assert(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
|
|
392
|
+
return provider.subscribe(type, method, params, cb);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
rpcSubscribeConnected(_request, cb, port) {
|
|
396
|
+
const provider = this.#injectedProviders.get(port);
|
|
397
|
+
assert(provider, 'Cannot call pub(rpc.subscribeConnected) before provider is set');
|
|
398
|
+
cb(null, provider.isConnected); // Immediately send back current isConnected
|
|
399
|
+
|
|
400
|
+
provider.on('connected', () => cb(null, true));
|
|
401
|
+
provider.on('disconnected', () => cb(null, false));
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
rpcUnsubscribe(request, port) {
|
|
405
|
+
const provider = this.#injectedProviders.get(port);
|
|
406
|
+
assert(provider, 'Cannot call pub(rpc.unsubscribe) before provider is set');
|
|
407
|
+
return provider.unsubscribe(request.type, request.method, request.subscriptionId);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
saveMetadata(meta) {
|
|
411
|
+
this.#metaStore.set(meta.genesisHash, meta);
|
|
412
|
+
addMetadata(meta);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
setNotification(notification) {
|
|
416
|
+
this.#notification = notification;
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
sign(url, request, account) {
|
|
421
|
+
const id = getId();
|
|
422
|
+
return new Promise((resolve, reject) => {
|
|
423
|
+
this.#signRequests[id] = { ...this.signComplete(id, resolve, reject),
|
|
424
|
+
account,
|
|
425
|
+
id,
|
|
426
|
+
request,
|
|
427
|
+
url
|
|
428
|
+
};
|
|
429
|
+
this.updateIconSign();
|
|
430
|
+
this.popupOpen();
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/// <reference types="chrome" />
|
|
2
|
+
import type { MessageTypes, RequestTypes, ResponseTypes } from '../types';
|
|
3
|
+
import State from './State';
|
|
4
|
+
export default class Tabs {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(state: State);
|
|
7
|
+
private authorize;
|
|
8
|
+
private accountsList;
|
|
9
|
+
private accountsSubscribe;
|
|
10
|
+
private getSigningPair;
|
|
11
|
+
private bytesSign;
|
|
12
|
+
private extrinsicSign;
|
|
13
|
+
private metadataProvide;
|
|
14
|
+
private metadataList;
|
|
15
|
+
private rpcListProviders;
|
|
16
|
+
private rpcSend;
|
|
17
|
+
private rpcStartProvider;
|
|
18
|
+
private rpcSubscribe;
|
|
19
|
+
private rpcSubscribeConnected;
|
|
20
|
+
private rpcUnsubscribe;
|
|
21
|
+
private redirectPhishingLanding;
|
|
22
|
+
protected redirectIfPhishing(url: string): Promise<boolean>;
|
|
23
|
+
handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], url: string, port: chrome.runtime.Port): Promise<ResponseTypes[keyof ResponseTypes]>;
|
|
24
|
+
}
|