@polkadot/extension-base 0.59.1 → 0.60.1
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/background/handlers/Extension.js +34 -34
- package/background/handlers/State.js +87 -69
- package/background/handlers/Tabs.js +21 -21
- package/cjs/background/handlers/Extension.js +34 -34
- package/cjs/background/handlers/State.js +87 -69
- package/cjs/background/handlers/Tabs.js +21 -21
- package/cjs/packageInfo.js +1 -1
- package/cjs/page/PostMessageProvider.js +15 -15
- package/cjs/stores/Base.js +7 -7
- package/package.json +14 -14
- package/packageInfo.js +1 -1
- package/page/PostMessageProvider.js +15 -15
- package/stores/Base.js +7 -7
|
@@ -66,35 +66,35 @@ async function extractMetadata(store) {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
class State {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
#authUrls = new Map();
|
|
70
|
+
#authRequests = {};
|
|
71
|
+
#metaStore = new index_js_1.MetadataStore();
|
|
72
72
|
// Map of providers currently injected in tabs
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
#injectedProviders = new Map();
|
|
74
|
+
#metaRequests = {};
|
|
75
|
+
#notification = ui_settings_1.settings.notification;
|
|
76
76
|
// Map of all providers exposed by the extension, they are retrievable by key
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
#providers;
|
|
78
|
+
#signRequests = {};
|
|
79
|
+
#windows = [];
|
|
80
|
+
#connectedTabsUrl = [];
|
|
81
81
|
authSubject = new rxjs_1.BehaviorSubject([]);
|
|
82
82
|
metaSubject = new rxjs_1.BehaviorSubject([]);
|
|
83
83
|
signSubject = new rxjs_1.BehaviorSubject([]);
|
|
84
84
|
authUrlSubjects = {};
|
|
85
85
|
defaultAuthAccountSelection = [];
|
|
86
86
|
constructor(providers = {}) {
|
|
87
|
-
this
|
|
87
|
+
this.#providers = providers;
|
|
88
88
|
}
|
|
89
89
|
async init() {
|
|
90
|
-
await extractMetadata(this
|
|
90
|
+
await extractMetadata(this.#metaStore);
|
|
91
91
|
// retrieve previously set authorizations
|
|
92
92
|
const storageAuthUrls = await chrome.storage.local.get(AUTH_URLS_KEY);
|
|
93
93
|
const authString = storageAuthUrls?.[AUTH_URLS_KEY] || '{}';
|
|
94
94
|
const previousAuth = JSON.parse(authString);
|
|
95
|
-
this
|
|
95
|
+
this.#authUrls = new Map(Object.entries(previousAuth));
|
|
96
96
|
// Initialize authUrlSubjects for each URL
|
|
97
|
-
|
|
97
|
+
this.#authUrls.forEach((authInfo, url) => {
|
|
98
98
|
this.authUrlSubjects[url] = new rxjs_1.BehaviorSubject(authInfo);
|
|
99
99
|
});
|
|
100
100
|
// retrieve previously set default auth accounts
|
|
@@ -107,49 +107,49 @@ class State {
|
|
|
107
107
|
return (0, extension_chains_1.knownMetadata)();
|
|
108
108
|
}
|
|
109
109
|
get numAuthRequests() {
|
|
110
|
-
return Object.keys(this
|
|
110
|
+
return Object.keys(this.#authRequests).length;
|
|
111
111
|
}
|
|
112
112
|
get numMetaRequests() {
|
|
113
|
-
return Object.keys(this
|
|
113
|
+
return Object.keys(this.#metaRequests).length;
|
|
114
114
|
}
|
|
115
115
|
get numSignRequests() {
|
|
116
|
-
return Object.keys(this
|
|
116
|
+
return Object.keys(this.#signRequests).length;
|
|
117
117
|
}
|
|
118
118
|
get allAuthRequests() {
|
|
119
119
|
return Object
|
|
120
|
-
.values(this
|
|
120
|
+
.values(this.#authRequests)
|
|
121
121
|
.map(({ id, request, url }) => ({ id, request, url }));
|
|
122
122
|
}
|
|
123
123
|
get allMetaRequests() {
|
|
124
124
|
return Object
|
|
125
|
-
.values(this
|
|
125
|
+
.values(this.#metaRequests)
|
|
126
126
|
.map(({ id, request, url }) => ({ id, request, url }));
|
|
127
127
|
}
|
|
128
128
|
get allSignRequests() {
|
|
129
129
|
return Object
|
|
130
|
-
.values(this
|
|
130
|
+
.values(this.#signRequests)
|
|
131
131
|
.map(({ account, id, request, url }) => ({ account, id, request, url }));
|
|
132
132
|
}
|
|
133
133
|
get authUrls() {
|
|
134
|
-
return this
|
|
134
|
+
return Object.fromEntries(this.#authUrls);
|
|
135
135
|
}
|
|
136
136
|
popupClose() {
|
|
137
|
-
this.
|
|
138
|
-
this
|
|
137
|
+
this.#windows.forEach((id) => (0, helpers_js_1.withErrorLog)(() => chrome.windows.remove(id)));
|
|
138
|
+
this.#windows = [];
|
|
139
139
|
}
|
|
140
140
|
popupOpen() {
|
|
141
|
-
this
|
|
142
|
-
chrome.windows.create(this
|
|
141
|
+
this.#notification !== 'extension' &&
|
|
142
|
+
chrome.windows.create(this.#notification === 'window'
|
|
143
143
|
? NORMAL_WINDOW_OPTS
|
|
144
144
|
: POPUP_WINDOW_OPTS, (window) => {
|
|
145
145
|
if (window) {
|
|
146
|
-
this.
|
|
146
|
+
this.#windows.push(window.id || 0);
|
|
147
147
|
}
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
150
|
authComplete = (id, resolve, reject) => {
|
|
151
151
|
const complete = async (authorizedAccounts = []) => {
|
|
152
|
-
const { idStr, request: { origin }, url } = this
|
|
152
|
+
const { idStr, request: { origin }, url } = this.#authRequests[id];
|
|
153
153
|
const strippedUrl = this.stripUrl(url);
|
|
154
154
|
const authInfo = {
|
|
155
155
|
authorizedAccounts,
|
|
@@ -158,7 +158,7 @@ class State {
|
|
|
158
158
|
origin,
|
|
159
159
|
url
|
|
160
160
|
};
|
|
161
|
-
this.
|
|
161
|
+
this.#authUrls.set(strippedUrl, authInfo);
|
|
162
162
|
if (!this.authUrlSubjects[strippedUrl]) {
|
|
163
163
|
this.authUrlSubjects[strippedUrl] = new rxjs_1.BehaviorSubject(authInfo);
|
|
164
164
|
}
|
|
@@ -167,14 +167,14 @@ class State {
|
|
|
167
167
|
}
|
|
168
168
|
await this.saveCurrentAuthList();
|
|
169
169
|
await this.updateDefaultAuthAccounts(authorizedAccounts);
|
|
170
|
-
delete this
|
|
170
|
+
delete this.#authRequests[id];
|
|
171
171
|
this.updateIconAuth(true);
|
|
172
172
|
};
|
|
173
173
|
return {
|
|
174
174
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
175
175
|
reject: async (error) => {
|
|
176
176
|
if (error.message === 'Cancelled') {
|
|
177
|
-
delete this
|
|
177
|
+
delete this.#authRequests[id];
|
|
178
178
|
this.updateIconAuth(true);
|
|
179
179
|
reject(new Error('Connection request was cancelled by the user.'));
|
|
180
180
|
}
|
|
@@ -212,17 +212,17 @@ class State {
|
|
|
212
212
|
: undefined;
|
|
213
213
|
})
|
|
214
214
|
.filter((value) => !!value);
|
|
215
|
-
this
|
|
215
|
+
this.#connectedTabsUrl = connectedTabs;
|
|
216
216
|
}
|
|
217
217
|
getConnectedTabsUrl() {
|
|
218
|
-
return this
|
|
218
|
+
return this.#connectedTabsUrl;
|
|
219
219
|
}
|
|
220
220
|
deleteAuthRequest(requestId) {
|
|
221
|
-
delete this
|
|
221
|
+
delete this.#authRequests[requestId];
|
|
222
222
|
this.updateIconAuth(true);
|
|
223
223
|
}
|
|
224
224
|
async saveCurrentAuthList() {
|
|
225
|
-
await chrome.storage.local.set({ [AUTH_URLS_KEY]: JSON.stringify(this
|
|
225
|
+
await chrome.storage.local.set({ [AUTH_URLS_KEY]: JSON.stringify(Object.fromEntries(this.#authUrls)) });
|
|
226
226
|
}
|
|
227
227
|
async saveDefaultAuthAccounts() {
|
|
228
228
|
await chrome.storage.local.set({ [DEFAULT_AUTH_ACCOUNTS]: JSON.stringify(this.defaultAuthAccountSelection) });
|
|
@@ -233,7 +233,7 @@ class State {
|
|
|
233
233
|
}
|
|
234
234
|
metaComplete = (id, resolve, reject) => {
|
|
235
235
|
const complete = () => {
|
|
236
|
-
delete this
|
|
236
|
+
delete this.#metaRequests[id];
|
|
237
237
|
this.updateIconMeta(true);
|
|
238
238
|
};
|
|
239
239
|
return {
|
|
@@ -249,7 +249,7 @@ class State {
|
|
|
249
249
|
};
|
|
250
250
|
signComplete = (id, resolve, reject) => {
|
|
251
251
|
const complete = () => {
|
|
252
|
-
delete this
|
|
252
|
+
delete this.#signRequests[id];
|
|
253
253
|
this.updateIconSign(true);
|
|
254
254
|
};
|
|
255
255
|
return {
|
|
@@ -264,9 +264,22 @@ class State {
|
|
|
264
264
|
};
|
|
265
265
|
};
|
|
266
266
|
stripUrl(url) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
267
|
+
try {
|
|
268
|
+
const parsedUrl = new URL(url);
|
|
269
|
+
if (!['http:', 'https:', 'ipfs:', 'ipns:'].includes(parsedUrl.protocol)) {
|
|
270
|
+
throw new Error(`Invalid protocol ${parsedUrl.protocol}`);
|
|
271
|
+
}
|
|
272
|
+
// For ipfs/ipns which don't have a standard origin, we handle it differently.
|
|
273
|
+
if (parsedUrl.protocol === 'ipfs:' || parsedUrl.protocol === 'ipns:') {
|
|
274
|
+
// ipfs://<hash> | ipns://<hash>
|
|
275
|
+
return `${parsedUrl.protocol}//${parsedUrl.hostname}`;
|
|
276
|
+
}
|
|
277
|
+
return parsedUrl.origin;
|
|
278
|
+
}
|
|
279
|
+
catch (e) {
|
|
280
|
+
console.error(e);
|
|
281
|
+
throw new Error('Invalid URL');
|
|
282
|
+
}
|
|
270
283
|
}
|
|
271
284
|
updateIcon(shouldClose) {
|
|
272
285
|
const authCount = this.numAuthRequests;
|
|
@@ -283,15 +296,15 @@ class State {
|
|
|
283
296
|
}
|
|
284
297
|
}
|
|
285
298
|
async removeAuthorization(url) {
|
|
286
|
-
const entry = this.
|
|
299
|
+
const entry = this.#authUrls.get(url);
|
|
287
300
|
(0, util_1.assert)(entry, `The source ${url} is not known`);
|
|
288
|
-
|
|
301
|
+
this.#authUrls.delete(url);
|
|
289
302
|
await this.saveCurrentAuthList();
|
|
290
303
|
if (this.authUrlSubjects[url]) {
|
|
291
304
|
entry.authorizedAccounts = [];
|
|
292
305
|
this.authUrlSubjects[url].next(entry);
|
|
293
306
|
}
|
|
294
|
-
return this.
|
|
307
|
+
return this.authUrls;
|
|
295
308
|
}
|
|
296
309
|
updateIconAuth(shouldClose) {
|
|
297
310
|
this.authSubject.next(this.allAuthRequests);
|
|
@@ -307,8 +320,12 @@ class State {
|
|
|
307
320
|
}
|
|
308
321
|
async updateAuthorizedAccounts(authorizedAccountsDiff) {
|
|
309
322
|
authorizedAccountsDiff.forEach(([url, authorizedAccountDiff]) => {
|
|
310
|
-
this.
|
|
311
|
-
|
|
323
|
+
const authInfo = this.#authUrls.get(url);
|
|
324
|
+
if (authInfo) {
|
|
325
|
+
authInfo.authorizedAccounts = authorizedAccountDiff;
|
|
326
|
+
this.#authUrls.set(url, authInfo);
|
|
327
|
+
this.authUrlSubjects[url].next(authInfo);
|
|
328
|
+
}
|
|
312
329
|
});
|
|
313
330
|
await this.saveCurrentAuthList();
|
|
314
331
|
}
|
|
@@ -316,12 +333,13 @@ class State {
|
|
|
316
333
|
const idStr = this.stripUrl(url);
|
|
317
334
|
// Do not enqueue duplicate authorization requests.
|
|
318
335
|
const isDuplicate = Object
|
|
319
|
-
.values(this
|
|
336
|
+
.values(this.#authRequests)
|
|
320
337
|
.some((request) => request.idStr === idStr);
|
|
321
338
|
(0, util_1.assert)(!isDuplicate, `The source ${url} has a pending authorization request`);
|
|
322
|
-
if (this.
|
|
339
|
+
if (this.#authUrls.has(idStr)) {
|
|
323
340
|
// this url was seen in the past
|
|
324
|
-
|
|
341
|
+
const authInfo = this.#authUrls.get(idStr);
|
|
342
|
+
(0, util_1.assert)(authInfo?.authorizedAccounts || authInfo?.isAllowed, `The source ${url} is not allowed to interact with this extension`);
|
|
325
343
|
return {
|
|
326
344
|
authorizedAccounts: [],
|
|
327
345
|
result: false
|
|
@@ -329,7 +347,7 @@ class State {
|
|
|
329
347
|
}
|
|
330
348
|
return new Promise((resolve, reject) => {
|
|
331
349
|
const id = (0, getId_js_1.getId)();
|
|
332
|
-
this
|
|
350
|
+
this.#authRequests[id] = {
|
|
333
351
|
...this.authComplete(id, resolve, reject),
|
|
334
352
|
id,
|
|
335
353
|
idStr,
|
|
@@ -341,14 +359,14 @@ class State {
|
|
|
341
359
|
});
|
|
342
360
|
}
|
|
343
361
|
ensureUrlAuthorized(url) {
|
|
344
|
-
const entry = this.
|
|
362
|
+
const entry = this.#authUrls.get(this.stripUrl(url));
|
|
345
363
|
(0, util_1.assert)(entry, `The source ${url} has not been enabled yet`);
|
|
346
364
|
return true;
|
|
347
365
|
}
|
|
348
366
|
injectMetadata(url, request) {
|
|
349
367
|
return new Promise((resolve, reject) => {
|
|
350
368
|
const id = (0, getId_js_1.getId)();
|
|
351
|
-
this
|
|
369
|
+
this.#metaRequests[id] = {
|
|
352
370
|
...this.metaComplete(id, resolve, reject),
|
|
353
371
|
id,
|
|
354
372
|
request,
|
|
@@ -359,73 +377,73 @@ class State {
|
|
|
359
377
|
});
|
|
360
378
|
}
|
|
361
379
|
getAuthRequest(id) {
|
|
362
|
-
return this
|
|
380
|
+
return this.#authRequests[id];
|
|
363
381
|
}
|
|
364
382
|
getMetaRequest(id) {
|
|
365
|
-
return this
|
|
383
|
+
return this.#metaRequests[id];
|
|
366
384
|
}
|
|
367
385
|
getSignRequest(id) {
|
|
368
|
-
return this
|
|
386
|
+
return this.#signRequests[id];
|
|
369
387
|
}
|
|
370
388
|
// List all providers the extension is exposing
|
|
371
389
|
rpcListProviders() {
|
|
372
|
-
return Promise.resolve(Object.keys(this
|
|
373
|
-
acc[key] = this
|
|
390
|
+
return Promise.resolve(Object.keys(this.#providers).reduce((acc, key) => {
|
|
391
|
+
acc[key] = this.#providers[key].meta;
|
|
374
392
|
return acc;
|
|
375
393
|
}, {}));
|
|
376
394
|
}
|
|
377
395
|
rpcSend(request, port) {
|
|
378
|
-
const provider = this.
|
|
396
|
+
const provider = this.#injectedProviders.get(port);
|
|
379
397
|
(0, util_1.assert)(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
|
|
380
398
|
return provider.send(request.method, request.params);
|
|
381
399
|
}
|
|
382
400
|
// Start a provider, return its meta
|
|
383
401
|
rpcStartProvider(key, port) {
|
|
384
|
-
(0, util_1.assert)(Object.keys(this
|
|
385
|
-
if (this.
|
|
386
|
-
return Promise.resolve(this
|
|
402
|
+
(0, util_1.assert)(Object.keys(this.#providers).includes(key), `Provider ${key} is not exposed by extension`);
|
|
403
|
+
if (this.#injectedProviders.get(port)) {
|
|
404
|
+
return Promise.resolve(this.#providers[key].meta);
|
|
387
405
|
}
|
|
388
406
|
// Instantiate the provider
|
|
389
|
-
this.
|
|
407
|
+
this.#injectedProviders.set(port, this.#providers[key].start());
|
|
390
408
|
// Close provider connection when page is closed
|
|
391
409
|
port.onDisconnect.addListener(() => {
|
|
392
|
-
const provider = this.
|
|
410
|
+
const provider = this.#injectedProviders.get(port);
|
|
393
411
|
if (provider) {
|
|
394
412
|
(0, helpers_js_1.withErrorLog)(() => provider.disconnect());
|
|
395
413
|
}
|
|
396
|
-
this.
|
|
414
|
+
this.#injectedProviders.delete(port);
|
|
397
415
|
});
|
|
398
|
-
return Promise.resolve(this
|
|
416
|
+
return Promise.resolve(this.#providers[key].meta);
|
|
399
417
|
}
|
|
400
418
|
rpcSubscribe({ method, params, type }, cb, port) {
|
|
401
|
-
const provider = this.
|
|
419
|
+
const provider = this.#injectedProviders.get(port);
|
|
402
420
|
(0, util_1.assert)(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
|
|
403
421
|
return provider.subscribe(type, method, params, cb);
|
|
404
422
|
}
|
|
405
423
|
rpcSubscribeConnected(_request, cb, port) {
|
|
406
|
-
const provider = this.
|
|
424
|
+
const provider = this.#injectedProviders.get(port);
|
|
407
425
|
(0, util_1.assert)(provider, 'Cannot call pub(rpc.subscribeConnected) before provider is set');
|
|
408
426
|
cb(null, provider.isConnected); // Immediately send back current isConnected
|
|
409
427
|
provider.on('connected', () => cb(null, true));
|
|
410
428
|
provider.on('disconnected', () => cb(null, false));
|
|
411
429
|
}
|
|
412
430
|
rpcUnsubscribe(request, port) {
|
|
413
|
-
const provider = this.
|
|
431
|
+
const provider = this.#injectedProviders.get(port);
|
|
414
432
|
(0, util_1.assert)(provider, 'Cannot call pub(rpc.unsubscribe) before provider is set');
|
|
415
433
|
return provider.unsubscribe(request.type, request.method, request.subscriptionId);
|
|
416
434
|
}
|
|
417
435
|
async saveMetadata(meta) {
|
|
418
|
-
await this.
|
|
436
|
+
await this.#metaStore.set(meta.genesisHash, meta);
|
|
419
437
|
(0, extension_chains_1.addMetadata)(meta);
|
|
420
438
|
}
|
|
421
439
|
setNotification(notification) {
|
|
422
|
-
this
|
|
440
|
+
this.#notification = notification;
|
|
423
441
|
return true;
|
|
424
442
|
}
|
|
425
443
|
sign(url, request, account) {
|
|
426
444
|
const id = (0, getId_js_1.getId)();
|
|
427
445
|
return new Promise((resolve, reject) => {
|
|
428
|
-
this
|
|
446
|
+
this.#signRequests[id] = {
|
|
429
447
|
...this.signComplete(id, resolve, reject),
|
|
430
448
|
account,
|
|
431
449
|
id,
|
|
@@ -26,13 +26,13 @@ function transformAccounts(accounts, anyType = false) {
|
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
28
28
|
class Tabs {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
#accountSubs = {};
|
|
30
|
+
#state;
|
|
31
31
|
constructor(state) {
|
|
32
|
-
this
|
|
32
|
+
this.#state = state;
|
|
33
33
|
}
|
|
34
34
|
filterForAuthorizedAccounts(accounts, url) {
|
|
35
|
-
const auth = this.
|
|
35
|
+
const auth = this.#state.authUrls[this.#state.stripUrl(url)];
|
|
36
36
|
if (!auth) {
|
|
37
37
|
return [];
|
|
38
38
|
}
|
|
@@ -43,7 +43,7 @@ class Tabs {
|
|
|
43
43
|
: auth.isAllowed);
|
|
44
44
|
}
|
|
45
45
|
authorize(url, request) {
|
|
46
|
-
return this.
|
|
46
|
+
return this.#state.authorizeUrl(url, request);
|
|
47
47
|
}
|
|
48
48
|
accountsListAuthorized(url, { anyType }) {
|
|
49
49
|
const transformedAccounts = transformAccounts(accounts_1.accounts.subject.getValue(), anyType);
|
|
@@ -51,13 +51,13 @@ class Tabs {
|
|
|
51
51
|
}
|
|
52
52
|
accountsSubscribeAuthorized(url, id, port) {
|
|
53
53
|
const cb = (0, subscriptions_js_1.createSubscription)(id, port);
|
|
54
|
-
const strippedUrl = this.
|
|
55
|
-
const authUrlObservable = this.
|
|
54
|
+
const strippedUrl = this.#state.stripUrl(url);
|
|
55
|
+
const authUrlObservable = this.#state.authUrlSubjects[strippedUrl]?.asObservable();
|
|
56
56
|
if (!authUrlObservable) {
|
|
57
57
|
console.error(`No authUrlSubject found for ${strippedUrl}`);
|
|
58
58
|
return id;
|
|
59
59
|
}
|
|
60
|
-
this
|
|
60
|
+
this.#accountSubs[id] = {
|
|
61
61
|
subscription: (0, rxjs_1.combineLatest)([accounts_1.accounts.subject, authUrlObservable]).subscribe(([accounts, _authUrlInfo]) => {
|
|
62
62
|
const transformedAccounts = transformAccounts(accounts);
|
|
63
63
|
cb(this.filterForAuthorizedAccounts(transformedAccounts, url));
|
|
@@ -70,11 +70,11 @@ class Tabs {
|
|
|
70
70
|
return id;
|
|
71
71
|
}
|
|
72
72
|
accountsUnsubscribe(url, { id }) {
|
|
73
|
-
const sub = this
|
|
73
|
+
const sub = this.#accountSubs[id];
|
|
74
74
|
if (!sub || sub.url !== url) {
|
|
75
75
|
return false;
|
|
76
76
|
}
|
|
77
|
-
delete this
|
|
77
|
+
delete this.#accountSubs[id];
|
|
78
78
|
(0, subscriptions_js_1.unsubscribe)(id);
|
|
79
79
|
sub.subscription.unsubscribe();
|
|
80
80
|
return true;
|
|
@@ -87,35 +87,35 @@ class Tabs {
|
|
|
87
87
|
bytesSign(url, request) {
|
|
88
88
|
const address = request.address;
|
|
89
89
|
const pair = this.getSigningPair(address);
|
|
90
|
-
return this.
|
|
90
|
+
return this.#state.sign(url, new RequestBytesSign_js_1.default(request), { address, ...pair.meta });
|
|
91
91
|
}
|
|
92
92
|
extrinsicSign(url, request) {
|
|
93
93
|
const address = request.address;
|
|
94
94
|
const pair = this.getSigningPair(address);
|
|
95
|
-
return this.
|
|
95
|
+
return this.#state.sign(url, new RequestExtrinsicSign_js_1.default(request), { address, ...pair.meta });
|
|
96
96
|
}
|
|
97
97
|
metadataProvide(url, request) {
|
|
98
|
-
return this.
|
|
98
|
+
return this.#state.injectMetadata(url, request);
|
|
99
99
|
}
|
|
100
100
|
metadataList(_url) {
|
|
101
|
-
return this.
|
|
101
|
+
return this.#state.knownMetadata.map(({ genesisHash, specVersion }) => ({
|
|
102
102
|
genesisHash,
|
|
103
103
|
specVersion
|
|
104
104
|
}));
|
|
105
105
|
}
|
|
106
106
|
rpcListProviders() {
|
|
107
|
-
return this.
|
|
107
|
+
return this.#state.rpcListProviders();
|
|
108
108
|
}
|
|
109
109
|
rpcSend(request, port) {
|
|
110
|
-
return this.
|
|
110
|
+
return this.#state.rpcSend(request, port);
|
|
111
111
|
}
|
|
112
112
|
rpcStartProvider(key, port) {
|
|
113
|
-
return this.
|
|
113
|
+
return this.#state.rpcStartProvider(key, port);
|
|
114
114
|
}
|
|
115
115
|
async rpcSubscribe(request, id, port) {
|
|
116
116
|
const innerCb = (0, subscriptions_js_1.createSubscription)(id, port);
|
|
117
117
|
const cb = (_error, data) => innerCb(data);
|
|
118
|
-
const subscriptionId = await this.
|
|
118
|
+
const subscriptionId = await this.#state.rpcSubscribe(request, cb, port);
|
|
119
119
|
port.onDisconnect.addListener(() => {
|
|
120
120
|
(0, subscriptions_js_1.unsubscribe)(id);
|
|
121
121
|
(0, helpers_js_1.withErrorLog)(() => this.rpcUnsubscribe({ ...request, subscriptionId }, port));
|
|
@@ -125,14 +125,14 @@ class Tabs {
|
|
|
125
125
|
rpcSubscribeConnected(request, id, port) {
|
|
126
126
|
const innerCb = (0, subscriptions_js_1.createSubscription)(id, port);
|
|
127
127
|
const cb = (_error, data) => innerCb(data);
|
|
128
|
-
this.
|
|
128
|
+
this.#state.rpcSubscribeConnected(request, cb, port);
|
|
129
129
|
port.onDisconnect.addListener(() => {
|
|
130
130
|
(0, subscriptions_js_1.unsubscribe)(id);
|
|
131
131
|
});
|
|
132
132
|
return Promise.resolve(true);
|
|
133
133
|
}
|
|
134
134
|
async rpcUnsubscribe(request, port) {
|
|
135
|
-
return this.
|
|
135
|
+
return this.#state.rpcUnsubscribe(request, port);
|
|
136
136
|
}
|
|
137
137
|
redirectPhishingLanding(phishingWebsite) {
|
|
138
138
|
const nonFragment = phishingWebsite.split('#')[0];
|
|
@@ -158,7 +158,7 @@ class Tabs {
|
|
|
158
158
|
return this.redirectIfPhishing(url);
|
|
159
159
|
}
|
|
160
160
|
if (type !== 'pub(authorize.tab)') {
|
|
161
|
-
this.
|
|
161
|
+
this.#state.ensureUrlAuthorized(url);
|
|
162
162
|
}
|
|
163
163
|
switch (type) {
|
|
164
164
|
case 'pub(authorize.tab)':
|
package/cjs/packageInfo.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.packageInfo = void 0;
|
|
4
|
-
exports.packageInfo = { name: '@polkadot/extension-base', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '0.
|
|
4
|
+
exports.packageInfo = { name: '@polkadot/extension-base', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '0.60.1' };
|
|
@@ -10,19 +10,19 @@ let sendRequest;
|
|
|
10
10
|
* @description Extension provider to be used by dapps
|
|
11
11
|
*/
|
|
12
12
|
class PostMessageProvider {
|
|
13
|
-
|
|
13
|
+
#eventemitter;
|
|
14
14
|
// Whether or not the actual extension background provider is connected
|
|
15
|
-
|
|
15
|
+
#isConnected = false;
|
|
16
16
|
// Subscription IDs are (historically) not guaranteed to be globally unique;
|
|
17
17
|
// only unique for a given subscription method; which is why we identify
|
|
18
18
|
// the subscriptions based on subscription id + type
|
|
19
|
-
|
|
19
|
+
#subscriptions = {}; // {[(type,subscriptionId)]: callback}
|
|
20
20
|
/**
|
|
21
21
|
* @param {function} sendRequest The function to be called to send requests to the node
|
|
22
22
|
* @param {function} subscriptionNotificationHandler Channel for receiving subscription messages
|
|
23
23
|
*/
|
|
24
24
|
constructor(_sendRequest) {
|
|
25
|
-
this
|
|
25
|
+
this.#eventemitter = new eventemitter3_1.EventEmitter();
|
|
26
26
|
sendRequest = _sendRequest;
|
|
27
27
|
}
|
|
28
28
|
get isClonable() {
|
|
@@ -62,7 +62,7 @@ class PostMessageProvider {
|
|
|
62
62
|
* @return {boolean} true if connected
|
|
63
63
|
*/
|
|
64
64
|
get isConnected() {
|
|
65
|
-
return this
|
|
65
|
+
return this.#isConnected;
|
|
66
66
|
}
|
|
67
67
|
listProviders() {
|
|
68
68
|
return sendRequest('pub(rpc.listProviders)', undefined);
|
|
@@ -74,9 +74,9 @@ class PostMessageProvider {
|
|
|
74
74
|
* @return unsubscribe function
|
|
75
75
|
*/
|
|
76
76
|
on(type, sub) {
|
|
77
|
-
this.
|
|
77
|
+
this.#eventemitter.on(type, sub);
|
|
78
78
|
return () => {
|
|
79
|
-
this.
|
|
79
|
+
this.#eventemitter.removeListener(type, sub);
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -86,7 +86,7 @@ class PostMessageProvider {
|
|
|
86
86
|
const id = await sendRequest('pub(rpc.subscribe)', { method, params, type }, (res) => {
|
|
87
87
|
subscription.callback(null, res);
|
|
88
88
|
});
|
|
89
|
-
this
|
|
89
|
+
this.#subscriptions[`${type}::${id}`] = callback;
|
|
90
90
|
return id;
|
|
91
91
|
}
|
|
92
92
|
return sendRequest('pub(rpc.send)', { method, params });
|
|
@@ -96,17 +96,17 @@ class PostMessageProvider {
|
|
|
96
96
|
*/
|
|
97
97
|
async startProvider(key) {
|
|
98
98
|
// Disconnect from the previous provider
|
|
99
|
-
this
|
|
100
|
-
this.
|
|
99
|
+
this.#isConnected = false;
|
|
100
|
+
this.#eventemitter.emit('disconnected');
|
|
101
101
|
const meta = await sendRequest('pub(rpc.startProvider)', key);
|
|
102
102
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
103
103
|
sendRequest('pub(rpc.subscribeConnected)', null, (connected) => {
|
|
104
|
-
this
|
|
104
|
+
this.#isConnected = connected;
|
|
105
105
|
if (connected) {
|
|
106
|
-
this.
|
|
106
|
+
this.#eventemitter.emit('connected');
|
|
107
107
|
}
|
|
108
108
|
else {
|
|
109
|
-
this.
|
|
109
|
+
this.#eventemitter.emit('disconnected');
|
|
110
110
|
}
|
|
111
111
|
return true;
|
|
112
112
|
});
|
|
@@ -124,11 +124,11 @@ class PostMessageProvider {
|
|
|
124
124
|
// the assigned id now does not match what the API user originally received. It has
|
|
125
125
|
// a slight complication in solving - since we cannot rely on the send id, but rather
|
|
126
126
|
// need to find the actual subscription id to map it
|
|
127
|
-
if ((0, util_1.isUndefined)(this
|
|
127
|
+
if ((0, util_1.isUndefined)(this.#subscriptions[subscription])) {
|
|
128
128
|
l.debug(() => `Unable to find active subscription=${subscription}`);
|
|
129
129
|
return false;
|
|
130
130
|
}
|
|
131
|
-
delete this
|
|
131
|
+
delete this.#subscriptions[subscription];
|
|
132
132
|
return this.send(method, [id]);
|
|
133
133
|
}
|
|
134
134
|
}
|
package/cjs/stores/Base.js
CHANGED
|
@@ -7,9 +7,9 @@ const lastError = (type) => {
|
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
9
|
class BaseStore {
|
|
10
|
-
|
|
10
|
+
#prefix;
|
|
11
11
|
constructor(prefix) {
|
|
12
|
-
this
|
|
12
|
+
this.#prefix = prefix ? `${prefix}:` : '';
|
|
13
13
|
}
|
|
14
14
|
async all(update) {
|
|
15
15
|
await this.allMap(async (map) => {
|
|
@@ -27,8 +27,8 @@ class BaseStore {
|
|
|
27
27
|
const map = {};
|
|
28
28
|
for (let i = 0, count = entries.length; i < count; i++) {
|
|
29
29
|
const [key, value] = entries[i];
|
|
30
|
-
if (key.startsWith(this
|
|
31
|
-
map[key.replace(this
|
|
30
|
+
if (key.startsWith(this.#prefix)) {
|
|
31
|
+
map[key.replace(this.#prefix, '')] = value;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
await update(map);
|
|
@@ -37,7 +37,7 @@ class BaseStore {
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
async get(key, update) {
|
|
40
|
-
const prefixedKey = `${this
|
|
40
|
+
const prefixedKey = `${this.#prefix}${key}`;
|
|
41
41
|
await chrome.storage.local.get([prefixedKey]).then(async (result) => {
|
|
42
42
|
lastError('get');
|
|
43
43
|
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
@@ -47,7 +47,7 @@ class BaseStore {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
async remove(key, update) {
|
|
50
|
-
const prefixedKey = `${this
|
|
50
|
+
const prefixedKey = `${this.#prefix}${key}`;
|
|
51
51
|
await chrome.storage.local.remove(prefixedKey).then(async () => {
|
|
52
52
|
lastError('remove');
|
|
53
53
|
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
@@ -57,7 +57,7 @@ class BaseStore {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
async set(key, value, update) {
|
|
60
|
-
const prefixedKey = `${this
|
|
60
|
+
const prefixedKey = `${this.#prefix}${key}`;
|
|
61
61
|
await chrome.storage.local.set({ [prefixedKey]: value }).then(async () => {
|
|
62
62
|
lastError('set');
|
|
63
63
|
// eslint-disable-next-line @typescript-eslint/await-thenable
|