@polkadot/extension-base 0.44.2-2 → 0.44.2

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.
@@ -18,8 +18,8 @@ export default class Extension {
18
18
  private accountsValidate;
19
19
  private accountsSubscribe;
20
20
  private authorizeApprove;
21
+ private authorizeUpdate;
21
22
  private getAuthList;
22
- private authorizeReject;
23
23
  private authorizeSubscribe;
24
24
  private metadataApprove;
25
25
  private metadataGet;
@@ -40,7 +40,7 @@ export default class Extension {
40
40
  private derive;
41
41
  private derivationValidate;
42
42
  private derivationCreate;
43
- private toggleAuthorization;
44
43
  private removeAuthorization;
44
+ private deleteAuthRequest;
45
45
  handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>>;
46
46
  }
@@ -143,6 +143,16 @@ export default class Extension {
143
143
  accountsForget({
144
144
  address
145
145
  }) {
146
+ const authorizedAccountsDiff = []; // cycle through authUrls and prepare the array of diff
147
+
148
+ Object.entries(this.#state.authUrls).forEach(([url, urlInfo]) => {
149
+ if (!urlInfo.authorizedAccounts.includes(address)) {
150
+ return;
151
+ }
152
+
153
+ authorizedAccountsDiff.push([url, urlInfo.authorizedAccounts.filter(previousAddress => previousAddress !== address)]);
154
+ });
155
+ this.#state.updateAuthorizedAccounts(authorizedAccountsDiff);
146
156
  keyring.forgetAccount(address);
147
157
  return true;
148
158
  }
@@ -197,8 +207,7 @@ export default class Extension {
197
207
  } catch (e) {
198
208
  return false;
199
209
  }
200
- } // FIXME This looks very much like what we have in Tabs
201
-
210
+ }
202
211
 
203
212
  accountsSubscribe(id, port) {
204
213
  const cb = createSubscription(id, port);
@@ -211,6 +220,7 @@ export default class Extension {
211
220
  }
212
221
 
213
222
  authorizeApprove({
223
+ authorizedAccounts,
214
224
  id
215
225
  }) {
216
226
  const queued = this.#state.getAuthRequest(id);
@@ -218,26 +228,24 @@ export default class Extension {
218
228
  const {
219
229
  resolve
220
230
  } = queued;
221
- resolve(true);
231
+ resolve({
232
+ authorizedAccounts,
233
+ result: true
234
+ });
222
235
  return true;
223
236
  }
224
237
 
238
+ authorizeUpdate({
239
+ authorizedAccounts,
240
+ url
241
+ }) {
242
+ return this.#state.updateAuthorizedAccounts([[url, authorizedAccounts]]);
243
+ }
244
+
225
245
  getAuthList() {
226
246
  return {
227
247
  list: this.#state.authUrls
228
248
  };
229
- }
230
-
231
- authorizeReject({
232
- id
233
- }) {
234
- const queued = this.#state.getAuthRequest(id);
235
- assert(queued, 'Unable to find request');
236
- const {
237
- reject
238
- } = queued;
239
- reject(new Error('Rejected'));
240
- return true;
241
249
  } // FIXME This looks very much like what we have in accounts
242
250
 
243
251
 
@@ -553,16 +561,14 @@ export default class Extension {
553
561
  return true;
554
562
  }
555
563
 
556
- toggleAuthorization(url) {
557
- return {
558
- list: this.#state.toggleAuthorization(url)
559
- };
560
- }
561
-
562
564
  removeAuthorization(url) {
563
565
  return {
564
566
  list: this.#state.removeAuthorization(url)
565
567
  };
568
+ }
569
+
570
+ deleteAuthRequest(requestId) {
571
+ return this.#state.deleteAuthRequest(requestId);
566
572
  } // Weird thought, the eslint override is not needed in Tabs
567
573
  // eslint-disable-next-line @typescript-eslint/require-await
568
574
 
@@ -575,18 +581,18 @@ export default class Extension {
575
581
  case 'pri(authorize.list)':
576
582
  return this.getAuthList();
577
583
 
578
- case 'pri(authorize.reject)':
579
- return this.authorizeReject(request);
580
-
581
- case 'pri(authorize.toggle)':
582
- return this.toggleAuthorization(request);
583
-
584
584
  case 'pri(authorize.remove)':
585
585
  return this.removeAuthorization(request);
586
586
 
587
+ case 'pri(authorize.delete.request)':
588
+ return this.deleteAuthRequest(request);
589
+
587
590
  case 'pri(authorize.requests)':
588
591
  return this.authorizeSubscribe(id, port);
589
592
 
593
+ case 'pri(authorize.update)':
594
+ return this.authorizeUpdate(request);
595
+
590
596
  case 'pri(accounts.create.external)':
591
597
  return this.accountsCreateExternal(request);
592
598
 
@@ -7,25 +7,31 @@ interface Resolver<T> {
7
7
  reject: (error: Error) => void;
8
8
  resolve: (result: T) => void;
9
9
  }
10
- interface AuthRequest extends Resolver<boolean> {
10
+ interface AuthRequest extends Resolver<AuthResponse> {
11
11
  id: string;
12
12
  idStr: string;
13
13
  request: RequestAuthorizeTab;
14
14
  url: string;
15
15
  }
16
16
  export declare type AuthUrls = Record<string, AuthUrlInfo>;
17
+ export declare type AuthorizedAccountsDiff = [url: string, authorizedAccounts: AuthUrlInfo['authorizedAccounts']][];
17
18
  export interface AuthUrlInfo {
18
19
  count: number;
19
20
  id: string;
20
- isAllowed: boolean;
21
+ isAllowed?: boolean;
21
22
  origin: string;
22
23
  url: string;
24
+ authorizedAccounts: string[];
23
25
  }
24
26
  interface MetaRequest extends Resolver<boolean> {
25
27
  id: string;
26
28
  request: MetadataDef;
27
29
  url: string;
28
30
  }
31
+ export interface AuthResponse {
32
+ result: boolean;
33
+ authorizedAccounts: string[];
34
+ }
29
35
  declare type Providers = Record<string, {
30
36
  meta: ProviderMeta;
31
37
  start: () => ProviderInterface;
@@ -58,17 +64,18 @@ export default class State {
58
64
  private popupClose;
59
65
  private popupOpen;
60
66
  private authComplete;
67
+ deleteAuthRequest(requestId: string): void;
61
68
  private saveCurrentAuthList;
62
69
  private metaComplete;
63
70
  private signComplete;
64
- private stripUrl;
71
+ stripUrl(url: string): string;
65
72
  private updateIcon;
66
- toggleAuthorization(url: string): AuthUrls;
67
73
  removeAuthorization(url: string): AuthUrls;
68
74
  private updateIconAuth;
69
75
  private updateIconMeta;
70
76
  private updateIconSign;
71
- authorizeUrl(url: string, request: RequestAuthorizeTab): Promise<boolean>;
77
+ updateAuthorizedAccounts(authorizedAccountDiff: AuthorizedAccountsDiff): void;
78
+ authorizeUrl(url: string, request: RequestAuthorizeTab): Promise<AuthResponse>;
72
79
  ensureUrlAuthorized(url: string): boolean;
73
80
  injectMetadata(url: string, request: MetadataDef): Promise<boolean>;
74
81
  getAuthRequest(id: string): AuthRequest;
@@ -171,8 +171,7 @@ export default class State {
171
171
  }
172
172
 
173
173
  authComplete = (id, resolve, reject) => {
174
- const complete = result => {
175
- const isAllowed = result === true;
174
+ const complete = (authorizedAccounts = []) => {
176
175
  const {
177
176
  idStr,
178
177
  request: {
@@ -181,9 +180,9 @@ export default class State {
181
180
  url
182
181
  } = this.#authRequests[id];
183
182
  this.#authUrls[this.stripUrl(url)] = {
183
+ authorizedAccounts,
184
184
  count: 0,
185
185
  id: idStr,
186
- isAllowed,
187
186
  origin,
188
187
  url
189
188
  };
@@ -194,16 +193,27 @@ export default class State {
194
193
 
195
194
  return {
196
195
  reject: error => {
197
- complete(error);
196
+ complete();
198
197
  reject(error);
199
198
  },
200
- resolve: result => {
201
- complete(result);
202
- resolve(result);
199
+ resolve: ({
200
+ authorizedAccounts,
201
+ result
202
+ }) => {
203
+ complete(authorizedAccounts);
204
+ resolve({
205
+ authorizedAccounts,
206
+ result
207
+ });
203
208
  }
204
209
  };
205
210
  };
206
211
 
212
+ deleteAuthRequest(requestId) {
213
+ delete this.#authRequests[requestId];
214
+ this.updateIconAuth(true);
215
+ }
216
+
207
217
  saveCurrentAuthList() {
208
218
  localStorage.setItem(AUTH_URLS_KEY, JSON.stringify(this.#authUrls));
209
219
  }
@@ -263,14 +273,6 @@ export default class State {
263
273
  }
264
274
  }
265
275
 
266
- toggleAuthorization(url) {
267
- const entry = this.#authUrls[url];
268
- assert(entry, `The source ${url} is not known`);
269
- this.#authUrls[url].isAllowed = !entry.isAllowed;
270
- this.saveCurrentAuthList();
271
- return this.#authUrls;
272
- }
273
-
274
276
  removeAuthorization(url) {
275
277
  const entry = this.#authUrls[url];
276
278
  assert(entry, `The source ${url} is not known`);
@@ -294,6 +296,13 @@ export default class State {
294
296
  this.updateIcon(shouldClose);
295
297
  }
296
298
 
299
+ updateAuthorizedAccounts(authorizedAccountDiff) {
300
+ authorizedAccountDiff.forEach(([url, authorizedAccountDiff]) => {
301
+ this.#authUrls[url].authorizedAccounts = authorizedAccountDiff;
302
+ });
303
+ this.saveCurrentAuthList();
304
+ }
305
+
297
306
  async authorizeUrl(url, request) {
298
307
  const idStr = this.stripUrl(url); // Do not enqueue duplicate authorization requests.
299
308
 
@@ -302,8 +311,11 @@ export default class State {
302
311
 
303
312
  if (this.#authUrls[idStr]) {
304
313
  // this url was seen in the past
305
- assert(this.#authUrls[idStr].isAllowed, `The source ${url} is not allowed to interact with this extension`);
306
- return false;
314
+ assert(this.#authUrls[idStr].authorizedAccounts || this.#authUrls[idStr].isAllowed, `The source ${url} is not allowed to interact with this extension`);
315
+ return {
316
+ authorizedAccounts: [],
317
+ result: false
318
+ };
307
319
  }
308
320
 
309
321
  return new Promise((resolve, reject) => {
@@ -322,7 +334,6 @@ export default class State {
322
334
  ensureUrlAuthorized(url) {
323
335
  const entry = this.#authUrls[this.stripUrl(url)];
324
336
  assert(entry, `The source ${url} has not been enabled yet`);
325
- assert(entry.isAllowed, `The source ${url} is not allowed to interact with this extension`);
326
337
  return true;
327
338
  }
328
339
 
@@ -4,9 +4,11 @@ import State from './State';
4
4
  export default class Tabs {
5
5
  #private;
6
6
  constructor(state: State);
7
+ private filterForAuthorizedAccounts;
7
8
  private authorize;
8
- private accountsList;
9
- private accountsSubscribe;
9
+ private accountsListAuthorized;
10
+ private accountsSubscribeAuthorized;
11
+ private accountsUnsubscribe;
10
12
  private getSigningPair;
11
13
  private bytesSign;
12
14
  private extrinsicSign;
@@ -38,31 +38,60 @@ function transformAccounts(accounts, anyType = false) {
38
38
  }
39
39
 
40
40
  export default class Tabs {
41
+ #accountSubs = {};
41
42
  #state;
42
43
 
43
44
  constructor(state) {
44
45
  this.#state = state;
45
46
  }
46
47
 
48
+ filterForAuthorizedAccounts(accounts, url) {
49
+ const auth = this.#state.authUrls[this.#state.stripUrl(url)];
50
+ return accounts.filter(allAcc => auth.authorizedAccounts // we have a list, use it
51
+ ? auth.authorizedAccounts.includes(allAcc.address) // if no authorizedAccounts and isAllowed return all - these are old converted urls
52
+ : auth.isAllowed);
53
+ }
54
+
47
55
  authorize(url, request) {
48
56
  return this.#state.authorizeUrl(url, request);
49
- } // eslint-disable-next-line @typescript-eslint/no-unused-vars
50
-
57
+ }
51
58
 
52
- accountsList(url, {
59
+ accountsListAuthorized(url, {
53
60
  anyType
54
61
  }) {
55
- return transformAccounts(accountsObservable.subject.getValue(), anyType);
56
- } // FIXME This looks very much like what we have in Extension
57
-
62
+ const transformedAccounts = transformAccounts(accountsObservable.subject.getValue(), anyType);
63
+ return this.filterForAuthorizedAccounts(transformedAccounts, url);
64
+ }
58
65
 
59
- accountsSubscribe(url, id, port) {
66
+ accountsSubscribeAuthorized(url, id, port) {
60
67
  const cb = createSubscription(id, port);
61
- const subscription = accountsObservable.subject.subscribe(accounts => cb(transformAccounts(accounts)));
68
+ this.#accountSubs[id] = {
69
+ subscription: accountsObservable.subject.subscribe(accounts => {
70
+ const transformedAccounts = transformAccounts(accounts);
71
+ cb(this.filterForAuthorizedAccounts(transformedAccounts, url));
72
+ }),
73
+ url
74
+ };
62
75
  port.onDisconnect.addListener(() => {
63
- unsubscribe(id);
64
- subscription.unsubscribe();
76
+ this.accountsUnsubscribe(url, {
77
+ id
78
+ });
65
79
  });
80
+ return id;
81
+ }
82
+
83
+ accountsUnsubscribe(url, {
84
+ id
85
+ }) {
86
+ const sub = this.#accountSubs[id];
87
+
88
+ if (!sub || sub.url !== url) {
89
+ return false;
90
+ }
91
+
92
+ delete this.#accountSubs[id];
93
+ unsubscribe(id);
94
+ sub.subscription.unsubscribe();
66
95
  return true;
67
96
  }
68
97
 
@@ -188,10 +217,13 @@ export default class Tabs {
188
217
  return this.authorize(url, request);
189
218
 
190
219
  case 'pub(accounts.list)':
191
- return this.accountsList(url, request);
220
+ return this.accountsListAuthorized(url, request);
192
221
 
193
222
  case 'pub(accounts.subscribe)':
194
- return this.accountsSubscribe(url, id, port);
223
+ return this.accountsSubscribeAuthorized(url, id, port);
224
+
225
+ case 'pub(accounts.unsubscribe)':
226
+ return this.accountsUnsubscribe(url, request);
195
227
 
196
228
  case 'pub(bytes.sign)':
197
229
  return this.bytesSign(url, request);
@@ -7,7 +7,7 @@ import type { HexString } from '@polkadot/util/types';
7
7
  import type { KeypairType } from '@polkadot/util-crypto/types';
8
8
  import { TypeRegistry } from '@polkadot/types';
9
9
  import { ALLOWED_PATH } from '../defaults';
10
- import { AuthUrls } from './handlers/State';
10
+ import { AuthResponse, AuthUrls } from './handlers/State';
11
11
  declare type KeysWithDefinedValues<T> = {
12
12
  [K in keyof T]: T[K] extends undefined ? never : K;
13
13
  }[keyof T];
@@ -40,6 +40,8 @@ export declare type AccountsContext = {
40
40
  accounts: AccountJson[];
41
41
  hierarchy: AccountWithChildren[];
42
42
  master?: AccountJson;
43
+ selectedAccounts?: AccountJson['address'][];
44
+ setSelectedAccounts?: (address: AccountJson['address'][]) => void;
43
45
  };
44
46
  export interface AuthorizeRequest {
45
47
  id: string;
@@ -65,6 +67,7 @@ export interface RequestSignatures {
65
67
  'pri(accounts.export)': [RequestAccountExport, ResponseAccountExport];
66
68
  'pri(accounts.batchExport)': [RequestAccountBatchExport, ResponseAccountsExport];
67
69
  'pri(accounts.forget)': [RequestAccountForget, boolean];
70
+ 'pri(accounts.list)': [RequestAccountList, InjectedAccount[]];
68
71
  'pri(accounts.show)': [RequestAccountShow, boolean];
69
72
  'pri(accounts.tie)': [RequestAccountTie, boolean];
70
73
  'pri(accounts.subscribe)': [RequestAccountSubscribe, boolean, AccountJson[]];
@@ -72,10 +75,10 @@ export interface RequestSignatures {
72
75
  'pri(accounts.changePassword)': [RequestAccountChangePassword, boolean];
73
76
  'pri(authorize.approve)': [RequestAuthorizeApprove, boolean];
74
77
  'pri(authorize.list)': [null, ResponseAuthorizeList];
75
- 'pri(authorize.reject)': [RequestAuthorizeReject, boolean];
76
78
  'pri(authorize.requests)': [RequestAuthorizeSubscribe, boolean, AuthorizeRequest[]];
77
- 'pri(authorize.toggle)': [string, ResponseAuthorizeList];
78
79
  'pri(authorize.remove)': [string, ResponseAuthorizeList];
80
+ 'pri(authorize.delete.request)': [string, void];
81
+ 'pri(authorize.update)': [RequestUpdateAuthorizedAccounts, void];
79
82
  'pri(derivation.create)': [RequestDeriveCreate, boolean];
80
83
  'pri(derivation.validate)': [RequestDeriveValidate, ResponseDeriveValidate];
81
84
  'pri(json.restore)': [RequestJsonRestore, void];
@@ -96,8 +99,9 @@ export interface RequestSignatures {
96
99
  'pri(signing.requests)': [RequestSigningSubscribe, boolean, SigningRequest[]];
97
100
  'pri(window.open)': [AllowedPath, boolean];
98
101
  'pub(accounts.list)': [RequestAccountList, InjectedAccount[]];
99
- 'pub(accounts.subscribe)': [RequestAccountSubscribe, boolean, InjectedAccount[]];
100
- 'pub(authorize.tab)': [RequestAuthorizeTab, null];
102
+ 'pub(accounts.subscribe)': [RequestAccountSubscribe, string, InjectedAccount[]];
103
+ 'pub(accounts.unsubscribe)': [RequestAccountUnsubscribe, boolean];
104
+ 'pub(authorize.tab)': [RequestAuthorizeTab, Promise<AuthResponse>];
101
105
  'pub(bytes.sign)': [SignerPayloadRaw, ResponseSigning];
102
106
  'pub(extrinsic.sign)': [SignerPayloadJSON, ResponseSigning];
103
107
  'pub(metadata.list)': [null, InjectedMetadataKnown[]];
@@ -126,9 +130,11 @@ export interface RequestAuthorizeTab {
126
130
  }
127
131
  export interface RequestAuthorizeApprove {
128
132
  id: string;
133
+ authorizedAccounts: string[];
129
134
  }
130
- export interface RequestAuthorizeReject {
131
- id: string;
135
+ export interface RequestUpdateAuthorizedAccounts {
136
+ url: string;
137
+ authorizedAccounts: string[];
132
138
  }
133
139
  export declare type RequestAuthorizeSubscribe = null;
134
140
  export interface RequestMetadataApprove {
@@ -208,6 +214,9 @@ export interface RequestAccountList {
208
214
  anyType?: boolean;
209
215
  }
210
216
  export declare type RequestAccountSubscribe = null;
217
+ export interface RequestAccountUnsubscribe {
218
+ id: string;
219
+ }
211
220
  export interface RequestRpcSend {
212
221
  method: string;
213
222
  params: unknown[];
@@ -184,6 +184,18 @@ class Extension {
184
184
  let {
185
185
  address
186
186
  } = _ref9;
187
+ const authorizedAccountsDiff = []; // cycle through authUrls and prepare the array of diff
188
+
189
+ Object.entries(this.#state.authUrls).forEach(_ref10 => {
190
+ let [url, urlInfo] = _ref10;
191
+
192
+ if (!urlInfo.authorizedAccounts.includes(address)) {
193
+ return;
194
+ }
195
+
196
+ authorizedAccountsDiff.push([url, urlInfo.authorizedAccounts.filter(previousAddress => previousAddress !== address)]);
197
+ });
198
+ this.#state.updateAuthorizedAccounts(authorizedAccountsDiff);
187
199
 
188
200
  _uiKeyring.default.forgetAccount(address);
189
201
 
@@ -206,11 +218,11 @@ class Extension {
206
218
  return remainingTime;
207
219
  }
208
220
 
209
- accountsShow(_ref10) {
221
+ accountsShow(_ref11) {
210
222
  let {
211
223
  address,
212
224
  isShowing
213
- } = _ref10;
225
+ } = _ref11;
214
226
 
215
227
  const pair = _uiKeyring.default.getPair(address);
216
228
 
@@ -223,11 +235,11 @@ class Extension {
223
235
  return true;
224
236
  }
225
237
 
226
- accountsTie(_ref11) {
238
+ accountsTie(_ref12) {
227
239
  let {
228
240
  address,
229
241
  genesisHash
230
- } = _ref11;
242
+ } = _ref12;
231
243
 
232
244
  const pair = _uiKeyring.default.getPair(address);
233
245
 
@@ -240,11 +252,11 @@ class Extension {
240
252
  return true;
241
253
  }
242
254
 
243
- accountsValidate(_ref12) {
255
+ accountsValidate(_ref13) {
244
256
  let {
245
257
  address,
246
258
  password
247
- } = _ref12;
259
+ } = _ref13;
248
260
 
249
261
  try {
250
262
  _uiKeyring.default.backupAccount(_uiKeyring.default.getPair(address), password);
@@ -253,8 +265,7 @@ class Extension {
253
265
  } catch (e) {
254
266
  return false;
255
267
  }
256
- } // FIXME This looks very much like what we have in Tabs
257
-
268
+ }
258
269
 
259
270
  accountsSubscribe(id, port) {
260
271
  const cb = (0, _subscriptions.createSubscription)(id, port);
@@ -268,36 +279,35 @@ class Extension {
268
279
  return true;
269
280
  }
270
281
 
271
- authorizeApprove(_ref13) {
282
+ authorizeApprove(_ref14) {
272
283
  let {
284
+ authorizedAccounts,
273
285
  id
274
- } = _ref13;
286
+ } = _ref14;
275
287
  const queued = this.#state.getAuthRequest(id);
276
288
  (0, _util.assert)(queued, 'Unable to find request');
277
289
  const {
278
290
  resolve
279
291
  } = queued;
280
- resolve(true);
292
+ resolve({
293
+ authorizedAccounts,
294
+ result: true
295
+ });
281
296
  return true;
282
297
  }
283
298
 
299
+ authorizeUpdate(_ref15) {
300
+ let {
301
+ authorizedAccounts,
302
+ url
303
+ } = _ref15;
304
+ return this.#state.updateAuthorizedAccounts([[url, authorizedAccounts]]);
305
+ }
306
+
284
307
  getAuthList() {
285
308
  return {
286
309
  list: this.#state.authUrls
287
310
  };
288
- }
289
-
290
- authorizeReject(_ref14) {
291
- let {
292
- id
293
- } = _ref14;
294
- const queued = this.#state.getAuthRequest(id);
295
- (0, _util.assert)(queued, 'Unable to find request');
296
- const {
297
- reject
298
- } = queued;
299
- reject(new Error('Rejected'));
300
- return true;
301
311
  } // FIXME This looks very much like what we have in accounts
302
312
 
303
313
 
@@ -311,10 +321,10 @@ class Extension {
311
321
  return true;
312
322
  }
313
323
 
314
- metadataApprove(_ref15) {
324
+ metadataApprove(_ref16) {
315
325
  let {
316
326
  id
317
- } = _ref15;
327
+ } = _ref16;
318
328
  const queued = this.#state.getMetaRequest(id);
319
329
  (0, _util.assert)(queued, 'Unable to find request');
320
330
  const {
@@ -334,10 +344,10 @@ class Extension {
334
344
  return this.#state.knownMetadata;
335
345
  }
336
346
 
337
- metadataReject(_ref16) {
347
+ metadataReject(_ref17) {
338
348
  let {
339
349
  id
340
- } = _ref16;
350
+ } = _ref17;
341
351
  const queued = this.#state.getMetaRequest(id);
342
352
  (0, _util.assert)(queued, 'Unable to find request');
343
353
  const {
@@ -357,11 +367,11 @@ class Extension {
357
367
  return true;
358
368
  }
359
369
 
360
- jsonRestore(_ref17) {
370
+ jsonRestore(_ref18) {
361
371
  let {
362
372
  file,
363
373
  password
364
- } = _ref17;
374
+ } = _ref18;
365
375
 
366
376
  try {
367
377
  _uiKeyring.default.restoreAccount(file, password);
@@ -370,11 +380,11 @@ class Extension {
370
380
  }
371
381
  }
372
382
 
373
- batchRestore(_ref18) {
383
+ batchRestore(_ref19) {
374
384
  let {
375
385
  file,
376
386
  password
377
- } = _ref18;
387
+ } = _ref19;
378
388
 
379
389
  try {
380
390
  _uiKeyring.default.restoreAccounts(file, password);
@@ -406,12 +416,12 @@ class Extension {
406
416
  }
407
417
  }
408
418
 
409
- seedCreate(_ref19) {
419
+ seedCreate(_ref20) {
410
420
  let {
411
421
  length = SEED_DEFAULT_LENGTH,
412
422
  seed: _seed,
413
423
  type
414
- } = _ref19;
424
+ } = _ref20;
415
425
 
416
426
  const seed = _seed || (0, _utilCrypto.mnemonicGenerate)(length);
417
427
 
@@ -421,11 +431,11 @@ class Extension {
421
431
  };
422
432
  }
423
433
 
424
- seedValidate(_ref20) {
434
+ seedValidate(_ref21) {
425
435
  let {
426
436
  suri,
427
437
  type
428
- } = _ref20;
438
+ } = _ref21;
429
439
  const {
430
440
  phrase
431
441
  } = (0, _utilCrypto.keyExtractSuri)(suri);
@@ -444,12 +454,12 @@ class Extension {
444
454
  };
445
455
  }
446
456
 
447
- signingApprovePassword(_ref21) {
457
+ signingApprovePassword(_ref22) {
448
458
  let {
449
459
  id,
450
460
  password,
451
461
  savePass
452
- } = _ref21;
462
+ } = _ref22;
453
463
  const queued = this.#state.getSignRequest(id);
454
464
  (0, _util.assert)(queued, 'Unable to find request');
455
465
  const {
@@ -512,11 +522,11 @@ class Extension {
512
522
  return true;
513
523
  }
514
524
 
515
- signingApproveSignature(_ref22) {
525
+ signingApproveSignature(_ref23) {
516
526
  let {
517
527
  id,
518
528
  signature
519
- } = _ref22;
529
+ } = _ref23;
520
530
  const queued = this.#state.getSignRequest(id);
521
531
  (0, _util.assert)(queued, 'Unable to find request');
522
532
  const {
@@ -529,10 +539,10 @@ class Extension {
529
539
  return true;
530
540
  }
531
541
 
532
- signingCancel(_ref23) {
542
+ signingCancel(_ref24) {
533
543
  let {
534
544
  id
535
- } = _ref23;
545
+ } = _ref24;
536
546
  const queued = this.#state.getSignRequest(id);
537
547
  (0, _util.assert)(queued, 'Unable to find request');
538
548
  const {
@@ -542,10 +552,10 @@ class Extension {
542
552
  return true;
543
553
  }
544
554
 
545
- signingIsLocked(_ref24) {
555
+ signingIsLocked(_ref25) {
546
556
  let {
547
557
  id
548
- } = _ref24;
558
+ } = _ref25;
549
559
  const queued = this.#state.getSignRequest(id);
550
560
  (0, _util.assert)(queued, 'Unable to find request');
551
561
  const address = queued.request.payload.address;
@@ -601,12 +611,12 @@ class Extension {
601
611
  }
602
612
  }
603
613
 
604
- derivationValidate(_ref25) {
614
+ derivationValidate(_ref26) {
605
615
  let {
606
616
  parentAddress,
607
617
  parentPassword,
608
618
  suri
609
- } = _ref25;
619
+ } = _ref26;
610
620
  const childPair = this.derive(parentAddress, suri, parentPassword, {});
611
621
  return {
612
622
  address: childPair.address,
@@ -614,7 +624,7 @@ class Extension {
614
624
  };
615
625
  }
616
626
 
617
- derivationCreate(_ref26) {
627
+ derivationCreate(_ref27) {
618
628
  let {
619
629
  genesisHash,
620
630
  name,
@@ -622,7 +632,7 @@ class Extension {
622
632
  parentPassword,
623
633
  password,
624
634
  suri
625
- } = _ref26;
635
+ } = _ref27;
626
636
  const childPair = this.derive(parentAddress, suri, parentPassword, {
627
637
  genesisHash,
628
638
  name,
@@ -635,16 +645,14 @@ class Extension {
635
645
  return true;
636
646
  }
637
647
 
638
- toggleAuthorization(url) {
639
- return {
640
- list: this.#state.toggleAuthorization(url)
641
- };
642
- }
643
-
644
648
  removeAuthorization(url) {
645
649
  return {
646
650
  list: this.#state.removeAuthorization(url)
647
651
  };
652
+ }
653
+
654
+ deleteAuthRequest(requestId) {
655
+ return this.#state.deleteAuthRequest(requestId);
648
656
  } // Weird thought, the eslint override is not needed in Tabs
649
657
  // eslint-disable-next-line @typescript-eslint/require-await
650
658
 
@@ -657,18 +665,18 @@ class Extension {
657
665
  case 'pri(authorize.list)':
658
666
  return this.getAuthList();
659
667
 
660
- case 'pri(authorize.reject)':
661
- return this.authorizeReject(request);
662
-
663
- case 'pri(authorize.toggle)':
664
- return this.toggleAuthorization(request);
665
-
666
668
  case 'pri(authorize.remove)':
667
669
  return this.removeAuthorization(request);
668
670
 
671
+ case 'pri(authorize.delete.request)':
672
+ return this.deleteAuthRequest(request);
673
+
669
674
  case 'pri(authorize.requests)':
670
675
  return this.authorizeSubscribe(id, port);
671
676
 
677
+ case 'pri(authorize.update)':
678
+ return this.authorizeUpdate(request);
679
+
672
680
  case 'pri(accounts.create.external)':
673
681
  return this.accountsCreateExternal(request);
674
682
 
@@ -206,39 +206,56 @@ class State {
206
206
  }
207
207
 
208
208
  authComplete = (id, resolve, reject) => {
209
- const complete = result => {
210
- const isAllowed = result === true;
209
+ var _this = this;
210
+
211
+ const complete = function () {
212
+ let authorizedAccounts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
211
213
  const {
212
214
  idStr,
213
215
  request: {
214
216
  origin
215
217
  },
216
218
  url
217
- } = this.#authRequests[id];
218
- this.#authUrls[this.stripUrl(url)] = {
219
+ } = _this.#authRequests[id];
220
+ _this.#authUrls[_this.stripUrl(url)] = {
221
+ authorizedAccounts,
219
222
  count: 0,
220
223
  id: idStr,
221
- isAllowed,
222
224
  origin,
223
225
  url
224
226
  };
225
- this.saveCurrentAuthList();
226
- delete this.#authRequests[id];
227
- this.updateIconAuth(true);
227
+
228
+ _this.saveCurrentAuthList();
229
+
230
+ delete _this.#authRequests[id];
231
+
232
+ _this.updateIconAuth(true);
228
233
  };
229
234
 
230
235
  return {
231
236
  reject: error => {
232
- complete(error);
237
+ complete();
233
238
  reject(error);
234
239
  },
235
- resolve: result => {
236
- complete(result);
237
- resolve(result);
240
+ resolve: _ref7 => {
241
+ let {
242
+ authorizedAccounts,
243
+ result
244
+ } = _ref7;
245
+ complete(authorizedAccounts);
246
+ resolve({
247
+ authorizedAccounts,
248
+ result
249
+ });
238
250
  }
239
251
  };
240
252
  };
241
253
 
254
+ deleteAuthRequest(requestId) {
255
+ delete this.#authRequests[requestId];
256
+ this.updateIconAuth(true);
257
+ }
258
+
242
259
  saveCurrentAuthList() {
243
260
  localStorage.setItem(AUTH_URLS_KEY, JSON.stringify(this.#authUrls));
244
261
  }
@@ -298,14 +315,6 @@ class State {
298
315
  }
299
316
  }
300
317
 
301
- toggleAuthorization(url) {
302
- const entry = this.#authUrls[url];
303
- (0, _util.assert)(entry, `The source ${url} is not known`);
304
- this.#authUrls[url].isAllowed = !entry.isAllowed;
305
- this.saveCurrentAuthList();
306
- return this.#authUrls;
307
- }
308
-
309
318
  removeAuthorization(url) {
310
319
  const entry = this.#authUrls[url];
311
320
  (0, _util.assert)(entry, `The source ${url} is not known`);
@@ -329,6 +338,14 @@ class State {
329
338
  this.updateIcon(shouldClose);
330
339
  }
331
340
 
341
+ updateAuthorizedAccounts(authorizedAccountDiff) {
342
+ authorizedAccountDiff.forEach(_ref8 => {
343
+ let [url, authorizedAccountDiff] = _ref8;
344
+ this.#authUrls[url].authorizedAccounts = authorizedAccountDiff;
345
+ });
346
+ this.saveCurrentAuthList();
347
+ }
348
+
332
349
  async authorizeUrl(url, request) {
333
350
  const idStr = this.stripUrl(url); // Do not enqueue duplicate authorization requests.
334
351
 
@@ -337,8 +354,11 @@ class State {
337
354
 
338
355
  if (this.#authUrls[idStr]) {
339
356
  // this url was seen in the past
340
- (0, _util.assert)(this.#authUrls[idStr].isAllowed, `The source ${url} is not allowed to interact with this extension`);
341
- return false;
357
+ (0, _util.assert)(this.#authUrls[idStr].authorizedAccounts || this.#authUrls[idStr].isAllowed, `The source ${url} is not allowed to interact with this extension`);
358
+ return {
359
+ authorizedAccounts: [],
360
+ result: false
361
+ };
342
362
  }
343
363
 
344
364
  return new Promise((resolve, reject) => {
@@ -357,7 +377,6 @@ class State {
357
377
  ensureUrlAuthorized(url) {
358
378
  const entry = this.#authUrls[this.stripUrl(url)];
359
379
  (0, _util.assert)(entry, `The source ${url} has not been enabled yet`);
360
- (0, _util.assert)(entry.isAllowed, `The source ${url} is not allowed to interact with this extension`);
361
380
  return true;
362
381
  }
363
382
 
@@ -423,12 +442,12 @@ class State {
423
442
  return Promise.resolve(this.#providers[key].meta);
424
443
  }
425
444
 
426
- rpcSubscribe(_ref7, cb, port) {
445
+ rpcSubscribe(_ref9, cb, port) {
427
446
  let {
428
447
  method,
429
448
  params,
430
449
  type
431
- } = _ref7;
450
+ } = _ref9;
432
451
  const provider = this.#injectedProviders.get(port);
433
452
  (0, _util.assert)(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
434
453
  return provider.subscribe(type, method, params, cb);
@@ -66,34 +66,62 @@ function transformAccounts(accounts) {
66
66
  }
67
67
 
68
68
  class Tabs {
69
+ #accountSubs = {};
69
70
  #state;
70
71
 
71
72
  constructor(state) {
72
73
  this.#state = state;
73
74
  }
74
75
 
76
+ filterForAuthorizedAccounts(accounts, url) {
77
+ const auth = this.#state.authUrls[this.#state.stripUrl(url)];
78
+ return accounts.filter(allAcc => auth.authorizedAccounts // we have a list, use it
79
+ ? auth.authorizedAccounts.includes(allAcc.address) // if no authorizedAccounts and isAllowed return all - these are old converted urls
80
+ : auth.isAllowed);
81
+ }
82
+
75
83
  authorize(url, request) {
76
84
  return this.#state.authorizeUrl(url, request);
77
- } // eslint-disable-next-line @typescript-eslint/no-unused-vars
78
-
85
+ }
79
86
 
80
- accountsList(url, _ref4) {
87
+ accountsListAuthorized(url, _ref4) {
81
88
  let {
82
89
  anyType
83
90
  } = _ref4;
84
- return transformAccounts(_accounts.accounts.subject.getValue(), anyType);
85
- } // FIXME This looks very much like what we have in Extension
86
-
91
+ const transformedAccounts = transformAccounts(_accounts.accounts.subject.getValue(), anyType);
92
+ return this.filterForAuthorizedAccounts(transformedAccounts, url);
93
+ }
87
94
 
88
- accountsSubscribe(url, id, port) {
95
+ accountsSubscribeAuthorized(url, id, port) {
89
96
  const cb = (0, _subscriptions.createSubscription)(id, port);
90
-
91
- const subscription = _accounts.accounts.subject.subscribe(accounts => cb(transformAccounts(accounts)));
92
-
97
+ this.#accountSubs[id] = {
98
+ subscription: _accounts.accounts.subject.subscribe(accounts => {
99
+ const transformedAccounts = transformAccounts(accounts);
100
+ cb(this.filterForAuthorizedAccounts(transformedAccounts, url));
101
+ }),
102
+ url
103
+ };
93
104
  port.onDisconnect.addListener(() => {
94
- (0, _subscriptions.unsubscribe)(id);
95
- subscription.unsubscribe();
105
+ this.accountsUnsubscribe(url, {
106
+ id
107
+ });
96
108
  });
109
+ return id;
110
+ }
111
+
112
+ accountsUnsubscribe(url, _ref5) {
113
+ let {
114
+ id
115
+ } = _ref5;
116
+ const sub = this.#accountSubs[id];
117
+
118
+ if (!sub || sub.url !== url) {
119
+ return false;
120
+ }
121
+
122
+ delete this.#accountSubs[id];
123
+ (0, _subscriptions.unsubscribe)(id);
124
+ sub.subscription.unsubscribe();
97
125
  return true;
98
126
  }
99
127
 
@@ -128,11 +156,11 @@ class Tabs {
128
156
 
129
157
 
130
158
  metadataList(url) {
131
- return this.#state.knownMetadata.map(_ref5 => {
159
+ return this.#state.knownMetadata.map(_ref6 => {
132
160
  let {
133
161
  genesisHash,
134
162
  specVersion
135
- } = _ref5;
163
+ } = _ref6;
136
164
  return {
137
165
  genesisHash,
138
166
  specVersion
@@ -190,10 +218,10 @@ class Tabs {
190
218
  chrome.tabs.query({
191
219
  url: nonFragment
192
220
  }, tabs => {
193
- tabs.map(_ref6 => {
221
+ tabs.map(_ref7 => {
194
222
  let {
195
223
  id
196
- } = _ref6;
224
+ } = _ref7;
197
225
  return id;
198
226
  }).filter(id => (0, _util.isNumber)(id)).forEach(id => (0, _helpers.withErrorLog)(() => chrome.tabs.update(id, {
199
227
  url
@@ -226,10 +254,13 @@ class Tabs {
226
254
  return this.authorize(url, request);
227
255
 
228
256
  case 'pub(accounts.list)':
229
- return this.accountsList(url, request);
257
+ return this.accountsListAuthorized(url, request);
230
258
 
231
259
  case 'pub(accounts.subscribe)':
232
- return this.accountsSubscribe(url, id, port);
260
+ return this.accountsSubscribeAuthorized(url, id, port);
261
+
262
+ case 'pub(accounts.unsubscribe)':
263
+ return this.accountsUnsubscribe(url, request);
233
264
 
234
265
  case 'pub(bytes.sign)':
235
266
  return this.bytesSign(url, request);
package/cjs/package.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
2
  "type": "commonjs"
3
- }
3
+ }
@@ -11,6 +11,6 @@ const packageInfo = {
11
11
  name: '@polkadot/extension-base',
12
12
  path: typeof __dirname === 'string' ? __dirname : 'auto',
13
13
  type: 'cjs',
14
- version: '0.44.2-2'
14
+ version: '0.44.2'
15
15
  };
16
16
  exports.packageInfo = packageInfo;
@@ -21,8 +21,14 @@ class Accounts {
21
21
  }
22
22
 
23
23
  subscribe(cb) {
24
- sendRequest('pub(accounts.subscribe)', null, cb).catch(error => console.error(error));
25
- return () => {// FIXME we need the ability to unsubscribe
24
+ let id = null;
25
+ sendRequest('pub(accounts.subscribe)', null, cb).then(subId => {
26
+ id = subId;
27
+ }).catch(console.error);
28
+ return () => {
29
+ id && sendRequest('pub(accounts.unsubscribe)', {
30
+ id
31
+ }).catch(console.error);
26
32
  };
27
33
  }
28
34
 
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "0.44.2-2",
20
+ "version": "0.44.2",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -182,21 +182,21 @@
182
182
  }
183
183
  },
184
184
  "dependencies": {
185
- "@babel/runtime": "^7.18.3",
186
- "@polkadot/api": "^8.7.1",
187
- "@polkadot/extension-chains": "^0.44.2-2",
188
- "@polkadot/extension-dapp": "^0.44.2-2",
189
- "@polkadot/extension-inject": "^0.44.2-2",
190
- "@polkadot/keyring": "^9.4.1",
191
- "@polkadot/networks": "^9.4.1",
192
- "@polkadot/phishing": "^0.13.81",
193
- "@polkadot/rpc-provider": "^8.7.1",
194
- "@polkadot/types": "^8.7.1",
195
- "@polkadot/ui-keyring": "^2.4.2-0",
196
- "@polkadot/ui-settings": "^2.4.2-0",
197
- "@polkadot/util": "^9.4.1",
198
- "@polkadot/util-crypto": "^9.4.1",
185
+ "@babel/runtime": "^7.18.9",
186
+ "@polkadot/api": "^8.14.1",
187
+ "@polkadot/extension-chains": "^0.44.2",
188
+ "@polkadot/extension-dapp": "^0.44.2",
189
+ "@polkadot/extension-inject": "^0.44.2",
190
+ "@polkadot/keyring": "^10.1.1",
191
+ "@polkadot/networks": "^10.1.1",
192
+ "@polkadot/phishing": "^0.18.1",
193
+ "@polkadot/rpc-provider": "^8.14.1",
194
+ "@polkadot/types": "^8.14.1",
195
+ "@polkadot/ui-keyring": "^2.9.1",
196
+ "@polkadot/ui-settings": "^2.9.1",
197
+ "@polkadot/util": "^10.1.1",
198
+ "@polkadot/util-crypto": "^10.1.1",
199
199
  "eventemitter3": "^4.0.7",
200
- "rxjs": "^7.5.5"
200
+ "rxjs": "^7.5.6"
201
201
  }
202
- }
202
+ }
package/packageInfo.js CHANGED
@@ -5,5 +5,5 @@ export const packageInfo = {
5
5
  name: '@polkadot/extension-base',
6
6
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
7
7
  type: 'esm',
8
- version: '0.44.2-2'
8
+ version: '0.44.2'
9
9
  };
package/page/Accounts.js CHANGED
@@ -14,8 +14,14 @@ export default class Accounts {
14
14
  }
15
15
 
16
16
  subscribe(cb) {
17
- sendRequest('pub(accounts.subscribe)', null, cb).catch(error => console.error(error));
18
- return () => {// FIXME we need the ability to unsubscribe
17
+ let id = null;
18
+ sendRequest('pub(accounts.subscribe)', null, cb).then(subId => {
19
+ id = subId;
20
+ }).catch(console.error);
21
+ return () => {
22
+ id && sendRequest('pub(accounts.unsubscribe)', {
23
+ id
24
+ }).catch(console.error);
19
25
  };
20
26
  }
21
27