@subwallet/extension-base 1.1.23-0 → 1.1.24-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.
@@ -13,6 +13,7 @@ import { KeyringPair$Json, KeyringPair$Meta } from '@subwallet/keyring/types';
13
13
  import { KeyringOptions } from '@subwallet/ui-keyring/options/types';
14
14
  import { KeyringAddress, KeyringPairs$Json } from '@subwallet/ui-keyring/types';
15
15
  import { SessionTypes } from '@walletconnect/types/dist/types/sign-client/session';
16
+ import { DexieExportJsonMeta } from 'dexie-export-import';
16
17
  import Web3 from 'web3';
17
18
  import { RequestArguments, TransactionConfig } from 'web3-core';
18
19
  import { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers';
@@ -36,7 +37,7 @@ export interface RuntimeEnvironmentInfo {
36
37
  host?: string;
37
38
  protocol?: string;
38
39
  }
39
- export declare type TargetEnvironment = 'extension' | 'webapp' | 'web-runner';
40
+ export declare type TargetEnvironment = 'extension' | 'webapp' | 'mobile';
40
41
  export interface EnvironmentSupport {
41
42
  MANTA_ZK: boolean;
42
43
  }
@@ -1419,6 +1420,10 @@ export interface RequestGetTransaction {
1419
1420
  id: string;
1420
1421
  }
1421
1422
  export declare type SubscriptionServiceType = 'chainRegistry' | 'balance' | 'crowdloan' | 'staking';
1423
+ export interface MobileData {
1424
+ storage: string;
1425
+ indexedDB: string;
1426
+ }
1422
1427
  export declare type CronServiceType = 'price' | 'nft' | 'staking' | 'history' | 'recoverApi' | 'checkApiStatus';
1423
1428
  export declare type CronType = 'recoverApiMap' | 'checkApiMapStatus' | 'refreshHistory' | 'refreshNft' | 'refreshPrice' | 'refreshStakeUnlockingInfo' | 'refreshStakingReward' | 'refreshPoolingStakingReward';
1424
1429
  export interface RequestInitCronAndSubscription {
@@ -1782,6 +1787,8 @@ export interface KoniRequestSignatures {
1782
1787
  'mobile(subscription.start)': [SubscriptionServiceType[], void];
1783
1788
  'mobile(subscription.stop)': [SubscriptionServiceType[], void];
1784
1789
  'mobile(subscription.restart)': [SubscriptionServiceType[], void];
1790
+ 'mobile(storage.backup)': [null, MobileData];
1791
+ 'mobile(storage.restore)': [Partial<MobileData>, null];
1785
1792
  'pub(token.add)': [RequestAddPspToken, boolean];
1786
1793
  'pri(walletConnect.connect)': [RequestConnectWalletConnect, boolean];
1787
1794
  'pri(walletConnect.requests.connect.subscribe)': [null, WalletConnectSessionRequest[], WalletConnectSessionRequest[]];
@@ -1798,6 +1805,9 @@ export interface KoniRequestSignatures {
1798
1805
  'pri(campaign.banner.complete)': [RequestCampaignBannerComplete, boolean];
1799
1806
  'pri(buyService.tokens.subscribe)': [null, Record<string, BuyTokenInfo>, Record<string, BuyTokenInfo>];
1800
1807
  'pri(buyService.services.subscribe)': [null, Record<string, BuyServiceInfo>, Record<string, BuyServiceInfo>];
1808
+ 'pri(database.export)': [null, string];
1809
+ 'pri(database.import)': [string, boolean];
1810
+ 'pri(database.checkMetadata)': [string, DexieExportJsonMeta];
1801
1811
  }
1802
1812
  export interface ApplicationMetadataType {
1803
1813
  version: string;
@@ -4164,6 +4164,15 @@ class KoniExtension {
4164
4164
  case 'pri(buyService.services.subscribe)':
4165
4165
  return this.subscribeBuyServices(id, port);
4166
4166
  /* Buy service */
4167
+
4168
+ /* Database */
4169
+ case 'pri(database.export)':
4170
+ return this.#koniState.dbService.exportDB();
4171
+ case 'pri(database.import)':
4172
+ return this.#koniState.dbService.importDB(request);
4173
+ case 'pri(database.checkMetadata)':
4174
+ return this.#koniState.dbService.checkImportMetadata(request);
4175
+ /* Database */
4167
4176
  // Default
4168
4177
  default:
4169
4178
  throw new Error(`Unable to handle message of type ${type}`);
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _promise = require("@subwallet/extension-base/utils/promise");
7
8
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
8
9
  // SPDX-License-Identifier: Apache-2.0
9
10
 
@@ -26,6 +27,7 @@ const DEFAULT_SERVICE_MAP = {
26
27
  class Mobile {
27
28
  // @ts-ignore
28
29
 
30
+ restoreHandler = (0, _promise.createPromiseHandler)();
29
31
  constructor(state) {
30
32
  this.state = state;
31
33
  }
@@ -102,6 +104,32 @@ class Mobile {
102
104
  restartSubscriptionServices(services) {
103
105
  console.log('restartSubscriptionServices');
104
106
  }
107
+ async mobileBackup() {
108
+ const indexedDB = await this.state.dbService.exportDB();
109
+ return {
110
+ storage: JSON.stringify(localStorage),
111
+ indexedDB
112
+ };
113
+ }
114
+ async mobileRestore(_ref5) {
115
+ let {
116
+ indexedDB,
117
+ storage
118
+ } = _ref5;
119
+ if (storage) {
120
+ const storageData = JSON.parse(storage);
121
+ for (const key in storageData) {
122
+ localStorage.setItem(key, JSON.stringify(storageData[key]));
123
+ }
124
+ }
125
+ if (indexedDB) {
126
+ await this.state.dbService.importDB(indexedDB);
127
+ }
128
+ this.restoreHandler.resolve();
129
+ }
130
+ waitRestore() {
131
+ return this.restoreHandler.promise;
132
+ }
105
133
 
106
134
  // eslint-disable-next-line @typescript-eslint/require-await
107
135
  async handle(id, type, request, port) {
@@ -130,6 +158,10 @@ class Mobile {
130
158
  return this.stopSubscriptionServices(request);
131
159
  case 'mobile(subscription.restart)':
132
160
  return this.restartSubscriptionServices(request);
161
+ case 'mobile(storage.restore)':
162
+ return this.mobileRestore(request);
163
+ case 'mobile(storage.backup)':
164
+ return this.mobileBackup();
133
165
  default:
134
166
  throw new Error(`Unable to handle message of type ${type}`);
135
167
  }
@@ -109,7 +109,9 @@ class KoniState {
109
109
  this.logger = (0, _util.logger)('State');
110
110
 
111
111
  // Init state
112
- this.init().catch(console.error);
112
+ if (_utils2.TARGET_ENV !== 'mobile') {
113
+ this.init().catch(console.error);
114
+ }
113
115
  }
114
116
 
115
117
  // Clone from polkadot.js
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.1.23-0'
16
+ version: '1.1.24-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -13,10 +13,12 @@ var _ChainStakingMetadata = _interopRequireDefault(require("@subwallet/extension
13
13
  var _MantaPay = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/MantaPay"));
14
14
  var _NominatorMetadata = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata"));
15
15
  var _utils = require("@subwallet/extension-base/utils");
16
+ var _dexieExportImport = require("dexie-export-import");
16
17
  var _util = require("@polkadot/util");
17
18
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
18
19
  // SPDX-License-Identifier: Apache-2.0
19
20
 
21
+ const EXPORT_EXCLUDE_TABLES = ['metadata'];
20
22
  class DatabaseService {
21
23
  // TODO: might remove this
22
24
 
@@ -287,5 +289,43 @@ class DatabaseService {
287
289
  upsertCampaign(campaign) {
288
290
  return this.stores.campaign.upsertCampaign(campaign);
289
291
  }
292
+ async exportDB() {
293
+ const blob = await (0, _dexieExportImport.exportDB)(this._db, {
294
+ filter: (table, value, key) => {
295
+ if (EXPORT_EXCLUDE_TABLES.indexOf(table) >= 0) {
296
+ return false;
297
+ }
298
+ return true;
299
+ }
300
+ });
301
+ return await blob.text();
302
+ }
303
+ async importDB(data) {
304
+ try {
305
+ const blob = new Blob([data], {
306
+ type: 'application/json'
307
+ });
308
+ await this._db.import(blob, {
309
+ overwriteValues: true,
310
+ acceptMissingTables: true,
311
+ acceptVersionDiff: true
312
+ });
313
+ return true;
314
+ } catch (e) {
315
+ this.logger.error(e);
316
+ return false;
317
+ }
318
+ }
319
+ async checkImportMetadata(data) {
320
+ try {
321
+ const blob = new Blob([data], {
322
+ type: 'application/json'
323
+ });
324
+ return await (0, _dexieExportImport.peakImportFile)(blob);
325
+ } catch (e) {
326
+ this.logger.error(e);
327
+ return null;
328
+ }
329
+ }
290
330
  }
291
331
  exports.default = DatabaseService;
@@ -4062,6 +4062,15 @@ export default class KoniExtension {
4062
4062
  case 'pri(buyService.services.subscribe)':
4063
4063
  return this.subscribeBuyServices(id, port);
4064
4064
  /* Buy service */
4065
+
4066
+ /* Database */
4067
+ case 'pri(database.export)':
4068
+ return this.#koniState.dbService.exportDB();
4069
+ case 'pri(database.import)':
4070
+ return this.#koniState.dbService.importDB(request);
4071
+ case 'pri(database.checkMetadata)':
4072
+ return this.#koniState.dbService.checkImportMetadata(request);
4073
+ /* Database */
4065
4074
  // Default
4066
4075
  default:
4067
4076
  throw new Error(`Unable to handle message of type ${type}`);
@@ -1,9 +1,10 @@
1
1
  /// <reference types="chrome" />
2
- import { ActiveCronAndSubscriptionMap, CronServiceType, RequestCronAndSubscriptionAction, RequestInitCronAndSubscription, SubscriptionServiceType } from '@subwallet/extension-base/background/KoniTypes';
2
+ import { ActiveCronAndSubscriptionMap, CronServiceType, MobileData, RequestCronAndSubscriptionAction, RequestInitCronAndSubscription, SubscriptionServiceType } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { MessageTypes, RequestTypes, ResponseType } from '@subwallet/extension-base/background/types';
4
4
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
5
  export default class Mobile {
6
6
  private state;
7
+ private restoreHandler;
7
8
  constructor(state: KoniState);
8
9
  ping(): string;
9
10
  initCronAndSubscription({ cron: { activeServices, intervalMap }, subscription: { activeServices } }: RequestInitCronAndSubscription): ActiveCronAndSubscriptionMap;
@@ -17,5 +18,8 @@ export default class Mobile {
17
18
  startSubscriptionServices(services: SubscriptionServiceType[]): void;
18
19
  stopSubscriptionServices(services: SubscriptionServiceType[]): void;
19
20
  restartSubscriptionServices(services: SubscriptionServiceType[]): void;
21
+ mobileBackup(): Promise<MobileData>;
22
+ mobileRestore({ indexedDB, storage }: Partial<MobileData>): Promise<void>;
23
+ waitRestore(): Promise<void>;
20
24
  handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>>;
21
25
  }
@@ -1,6 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
4
5
  const DEFAULT_SERVICE_MAP = {
5
6
  subscription: {
6
7
  chainRegistry: true,
@@ -20,6 +21,7 @@ const DEFAULT_SERVICE_MAP = {
20
21
  export default class Mobile {
21
22
  // @ts-ignore
22
23
 
24
+ restoreHandler = createPromiseHandler();
23
25
  constructor(state) {
24
26
  this.state = state;
25
27
  }
@@ -92,6 +94,31 @@ export default class Mobile {
92
94
  restartSubscriptionServices(services) {
93
95
  console.log('restartSubscriptionServices');
94
96
  }
97
+ async mobileBackup() {
98
+ const indexedDB = await this.state.dbService.exportDB();
99
+ return {
100
+ storage: JSON.stringify(localStorage),
101
+ indexedDB
102
+ };
103
+ }
104
+ async mobileRestore({
105
+ indexedDB,
106
+ storage
107
+ }) {
108
+ if (storage) {
109
+ const storageData = JSON.parse(storage);
110
+ for (const key in storageData) {
111
+ localStorage.setItem(key, JSON.stringify(storageData[key]));
112
+ }
113
+ }
114
+ if (indexedDB) {
115
+ await this.state.dbService.importDB(indexedDB);
116
+ }
117
+ this.restoreHandler.resolve();
118
+ }
119
+ waitRestore() {
120
+ return this.restoreHandler.promise;
121
+ }
95
122
 
96
123
  // eslint-disable-next-line @typescript-eslint/require-await
97
124
  async handle(id, type, request, port) {
@@ -120,6 +147,10 @@ export default class Mobile {
120
147
  return this.stopSubscriptionServices(request);
121
148
  case 'mobile(subscription.restart)':
122
149
  return this.restartSubscriptionServices(request);
150
+ case 'mobile(storage.restore)':
151
+ return this.mobileRestore(request);
152
+ case 'mobile(storage.backup)':
153
+ return this.mobileBackup();
123
154
  default:
124
155
  throw new Error(`Unable to handle message of type ${type}`);
125
156
  }
@@ -27,7 +27,7 @@ import { SUBSCAN_API_CHAIN_MAP, SUBSCAN_BALANCE_CHAIN_MAP_REVERSE } from '@subwa
27
27
  import TransactionService from '@subwallet/extension-base/services/transaction-service';
28
28
  import WalletConnectService from '@subwallet/extension-base/services/wallet-connect-service';
29
29
  import AccountRefStore from '@subwallet/extension-base/stores/AccountRef';
30
- import { stripUrl } from '@subwallet/extension-base/utils';
30
+ import { stripUrl, TARGET_ENV } from '@subwallet/extension-base/utils';
31
31
  import { isContractAddress, parseContractInput } from '@subwallet/extension-base/utils/eth/parseTransaction';
32
32
  import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
33
33
  import { decodePair } from '@subwallet/keyring/pair/decode';
@@ -102,7 +102,9 @@ export default class KoniState {
102
102
  this.logger = createLogger('State');
103
103
 
104
104
  // Init state
105
- this.init().catch(console.error);
105
+ if (TARGET_ENV !== 'mobile') {
106
+ this.init().catch(console.error);
107
+ }
106
108
  }
107
109
 
108
110
  // Clone from polkadot.js
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.1.23-0",
20
+ "version": "1.1.24-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1323,10 +1323,10 @@
1323
1323
  "@sora-substrate/type-definitions": "^1.17.7",
1324
1324
  "@substrate/connect": "^0.7.26",
1325
1325
  "@subwallet/chain-list": "0.2.26",
1326
- "@subwallet/extension-base": "^1.1.23-0",
1327
- "@subwallet/extension-chains": "^1.1.23-0",
1328
- "@subwallet/extension-dapp": "^1.1.23-0",
1329
- "@subwallet/extension-inject": "^1.1.23-0",
1326
+ "@subwallet/extension-base": "^1.1.24-0",
1327
+ "@subwallet/extension-chains": "^1.1.24-0",
1328
+ "@subwallet/extension-dapp": "^1.1.24-0",
1329
+ "@subwallet/extension-inject": "^1.1.24-0",
1330
1330
  "@subwallet/keyring": "^0.1.1",
1331
1331
  "@subwallet/ui-keyring": "^0.1.1",
1332
1332
  "@walletconnect/sign-client": "^2.8.4",
@@ -1341,6 +1341,7 @@
1341
1341
  "buffer": "^6.0.3",
1342
1342
  "cross-fetch": "^3.1.5",
1343
1343
  "dexie": "^3.2.2",
1344
+ "dexie-export-import": "^4.0.7",
1344
1345
  "eth-simple-keyring": "^4.2.0",
1345
1346
  "ethereumjs-tx": "^2.1.2",
1346
1347
  "ethereumjs-util": "^7.1.5",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.1.23-0'
10
+ version: '1.1.24-0'
11
11
  };
@@ -83,4 +83,7 @@ export default class DatabaseService {
83
83
  getProcessingCampaign(): Promise<import("@subwallet/extension-base/background/KoniTypes").CampaignData[]>;
84
84
  getCampaign(slug: string): Promise<import("@subwallet/extension-base/background/KoniTypes").CampaignData | undefined>;
85
85
  upsertCampaign(campaign: ICampaign): import("dexie").PromiseExtended<unknown>;
86
+ exportDB(): Promise<string>;
87
+ importDB(data: string): Promise<boolean>;
88
+ checkImportMetadata(data: string): Promise<import("dexie-export-import").DexieExportJsonMeta | null>;
86
89
  }
@@ -9,7 +9,9 @@ import ChainStakingMetadataStore from '@subwallet/extension-base/services/storag
9
9
  import MantaPayStore from '@subwallet/extension-base/services/storage-service/db-stores/MantaPay';
10
10
  import NominatorMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata';
11
11
  import { reformatAddress } from '@subwallet/extension-base/utils';
12
+ import { exportDB, peakImportFile } from 'dexie-export-import';
12
13
  import { logger as createLogger } from '@polkadot/util';
14
+ const EXPORT_EXCLUDE_TABLES = ['metadata'];
13
15
  export default class DatabaseService {
14
16
  // TODO: might remove this
15
17
 
@@ -279,4 +281,42 @@ export default class DatabaseService {
279
281
  upsertCampaign(campaign) {
280
282
  return this.stores.campaign.upsertCampaign(campaign);
281
283
  }
284
+ async exportDB() {
285
+ const blob = await exportDB(this._db, {
286
+ filter: (table, value, key) => {
287
+ if (EXPORT_EXCLUDE_TABLES.indexOf(table) >= 0) {
288
+ return false;
289
+ }
290
+ return true;
291
+ }
292
+ });
293
+ return await blob.text();
294
+ }
295
+ async importDB(data) {
296
+ try {
297
+ const blob = new Blob([data], {
298
+ type: 'application/json'
299
+ });
300
+ await this._db.import(blob, {
301
+ overwriteValues: true,
302
+ acceptMissingTables: true,
303
+ acceptVersionDiff: true
304
+ });
305
+ return true;
306
+ } catch (e) {
307
+ this.logger.error(e);
308
+ return false;
309
+ }
310
+ }
311
+ async checkImportMetadata(data) {
312
+ try {
313
+ const blob = new Blob([data], {
314
+ type: 'application/json'
315
+ });
316
+ return await peakImportFile(blob);
317
+ } catch (e) {
318
+ this.logger.error(e);
319
+ return null;
320
+ }
321
+ }
282
322
  }