@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
|
@@ -23,13 +23,13 @@ function transformAccounts(accounts, anyType = false) {
|
|
|
23
23
|
}));
|
|
24
24
|
}
|
|
25
25
|
export default class Tabs {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
#accountSubs = {};
|
|
27
|
+
#state;
|
|
28
28
|
constructor(state) {
|
|
29
|
-
this
|
|
29
|
+
this.#state = state;
|
|
30
30
|
}
|
|
31
31
|
filterForAuthorizedAccounts(accounts, url) {
|
|
32
|
-
const auth = this.
|
|
32
|
+
const auth = this.#state.authUrls[this.#state.stripUrl(url)];
|
|
33
33
|
if (!auth) {
|
|
34
34
|
return [];
|
|
35
35
|
}
|
|
@@ -40,7 +40,7 @@ export default class Tabs {
|
|
|
40
40
|
: auth.isAllowed);
|
|
41
41
|
}
|
|
42
42
|
authorize(url, request) {
|
|
43
|
-
return this.
|
|
43
|
+
return this.#state.authorizeUrl(url, request);
|
|
44
44
|
}
|
|
45
45
|
accountsListAuthorized(url, { anyType }) {
|
|
46
46
|
const transformedAccounts = transformAccounts(accountsObservable.subject.getValue(), anyType);
|
|
@@ -48,13 +48,13 @@ export default class Tabs {
|
|
|
48
48
|
}
|
|
49
49
|
accountsSubscribeAuthorized(url, id, port) {
|
|
50
50
|
const cb = createSubscription(id, port);
|
|
51
|
-
const strippedUrl = this.
|
|
52
|
-
const authUrlObservable = this.
|
|
51
|
+
const strippedUrl = this.#state.stripUrl(url);
|
|
52
|
+
const authUrlObservable = this.#state.authUrlSubjects[strippedUrl]?.asObservable();
|
|
53
53
|
if (!authUrlObservable) {
|
|
54
54
|
console.error(`No authUrlSubject found for ${strippedUrl}`);
|
|
55
55
|
return id;
|
|
56
56
|
}
|
|
57
|
-
this
|
|
57
|
+
this.#accountSubs[id] = {
|
|
58
58
|
subscription: combineLatest([accountsObservable.subject, authUrlObservable]).subscribe(([accounts, _authUrlInfo]) => {
|
|
59
59
|
const transformedAccounts = transformAccounts(accounts);
|
|
60
60
|
cb(this.filterForAuthorizedAccounts(transformedAccounts, url));
|
|
@@ -67,11 +67,11 @@ export default class Tabs {
|
|
|
67
67
|
return id;
|
|
68
68
|
}
|
|
69
69
|
accountsUnsubscribe(url, { id }) {
|
|
70
|
-
const sub = this
|
|
70
|
+
const sub = this.#accountSubs[id];
|
|
71
71
|
if (!sub || sub.url !== url) {
|
|
72
72
|
return false;
|
|
73
73
|
}
|
|
74
|
-
delete this
|
|
74
|
+
delete this.#accountSubs[id];
|
|
75
75
|
unsubscribe(id);
|
|
76
76
|
sub.subscription.unsubscribe();
|
|
77
77
|
return true;
|
|
@@ -84,35 +84,35 @@ export default class Tabs {
|
|
|
84
84
|
bytesSign(url, request) {
|
|
85
85
|
const address = request.address;
|
|
86
86
|
const pair = this.getSigningPair(address);
|
|
87
|
-
return this.
|
|
87
|
+
return this.#state.sign(url, new RequestBytesSign(request), { address, ...pair.meta });
|
|
88
88
|
}
|
|
89
89
|
extrinsicSign(url, request) {
|
|
90
90
|
const address = request.address;
|
|
91
91
|
const pair = this.getSigningPair(address);
|
|
92
|
-
return this.
|
|
92
|
+
return this.#state.sign(url, new RequestExtrinsicSign(request), { address, ...pair.meta });
|
|
93
93
|
}
|
|
94
94
|
metadataProvide(url, request) {
|
|
95
|
-
return this.
|
|
95
|
+
return this.#state.injectMetadata(url, request);
|
|
96
96
|
}
|
|
97
97
|
metadataList(_url) {
|
|
98
|
-
return this.
|
|
98
|
+
return this.#state.knownMetadata.map(({ genesisHash, specVersion }) => ({
|
|
99
99
|
genesisHash,
|
|
100
100
|
specVersion
|
|
101
101
|
}));
|
|
102
102
|
}
|
|
103
103
|
rpcListProviders() {
|
|
104
|
-
return this.
|
|
104
|
+
return this.#state.rpcListProviders();
|
|
105
105
|
}
|
|
106
106
|
rpcSend(request, port) {
|
|
107
|
-
return this.
|
|
107
|
+
return this.#state.rpcSend(request, port);
|
|
108
108
|
}
|
|
109
109
|
rpcStartProvider(key, port) {
|
|
110
|
-
return this.
|
|
110
|
+
return this.#state.rpcStartProvider(key, port);
|
|
111
111
|
}
|
|
112
112
|
async rpcSubscribe(request, id, port) {
|
|
113
113
|
const innerCb = createSubscription(id, port);
|
|
114
114
|
const cb = (_error, data) => innerCb(data);
|
|
115
|
-
const subscriptionId = await this.
|
|
115
|
+
const subscriptionId = await this.#state.rpcSubscribe(request, cb, port);
|
|
116
116
|
port.onDisconnect.addListener(() => {
|
|
117
117
|
unsubscribe(id);
|
|
118
118
|
withErrorLog(() => this.rpcUnsubscribe({ ...request, subscriptionId }, port));
|
|
@@ -122,14 +122,14 @@ export default class Tabs {
|
|
|
122
122
|
rpcSubscribeConnected(request, id, port) {
|
|
123
123
|
const innerCb = createSubscription(id, port);
|
|
124
124
|
const cb = (_error, data) => innerCb(data);
|
|
125
|
-
this.
|
|
125
|
+
this.#state.rpcSubscribeConnected(request, cb, port);
|
|
126
126
|
port.onDisconnect.addListener(() => {
|
|
127
127
|
unsubscribe(id);
|
|
128
128
|
});
|
|
129
129
|
return Promise.resolve(true);
|
|
130
130
|
}
|
|
131
131
|
async rpcUnsubscribe(request, port) {
|
|
132
|
-
return this.
|
|
132
|
+
return this.#state.rpcUnsubscribe(request, port);
|
|
133
133
|
}
|
|
134
134
|
redirectPhishingLanding(phishingWebsite) {
|
|
135
135
|
const nonFragment = phishingWebsite.split('#')[0];
|
|
@@ -155,7 +155,7 @@ export default class Tabs {
|
|
|
155
155
|
return this.redirectIfPhishing(url);
|
|
156
156
|
}
|
|
157
157
|
if (type !== 'pub(authorize.tab)') {
|
|
158
|
-
this.
|
|
158
|
+
this.#state.ensureUrlAuthorized(url);
|
|
159
159
|
}
|
|
160
160
|
switch (type) {
|
|
161
161
|
case 'pub(authorize.tab)':
|
|
@@ -21,16 +21,16 @@ function isJsonPayload(value) {
|
|
|
21
21
|
return value.genesisHash !== undefined;
|
|
22
22
|
}
|
|
23
23
|
class Extension {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
#cachedUnlocks;
|
|
25
|
+
#state;
|
|
26
26
|
constructor(state) {
|
|
27
|
-
this
|
|
28
|
-
this
|
|
27
|
+
this.#cachedUnlocks = {};
|
|
28
|
+
this.#state = state;
|
|
29
29
|
}
|
|
30
30
|
transformAccounts(accounts) {
|
|
31
31
|
return Object.values(accounts).map(({ json: { address, meta }, type }) => ({
|
|
32
32
|
address,
|
|
33
|
-
isDefaultAuthSelected: this.
|
|
33
|
+
isDefaultAuthSelected: this.#state.defaultAuthAccountSelection.includes(address),
|
|
34
34
|
...meta,
|
|
35
35
|
type
|
|
36
36
|
}));
|
|
@@ -79,26 +79,26 @@ class Extension {
|
|
|
79
79
|
async accountsForget({ address }) {
|
|
80
80
|
const authorizedAccountsDiff = [];
|
|
81
81
|
// cycle through authUrls and prepare the array of diff
|
|
82
|
-
Object.entries(this.
|
|
82
|
+
Object.entries(this.#state.authUrls).forEach(([url, urlInfo]) => {
|
|
83
83
|
// Note that urlInfo.authorizedAccounts may be undefined if this website entry
|
|
84
84
|
// was created before the "account authorization per website" functionality was introduced
|
|
85
85
|
if (urlInfo.authorizedAccounts?.includes(address)) {
|
|
86
86
|
authorizedAccountsDiff.push([url, urlInfo.authorizedAccounts.filter((previousAddress) => previousAddress !== address)]);
|
|
87
87
|
}
|
|
88
88
|
});
|
|
89
|
-
await this.
|
|
89
|
+
await this.#state.updateAuthorizedAccounts(authorizedAccountsDiff);
|
|
90
90
|
// cycle through default account selection for auth and remove any occurrence of the account
|
|
91
|
-
const newDefaultAuthAccounts = this.
|
|
92
|
-
await this.
|
|
91
|
+
const newDefaultAuthAccounts = this.#state.defaultAuthAccountSelection.filter((defaultSelectionAddress) => defaultSelectionAddress !== address);
|
|
92
|
+
await this.#state.updateDefaultAuthAccounts(newDefaultAuthAccounts);
|
|
93
93
|
ui_keyring_1.keyring.forgetAccount(address);
|
|
94
94
|
return true;
|
|
95
95
|
}
|
|
96
96
|
refreshAccountPasswordCache(pair) {
|
|
97
97
|
const { address } = pair;
|
|
98
|
-
const savedExpiry = this
|
|
98
|
+
const savedExpiry = this.#cachedUnlocks[address] || 0;
|
|
99
99
|
const remainingTime = savedExpiry - Date.now();
|
|
100
100
|
if (remainingTime < 0) {
|
|
101
|
-
this
|
|
101
|
+
this.#cachedUnlocks[address] = 0;
|
|
102
102
|
pair.lock();
|
|
103
103
|
return 0;
|
|
104
104
|
}
|
|
@@ -135,22 +135,22 @@ class Extension {
|
|
|
135
135
|
return true;
|
|
136
136
|
}
|
|
137
137
|
authorizeApprove({ authorizedAccounts, id }) {
|
|
138
|
-
const queued = this.
|
|
138
|
+
const queued = this.#state.getAuthRequest(id);
|
|
139
139
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
140
140
|
const { resolve } = queued;
|
|
141
141
|
resolve({ authorizedAccounts, result: true });
|
|
142
142
|
return true;
|
|
143
143
|
}
|
|
144
144
|
async authorizeUpdate({ authorizedAccounts, url }) {
|
|
145
|
-
return await this.
|
|
145
|
+
return await this.#state.updateAuthorizedAccounts([[url, authorizedAccounts]]);
|
|
146
146
|
}
|
|
147
147
|
getAuthList() {
|
|
148
|
-
return { list: this.
|
|
148
|
+
return { list: this.#state.authUrls };
|
|
149
149
|
}
|
|
150
150
|
// FIXME This looks very much like what we have in accounts
|
|
151
151
|
authorizeSubscribe(id, port) {
|
|
152
152
|
const cb = (0, subscriptions_js_1.createSubscription)(id, port);
|
|
153
|
-
const subscription = this.
|
|
153
|
+
const subscription = this.#state.authSubject.subscribe((requests) => cb(requests));
|
|
154
154
|
port.onDisconnect.addListener(() => {
|
|
155
155
|
(0, subscriptions_js_1.unsubscribe)(id);
|
|
156
156
|
subscription.unsubscribe();
|
|
@@ -158,21 +158,21 @@ class Extension {
|
|
|
158
158
|
return true;
|
|
159
159
|
}
|
|
160
160
|
async metadataApprove({ id }) {
|
|
161
|
-
const queued = this.
|
|
161
|
+
const queued = this.#state.getMetaRequest(id);
|
|
162
162
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
163
163
|
const { request, resolve } = queued;
|
|
164
|
-
await this.
|
|
164
|
+
await this.#state.saveMetadata(request);
|
|
165
165
|
resolve(true);
|
|
166
166
|
return true;
|
|
167
167
|
}
|
|
168
168
|
metadataGet(genesisHash) {
|
|
169
|
-
return this.
|
|
169
|
+
return this.#state.knownMetadata.find((result) => result.genesisHash === genesisHash) || null;
|
|
170
170
|
}
|
|
171
171
|
metadataList() {
|
|
172
|
-
return this.
|
|
172
|
+
return this.#state.knownMetadata;
|
|
173
173
|
}
|
|
174
174
|
metadataReject({ id }) {
|
|
175
|
-
const queued = this.
|
|
175
|
+
const queued = this.#state.getMetaRequest(id);
|
|
176
176
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
177
177
|
const { reject } = queued;
|
|
178
178
|
reject(new Error('Rejected'));
|
|
@@ -180,7 +180,7 @@ class Extension {
|
|
|
180
180
|
}
|
|
181
181
|
metadataSubscribe(id, port) {
|
|
182
182
|
const cb = (0, subscriptions_js_1.createSubscription)(id, port);
|
|
183
|
-
const subscription = this.
|
|
183
|
+
const subscription = this.#state.metaSubject.subscribe((requests) => cb(requests));
|
|
184
184
|
port.onDisconnect.addListener(() => {
|
|
185
185
|
(0, subscriptions_js_1.unsubscribe)(id);
|
|
186
186
|
subscription.unsubscribe();
|
|
@@ -241,7 +241,7 @@ class Extension {
|
|
|
241
241
|
};
|
|
242
242
|
}
|
|
243
243
|
signingApprovePassword({ id, password, savePass }) {
|
|
244
|
-
const queued = this.
|
|
244
|
+
const queued = this.#state.getSignRequest(id);
|
|
245
245
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
246
246
|
const { reject, request, resolve } = queued;
|
|
247
247
|
const pair = ui_keyring_1.keyring.getPair(queued.account.address);
|
|
@@ -262,7 +262,7 @@ class Extension {
|
|
|
262
262
|
const { payload } = request;
|
|
263
263
|
if (isJsonPayload(payload)) {
|
|
264
264
|
// Get the metadata for the genesisHash
|
|
265
|
-
const metadata = this.
|
|
265
|
+
const metadata = this.#state.knownMetadata.find(({ genesisHash }) => genesisHash === payload.genesisHash);
|
|
266
266
|
if (metadata) {
|
|
267
267
|
// we have metadata, expand it and extract the info/registry
|
|
268
268
|
const expanded = (0, extension_chains_1.metadataExpand)(metadata, false);
|
|
@@ -284,7 +284,7 @@ class Extension {
|
|
|
284
284
|
// unlike queued.account.address the following
|
|
285
285
|
// address is encoded with the default prefix
|
|
286
286
|
// which what is used for password caching mapping
|
|
287
|
-
this
|
|
287
|
+
this.#cachedUnlocks[pair.address] = Date.now() + defaults_1.PASSWORD_EXPIRY_MS;
|
|
288
288
|
}
|
|
289
289
|
else {
|
|
290
290
|
pair.lock();
|
|
@@ -296,21 +296,21 @@ class Extension {
|
|
|
296
296
|
return true;
|
|
297
297
|
}
|
|
298
298
|
signingApproveSignature({ id, signature, signedTransaction }) {
|
|
299
|
-
const queued = this.
|
|
299
|
+
const queued = this.#state.getSignRequest(id);
|
|
300
300
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
301
301
|
const { resolve } = queued;
|
|
302
302
|
resolve({ id, signature, signedTransaction });
|
|
303
303
|
return true;
|
|
304
304
|
}
|
|
305
305
|
signingCancel({ id }) {
|
|
306
|
-
const queued = this.
|
|
306
|
+
const queued = this.#state.getSignRequest(id);
|
|
307
307
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
308
308
|
const { reject } = queued;
|
|
309
309
|
reject(new Error('Cancelled'));
|
|
310
310
|
return true;
|
|
311
311
|
}
|
|
312
312
|
signingIsLocked({ id }) {
|
|
313
|
-
const queued = this.
|
|
313
|
+
const queued = this.#state.getSignRequest(id);
|
|
314
314
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
315
315
|
const address = queued.request.payload.address;
|
|
316
316
|
const pair = ui_keyring_1.keyring.getPair(address);
|
|
@@ -324,7 +324,7 @@ class Extension {
|
|
|
324
324
|
// FIXME This looks very much like what we have in authorization
|
|
325
325
|
signingSubscribe(id, port) {
|
|
326
326
|
const cb = (0, subscriptions_js_1.createSubscription)(id, port);
|
|
327
|
-
const subscription = this.
|
|
327
|
+
const subscription = this.#state.signSubject.subscribe((requests) => cb(requests));
|
|
328
328
|
port.onDisconnect.addListener(() => {
|
|
329
329
|
(0, subscriptions_js_1.unsubscribe)(id);
|
|
330
330
|
subscription.unsubscribe();
|
|
@@ -373,13 +373,13 @@ class Extension {
|
|
|
373
373
|
return true;
|
|
374
374
|
}
|
|
375
375
|
async removeAuthorization(url) {
|
|
376
|
-
const remAuth = await this.
|
|
376
|
+
const remAuth = await this.#state.removeAuthorization(url);
|
|
377
377
|
return { list: remAuth };
|
|
378
378
|
}
|
|
379
379
|
// Reject the authorization request and add the URL to the authorized list with no keys.
|
|
380
380
|
// The site will not prompt for re-authorization on future visits.
|
|
381
381
|
rejectAuthRequest(id) {
|
|
382
|
-
const queued = this.
|
|
382
|
+
const queued = this.#state.getAuthRequest(id);
|
|
383
383
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
384
384
|
const { reject } = queued;
|
|
385
385
|
reject(new Error('Rejected'));
|
|
@@ -387,16 +387,16 @@ class Extension {
|
|
|
387
387
|
// Cancel the authorization request and do not add the URL to the authorized list.
|
|
388
388
|
// The site will prompt for authorization on future visits.
|
|
389
389
|
cancelAuthRequest(id) {
|
|
390
|
-
const queued = this.
|
|
390
|
+
const queued = this.#state.getAuthRequest(id);
|
|
391
391
|
(0, util_1.assert)(queued, 'Unable to find request');
|
|
392
392
|
const { reject } = queued;
|
|
393
393
|
reject(new Error('Cancelled'));
|
|
394
394
|
}
|
|
395
395
|
updateCurrentTabs({ urls }) {
|
|
396
|
-
this.
|
|
396
|
+
this.#state.updateCurrentTabsUrl(urls);
|
|
397
397
|
}
|
|
398
398
|
getConnectedTabsUrl() {
|
|
399
|
-
return this.
|
|
399
|
+
return this.#state.getConnectedTabsUrl();
|
|
400
400
|
}
|
|
401
401
|
// Weird thought, the eslint override is not needed in Tabs
|
|
402
402
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
@@ -471,7 +471,7 @@ class Extension {
|
|
|
471
471
|
case 'pri(seed.validate)':
|
|
472
472
|
return this.seedValidate(request);
|
|
473
473
|
case 'pri(settings.notification)':
|
|
474
|
-
return this.
|
|
474
|
+
return this.#state.setNotification(request);
|
|
475
475
|
case 'pri(signing.approve.password)':
|
|
476
476
|
return this.signingApprovePassword(request);
|
|
477
477
|
case 'pri(signing.approve.signature)':
|