@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.
Files changed (166) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +10 -0
  3. package/build/LICENSE +201 -0
  4. package/build/README.md +10 -0
  5. package/build/background/KoniTypes.d.ts +462 -0
  6. package/build/background/KoniTypes.js +57 -0
  7. package/build/background/RequestBytesSign.d.ts +12 -0
  8. package/build/background/RequestBytesSign.js +16 -0
  9. package/build/background/RequestExtrinsicSign.d.ts +12 -0
  10. package/build/background/RequestExtrinsicSign.js +14 -0
  11. package/build/background/handlers/Extension.d.ts +49 -0
  12. package/build/background/handlers/Extension.js +676 -0
  13. package/build/background/handlers/State.d.ts +87 -0
  14. package/build/background/handlers/State.js +434 -0
  15. package/build/background/handlers/Tabs.d.ts +24 -0
  16. package/build/background/handlers/Tabs.js +230 -0
  17. package/build/background/handlers/helpers.d.ts +1 -0
  18. package/build/background/handlers/helpers.js +13 -0
  19. package/build/background/handlers/index.d.ts +3 -0
  20. package/build/background/handlers/index.js +43 -0
  21. package/build/background/handlers/subscriptions.d.ts +4 -0
  22. package/build/background/handlers/subscriptions.js +24 -0
  23. package/build/background/types.d.ts +345 -0
  24. package/build/background/types.js +1 -0
  25. package/build/bundle.d.ts +1 -0
  26. package/build/bundle.js +3 -0
  27. package/build/cjs/background/KoniTypes.js +69 -0
  28. package/build/cjs/background/RequestBytesSign.js +27 -0
  29. package/build/cjs/background/RequestExtrinsicSign.js +23 -0
  30. package/build/cjs/background/handlers/Extension.js +764 -0
  31. package/build/cjs/background/handlers/State.js +472 -0
  32. package/build/cjs/background/handlers/Tabs.js +273 -0
  33. package/build/cjs/background/handlers/helpers.js +20 -0
  34. package/build/cjs/background/handlers/index.js +60 -0
  35. package/build/cjs/background/handlers/subscriptions.js +32 -0
  36. package/build/cjs/background/types.js +1 -0
  37. package/build/cjs/bundle.js +13 -0
  38. package/build/cjs/defaults.js +26 -0
  39. package/build/cjs/detectOther.js +17 -0
  40. package/build/cjs/detectPackage.js +14 -0
  41. package/build/cjs/index.js +18 -0
  42. package/build/cjs/package.json +3 -0
  43. package/build/cjs/packageInfo.js +16 -0
  44. package/build/cjs/page/Accounts.js +31 -0
  45. package/build/cjs/page/Injected.js +30 -0
  46. package/build/cjs/page/Metadata.js +27 -0
  47. package/build/cjs/page/PostMessageProvider.js +184 -0
  48. package/build/cjs/page/Signer.js +44 -0
  49. package/build/cjs/page/index.js +76 -0
  50. package/build/cjs/page/types.js +1 -0
  51. package/build/cjs/stores/Accounts.js +33 -0
  52. package/build/cjs/stores/Base.js +84 -0
  53. package/build/cjs/stores/Metadata.js +23 -0
  54. package/build/cjs/stores/index.js +23 -0
  55. package/build/cjs/types.js +1 -0
  56. package/build/cjs/utils/canDerive.js +12 -0
  57. package/build/cjs/utils/getId.js +16 -0
  58. package/build/cjs/utils/index.js +13 -0
  59. package/build/defaults.d.ts +10 -0
  60. package/build/defaults.js +12 -0
  61. package/build/detectOther.d.ts +7 -0
  62. package/build/detectOther.js +6 -0
  63. package/build/detectPackage.d.ts +1 -0
  64. package/build/detectPackage.js +7 -0
  65. package/build/index.d.ts +1 -0
  66. package/build/index.js +5 -0
  67. package/build/package.json +210 -0
  68. package/build/packageInfo.d.ts +6 -0
  69. package/build/packageInfo.js +9 -0
  70. package/build/page/Accounts.d.ts +7 -0
  71. package/build/page/Accounts.js +22 -0
  72. package/build/page/Injected.d.ts +13 -0
  73. package/build/page/Injected.js +15 -0
  74. package/build/page/Metadata.d.ts +7 -0
  75. package/build/page/Metadata.js +18 -0
  76. package/build/page/PostMessageProvider.d.ts +62 -0
  77. package/build/page/PostMessageProvider.js +171 -0
  78. package/build/page/Signer.d.ts +8 -0
  79. package/build/page/Signer.js +35 -0
  80. package/build/page/index.d.ts +16 -0
  81. package/build/page/index.js +64 -0
  82. package/build/page/types.d.ts +6 -0
  83. package/build/page/types.js +1 -0
  84. package/build/stores/Accounts.d.ts +6 -0
  85. package/build/stores/Accounts.js +20 -0
  86. package/build/stores/Base.d.ts +10 -0
  87. package/build/stores/Base.js +74 -0
  88. package/build/stores/Metadata.d.ts +5 -0
  89. package/build/stores/Metadata.js +10 -0
  90. package/build/stores/index.d.ts +2 -0
  91. package/build/stores/index.js +4 -0
  92. package/build/types.d.ts +9 -0
  93. package/build/types.js +1 -0
  94. package/build/utils/canDerive.d.ts +2 -0
  95. package/build/utils/canDerive.js +5 -0
  96. package/build/utils/getId.d.ts +1 -0
  97. package/build/utils/getId.js +7 -0
  98. package/build/utils/index.d.ts +1 -0
  99. package/build/utils/index.js +3 -0
  100. package/build-cjs/background/KoniTypes.js +69 -0
  101. package/build-cjs/background/RequestBytesSign.js +27 -0
  102. package/build-cjs/background/RequestExtrinsicSign.js +23 -0
  103. package/build-cjs/background/handlers/Extension.js +764 -0
  104. package/build-cjs/background/handlers/State.js +472 -0
  105. package/build-cjs/background/handlers/Tabs.js +273 -0
  106. package/build-cjs/background/handlers/helpers.js +20 -0
  107. package/build-cjs/background/handlers/index.js +60 -0
  108. package/build-cjs/background/handlers/subscriptions.js +32 -0
  109. package/build-cjs/background/types.js +1 -0
  110. package/build-cjs/bundle.js +13 -0
  111. package/build-cjs/defaults.js +26 -0
  112. package/build-cjs/detectOther.js +17 -0
  113. package/build-cjs/detectPackage.js +14 -0
  114. package/build-cjs/index.js +18 -0
  115. package/build-cjs/packageInfo.js +16 -0
  116. package/build-cjs/page/Accounts.js +31 -0
  117. package/build-cjs/page/Injected.js +30 -0
  118. package/build-cjs/page/Metadata.js +27 -0
  119. package/build-cjs/page/PostMessageProvider.js +184 -0
  120. package/build-cjs/page/Signer.js +44 -0
  121. package/build-cjs/page/index.js +76 -0
  122. package/build-cjs/page/types.js +1 -0
  123. package/build-cjs/stores/Accounts.js +33 -0
  124. package/build-cjs/stores/Base.js +84 -0
  125. package/build-cjs/stores/Metadata.js +23 -0
  126. package/build-cjs/stores/index.js +23 -0
  127. package/build-cjs/types.js +1 -0
  128. package/build-cjs/utils/canDerive.js +12 -0
  129. package/build-cjs/utils/getId.js +16 -0
  130. package/build-cjs/utils/index.js +13 -0
  131. package/package.json +46 -0
  132. package/src/background/KoniTypes.ts +537 -0
  133. package/src/background/RequestBytesSign.ts +30 -0
  134. package/src/background/RequestExtrinsicSign.ts +23 -0
  135. package/src/background/handlers/Extension.spec.ts +456 -0
  136. package/src/background/handlers/Extension.ts +627 -0
  137. package/src/background/handlers/State.ts +513 -0
  138. package/src/background/handlers/Tabs.ts +223 -0
  139. package/src/background/handlers/helpers.ts +14 -0
  140. package/src/background/handlers/index.ts +49 -0
  141. package/src/background/handlers/subscriptions.ts +30 -0
  142. package/src/background/types.ts +437 -0
  143. package/src/bundle.ts +4 -0
  144. package/src/defaults.ts +24 -0
  145. package/src/detectOther.ts +8 -0
  146. package/src/detectPackage.ts +11 -0
  147. package/src/index.ts +7 -0
  148. package/src/packageInfo.ts +6 -0
  149. package/src/page/Accounts.ts +27 -0
  150. package/src/page/Injected.ts +27 -0
  151. package/src/page/Metadata.ts +22 -0
  152. package/src/page/PostMessageProvider.ts +178 -0
  153. package/src/page/Signer.ts +45 -0
  154. package/src/page/index.ts +87 -0
  155. package/src/page/types.ts +10 -0
  156. package/src/stores/Accounts.ts +24 -0
  157. package/src/stores/Base.ts +81 -0
  158. package/src/stores/Metadata.ts +13 -0
  159. package/src/stores/index.ts +5 -0
  160. package/src/types.ts +12 -0
  161. package/src/utils/canDerive.ts +8 -0
  162. package/src/utils/getId.ts +10 -0
  163. package/src/utils/index.ts +4 -0
  164. package/tsconfig.build.json +18 -0
  165. package/tsconfig.build.tsbuildinfo +1 -0
  166. package/tsconfig.json +14 -0
@@ -0,0 +1,676 @@
1
+ // Copyright 2019-2022 @subwallet/extension authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { ALLOWED_PATH, PASSWORD_EXPIRY_MS } from '@subwallet/extension-base/defaults';
4
+ import { TypeRegistry } from '@polkadot/types';
5
+ import keyring from '@polkadot/ui-keyring';
6
+ import { accounts as accountsObservable } from '@polkadot/ui-keyring/observable/accounts';
7
+ import { assert, isHex } from '@polkadot/util';
8
+ import { keyExtractSuri, mnemonicGenerate, mnemonicValidate } from '@polkadot/util-crypto';
9
+ import { withErrorLog } from "./helpers.js";
10
+ import { createSubscription, unsubscribe } from "./subscriptions.js";
11
+ export const SEED_DEFAULT_LENGTH = 12;
12
+ export const SEED_LENGTHS = [12, 15, 18, 21, 24];
13
+ export const ETH_DERIVE_DEFAULT = '/m/44\'/60\'/0\'/0/0'; // a global registry to use internally
14
+
15
+ const registry = new TypeRegistry();
16
+ export function getSuri(seed, type) {
17
+ return type === 'ethereum' ? `${seed}${ETH_DERIVE_DEFAULT}` : seed;
18
+ }
19
+
20
+ function transformAccounts(accounts) {
21
+ return Object.values(accounts).map(({
22
+ json: {
23
+ address,
24
+ meta
25
+ },
26
+ type
27
+ }) => ({
28
+ address,
29
+ ...meta,
30
+ type
31
+ }));
32
+ }
33
+
34
+ function isJsonPayload(value) {
35
+ return value.genesisHash !== undefined;
36
+ }
37
+
38
+ export default class Extension {
39
+ #cachedUnlocks;
40
+ #state;
41
+
42
+ constructor(state) {
43
+ this.#cachedUnlocks = {};
44
+ this.#state = state;
45
+ }
46
+
47
+ accountsCreateExternal({
48
+ address,
49
+ genesisHash,
50
+ name
51
+ }) {
52
+ keyring.addExternal(address, {
53
+ genesisHash,
54
+ name
55
+ });
56
+ return true;
57
+ }
58
+
59
+ accountsCreateHardware({
60
+ accountIndex,
61
+ address,
62
+ addressOffset,
63
+ genesisHash,
64
+ hardwareType,
65
+ name
66
+ }) {
67
+ keyring.addHardware(address, hardwareType, {
68
+ accountIndex,
69
+ addressOffset,
70
+ genesisHash,
71
+ name
72
+ });
73
+ return true;
74
+ }
75
+
76
+ accountsCreateSuri({
77
+ genesisHash,
78
+ name,
79
+ password,
80
+ suri,
81
+ type
82
+ }) {
83
+ keyring.addUri(getSuri(suri, type), password, {
84
+ genesisHash,
85
+ name
86
+ }, type);
87
+ return true;
88
+ }
89
+
90
+ accountsChangePassword({
91
+ address,
92
+ newPass,
93
+ oldPass
94
+ }) {
95
+ const pair = keyring.getPair(address);
96
+ assert(pair, 'Unable to find pair');
97
+
98
+ try {
99
+ if (!pair.isLocked) {
100
+ pair.lock();
101
+ }
102
+
103
+ pair.decodePkcs8(oldPass);
104
+ } catch (error) {
105
+ throw new Error('oldPass is invalid');
106
+ }
107
+
108
+ keyring.encryptAccount(pair, newPass);
109
+ return true;
110
+ }
111
+
112
+ accountsEdit({
113
+ address,
114
+ name
115
+ }) {
116
+ const pair = keyring.getPair(address);
117
+ assert(pair, 'Unable to find pair');
118
+ keyring.saveAccountMeta(pair, { ...pair.meta,
119
+ name
120
+ });
121
+ return true;
122
+ }
123
+
124
+ accountsExport({
125
+ address,
126
+ password
127
+ }) {
128
+ return {
129
+ exportedJson: keyring.backupAccount(keyring.getPair(address), password)
130
+ };
131
+ } // private async accountsBatchExport ({ addresses, password }: RequestAccountBatchExport): Promise<ResponseAccountsExport> {
132
+ // return {
133
+ // exportedJson: await keyring.backupAccounts(addresses, password)
134
+ // };
135
+ // }
136
+
137
+
138
+ accountsForget({
139
+ address
140
+ }) {
141
+ keyring.forgetAccount(address);
142
+ return true;
143
+ }
144
+
145
+ refreshAccountPasswordCache(pair) {
146
+ const {
147
+ address
148
+ } = pair;
149
+ const savedExpiry = this.#cachedUnlocks[address] || 0;
150
+ const remainingTime = savedExpiry - Date.now();
151
+
152
+ if (remainingTime < 0) {
153
+ this.#cachedUnlocks[address] = 0;
154
+ pair.lock();
155
+ return 0;
156
+ }
157
+
158
+ return remainingTime;
159
+ }
160
+
161
+ accountsShow({
162
+ address,
163
+ isShowing
164
+ }) {
165
+ const pair = keyring.getPair(address);
166
+ assert(pair, 'Unable to find pair');
167
+ keyring.saveAccountMeta(pair, { ...pair.meta,
168
+ isHidden: !isShowing
169
+ });
170
+ return true;
171
+ }
172
+
173
+ accountsTie({
174
+ address,
175
+ genesisHash
176
+ }) {
177
+ const pair = keyring.getPair(address);
178
+ assert(pair, 'Unable to find pair');
179
+ keyring.saveAccountMeta(pair, { ...pair.meta,
180
+ genesisHash
181
+ });
182
+ return true;
183
+ }
184
+
185
+ accountsValidate({
186
+ address,
187
+ password
188
+ }) {
189
+ try {
190
+ keyring.backupAccount(keyring.getPair(address), password);
191
+ return true;
192
+ } catch (e) {
193
+ return false;
194
+ }
195
+ } // FIXME This looks very much like what we have in Tabs
196
+
197
+
198
+ accountsSubscribe(id, port) {
199
+ const cb = createSubscription(id, port);
200
+ const subscription = accountsObservable.subject.subscribe(accounts => cb(transformAccounts(accounts)));
201
+ port.onDisconnect.addListener(() => {
202
+ unsubscribe(id);
203
+ subscription.unsubscribe();
204
+ });
205
+ return true;
206
+ }
207
+
208
+ authorizeApprove({
209
+ id
210
+ }) {
211
+ const queued = this.#state.getAuthRequest(id);
212
+ assert(queued, 'Unable to find request');
213
+ const {
214
+ resolve
215
+ } = queued;
216
+ resolve(true);
217
+ return true;
218
+ }
219
+
220
+ getAuthList() {
221
+ return {
222
+ list: this.#state.authUrls
223
+ };
224
+ }
225
+
226
+ authorizeReject({
227
+ id
228
+ }) {
229
+ const queued = this.#state.getAuthRequest(id);
230
+ assert(queued, 'Unable to find request');
231
+ const {
232
+ reject
233
+ } = queued;
234
+ reject(new Error('Rejected'));
235
+ return true;
236
+ } // FIXME This looks very much like what we have in accounts
237
+
238
+
239
+ authorizeSubscribe(id, port) {
240
+ const cb = createSubscription(id, port);
241
+ const subscription = this.#state.authSubject.subscribe(requests => cb(requests));
242
+ port.onDisconnect.addListener(() => {
243
+ unsubscribe(id);
244
+ subscription.unsubscribe();
245
+ });
246
+ return true;
247
+ }
248
+
249
+ metadataApprove({
250
+ id
251
+ }) {
252
+ const queued = this.#state.getMetaRequest(id);
253
+ assert(queued, 'Unable to find request');
254
+ const {
255
+ request,
256
+ resolve
257
+ } = queued;
258
+ this.#state.saveMetadata(request);
259
+ resolve(true);
260
+ return true;
261
+ }
262
+
263
+ metadataGet(genesisHash) {
264
+ return this.#state.knownMetadata.find(result => result.genesisHash === genesisHash) || null;
265
+ }
266
+
267
+ metadataList() {
268
+ return this.#state.knownMetadata;
269
+ }
270
+
271
+ metadataReject({
272
+ id
273
+ }) {
274
+ const queued = this.#state.getMetaRequest(id);
275
+ assert(queued, 'Unable to find request');
276
+ const {
277
+ reject
278
+ } = queued;
279
+ reject(new Error('Rejected'));
280
+ return true;
281
+ }
282
+
283
+ metadataSubscribe(id, port) {
284
+ const cb = createSubscription(id, port);
285
+ const subscription = this.#state.metaSubject.subscribe(requests => cb(requests));
286
+ port.onDisconnect.addListener(() => {
287
+ unsubscribe(id);
288
+ subscription.unsubscribe();
289
+ });
290
+ return true;
291
+ }
292
+
293
+ jsonRestore({
294
+ file,
295
+ password
296
+ }) {
297
+ try {
298
+ keyring.restoreAccount(file, password);
299
+ } catch (error) {
300
+ throw new Error(error.message);
301
+ }
302
+ }
303
+
304
+ batchRestore({
305
+ file,
306
+ password
307
+ }) {
308
+ try {
309
+ keyring.restoreAccounts(file, password);
310
+ } catch (error) {
311
+ throw new Error(error.message);
312
+ }
313
+ }
314
+
315
+ jsonGetAccountInfo(json) {
316
+ try {
317
+ const {
318
+ address,
319
+ meta: {
320
+ genesisHash,
321
+ name
322
+ },
323
+ type
324
+ } = keyring.createFromJson(json);
325
+ return {
326
+ address,
327
+ genesisHash,
328
+ name,
329
+ type
330
+ };
331
+ } catch (e) {
332
+ console.error(e);
333
+ throw new Error(e.message);
334
+ }
335
+ }
336
+
337
+ seedCreate({
338
+ length = SEED_DEFAULT_LENGTH,
339
+ seed: _seed,
340
+ type
341
+ }) {
342
+ const seed = _seed || mnemonicGenerate(length);
343
+
344
+ return {
345
+ address: keyring.createFromUri(getSuri(seed, type), {}, type).address,
346
+ seed
347
+ };
348
+ }
349
+
350
+ seedValidate({
351
+ suri,
352
+ type
353
+ }) {
354
+ const {
355
+ phrase
356
+ } = keyExtractSuri(suri);
357
+
358
+ if (isHex(phrase)) {
359
+ assert(isHex(phrase, 256), 'Hex seed needs to be 256-bits');
360
+ } else {
361
+ // sadly isHex detects as string, so we need a cast here
362
+ assert(SEED_LENGTHS.includes(phrase.split(' ').length), `Mnemonic needs to contain ${SEED_LENGTHS.join(', ')} words`);
363
+ assert(mnemonicValidate(phrase), 'Not a valid mnemonic seed');
364
+ }
365
+
366
+ return {
367
+ address: keyring.createFromUri(getSuri(suri, type), {}, type).address,
368
+ suri
369
+ };
370
+ }
371
+
372
+ signingApprovePassword({
373
+ id,
374
+ password,
375
+ savePass
376
+ }) {
377
+ const queued = this.#state.getSignRequest(id);
378
+ assert(queued, 'Unable to find request');
379
+ const {
380
+ reject,
381
+ request,
382
+ resolve
383
+ } = queued;
384
+ const pair = keyring.getPair(queued.account.address); // unlike queued.account.address the following
385
+ // address is encoded with the default prefix
386
+ // which what is used for password caching mapping
387
+
388
+ const {
389
+ address
390
+ } = pair;
391
+
392
+ if (!pair) {
393
+ reject(new Error('Unable to find pair'));
394
+ return false;
395
+ }
396
+
397
+ this.refreshAccountPasswordCache(pair); // if the keyring pair is locked, the password is needed
398
+
399
+ if (pair.isLocked && !password) {
400
+ reject(new Error('Password needed to unlock the account'));
401
+ }
402
+
403
+ if (pair.isLocked) {
404
+ pair.decodePkcs8(password);
405
+ }
406
+
407
+ const {
408
+ payload
409
+ } = request;
410
+
411
+ if (isJsonPayload(payload)) {
412
+ // Get the metadata for the genesisHash
413
+ const currentMetadata = this.#state.knownMetadata.find(meta => meta.genesisHash === payload.genesisHash); // set the registry before calling the sign function
414
+
415
+ registry.setSignedExtensions(payload.signedExtensions, currentMetadata === null || currentMetadata === void 0 ? void 0 : currentMetadata.userExtensions);
416
+
417
+ if (currentMetadata) {
418
+ registry.register(currentMetadata === null || currentMetadata === void 0 ? void 0 : currentMetadata.types);
419
+ }
420
+ }
421
+
422
+ const result = request.sign(registry, pair);
423
+
424
+ if (savePass) {
425
+ this.#cachedUnlocks[address] = Date.now() + PASSWORD_EXPIRY_MS;
426
+ } else {
427
+ pair.lock();
428
+ }
429
+
430
+ resolve({
431
+ id,
432
+ ...result
433
+ });
434
+ return true;
435
+ }
436
+
437
+ signingApproveSignature({
438
+ id,
439
+ signature
440
+ }) {
441
+ const queued = this.#state.getSignRequest(id);
442
+ assert(queued, 'Unable to find request');
443
+ const {
444
+ resolve
445
+ } = queued;
446
+ resolve({
447
+ id,
448
+ signature
449
+ });
450
+ return true;
451
+ }
452
+
453
+ signingCancel({
454
+ id
455
+ }) {
456
+ const queued = this.#state.getSignRequest(id);
457
+ assert(queued, 'Unable to find request');
458
+ const {
459
+ reject
460
+ } = queued;
461
+ reject(new Error('Cancelled'));
462
+ return true;
463
+ }
464
+
465
+ signingIsLocked({
466
+ id
467
+ }) {
468
+ const queued = this.#state.getSignRequest(id);
469
+ assert(queued, 'Unable to find request');
470
+ const address = queued.request.payload.address;
471
+ const pair = keyring.getPair(address);
472
+ assert(pair, 'Unable to find pair');
473
+ const remainingTime = this.refreshAccountPasswordCache(pair);
474
+ return {
475
+ isLocked: pair.isLocked,
476
+ remainingTime
477
+ };
478
+ } // FIXME This looks very much like what we have in authorization
479
+
480
+
481
+ signingSubscribe(id, port) {
482
+ const cb = createSubscription(id, port);
483
+ const subscription = this.#state.signSubject.subscribe(requests => cb(requests));
484
+ port.onDisconnect.addListener(() => {
485
+ unsubscribe(id);
486
+ subscription.unsubscribe();
487
+ });
488
+ return true;
489
+ }
490
+
491
+ windowOpen(path) {
492
+ const url = `${chrome.extension.getURL('index.html')}#${path}`;
493
+
494
+ if (!ALLOWED_PATH.includes(path)) {
495
+ console.error('Not allowed to open the url:', url);
496
+ return false;
497
+ }
498
+
499
+ withErrorLog(() => chrome.tabs.create({
500
+ url
501
+ }));
502
+ return true;
503
+ }
504
+
505
+ derive(parentAddress, suri, password, metadata) {
506
+ const parentPair = keyring.getPair(parentAddress);
507
+
508
+ try {
509
+ parentPair.decodePkcs8(password);
510
+ } catch (e) {
511
+ throw new Error('invalid password');
512
+ }
513
+
514
+ try {
515
+ return parentPair.derive(suri, metadata);
516
+ } catch (err) {
517
+ throw new Error(`"${suri}" is not a valid derivation path`);
518
+ }
519
+ }
520
+
521
+ derivationValidate({
522
+ parentAddress,
523
+ parentPassword,
524
+ suri
525
+ }) {
526
+ const childPair = this.derive(parentAddress, suri, parentPassword, {});
527
+ return {
528
+ address: childPair.address,
529
+ suri
530
+ };
531
+ }
532
+
533
+ derivationCreate({
534
+ genesisHash,
535
+ name,
536
+ parentAddress,
537
+ parentPassword,
538
+ password,
539
+ suri
540
+ }) {
541
+ const childPair = this.derive(parentAddress, suri, parentPassword, {
542
+ genesisHash,
543
+ name,
544
+ parentAddress,
545
+ suri
546
+ });
547
+ keyring.addPair(childPair, password);
548
+ return true;
549
+ }
550
+
551
+ toggleAuthorization(url) {
552
+ return {
553
+ list: this.#state.toggleAuthorization(url)
554
+ };
555
+ } // Weird thought, the eslint override is not needed in Tabs
556
+ // eslint-disable-next-line @typescript-eslint/require-await
557
+
558
+
559
+ async handle(id, type, request, port) {
560
+ switch (type) {
561
+ case 'pri(authorize.approve)':
562
+ return this.authorizeApprove(request);
563
+
564
+ case 'pri(authorize.list)':
565
+ return this.getAuthList();
566
+
567
+ case 'pri(authorize.reject)':
568
+ return this.authorizeReject(request);
569
+
570
+ case 'pri(authorize.toggle)':
571
+ return this.toggleAuthorization(request);
572
+
573
+ case 'pri(authorize.requests)':
574
+ return this.authorizeSubscribe(id, port);
575
+
576
+ case 'pri(accounts.create.external)':
577
+ return this.accountsCreateExternal(request);
578
+
579
+ case 'pri(accounts.create.hardware)':
580
+ return this.accountsCreateHardware(request);
581
+
582
+ case 'pri(accounts.create.suri)':
583
+ return this.accountsCreateSuri(request);
584
+
585
+ case 'pri(accounts.changePassword)':
586
+ return this.accountsChangePassword(request);
587
+
588
+ case 'pri(accounts.edit)':
589
+ return this.accountsEdit(request);
590
+
591
+ case 'pri(accounts.export)':
592
+ return this.accountsExport(request);
593
+
594
+ case 'pri(accounts.batchExport)':
595
+ // return this.accountsBatchExport(request as RequestAccountBatchExport);
596
+ // Disable export all util use master password
597
+ return null;
598
+
599
+ case 'pri(accounts.forget)':
600
+ return this.accountsForget(request);
601
+
602
+ case 'pri(accounts.show)':
603
+ return this.accountsShow(request);
604
+
605
+ case 'pri(accounts.subscribe)':
606
+ return this.accountsSubscribe(id, port);
607
+
608
+ case 'pri(accounts.tie)':
609
+ return this.accountsTie(request);
610
+
611
+ case 'pri(accounts.validate)':
612
+ return this.accountsValidate(request);
613
+
614
+ case 'pri(metadata.approve)':
615
+ return this.metadataApprove(request);
616
+
617
+ case 'pri(metadata.get)':
618
+ return this.metadataGet(request);
619
+
620
+ case 'pri(metadata.list)':
621
+ return this.metadataList();
622
+
623
+ case 'pri(metadata.reject)':
624
+ return this.metadataReject(request);
625
+
626
+ case 'pri(metadata.requests)':
627
+ return this.metadataSubscribe(id, port);
628
+
629
+ case 'pri(derivation.create)':
630
+ return this.derivationCreate(request);
631
+
632
+ case 'pri(derivation.validate)':
633
+ return this.derivationValidate(request);
634
+
635
+ case 'pri(json.restore)':
636
+ return this.jsonRestore(request);
637
+
638
+ case 'pri(json.batchRestore)':
639
+ return this.batchRestore(request);
640
+
641
+ case 'pri(json.account.info)':
642
+ return this.jsonGetAccountInfo(request);
643
+
644
+ case 'pri(seed.create)':
645
+ return this.seedCreate(request);
646
+
647
+ case 'pri(seed.validate)':
648
+ return this.seedValidate(request);
649
+
650
+ case 'pri(settings.notification)':
651
+ return this.#state.setNotification(request);
652
+
653
+ case 'pri(signing.approve.password)':
654
+ return this.signingApprovePassword(request);
655
+
656
+ case 'pri(signing.approve.signature)':
657
+ return this.signingApproveSignature(request);
658
+
659
+ case 'pri(signing.cancel)':
660
+ return this.signingCancel(request);
661
+
662
+ case 'pri(signing.isLocked)':
663
+ return this.signingIsLocked(request);
664
+
665
+ case 'pri(signing.requests)':
666
+ return this.signingSubscribe(id, port);
667
+
668
+ case 'pri(window.open)':
669
+ return this.windowOpen(request);
670
+
671
+ default:
672
+ throw new Error(`Unable to handle message of type ${type}`);
673
+ }
674
+ }
675
+
676
+ }