From fd3176c36e309dadbd9461d129082527313940c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=AA=E9=9C=81?= Date: Wed, 10 Mar 2021 02:55:31 +0800 Subject: [PATCH] Batch export (#449) * . * . * fix lint * . * change on request --- packages/ui-keyring/src/Keyring.ts | 33 +++++++++++++++++++++++++++--- packages/ui-keyring/src/types.ts | 6 ++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/packages/ui-keyring/src/Keyring.ts b/packages/ui-keyring/src/Keyring.ts index 47fb8b81..ab50e81d 100644 --- a/packages/ui-keyring/src/Keyring.ts +++ b/packages/ui-keyring/src/Keyring.ts @@ -2,16 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '@polkadot/keyring/types'; +import type { EncryptedJson } from '@polkadot/util-crypto/json/types'; import type { KeypairType } from '@polkadot/util-crypto/types'; import type { AddressSubject, SingleAddress } from './observable/types'; -import type { CreateResult, KeyringAddress, KeyringAddressType, KeyringItemType, KeyringJson, KeyringJson$Meta, KeyringOptions, KeyringStruct } from './types'; +import type { CreateResult, KeyringAddress, KeyringAddressType, KeyringItemType, KeyringJson, KeyringJson$Meta, KeyringOptions, KeyringPairs$Json, KeyringStruct } from './types'; import BN from 'bn.js'; import { createPair } from '@polkadot/keyring/pair'; import { chains } from '@polkadot/ui-settings/defaults/chains'; -import { bnToBn, hexToU8a, isHex, isString, u8aSorted } from '@polkadot/util'; -import { base64Decode, createKeyMulti } from '@polkadot/util-crypto'; +import { bnToBn, hexToU8a, isHex, isString, stringToU8a, u8aSorted, u8aToString } from '@polkadot/util'; +import { base64Decode, createKeyMulti, jsonDecrypt, jsonEncrypt } from '@polkadot/util-crypto'; import { env } from './observable/env'; import { Base } from './Base'; @@ -82,6 +83,24 @@ export class Keyring extends Base implements KeyringStruct { return pair.toJson(password); } + public async backupAccounts (addresses: string[]): Promise { + const accountPromises = addresses.map((address) => { + return new Promise((resolve) => { + this._store.get(accountKey(address), resolve); + }); + }); + + const accounts = await Promise.all(accountPromises); + + return { + ...jsonEncrypt(stringToU8a(JSON.stringify(accounts)), ['batch-pkcs8']), + accounts: accounts.map((account) => ({ + address: account.address, + meta: account.meta + })) + }; + } + public createFromJson (json: KeyringPair$Json, meta: KeyringPair$Meta = {}): KeyringPair { return this.keyring.createFromJson({ ...json, meta: { ...(json.meta || {}), meta } }); } @@ -310,6 +329,14 @@ export class Keyring extends Base implements KeyringStruct { return pair; } + public restoreAccounts (json: EncryptedJson): void { + const accounts: KeyringJson[] = JSON.parse(u8aToString(jsonDecrypt(json))) as KeyringJson[]; + + accounts.forEach((account) => { + this.loadAccount(account, accountKey(account.address)); + }); + } + public saveAccount (pair: KeyringPair, password?: string): KeyringPair$Json { this.addTimestamp(pair); diff --git a/packages/ui-keyring/src/types.ts b/packages/ui-keyring/src/types.ts index a0e237e5..62606488 100644 --- a/packages/ui-keyring/src/types.ts +++ b/packages/ui-keyring/src/types.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { KeyringInstance as BaseKeyringInstance, KeyringOptions as KeyringOptionsBase, KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '@polkadot/keyring/types'; +import type { EncryptedJson } from '@polkadot/util-crypto/json/types'; import type { KeypairType } from '@polkadot/util-crypto/types'; import type { AddressSubject, SingleAddress } from './observable/types'; @@ -30,6 +31,10 @@ export interface KeyringJson { meta: KeyringJson$Meta; } +export interface KeyringPairs$Json extends EncryptedJson { + accounts: KeyringJson[]; +} + export interface KeyringStore { all: (cb: (key: string, value: KeyringJson) => void) => void; get: (key: string, cb: (value: KeyringJson) => void) => void; @@ -70,6 +75,7 @@ export interface KeyringStruct { addPair: (pair: KeyringPair, password: string) => CreateResult; addUri: (suri: string, password?: string, meta?: KeyringPair$Meta, type?: KeypairType) => CreateResult; backupAccount: (pair: KeyringPair, password: string) => KeyringPair$Json; + backupAccounts: (addresses: string[]) => Promise createFromUri (suri: string, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair; decodeAddress: (key: string | Uint8Array) => Uint8Array; encodeAddress: (key: string | Uint8Array) => string;