@polkadot/extension-base 0.44.5 → 0.44.7

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.
Files changed (63) hide show
  1. package/background/RequestBytesSign.js +1 -2
  2. package/background/RequestExtrinsicSign.js +1 -2
  3. package/background/handlers/Extension.d.ts +4 -1
  4. package/background/handlers/Extension.js +79 -146
  5. package/background/handlers/State.d.ts +8 -3
  6. package/background/handlers/State.js +60 -67
  7. package/background/handlers/Tabs.d.ts +1 -1
  8. package/background/handlers/Tabs.js +17 -57
  9. package/background/handlers/helpers.js +1 -1
  10. package/background/handlers/index.d.ts +1 -1
  11. package/background/handlers/index.js +6 -4
  12. package/background/handlers/subscriptions.js +5 -2
  13. package/background/types.d.ts +33 -25
  14. package/bundle.js +1 -0
  15. package/cjs/background/RequestBytesSign.js +1 -6
  16. package/cjs/background/RequestExtrinsicSign.js +1 -4
  17. package/cjs/background/handlers/Extension.js +95 -207
  18. package/cjs/background/handlers/State.js +60 -82
  19. package/cjs/background/handlers/Tabs.js +17 -70
  20. package/cjs/background/handlers/helpers.js +1 -2
  21. package/cjs/background/handlers/index.js +6 -12
  22. package/cjs/background/handlers/subscriptions.js +5 -3
  23. package/cjs/bundle.js +0 -1
  24. package/cjs/defaults.js +16 -8
  25. package/cjs/detectOther.js +0 -4
  26. package/cjs/detectPackage.js +2 -4
  27. package/cjs/index.js +0 -2
  28. package/cjs/packageInfo.js +3 -1
  29. package/cjs/page/Accounts.js +1 -5
  30. package/cjs/page/Injected.js +6 -8
  31. package/cjs/page/Metadata.js +1 -5
  32. package/cjs/page/PostMessageProvider.js +25 -38
  33. package/cjs/page/Signer.js +12 -12
  34. package/cjs/page/index.js +8 -14
  35. package/cjs/stores/Accounts.js +2 -9
  36. package/cjs/stores/Base.js +1 -14
  37. package/cjs/stores/Metadata.js +2 -7
  38. package/cjs/stores/index.js +0 -3
  39. package/cjs/utils/canDerive.js +1 -1
  40. package/cjs/utils/getId.js +1 -3
  41. package/cjs/utils/index.js +0 -1
  42. package/defaults.d.ts +2 -2
  43. package/defaults.js +14 -5
  44. package/detectOther.js +1 -0
  45. package/detectPackage.js +2 -0
  46. package/index.js +2 -0
  47. package/package.json +16 -16
  48. package/packageInfo.js +3 -1
  49. package/page/Accounts.js +1 -3
  50. package/page/Injected.js +6 -1
  51. package/page/Metadata.js +1 -3
  52. package/page/PostMessageProvider.d.ts +2 -1
  53. package/page/PostMessageProvider.js +25 -33
  54. package/page/Signer.js +12 -10
  55. package/page/index.d.ts +1 -1
  56. package/page/index.js +11 -7
  57. package/stores/Accounts.js +2 -4
  58. package/stores/Base.js +1 -12
  59. package/stores/Metadata.js +2 -2
  60. package/stores/index.js +1 -0
  61. package/utils/canDerive.js +1 -0
  62. package/utils/getId.js +1 -0
  63. package/utils/index.js +1 -0
@@ -1,30 +1,21 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.default = exports.NotificationOptions = void 0;
9
-
10
8
  var _rxjs = require("rxjs");
11
-
12
9
  var _getId = require("@polkadot/extension-base/utils/getId");
13
-
14
10
  var _extensionChains = require("@polkadot/extension-chains");
15
-
16
11
  var _defaults = require("@polkadot/networks/defaults");
17
-
18
12
  var _uiSettings = _interopRequireDefault(require("@polkadot/ui-settings"));
19
-
20
13
  var _util = require("@polkadot/util");
21
-
22
14
  var _stores = require("../../stores");
23
-
24
15
  var _helpers = require("./helpers");
25
-
26
16
  // Copyright 2019-2022 @polkadot/extension-bg authors & contributors
27
17
  // SPDX-License-Identifier: Apache-2.0
18
+
28
19
  const NOTIFICATION_URL = chrome.extension.getURL('notification.html');
29
20
  const POPUP_WINDOW_OPTS = {
30
21
  focused: true,
@@ -42,15 +33,13 @@ const NORMAL_WINDOW_OPTS = {
42
33
  };
43
34
  let NotificationOptions;
44
35
  exports.NotificationOptions = NotificationOptions;
45
-
46
36
  (function (NotificationOptions) {
47
37
  NotificationOptions[NotificationOptions["None"] = 0] = "None";
48
38
  NotificationOptions[NotificationOptions["Normal"] = 1] = "Normal";
49
39
  NotificationOptions[NotificationOptions["PopUp"] = 2] = "PopUp";
50
40
  })(NotificationOptions || (exports.NotificationOptions = NotificationOptions = {}));
51
-
52
41
  const AUTH_URLS_KEY = 'authUrls';
53
-
42
+ const DEFAULT_AUTH_ACCOUNTS = 'defaultAuthAccounts';
54
43
  function extractMetadata(store) {
55
44
  store.allMap(map => {
56
45
  const knownEntries = Object.entries(_defaults.knownGenesis);
@@ -62,18 +51,17 @@ function extractMetadata(store) {
62
51
  let [, hashes] = _ref2;
63
52
  return hashes.includes(def.genesisHash);
64
53
  });
65
-
66
54
  if (entry) {
67
55
  const [name, hashes] = entry;
68
- const index = hashes.indexOf(def.genesisHash); // flatten the known metadata based on the genesis index
69
- // (lower is better/newer)
56
+ const index = hashes.indexOf(def.genesisHash);
70
57
 
58
+ // flatten the known metadata based on the genesis index
59
+ // (lower is better/newer)
71
60
  if (!defs[name] || defs[name].index > index) {
72
61
  if (defs[name]) {
73
62
  // remove the old version of the metadata
74
63
  removals.push(defs[name].key);
75
64
  }
76
-
77
65
  defs[name] = {
78
66
  def,
79
67
  index,
@@ -98,49 +86,52 @@ function extractMetadata(store) {
98
86
  });
99
87
  });
100
88
  }
101
-
102
89
  class State {
103
90
  #authUrls = {};
104
91
  #authRequests = {};
105
- #metaStore = new _stores.MetadataStore(); // Map of providers currently injected in tabs
92
+ #metaStore = new _stores.MetadataStore();
106
93
 
94
+ // Map of providers currently injected in tabs
107
95
  #injectedProviders = new Map();
108
96
  #metaRequests = {};
109
- #notification = _uiSettings.default.notification; // Map of all providers exposed by the extension, they are retrievable by key
97
+ #notification = _uiSettings.default.notification;
110
98
 
99
+ // Map of all providers exposed by the extension, they are retrievable by key
111
100
  #providers;
112
101
  #signRequests = {};
113
102
  #windows = [];
103
+ #connectedTabsUrl = [];
114
104
  authSubject = new _rxjs.BehaviorSubject([]);
115
105
  metaSubject = new _rxjs.BehaviorSubject([]);
116
106
  signSubject = new _rxjs.BehaviorSubject([]);
117
-
107
+ defaultAuthAccountSelection = [];
118
108
  constructor() {
119
109
  let providers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
120
110
  this.#providers = providers;
121
- extractMetadata(this.#metaStore); // retrieve previously set authorizations
111
+ extractMetadata(this.#metaStore);
122
112
 
113
+ // retrieve previously set authorizations
123
114
  const authString = localStorage.getItem(AUTH_URLS_KEY) || '{}';
124
115
  const previousAuth = JSON.parse(authString);
125
116
  this.#authUrls = previousAuth;
126
- }
127
117
 
118
+ // retrieve previously set default auth accounts
119
+ const defaultAuthString = localStorage.getItem(DEFAULT_AUTH_ACCOUNTS) || '[]';
120
+ const previousDefaultAuth = JSON.parse(defaultAuthString);
121
+ this.defaultAuthAccountSelection = previousDefaultAuth;
122
+ }
128
123
  get knownMetadata() {
129
124
  return (0, _extensionChains.knownMetadata)();
130
125
  }
131
-
132
126
  get numAuthRequests() {
133
127
  return Object.keys(this.#authRequests).length;
134
128
  }
135
-
136
129
  get numMetaRequests() {
137
130
  return Object.keys(this.#metaRequests).length;
138
131
  }
139
-
140
132
  get numSignRequests() {
141
133
  return Object.keys(this.#signRequests).length;
142
134
  }
143
-
144
135
  get allAuthRequests() {
145
136
  return Object.values(this.#authRequests).map(_ref4 => {
146
137
  let {
@@ -155,7 +146,6 @@ class State {
155
146
  };
156
147
  });
157
148
  }
158
-
159
149
  get allMetaRequests() {
160
150
  return Object.values(this.#metaRequests).map(_ref5 => {
161
151
  let {
@@ -170,7 +160,6 @@ class State {
170
160
  };
171
161
  });
172
162
  }
173
-
174
163
  get allSignRequests() {
175
164
  return Object.values(this.#signRequests).map(_ref6 => {
176
165
  let {
@@ -187,16 +176,13 @@ class State {
187
176
  };
188
177
  });
189
178
  }
190
-
191
179
  get authUrls() {
192
180
  return this.#authUrls;
193
181
  }
194
-
195
182
  popupClose() {
196
183
  this.#windows.forEach(id => (0, _helpers.withErrorLog)(() => chrome.windows.remove(id)));
197
184
  this.#windows = [];
198
185
  }
199
-
200
186
  popupOpen() {
201
187
  this.#notification !== 'extension' && chrome.windows.create(this.#notification === 'window' ? NORMAL_WINDOW_OPTS : POPUP_WINDOW_OPTS, window => {
202
188
  if (window) {
@@ -204,10 +190,8 @@ class State {
204
190
  }
205
191
  });
206
192
  }
207
-
208
193
  authComplete = (id, resolve, reject) => {
209
194
  var _this = this;
210
-
211
195
  const complete = function () {
212
196
  let authorizedAccounts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
213
197
  const {
@@ -224,14 +208,11 @@ class State {
224
208
  origin,
225
209
  url
226
210
  };
227
-
228
211
  _this.saveCurrentAuthList();
229
-
212
+ _this.updateDefaultAuthAccounts(authorizedAccounts);
230
213
  delete _this.#authRequests[id];
231
-
232
214
  _this.updateIconAuth(true);
233
215
  };
234
-
235
216
  return {
236
217
  reject: error => {
237
218
  complete();
@@ -250,22 +231,44 @@ class State {
250
231
  }
251
232
  };
252
233
  };
234
+ udateCurrentTabsUrl(urls) {
235
+ const connectedTabs = urls.map(url => {
236
+ let strippedUrl = '';
237
+
238
+ // the assert in stripUrl may throw for new tabs with "chrome://newtab/"
239
+ try {
240
+ strippedUrl = this.stripUrl(url);
241
+ } catch (e) {
242
+ console.error(e);
243
+ }
253
244
 
245
+ // return the stripped url only if this website is known
246
+ return !!strippedUrl && this.authUrls[strippedUrl] ? strippedUrl : undefined;
247
+ }).filter(value => !!value);
248
+ this.#connectedTabsUrl = connectedTabs;
249
+ }
250
+ getConnectedTabsUrl() {
251
+ return this.#connectedTabsUrl;
252
+ }
254
253
  deleteAuthRequest(requestId) {
255
254
  delete this.#authRequests[requestId];
256
255
  this.updateIconAuth(true);
257
256
  }
258
-
259
257
  saveCurrentAuthList() {
260
258
  localStorage.setItem(AUTH_URLS_KEY, JSON.stringify(this.#authUrls));
261
259
  }
262
-
260
+ saveDefaultAuthAccounts() {
261
+ localStorage.setItem(DEFAULT_AUTH_ACCOUNTS, JSON.stringify(this.defaultAuthAccountSelection));
262
+ }
263
+ updateDefaultAuthAccounts(newList) {
264
+ this.defaultAuthAccountSelection = newList;
265
+ this.saveDefaultAuthAccounts();
266
+ }
263
267
  metaComplete = (id, resolve, reject) => {
264
268
  const complete = () => {
265
269
  delete this.#metaRequests[id];
266
270
  this.updateIconMeta(true);
267
271
  };
268
-
269
272
  return {
270
273
  reject: error => {
271
274
  complete();
@@ -282,7 +285,6 @@ class State {
282
285
  delete this.#signRequests[id];
283
286
  this.updateIconSign(true);
284
287
  };
285
-
286
288
  return {
287
289
  reject: error => {
288
290
  complete();
@@ -294,13 +296,11 @@ class State {
294
296
  }
295
297
  };
296
298
  };
297
-
298
299
  stripUrl(url) {
299
300
  (0, _util.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:`);
300
301
  const parts = url.split('/');
301
302
  return parts[2];
302
303
  }
303
-
304
304
  updateIcon(shouldClose) {
305
305
  const authCount = this.numAuthRequests;
306
306
  const metaCount = this.numMetaRequests;
@@ -309,12 +309,10 @@ class State {
309
309
  (0, _helpers.withErrorLog)(() => chrome.browserAction.setBadgeText({
310
310
  text
311
311
  }));
312
-
313
312
  if (shouldClose && text === '') {
314
313
  this.popupClose();
315
314
  }
316
315
  }
317
-
318
316
  removeAuthorization(url) {
319
317
  const entry = this.#authUrls[url];
320
318
  (0, _util.assert)(entry, `The source ${url} is not known`);
@@ -322,22 +320,18 @@ class State {
322
320
  this.saveCurrentAuthList();
323
321
  return this.#authUrls;
324
322
  }
325
-
326
323
  updateIconAuth(shouldClose) {
327
324
  this.authSubject.next(this.allAuthRequests);
328
325
  this.updateIcon(shouldClose);
329
326
  }
330
-
331
327
  updateIconMeta(shouldClose) {
332
328
  this.metaSubject.next(this.allMetaRequests);
333
329
  this.updateIcon(shouldClose);
334
330
  }
335
-
336
331
  updateIconSign(shouldClose) {
337
332
  this.signSubject.next(this.allSignRequests);
338
333
  this.updateIcon(shouldClose);
339
334
  }
340
-
341
335
  updateAuthorizedAccounts(authorizedAccountDiff) {
342
336
  authorizedAccountDiff.forEach(_ref8 => {
343
337
  let [url, authorizedAccountDiff] = _ref8;
@@ -345,13 +339,12 @@ class State {
345
339
  });
346
340
  this.saveCurrentAuthList();
347
341
  }
348
-
349
342
  async authorizeUrl(url, request) {
350
- const idStr = this.stripUrl(url); // Do not enqueue duplicate authorization requests.
343
+ const idStr = this.stripUrl(url);
351
344
 
345
+ // Do not enqueue duplicate authorization requests.
352
346
  const isDuplicate = Object.values(this.#authRequests).some(request => request.idStr === idStr);
353
347
  (0, _util.assert)(!isDuplicate, `The source ${url} has a pending authorization request`);
354
-
355
348
  if (this.#authUrls[idStr]) {
356
349
  // this url was seen in the past
357
350
  (0, _util.assert)(this.#authUrls[idStr].authorizedAccounts || this.#authUrls[idStr].isAllowed, `The source ${url} is not allowed to interact with this extension`);
@@ -360,10 +353,10 @@ class State {
360
353
  result: false
361
354
  };
362
355
  }
363
-
364
356
  return new Promise((resolve, reject) => {
365
357
  const id = (0, _getId.getId)();
366
- this.#authRequests[id] = { ...this.authComplete(id, resolve, reject),
358
+ this.#authRequests[id] = {
359
+ ...this.authComplete(id, resolve, reject),
367
360
  id,
368
361
  idStr,
369
362
  request,
@@ -373,17 +366,16 @@ class State {
373
366
  this.popupOpen();
374
367
  });
375
368
  }
376
-
377
369
  ensureUrlAuthorized(url) {
378
370
  const entry = this.#authUrls[this.stripUrl(url)];
379
371
  (0, _util.assert)(entry, `The source ${url} has not been enabled yet`);
380
372
  return true;
381
373
  }
382
-
383
374
  injectMetadata(url, request) {
384
375
  return new Promise((resolve, reject) => {
385
376
  const id = (0, _getId.getId)();
386
- this.#metaRequests[id] = { ...this.metaComplete(id, resolve, reject),
377
+ this.#metaRequests[id] = {
378
+ ...this.metaComplete(id, resolve, reject),
387
379
  id,
388
380
  request,
389
381
  url
@@ -392,56 +384,49 @@ class State {
392
384
  this.popupOpen();
393
385
  });
394
386
  }
395
-
396
387
  getAuthRequest(id) {
397
388
  return this.#authRequests[id];
398
389
  }
399
-
400
390
  getMetaRequest(id) {
401
391
  return this.#metaRequests[id];
402
392
  }
403
-
404
393
  getSignRequest(id) {
405
394
  return this.#signRequests[id];
406
- } // List all providers the extension is exposing
407
-
395
+ }
408
396
 
397
+ // List all providers the extension is exposing
409
398
  rpcListProviders() {
410
399
  return Promise.resolve(Object.keys(this.#providers).reduce((acc, key) => {
411
400
  acc[key] = this.#providers[key].meta;
412
401
  return acc;
413
402
  }, {}));
414
403
  }
415
-
416
404
  rpcSend(request, port) {
417
405
  const provider = this.#injectedProviders.get(port);
418
406
  (0, _util.assert)(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
419
407
  return provider.send(request.method, request.params);
420
- } // Start a provider, return its meta
421
-
408
+ }
422
409
 
410
+ // Start a provider, return its meta
423
411
  rpcStartProvider(key, port) {
424
412
  (0, _util.assert)(Object.keys(this.#providers).includes(key), `Provider ${key} is not exposed by extension`);
425
-
426
413
  if (this.#injectedProviders.get(port)) {
427
414
  return Promise.resolve(this.#providers[key].meta);
428
- } // Instantiate the provider
429
-
415
+ }
430
416
 
431
- this.#injectedProviders.set(port, this.#providers[key].start()); // Close provider connection when page is closed
417
+ // Instantiate the provider
418
+ this.#injectedProviders.set(port, this.#providers[key].start());
432
419
 
420
+ // Close provider connection when page is closed
433
421
  port.onDisconnect.addListener(() => {
434
422
  const provider = this.#injectedProviders.get(port);
435
-
436
423
  if (provider) {
437
424
  (0, _helpers.withErrorLog)(() => provider.disconnect());
438
425
  }
439
-
440
426
  this.#injectedProviders.delete(port);
441
427
  });
442
428
  return Promise.resolve(this.#providers[key].meta);
443
429
  }
444
-
445
430
  rpcSubscribe(_ref9, cb, port) {
446
431
  let {
447
432
  method,
@@ -452,36 +437,31 @@ class State {
452
437
  (0, _util.assert)(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
453
438
  return provider.subscribe(type, method, params, cb);
454
439
  }
455
-
456
440
  rpcSubscribeConnected(_request, cb, port) {
457
441
  const provider = this.#injectedProviders.get(port);
458
442
  (0, _util.assert)(provider, 'Cannot call pub(rpc.subscribeConnected) before provider is set');
459
443
  cb(null, provider.isConnected); // Immediately send back current isConnected
460
-
461
444
  provider.on('connected', () => cb(null, true));
462
445
  provider.on('disconnected', () => cb(null, false));
463
446
  }
464
-
465
447
  rpcUnsubscribe(request, port) {
466
448
  const provider = this.#injectedProviders.get(port);
467
449
  (0, _util.assert)(provider, 'Cannot call pub(rpc.unsubscribe) before provider is set');
468
450
  return provider.unsubscribe(request.type, request.method, request.subscriptionId);
469
451
  }
470
-
471
452
  saveMetadata(meta) {
472
453
  this.#metaStore.set(meta.genesisHash, meta);
473
454
  (0, _extensionChains.addMetadata)(meta);
474
455
  }
475
-
476
456
  setNotification(notification) {
477
457
  this.#notification = notification;
478
458
  return true;
479
459
  }
480
-
481
460
  sign(url, request, account) {
482
461
  const id = (0, _getId.getId)();
483
462
  return new Promise((resolve, reject) => {
484
- this.#signRequests[id] = { ...this.signComplete(id, resolve, reject),
463
+ this.#signRequests[id] = {
464
+ ...this.signComplete(id, resolve, reject),
485
465
  account,
486
466
  id,
487
467
  request,
@@ -491,7 +471,5 @@ class State {
491
471
  this.popupOpen();
492
472
  });
493
473
  }
494
-
495
474
  }
496
-
497
475
  exports.default = State;